diff --git a/.drone.yml b/.drone.yml index 0dda1d453ce88..d96eb94e0e1b4 100644 --- a/.drone.yml +++ b/.drone.yml @@ -39,7 +39,7 @@ name: push-build-linux-amd64 environment: BUILDBOX_VERSION: teleport14 GID: "1000" - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 UID: "1000" trigger: event: @@ -155,7 +155,7 @@ name: push-build-linux-386 environment: BUILDBOX_VERSION: teleport14 GID: "1000" - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 UID: "1000" trigger: event: @@ -269,7 +269,7 @@ name: push-build-linux-amd64-fips environment: BUILDBOX_VERSION: teleport14 GID: "1000" - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 UID: "1000" trigger: event: @@ -387,7 +387,7 @@ name: push-build-windows-amd64 environment: BUILDBOX_VERSION: teleport14 GID: "1000" - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 UID: "1000" trigger: event: @@ -1042,7 +1042,7 @@ name: push-build-linux-arm environment: BUILDBOX_VERSION: teleport14 GID: "1000" - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 UID: "1000" trigger: event: @@ -1479,7 +1479,7 @@ type: kubernetes name: build-linux-amd64-centos7 environment: BUILDBOX_VERSION: teleport14 - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 trigger: event: include: @@ -1688,7 +1688,7 @@ type: kubernetes name: build-linux-amd64-centos7-fips environment: BUILDBOX_VERSION: teleport14 - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 trigger: event: include: @@ -1896,7 +1896,7 @@ type: kubernetes name: build-linux-amd64 environment: BUILDBOX_VERSION: teleport14 - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 trigger: event: include: @@ -2111,7 +2111,7 @@ type: kubernetes name: build-linux-amd64-fips environment: BUILDBOX_VERSION: teleport14 - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 trigger: event: include: @@ -3411,7 +3411,7 @@ type: kubernetes name: build-linux-386 environment: BUILDBOX_VERSION: teleport14 - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 trigger: event: include: @@ -4237,7 +4237,7 @@ type: kubernetes name: build-linux-arm environment: BUILDBOX_VERSION: teleport14 - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 trigger: event: include: @@ -5566,7 +5566,7 @@ type: kubernetes name: build-windows-amd64 environment: BUILDBOX_VERSION: teleport14 - RUNTIME: go1.20.4 + RUNTIME: go1.20.5 trigger: event: include: @@ -6236,29 +6236,6 @@ steps: path: /var/run - name: dockerconfig path: /root/.docker -- name: Build and push buildbox-fips - image: docker - pull: if-not-exists - commands: - - apk add --no-cache make aws-cli - - chown -R $UID:$GID /go - - aws ecr get-login-password --profile staging --region=us-west-2 | docker login - -u="AWS" --password-stdin 146628656107.dkr.ecr.us-west-2.amazonaws.com - - make -C build.assets buildbox-fips - - docker tag public.ecr.aws/gravitational/teleport-buildbox-fips:$BUILDBOX_VERSION - 146628656107.dkr.ecr.us-west-2.amazonaws.com/gravitational/teleport-buildbox-fips:$BUILDBOX_VERSION-$DRONE_COMMIT_SHA - - docker push 146628656107.dkr.ecr.us-west-2.amazonaws.com/gravitational/teleport-buildbox-fips:$BUILDBOX_VERSION-$DRONE_COMMIT_SHA - - docker logout 146628656107.dkr.ecr.us-west-2.amazonaws.com - - aws ecr-public get-login-password --profile production --region=us-east-1 | docker - login -u="AWS" --password-stdin public.ecr.aws - - docker push public.ecr.aws/gravitational/teleport-buildbox-fips:$BUILDBOX_VERSION - volumes: - - name: awsconfig - path: /root/.aws - - name: dockersock - path: /var/run - - name: dockerconfig - path: /root/.docker - name: Build and push buildbox-arm image: docker pull: if-not-exists @@ -7051,6 +7028,66 @@ image_pull_secrets: # Generated at dronegen/gha.go (main.ghaMultiBuildPipeline) ################################################ +kind: pipeline +type: kubernetes +name: promote-teleport-hardened-amis +trigger: + event: + include: + - promote + target: + include: + - production + - promote-hardened-amis + repo: + include: + - gravitational/* +workspace: + path: /go +clone: + disable: true +steps: +- name: Check out code + image: docker:git + pull: if-not-exists + commands: + - mkdir -pv "/go/src/github.com/gravitational/teleport" + - cd "/go/src/github.com/gravitational/teleport" + - git init + - git remote add origin ${DRONE_REMOTE_URL} + - git fetch origin --tags + - git checkout -qf "${DRONE_COMMIT_SHA}" + - mkdir -m 0700 /root/.ssh && echo "$GITHUB_PRIVATE_KEY" > /root/.ssh/id_rsa && + chmod 600 /root/.ssh/id_rsa + - ssh-keyscan -H github.com > /root/.ssh/known_hosts 2>/dev/null && chmod 600 /root/.ssh/known_hosts + - git submodule update --init e + - mkdir -pv /go/cache + - rm -f /root/.ssh/id_rsa + environment: + GITHUB_PRIVATE_KEY: + from_secret: GITHUB_PRIVATE_KEY +- name: Delegate build to GitHub + image: golang:1.18-alpine + pull: if-not-exists + commands: + - cd "/go/src/github.com/gravitational/teleport/build.assets/tooling" + - 'go run ./cmd/gh-trigger-workflow -owner ${DRONE_REPO_OWNER} -repo teleport.e + -tag-workflow -timeout 2h30m0s -workflow promote-teleport-hardened-amis.yaml -workflow-ref=${DRONE_TAG} + -input oss-teleport-repo=${DRONE_REPO} -input oss-teleport-ref=${DRONE_TAG} -input + "release-source-tag=${DRONE_TAG}" ' + environment: + GHA_APP_KEY: + from_secret: GITHUB_WORKFLOW_APP_PRIVATE_KEY +image_pull_secrets: +- DOCKERHUB_CREDENTIALS + +--- +################################################ +# Generated using dronegen, do not edit by hand! +# Use 'make dronegen' to update. +# Generated at dronegen/gha.go (main.ghaMultiBuildPipeline) +################################################ + kind: pipeline type: kubernetes name: promote-teleport-kube-agent-updater-oci-images @@ -8420,7 +8457,9 @@ clone: depends_on: - clean-up-previous-build - build-linux-amd64-deb +- build-linux-amd64-fips-deb - build-linux-arm64-deb +- build-linux-arm-deb steps: - name: Check out code image: docker:git @@ -8462,6 +8501,68 @@ image_pull_secrets: # Generated at dronegen/gha.go (main.ghaMultiBuildPipeline) ################################################ +kind: pipeline +type: kubernetes +name: build-teleport-hardened-amis +trigger: + event: + include: + - tag + ref: + include: + - refs/tags/v* + repo: + include: + - gravitational/* +workspace: + path: /go +clone: + disable: true +depends_on: +- clean-up-previous-build +- build-linux-amd64-deb +- build-linux-amd64-fips-deb +steps: +- name: Check out code + image: docker:git + pull: if-not-exists + commands: + - mkdir -pv "/go/src/github.com/gravitational/teleport" + - cd "/go/src/github.com/gravitational/teleport" + - git init + - git remote add origin ${DRONE_REMOTE_URL} + - git fetch origin --tags + - git checkout -qf "${DRONE_COMMIT_SHA}" + - mkdir -m 0700 /root/.ssh && echo "$GITHUB_PRIVATE_KEY" > /root/.ssh/id_rsa && + chmod 600 /root/.ssh/id_rsa + - ssh-keyscan -H github.com > /root/.ssh/known_hosts 2>/dev/null && chmod 600 /root/.ssh/known_hosts + - git submodule update --init e + - mkdir -pv /go/cache + - rm -f /root/.ssh/id_rsa + environment: + GITHUB_PRIVATE_KEY: + from_secret: GITHUB_PRIVATE_KEY +- name: Delegate build to GitHub + image: golang:1.18-alpine + pull: if-not-exists + commands: + - cd "/go/src/github.com/gravitational/teleport/build.assets/tooling" + - 'go run ./cmd/gh-trigger-workflow -owner ${DRONE_REPO_OWNER} -repo teleport.e + -tag-workflow -timeout 2h30m0s -workflow release-teleport-hardened-amis.yaml -workflow-ref=${DRONE_TAG} + -input oss-teleport-repo=${DRONE_REPO} -input oss-teleport-ref=${DRONE_TAG} ' + environment: + GHA_APP_KEY: + from_secret: GITHUB_WORKFLOW_APP_PRIVATE_KEY +image_pull_secrets: +- DOCKERHUB_CREDENTIALS + +--- +################################################ +# Generated using dronegen, do not edit by hand! +# Use 'make dronegen' to update. +# Generated at dronegen/gha.go (main.ghaMultiBuildPipeline) +################################################ + kind: pipeline type: kubernetes name: build-teleport-kube-agent-updater-oci-images @@ -16996,6 +17097,7 @@ depends_on: - teleport-container-images-branch-promote - publish-os-package-repos - promote-teleport-oci-distroless-images +- promote-teleport-hardened-amis - promote-teleport-kube-agent-updater-oci-images steps: - name: Check if commit is tagged @@ -17106,6 +17208,6 @@ image_pull_secrets: - DOCKERHUB_CREDENTIALS --- kind: signature -hmac: c12537f0b20719e1d7b3247410ec676e00d60db9c892bdaf02b08f13b0c224d0 +hmac: d3185434ba38b96a9cbf435a59a3ab0d7e4d3ef6ef39a198164e0e2198f1286d ... diff --git a/.github/ISSUE_TEMPLATE/webtestplan.md b/.github/ISSUE_TEMPLATE/webtestplan.md index 898e1b34ea158..6a6791fefb40e 100644 --- a/.github/ISSUE_TEMPLATE/webtestplan.md +++ b/.github/ISSUE_TEMPLATE/webtestplan.md @@ -572,8 +572,6 @@ Use Discover Wizard to enroll new resources and access them: - Run the program: `$ mc` - Resize Teleport Connect to see if the panels resize with it - [ ] Verify that the tab automatically closes on `$ exit` command. - - [ ] Execute `tsh ssh nonexistent-node` in the command bar. Verify that you see a new tab with an - error from tsh ssh. - Kubernetes access - [ ] Open a new kubernetes tab, run `echo $KUBECONFIG` and check if it points to the file within Connect's app data directory. - [ ] Close the tab and open it again (to the same resource). Verify if the kubeconfig path didn't change. @@ -634,23 +632,24 @@ Use Discover Wizard to enroll new resources and access them: - [ ] Click "Add another cluster", provide an address to a new cluster and submit the form. Close the modal when asked for credentials. Verify that the cluster was still added and is visible in the profile selector. -- Command bar & autocomplete - - Do the steps for the root cluster, then switch to a leaf cluster and repeat them. - - [ ] Verify that the autocomplete for tsh ssh filters SSH logins and autocompletes them. - - [ ] Verify that the autocomplete for tsh ssh filters SSH hosts by name and label and - autocompletes them. - - [ ] Verify that launching an invalid tsh ssh command shows the error in a new tab. - - [ ] Verify that launching a valid tsh ssh command opens a new tab with the session opened. - - [ ] Verify that the autocomplete for tsh proxy db filters databases by name and label and - autocompletes them. - - [ ] Verify that launching a tsh proxy db command opens a new local shell with the command - running. - - [ ] Verify that the autocomplete for tsh ssh doesn't break when you cut/paste commands in - various points. - - [ ] Verify that manually typing out what the autocomplete would suggest doesn't break the - command bar. - - [ ] Verify that launching any other command that's not supported by the autocomplete opens a - new local shell with that command running. +- Search bar + - [ ] Verify that you can connect to all three resources types on root clusters and leaf + clusters. + - [ ] Verify that picking a resource filter and a cluster filter at the same time works as + expected. + - [ ] Verify that connecting to a resource from a different root cluster switches to the + workspace of that root cluster. + - Shut down a root cluster. + - [ ] Verify that attempting to search returns "Some of the search results are incomplete" in + the search bar. + - [ ] Verify that clicking "Show details" next to the error message and then closing the modal + by clicking one of the buttons or by pressing Escape does not close the search bar. + - Log in as a user with a short TTL. Make sure you're not logged in to any other cluster. Wait for + the cert to expire. Enter a search term that usually returns some results. + - [ ] Relogin when asked. Verify that the search bar is not collapsed and shows search + results. + - [ ] Close the login modal instead of logging in. Verify that the search bar is not collapsed + and shows "No matching results found". - Resilience when resources become unavailable - DocumentCluster - For each scenario, create at least one DocumentCluster tab for each available resource kind. @@ -701,7 +700,8 @@ Use Discover Wizard to enroll new resources and access them: - [ ] Verify that closing the login modal without logging in shows an appropriate error. - Log in, create a db connection, then remove access to that db server for that user; wait for the cert to expire, then attempt to make a connection through the proxy; log in. - - [ ] Verify that the db tab shows an appropriate error. + - [ ] Verify that psql shows an appropriate access denied error ("access to db denied. User + does not have permissions. Confirm database user and name"). - Log in, open a cluster tab, wait for the cert to expire. Switch from a servers view to databases view. - [ ] Verify that a login modal was shown. diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5fc42240a6a7f..eb408b1227096 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,8 +11,6 @@ updates: - dependency-name: github.com/gravitational/ttlmap # Breaks backwards compatibility - dependency-name: github.com/go-webauthn/webauthn - # TODO(greedy52): Update mongo-driver and fix API changes. - - dependency-name: go.mongodb.org/mongo-driver # Must be kept in-sync with libbpf - dependency-name: github.com/aquasecurity/libbpfgo # Forked/replaced dependencies diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000000000..cca83e1e3482a --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,122 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base" + ], + "enabledManagers": ["gomod", "cargo"], + "reviewers": ["codingllama", "jentfoo", "rosstimothy", "zmb3"], + "branchConcurrentLimit": 10, + "prConcurrentLimit": 10, + "prHourlyLimit": 0, + "packageRules": [ + { + "matchManagers": ["gomod"], + "postUpdateOptions": ["gomodTidy"], + "enabled": true, + "matchFiles": ["go.mod"], + "groupName": "Teleport - Go" + }, + { + "matchManagers": ["gomod"], + "enabled": false, + "matchFiles": ["go.mod"], + "groupName": "Teleport - Go", + "packageNames": [ + "github.com/alecthomas/kingpin/v2", + "github.com/aquasecurity/libbpfgo", + "github.com/coreos/go-oidc", + "github.com/go-mysql-org/go-mysql", + "github.com/go-redis/redis/v9", + "github.com/go-webauthn/webauthn", + "github.com/gogo/protobuf", + "github.com/gravitational/ttlmap", + "github.com/julienschmidt/httprouter", + "github.com/keys-pub/go-libfido2", + "github.com/microsoft/go-mssqldb", + "github.com/vulcand/predicate", + "go.mongodb.org/mongo-driver", + "golang.org/x/crypto" + ] + }, + { + "matchManagers": ["gomod"], + "postUpdateOptions": ["gomodTidy"], + "enabled": true, + "matchFiles": ["api/go.mod"], + "groupName": "Teleport API" + }, + { + "matchManagers": ["cargo"], + "enabled": true, + "matchFiles": ["Cargo.toml"], + "groupName": "Teleport - Rust" + }, + { + "matchManagers": ["cargo"], + "enabled": true, + "matchFiles": ["lib/srv/desktop/rdp/rdpclient/Cargo.toml"], + "groupName": "RDP Client" + }, + { + "matchManagers": ["gomod"], + "postUpdateOptions": ["gomodTidy"], + "enabled": true, + "matchFiles": ["assets/aws/go.mod"], + "groupName": "Assets - AWS ", + "excludePackageNames": [ + "github.com/alecthomas/kingpin/v2" + ] + }, + { + "matchManagers": ["gomod"], + "enabled": false, + "matchFiles": ["assets/aws/go.mod"], + "groupName": "Assets - AWS ", + "packageNames": [ + "github.com/alecthomas/kingpin/v2" + ] + }, + { + "matchManagers": ["gomod"], + "postUpdateOptions": ["gomodTidy"], + "enabled": true, + "matchFiles": ["assets/backport/go.mod"], + "groupName": "Assets - Backport" + }, + { + "matchManagers": ["gomod"], + "postUpdateOptions": ["gomodTidy"], + "enabled": true, + "matchFiles": ["build.assets/tooling/go.mod"], + "groupName": "Build Assets - Tooling" + }, + { + "matchManagers": ["gomod"], + "enabled": false, + "matchFiles": ["build.assets/tooling/go.mod"], + "groupName": "Build Assets - Tooling", + "packageNames": [ + "github.com/alecthomas/kingpin/v2" + ] + }, + { + "matchManagers": ["gomod"], + "postUpdateOptions": ["gomodTidy"], + "enabled": true, + "matchFiles": ["integrations/kube-agent-updater/go.mod"], + "groupName": "Integrations - Kube Updater" + } + ], + "ignoreDeps": ["dockerfile"], + "ignorePaths": [ + ".drone.yml", + ".github/actions", + ".github/services", + ".github/workflows", + "assets/loadtest", + "docker", + "examples", + "package.json", + "web" + ] +} diff --git a/.github/workflows/check-devbox-bypass.yaml b/.github/workflows/check-devbox-bypass.yaml new file mode 100644 index 0000000000000..24db1964cc9cf --- /dev/null +++ b/.github/workflows/check-devbox-bypass.yaml @@ -0,0 +1,26 @@ +name: Check Devbox +run-name: Check Devbox - ${{ github.run_id }} - @${{ github.actor }} + +on: + pull_request: + paths-ignore: + - 'devbox.json' + - 'devbox.lock' + - 'build.assets/flake/**' + merge_group: + paths-ignore: + - 'devbox.json' + - 'devbox.lock' + - 'build.assets/flake/**' + +jobs: + check-devbox: + if: ${{ !startsWith(github.head_ref, 'dependabot/') }} + name: Check Devbox + runs-on: ubuntu-latest + + permissions: + contents: none + + steps: + - run: 'echo "No changes to verify"' diff --git a/.github/workflows/check-devbox.yaml b/.github/workflows/check-devbox.yaml new file mode 100644 index 0000000000000..88e6cb43496a3 --- /dev/null +++ b/.github/workflows/check-devbox.yaml @@ -0,0 +1,34 @@ +name: Check Devbox +run-name: Check Devbox - ${{ github.run_id }} - @${{ github.actor }} + +on: + pull_request: + paths: + - 'devbox.json' + - 'devbox.lock' + - 'build.assets/flake/**' + merge_group: + paths: + - 'devbox.json' + - 'devbox.lock' + - 'build.assets/flake/**' + +jobs: + check-devbox: + if: ${{ !startsWith(github.head_ref, 'dependabot/') }} + name: Check Devbox + runs-on: ubuntu-latest + + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install devbox + run: curl -fsSL https://get.jetpack.io/devbox | FORCE=1 bash + + - name: Install devbox dependencies + run: | + devbox install \ No newline at end of file diff --git a/.github/workflows/doc-tests-bypass.yaml b/.github/workflows/doc-tests-bypass.yaml index 4cc3171dc9ca2..dafae0fc02f13 100644 --- a/.github/workflows/doc-tests-bypass.yaml +++ b/.github/workflows/doc-tests-bypass.yaml @@ -16,10 +16,12 @@ on: paths-ignore: - 'docs/**' - 'examples/**' + - 'CHANGELOG.md' merge_group: paths-ignore: - 'docs/**' - - 'examples/**' + - 'examples/**' + - 'CHANGELOG.md' jobs: lint: diff --git a/.github/workflows/doc-tests.yaml b/.github/workflows/doc-tests.yaml index 35517775248da..fa64ce32a32d2 100644 --- a/.github/workflows/doc-tests.yaml +++ b/.github/workflows/doc-tests.yaml @@ -3,12 +3,14 @@ run-name: Lint (Docs) on: pull_request: paths: + - 'CHANGELOG.md' - 'docs/**' - 'examples/**' merge_group: paths: - 'docs/**' - 'examples/**' + - 'CHANGELOG.md' jobs: doc-tests: diff --git a/.github/workflows/renovate.yaml b/.github/workflows/renovate.yaml new file mode 100644 index 0000000000000..494c86a92dfd5 --- /dev/null +++ b/.github/workflows/renovate.yaml @@ -0,0 +1,94 @@ +name: Renovate +on: + workflow_dispatch: + schedule: + - cron: '0 21 * * 0' # At 9:00 PM every Sunday UTC +jobs: + renovate: + name: 'Renovate' + runs-on: ubuntu-latest + steps: + - name: Get token + id: get_token + uses: tibdex/github-app-token@v1 + with: + APP_ID: ${{ vars.PUBLIC_RENOVATE_GHA_APP_ID }} + PRIVATE_KEY: ${{ secrets.PUBLIC_RENOVATE_GHA_PRIVATE_KEY }} + + - name: Checkout + uses: actions/checkout@v3.3.0 + + # This script/action will be moved to a separate action in my work + # immediately following this project. For now it lives here to + # avoid scope creep. + # + # Github can be notoriously difficult to authenticate and talk with. + # There are four different types of authentication. This step + # generates an app JWT token, and an app installation token, for + # other steps that need a specific one. + - name: Install NPM dependencies + run: npm install '@octokit/auth-app' '@actions/github' --force + - name: Generate Github access tokens + uses: actions/github-script@v6.4.1 + id: generate-tokens + env: + APP_ID: ${{ vars.PUBLIC_RENOVATE_GHA_APP_ID }} + PRIVATE_KEY: ${{ secrets.PUBLIC_RENOVATE_GHA_PRIVATE_KEY }} + with: + script: | + const { createAppAuth } = require("@octokit/auth-app"); + const { getOctokit } = require("@actions/github"); + // App authentication, which uses a JWT + const appAuthFunction = createAppAuth({appId: process.env.APP_ID, privateKey: process.env.PRIVATE_KEY}); + const appAuth = await appAuthFunction({ type: "app" }); + // TODO export token via `appAuth.token` + core.setSecret(appAuth.token) + core.setOutput("app-jwt-token", appAuth.token) + const appOctokit = getOctokit(appAuth.token); + // Installation authentication, which uses an installation token + let installationId = process.env["INSTALLATION_ID"]; + if (installationId === undefined) { + try { + // Repo can be specified via `GITHUB_REPOSITORY` env variable + installationId = (await appOctokit.rest.apps.getRepoInstallation(context.repo)).data.id; + } catch (error) { + throw new Error( + "Could not get repo installation to find ID. Is the app installed on this repo?", + { cause: error }, + ); + } + } + const installationToken = (await appOctokit.rest.apps.createInstallationAccessToken({installation_id: installationId})).data.token; + core.setSecret(installationToken) + core.setOutput("app-installation-token", installationToken) + # These two actions will also be moved out to a separate repo after this project is complete + - name: Get app JWT information + uses: actions/github-script@v6.4.1 + id: app-jwt-info + with: + github-token: ${{ steps.generate-tokens.outputs.app-jwt-token }} + script: | + const appSlug = (await github.rest.apps.getAuthenticated()).data.slug; + const appUserName = `${appSlug}[bot]` + core.setOutput("app-username", appUserName); + - name: Get app installation information + uses: actions/github-script@v6.4.1 + id: app-installation-info + env: + APP_USERNAME: ${{ steps.app-jwt-info.outputs.app-username }} + with: + github-token: ${{ steps.generate-tokens.outputs.app-installation-token }} + script: | + const userId = (await github.rest.users.getByUsername({username: process.env.APP_USERNAME})).data.id + core.setOutput("user-id", userId); + core.setOutput("user-email", `${userId}+${process.env.APP_USERNAME}@users.noreply.github.com`); + - name: Renovate + uses: renovatebot/github-action@v36.0.0 + env: + LOG_LEVEL: 'debug' + RENOVATE_USERNAME: ${{ steps.app-jwt-info.outputs.app-username }} + RENOVATE_GIT_AUTHOR: "${{ steps.app-jwt-info.outputs.app-username }} <${{ steps.app-installation-info.outputs.user-email }}>" + RENOVATE_REPOSITORIES: ${{ github.repository }} + with: + token: ${{ steps.generate-tokens.outputs.app-installation-token }} + configurationFile: .github/renovate.json diff --git a/.github/workflows/unit-tests-integrations-bypass.yaml b/.github/workflows/unit-tests-integrations-bypass.yaml index 9cefbd4867465..22b1559a4272c 100644 --- a/.github/workflows/unit-tests-integrations-bypass.yaml +++ b/.github/workflows/unit-tests-integrations-bypass.yaml @@ -1,5 +1,5 @@ # This workflow is required to ensure that required Github check passes even if -# the actual "Unit Tests (Operator)" workflow skipped due to path filtering. Otherwise +# the actual "Unit Tests (Integrations)" workflow skipped due to path filtering. Otherwise # it will stay forever pending. # # See "Handling skipped but required checks" for more info: diff --git a/.github/workflows/unit-tests-integrations.yaml b/.github/workflows/unit-tests-integrations.yaml index 2c00c1d4c4082..4202481f69f5e 100644 --- a/.github/workflows/unit-tests-integrations.yaml +++ b/.github/workflows/unit-tests-integrations.yaml @@ -43,9 +43,6 @@ jobs: container: image: ghcr.io/gravitational/teleport-buildbox:teleport14 options: --cap-add=SYS_ADMIN --privileged - env: - TELEPORT_GET_VERSION: v12.1.0 - TELEPORT_ENTERPRISE_LICENSE: ${{ secrets.TELEPORT_ENTERPRISE_LICENSE }} steps: - name: Checkout Teleport @@ -54,6 +51,9 @@ jobs: - name: Prepare workspace uses: ./.github/actions/prepare-workspace + - name: Build teleport binaries + run: make build/tctl build/teleport build/tsh && echo "$PWD/build" >> "$GITHUB_PATH" + - name: Run access plugin tests run: make test-access-integrations timeout-minutes: 5 diff --git a/CHANGELOG.md b/CHANGELOG.md index 707ea6248beb4..ae61d5339f549 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,7 +102,8 @@ cluster. This will allow users to view the OpenSSH nodes in Web UI and using `tsh ls` and use RBAC to control access to them. -See updated OpenSSH integration guide: https://goteleport.com/docs/ver/13.x/server-access/guides/openssh/. +See the updated [OpenSSH integration +guide](docs/pages/server-access/guides/openssh.mdx). ### Cross-cluster search for Teleport Connect @@ -194,7 +195,8 @@ create users and assign them invalid roles. In Teleport 13 this is a hard error. Quay.io registry was deprecated in Teleport 11 and starting with Teleport 13, Teleport container images are no longer being published to it. -Users should use the public ECR registry: https://goteleport.com/docs/installation/#docker. +Users should use the [public ECR +registry](https://gallery.ecr.aws/gravitational). #### Helm chart uses `distroless`-based container image by default @@ -234,7 +236,7 @@ This release of Teleport contains multiple improvements and bug fixes. * Fixed issue where Github SSO would fail if a user is a part of more than 30 teams. [#25098](https://github.com/gravitational/teleport/pull/25098) * Fixed issue with `tsh login` with "required" hardware key policy returning "policy not met" error. [#24956](https://github.com/gravitational/teleport/pull/24956) * Improved device trust logging and error reporting. [#24912](https://github.com/gravitational/teleport/pull/24912) - * Detect and warn about RPID changes when using webautn. [#25289](https://github.com/gravitational/teleport/pull/25289) + * Detect and warn about RPID changes when using WebAuthn. [#25289](https://github.com/gravitational/teleport/pull/25289) * Access Management * Fixed issue with running install script on macOS for enterprise clusters. [#25076](https://github.com/gravitational/teleport/pull/25076) * Server Access @@ -502,7 +504,7 @@ This release of Teleport contains multiple security fixes, improvements and bug * Added support for assuming roles in `tsh proxy aws`. [#21990](https://github.com/gravitational/teleport/pull/21990) * Added early feedback for successful security key taps in `tsh`. [#21780](https://github.com/gravitational/teleport/pull/21780) * Added device lock support. [#21751](https://github.com/gravitational/teleport/pull/21751) -* Added suppport for security contexts in `teleport-kube-agent` Helm chart. [#21535](https://github.com/gravitational/teleport/pull/21535) +* Added support for security contexts in `teleport-kube-agent` Helm chart. [#21535](https://github.com/gravitational/teleport/pull/21535) * Updated `tsh version` command to display client version only via `--client` flag. [#22167](https://github.com/gravitational/teleport/pull/22167) * Updated install script to use enterprise packages for enterprise clusters. [#22109](https://github.com/gravitational/teleport/pull/22109) * Updated install script to use deb/rpm repositories. [#22108](https://github.com/gravitational/teleport/pull/22108) @@ -529,7 +531,7 @@ This release of Teleport contains a security fix as well as multiple improvement * Fixed issue with invalid role template namespaces leading to cluster lockouts. [#21573](https://github.com/gravitational/teleport/pull/21573) * Fixed issue with Teleport Connect failing to recognize logged in user sometimes. [#21467](https://github.com/gravitational/teleport/pull/21467) * Fixed issue with the back button not working in Web UI navigation. [#21236](https://github.com/gravitational/teleport/pull/21236) -* Fixed issue with Web UI SSH player having scrollbars. [#20868](https://github.com/gravitational/teleport/pull/20868) +* Fixed issue with Web UI SSH player having scroll bars. [#20868](https://github.com/gravitational/teleport/pull/20868) * Added support for `tsh request search --kind=pod` command. [#21456](https://github.com/gravitational/teleport/pull/21456) * Updated `tsh db configure create` to require flag for dynamic resources matching. [#21395](https://github.com/gravitational/teleport/pull/21395) * Improved reconnect stability after Database Service restart. [#21635](https://github.com/gravitational/teleport/pull/21635) @@ -605,9 +607,8 @@ The “teleport-cluster” Helm chart underwent significant refactoring in Telep deployments and the new “scratch” chart mode makes it easier to provide a custom Teleport config. -“Custom” mode users should follow the migration guide: - -https://goteleport.com/docs/deploy-a-cluster/helm-deployments/migration-v12/ +“Custom” mode users should follow the [migration +guide](./docs/pages/deploy-a-cluster/helm-deployments/migration-v12.mdx). ### Dropped support for SHA1 in Server Access @@ -632,10 +633,9 @@ Teleport 12 before upgrading. #### Helm charts The teleport-cluster Helm chart underwent significant changes in Teleport 12. To -upgrade from an older version of the Helm chart deployed in “custom” mode, use -the following migration guide: - -https://goteleport.com/docs/ver/12.x/deploy-a-cluster/helm-deployments/migration-v12/ +upgrade from an older version of the Helm chart deployed in “custom” mode, +follow +the [migration guide](./docs/pages/deploy-a-cluster/helm-deployments/migration-v12.mdx). Additionally, PSPs are removed from the chart when installing on Kubernetes 1.23 and higher to account for the deprecation/removal of PSPs by Kubernetes. @@ -751,8 +751,9 @@ Visit the individual repositories to find out more and see usage examples: - https://github.com/teleport-actions/auth - https://github.com/teleport-actions/auth-k8s -For a more in-depth guide, see our refreshed documentation for using Teleport with -GitHub Actions at https://goteleport.com/docs/machine-id/guides/github-actions/ +For a more in-depth guide, see our +[documentation](./docs/pages/machine-id/guides/github-actions.mdx) for using +Teleport with GitHub Actions. ### Secure certificate mapping for Desktop Access @@ -853,7 +854,7 @@ window. * Fixed issue with using desktop access with Windows 10. [#19504](https://github.com/gravitational/teleport/pull/19504) * Fixed issue with `session.start` events being overwritten by `session.exec` events. [#19497](https://github.com/gravitational/teleport/pull/19497) * Fixed issue with `tsh login --format kubernetes` not setting SNI info. [#19433](https://github.com/gravitational/teleport/pull/19433) -* Fixed issue with websockets not working via app access if the upstream web server is using HTTP/2. [#19423](https://github.com/gravitational/teleport/pull/19423) +* Fixed issue with WebSockets not working via app access if the upstream web server is using HTTP/2. [#19423](https://github.com/gravitational/teleport/pull/19423) * Fixed TLS routing in insecure mode. [#19410](https://github.com/gravitational/teleport/pull/19410) * Fixed issue with connecting to ElastiCache 7.0.4 in database access. [#19400](https://github.com/gravitational/teleport/pull/19400) * Fixed issue with SAML connector validation calling descriptor URL prior to authz checks. [#19317](https://github.com/gravitational/teleport/pull/19317) @@ -1005,9 +1006,8 @@ Teleport 11 clients (such as tsh or Connect) support storing their private key material on Yubikey devices instead of filesystem which helps prevent credentials exfiltration attacks. -See how to enable it in this guide: - -https://goteleport.com/docs/access-controls/guides/hardware-key-support/ +See how to enable it in the +[documentation](./docs/pages/access-controls/guides/hardware-key-support.mdx): Hardware-backed private keys is an enterprise only feature, and is currently supported for server access only. @@ -1021,8 +1021,8 @@ editing files on remote systems. The following guides explain how to use IDEs to connect to a remote machine via Teleport: -https://goteleport.com/docs/server-access/guides/vscode/ -https://goteleport.com/docs/server-access/guides/jetbrains-sftp/ +- [VS Code](./docs/pages/server-access/guides/vscode.mdx) +- [JetBrains](./docs/pages/server-access/guides/jetbrains-sftp.mdx) In addition, Teleport 11 clients will use SFTP protocol for file transfer under the hood instead of the obsolete scp protocol. Server-side scp is still @@ -1051,8 +1051,9 @@ Teleport agents running on Azure VMs will now automatically import Azure tags to label resources. Teleport database access now supports auto-discovery for Azure-hosted PostgreSQL -and MySQL databases. See the updated Azure guide for more details: -https://goteleport.com/docs/ver/11.0/database-access/guides/azure-postgres-mysql/. +and MySQL databases. See the [Azure +guide](docs/pages/database-access/guides/azure-postgres-mysql.mdx) for more +details. In addition, Teleport database access will now use Azure AD managed identity authentication for Azure-hosted SQL Server databases. @@ -1112,8 +1113,8 @@ redirect_url = [ "http://example.com" ] #### Deprecated Quay.io registry Starting with Teleport 11, Quay.io as a container registry has been deprecated. -Customers should use the new AWS ECR registry to pull Teleport Docker images: -https://goteleport.com/docs/installation/#docker. +Customers should use the new AWS ECR registry to pull [Teleport Docker +images](./docs/pages/installation.mdx#docker). Quay.io registry support will be removed in a future release. @@ -1122,7 +1123,7 @@ Quay.io registry support will be removed in a future release. In Teleport 11, old deb/rpm repositories (deb.releases.teleport.dev and rpm.releases.teleport.dev) have been deprecated. Customers should use the new repositories (apt.releases.teleport.dev and yum.releases.teleport.dev) to -install Teleport: https://goteleport.com/docs/installation/#linux. +[install Teleport](docs/pages/installation.mdx#linux). Support for our old deb/rpm repositories will be removed in a future release. @@ -1186,7 +1187,7 @@ Teleport 10 introduces passwordless support to your clusters. To use passwordles users may register a security key with resident credentials or use a built-in authenticator, like Touch ID. -See https://goteleport.com/docs/access-controls/guides/passwordless/. +See the [documentation](./docs/pages/access-controls/guides/passwordless.mdx). ### Resource Access Requests (Preview) @@ -1238,8 +1239,8 @@ Teleport 10 can be configured to automatically create Linux host users upon login without having to use Teleport's PAM integration. Users can be added to specific Linux groups and assigned appropriate “sudoer” privileges. -To learn more about configuring automatic user provisioning read the guide: -https://goteleport.com/docs/server-access/guides/host-user-creation/. +To learn more about configuring automatic user provisioning read the +[documentation](docs/pages/server-access/guides/host-user-creation.mdx). ### Audit Logging for Microsoft SQL Server database access @@ -1251,8 +1252,8 @@ to other supported database protocols. Teleport database access for SQL Server remains in Preview mode with more UX improvements coming in future releases. -Refer to the guide to set up access to a SQL Server with Active Directory -authentication: https://goteleport.com/docs/database-access/guides/sql-server-ad/. +Refer to [the guide](docs/pages/database-access/guides/sql-server-ad.mdx) to set +up access to a SQL Server with Active Directory authentication. ### Snowflake database access (Preview) @@ -1261,8 +1262,8 @@ set up access to Snowflake databases through Teleport for their users with standard database access features like role-based access control and audit logging, including query activity. -Connect your Snowflake database to Teleport following this guide: -https://goteleport.com/docs/database-access/guides/snowflake/. +Connect your Snowflake database to Teleport following the +[documentation](docs/pages/database-access/guides/snowflake.mdx). ### Elasticache/MemoryDB database access (Preview) @@ -1271,8 +1272,8 @@ this integration by adding native support for AWS-hosted Elasticache and MemoryDB, including auto-discovery and automatic credential management in some deployment configurations. -Learn more about it in this guide: -https://goteleport.com/docs/database-access/guides/redis-aws/. +Learn more about it in the [documentation]( +docs/pages/database-access/guides/redis-aws.mdx). ### Teleport Connect for server and database access (Preview) @@ -1288,8 +1289,8 @@ https://goteleport.com/download/. In Teleport 10 we’ve added database access support to Machine ID. Applications can use Machine ID to access databases protected by Teleport. -You can find Machine ID guide for database access in the documentation: -https://goteleport.com/docs/machine-id/guides/databases/. +You can find Machine ID guide for database access in the +[documentation](docs/pages/machine-id/guides/databases.mdx). ### Breaking changes @@ -1302,8 +1303,8 @@ Teleport 10 agents will now refuse to start if they detect that the Auth Service is more than one major version behind them. You can use the `--skip-version-check` flag to bypass the version check. -Take a look at component compatibility guarantees in the documentation: -https://goteleport.com/docs/setup/operations/upgrading/#component-compatibility. +Take a look at component compatibility guarantees in the +[documentation](docs/pages/management/operations/upgrading.mdx). #### HTTP_PROXY for reverse tunnels @@ -1312,8 +1313,9 @@ This may result in reverse tunnel agents not being able to re-establish connections if the HTTP proxy is set in their environment and does not allow connections to the Teleport Proxy Service. -Refer to the following documentation section for more details: -https://goteleport.com/docs/setup/reference/networking/#http-connect-proxies. +Refer to the +[documentation](docs/pages/reference/networking.mdx#http-connect-proxies) +for more details. #### New APT repos @@ -1323,8 +1325,8 @@ repositories have been backfilled with Teleport versions starting from 6.2.31 and we recommend upgrading to them. The old repositories will be maintained for the foreseeable future. -See updated installation instructions: -https://goteleport.com/docs/server-access/getting-started/#step-14-install-teleport-on-your-linux-host. +See the [installation +instructions](docs/pages/server-access/getting-started.mdx#step-14-install-teleport-on-your-linux-host). #### Removed “tctl access ls” @@ -1339,8 +1341,9 @@ pod in order to join a session. Teleport 10 relaxes this requirement. Joining sessions remains deny-by-default but now only `join_sessions` statements are checked for session join RBAC. -See the Moderated Sessions guide for more details: -https://goteleport.com/docs/access-controls/guides/moderated-sessions/. +See the [Moderated Sessions +guide](docs/pages/access-controls/guides/moderated-sessions.mdx) for more +details. #### GitHub connectors @@ -1358,8 +1361,8 @@ for example: s3://bucket/path?region=us-east-1&use_fips_endpoint=false ``` -See the S3/DynamoDB backends documentation for more information: -https://goteleport.com/docs/setup/reference/backends/#s3. +See the [S3/DynamoDB backend +documentation](docs/pages/reference/backends.mdx) for more information. ## 9.3.9 @@ -1373,7 +1376,7 @@ order roles are received from the backend. ### Other improvements and fixes -* Fixed issue with per-session MFA swallowing keypresses. [#13822](https://github.com/gravitational/teleport/pull/13822) +* Fixed issue with per-session MFA swallowing key presses. [#13822](https://github.com/gravitational/teleport/pull/13822) * Fixed issue with `tsh db ls -R` now showing allowed users. [#13626](https://github.com/gravitational/teleport/pull/13626) * Fixed vertical and horizontal scroll in desktop access. [#13905](https://github.com/gravitational/teleport/pull/13905) * Fixed issue with invalid query filters forcing `tsh` relogin. [#13747](https://github.com/gravitational/teleport/pull/13747) @@ -1432,7 +1435,7 @@ When setting up agent forwarding on the node, Teleport did not handle unix socke This could have given a potential attacker an opportunity to get Teleport to change arbitrary file permissions to the attacker’s user. -### Websockets CSRF +### WebSockets CSRF When handling websocket requests, Teleport did not verify that the provided Bearer token was generated for the correct user. @@ -1490,9 +1493,9 @@ Teleport 9.3.0 reduces the minimum GLIBC requirement to 2.18 and enforces more secure cipher suites for desktop access. As a result of these changes, desktop access users with desktops running Windows -Server 2012R2 will need to perform -[additional configuration](https://goteleport.com/docs/desktop-access/getting-started/#step-47-configure-a-certificate-for-rdp-connections) -to force Windows to use compatible cipher suites. +Server 2012R2 will need to perform [additional +configuration](docs/pages/desktop-access/getting-started.mdx) to force Windows +to use compatible cipher suites. Windows desktops running Windows Server 2016 and newer will continue to operate normally - no additional configuration is required. @@ -1598,9 +1601,7 @@ Teleport build infrastructure was updated to use Go v1.17.9 to fix CVE-2022-2467 Teleport users can now use PostgreSQL or CockroachDB for storing auth server data. -See the documentation for more information: - -https://goteleport.com/docs/setup/reference/backends/#postgresqlcockroachdb-preview +See the [documentation](docs/pages/reference/backends.mdx) for more information. ### Server-side filtering and pagination @@ -2138,7 +2139,13 @@ Teleport 6.1 contains multiple new features, improvements, and bug fixes. Added support for U2F authentication on every SSH and Kubernetes "connection" (a single `tsh ssh` or `kubectl` call). This is an advanced security feature that protects users against compromises of their on-disk Teleport certificates. Per-session MFA can be enforced cluster-wide or only for some specific roles. -For more details see [Per-Session MFA](https://goteleport.com/docs/access-controls/guides/per-session-mfa) documentation or [RFD 14](https://github.com/gravitational/teleport/blob/master/rfd/0014-session-2FA.md) and [RFD 15](https://github.com/gravitational/teleport/blob/master/rfd/0015-2fa-management.md) for technical details. +For more details see [Per-Session +MFA](docs/pages/access-controls/guides/per-session-mfa.mdx) documentation or +[RFD +14](https://github.com/gravitational/teleport/blob/master/rfd/0014-session-2FA.md) +and [RFD +15](https://github.com/gravitational/teleport/blob/master/rfd/0015-2fa-management.md) +for technical details. #### Dual Authorization Workflows @@ -2210,13 +2217,13 @@ Configure database access following the [Getting Started](./docs/pages/database- * [AWS RDS/Aurora MySQL](./docs/pages/database-access/guides/rds.mdx) * [Self-hosted PostgreSQL](./docs/pages/database-access/guides/postgres-self-hosted.mdx) * [Self-hosted MySQL](./docs/pages/database-access/guides/mysql-self-hosted.mdx) -* [GUI clients](https://goteleport.com/docs/connect-your-client/gui-clients/) +* [GUI clients](docs/pages/connect-your-client/gui-clients.mdx) ##### Resources -To learn more about configuring role-based access control for database access, check out the [RBAC](./docs/pages/database-access/introduction.mdx/) section. +To learn more about configuring role-based access control for database access, check out the [RBAC](./docs/pages/database-access/introduction.mdx) section. -[Architecture](./docs/pages/database-access/introduction.mdx/) provides a more in-depth look at database access internals such as networking and security. +[Architecture](./docs/pages/database-access/introduction.mdx) provides a more in-depth look at database access internals such as networking and security. See [Reference](./docs/pages/database-access/reference.mdx) for an overview of database access related configuration and CLI commands. @@ -2565,7 +2572,7 @@ Enterprise Only: #### Documentation -We've added an [API Reference](https://goteleport.com/docs/api-reference/) to simply developing applications against Teleport. +We've added an [API Guide](docs/pages/api/introduction.mdx) to simply developing applications against Teleport. #### Upgrade Notes @@ -2945,7 +2952,7 @@ To mitigate this issue, upgrade and restart all Teleport proxy processes. This release of Teleport contains a bug fix. -* Fixed a regression in certificate reissuance that could cause nodes to not start. [#3449](https://github.com/gravitational/teleport/pull/3449) +* Fixed a regression in reissuing certificate that could cause nodes to not start. [#3449](https://github.com/gravitational/teleport/pull/3449) ## 4.2.5 @@ -3434,7 +3441,7 @@ Teleport 3.1.1 contains a security fix. We strongly encourage anyone running Tel This is a major Teleport release with a focus on backwards compatibility, stability, and bug fixes. Some of the improvements: * Added support for regular expressions in RBAC label keys and values. [#2161](https://github.com/gravitational/teleport/issues/2161) -* Added support for configurable server side keep-alives. [#2334](https://github.com/gravitational/teleport/issues/2334) +* Added support for configurable server side keepalives. [#2334](https://github.com/gravitational/teleport/issues/2334) * Added support for some `-o` to improve OpenSSH interoperability. [#2330](https://github.com/gravitational/teleport/issues/2330) * Added i386 binaries as well as binaries built with older version of Go to support legacy systems. [#2277](https://github.com/gravitational/teleport/issues/2277) * Added SOCKS5 support to `tsh`. [#1693](https://github.com/gravitational/teleport/issues/1693) diff --git a/Cargo.lock b/Cargo.lock index 60b63a0245704..e6053f451fe97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "synstructure", ] @@ -53,7 +53,7 @@ checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -121,9 +121,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" [[package]] name = "block-buffer" @@ -195,9 +195,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cbindgen" -version = "0.24.3" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb" +checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d" dependencies = [ "clap", "heck", @@ -207,7 +207,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn", + "syn 1.0.107", "tempfile", "toml", ] @@ -403,7 +403,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -433,7 +433,7 @@ checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -462,13 +462,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -533,7 +533,7 @@ checksum = "c8469d0d40519bc608ec6863f1cc88f3f1deee15913f2f3b3e573d81ed38cccc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -651,6 +651,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hmac" version = "0.7.1" @@ -697,12 +703,13 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.3" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ + "hermit-abi 0.3.1", "libc", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -768,9 +775,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.144" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libloading" @@ -796,9 +803,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.3.0" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd550e73688e6d578f0ac2119e32b797a327631a42f9433e59d02e139c8df60d" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" @@ -812,9 +819,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "md-5" @@ -921,13 +928,13 @@ dependencies = [ [[package]] name = "num-derive" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.23", ] [[package]] @@ -980,7 +987,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1079,9 +1086,9 @@ dependencies = [ [[package]] name = "png" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa" +checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -1107,18 +1114,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -1207,7 +1214,7 @@ dependencies = [ name = "rdp-client" version = "0.1.0" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "byteorder", "cbindgen", "env_logger", @@ -1375,16 +1382,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.4" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c348b5dc624ecee40108aa2922fed8bad89d7fcc2b9f8cb18f632898ac4a37f9" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags 1.3.2", - "errno 0.3.0", + "errno 0.3.1", "io-lifetimes", "libc", - "linux-raw-sys 0.3.0", - "windows-sys 0.45.0", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", ] [[package]] @@ -1444,7 +1451,7 @@ checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1556,6 +1563,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -1564,21 +1582,22 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "unicode-xid", ] [[package]] name = "tempfile" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", "redox_syscall", - "rustix 0.37.4", - "windows-sys 0.45.0", + "rustix 0.37.19", + "windows-sys 0.48.0", ] [[package]] @@ -1613,7 +1632,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1693,9 +1712,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.3.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" +checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" dependencies = [ "getrandom 0.2.8", ] @@ -1739,7 +1758,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-shared", ] @@ -1761,7 +1780,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1829,37 +1848,37 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -1868,42 +1887,84 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "x509-parser" version = "0.14.0" diff --git a/Makefile b/Makefile index 8552cdcaebf77..b4e699fe01aef 100644 --- a/Makefile +++ b/Makefile @@ -648,6 +648,10 @@ DIFF_TEST := $(TOOLINGDIR)/bin/difftest $(DIFF_TEST): $(wildcard $(TOOLINGDIR)/cmd/difftest/*.go) cd $(TOOLINGDIR) && go build -o "$@" ./cmd/difftest +RERUN := $(TOOLINGDIR)/bin/rerun +$(RERUN): $(wildcard $(TOOLINGDIR)/cmd/rerun/*.go) + cd $(TOOLINGDIR) && go build -o "$@" ./cmd/rerun + .PHONY: tooling tooling: $(RENDER_TESTS) $(DIFF_TEST) @@ -663,7 +667,7 @@ $(TEST_LOG_DIR): .PHONY: helmunit/installed helmunit/installed: @if ! helm unittest -h >/dev/null; then \ - echo 'Helm unittest plugin is required to test Helm charts. Run `helm plugin install https://github.com/quintush/helm-unittest` to install it'; \ + echo 'Helm unittest plugin is required to test Helm charts. Run `helm plugin install https://github.com/quintush/helm-unittest --version 0.2.11` to install it'; \ exit 1; \ fi @@ -730,7 +734,7 @@ endif # Runs ci tsh tests .PHONY: test-go-tsh test-go-tsh: FLAGS ?= -race -shuffle on -test-go-tsh: SUBJECT ?= github.com/gravitational/teleport/tool/tsh +test-go-tsh: SUBJECT ?= github.com/gravitational/teleport/tool/tsh/... test-go-tsh: $(CGOFLAG_TSH) go test -cover -json -tags "$(PAM_TAG) $(FIPS_TAG) $(LIBFIDO2_TEST_TAG) $(TOUCHID_TAG) $(PIV_TEST_TAG)" $(PACKAGES) $(SUBJECT) $(FLAGS) $(ADDFLAGS) \ | tee $(TEST_LOG_DIR)/unit.json \ @@ -808,6 +812,24 @@ test-teleport-usage: | tee $(TEST_LOG_DIR)/teleport-usage.json \ | ${RENDER_TESTS} +# +# Flaky test detection. Usually run from CI nightly, overriding these default parameters +# This runs the same tests as test-go-unit but repeatedly to try to detect flaky tests. +# +.PHONY: test-go-flaky +FLAKY_RUNS ?= 3 +FLAKY_TIMEOUT ?= 1h +FLAKY_TOP_N ?= 20 +FLAKY_SUMMARY_FILE ?= /tmp/flaky-report.txt +test-go-flaky: FLAGS ?= -race -shuffle on +test-go-flaky: SUBJECT ?= $(shell go list ./... | grep -v -e integration -e tool/tsh -e integrations/operator -e integrations/access -e integrations/lib ) +test-go-flaky: GO_BUILD_TAGS ?= $(PAM_TAG) $(FIPS_TAG) $(BPF_TAG) $(RDPCLIENT_TAG) $(TOUCHID_TAG) $(PIV_TEST_TAG) +test-go-flaky: RENDER_FLAGS ?= -report-by flakiness -summary-file $(FLAKY_SUMMARY_FILE) -top $(FLAKY_TOP_N) +test-go-flaky: test-go-prepare $(RERUN) + $(CGOFLAG) $(RERUN) -n $(FLAKY_RUNS) -t $(FLAKY_TIMEOUT) \ + go test -count=1 -cover -json -tags "$(GO_BUILD_TAGS)" $(SUBJECT) $(FLAGS) $(ADDFLAGS) \ + | $(RENDER_TESTS) $(RENDER_FLAGS) + # # Runs cargo test on our Rust modules. # (a no-op if cargo and rustc are not installed) @@ -911,7 +933,11 @@ lint-go: .PHONY: fix-imports fix-imports: - make -C build.assets/ fix-imports +ifndef TELEPORT_DEVBOX + $(MAKE) -C build.assets/ fix-imports +else + $(MAKE) fix-imports/host +endif .PHONY: fix-imports/host fix-imports/host: @@ -949,6 +975,7 @@ lint-sh: find . -type f \( -name '*.sh' -or -name '*.sh.tmpl' \) -not -path "*/node_modules/*" | xargs \ shellcheck \ --exclude=SC2086 \ + --exclude=SC1091 \ $(SH_LINT_FLAGS) # lint AWS AMI scripts @@ -1164,7 +1191,11 @@ buf/installed: # This target runs in the buildbox container. .PHONY: grpc grpc: +ifndef TELEPORT_DEVBOX $(MAKE) -C build.assets grpc +else + $(MAKE) grpc/host +endif # grpc/host generates GRPC stubs. # Unlike grpc, this target runs locally. @@ -1176,7 +1207,11 @@ grpc/host: protos/all # This target runs in the buildbox container. .PHONY: protos-up-to-date protos-up-to-date: +ifndef TELEPORT_DEVBOX $(MAKE) -C build.assets protos-up-to-date +else + $(MAKE) protos-up-to-date/host +endif # protos-up-to-date/host checks if the generated GRPC stubs are up to date. # Unlike protos-up-to-date, this target runs locally. diff --git a/README.md b/README.md index 2d168344f131b..811598681418e 100644 --- a/README.md +++ b/README.md @@ -107,8 +107,8 @@ Teleport Team If you wish to deploy Teleport inside a Docker container: ``` -# This command will pull the Teleport container image for version 8 -docker pull public.ecr.aws/gravitational/teleport:8 +# This command will pull the Teleport container image for version 13 +docker pull public.ecr.aws/gravitational/teleport:13 ``` View latest tags on [Amazon ECR Public | gravitational/teleport](https://gallery.ecr.aws/gravitational/teleport) @@ -128,7 +128,7 @@ If your intention is to build and deploy for use in a production infrastructure a released tag should be used. The default branch, `master`, is the current development branch for an upcoming major version. Get the latest release tags listed at https://goteleport.com/download/ and then use that tag in the `git clone`. -For example `git clone https://github.com/gravitational/teleport.git -b v9.1.2` gets release v9.1.2. +For example `git clone https://github.com/gravitational/teleport.git -b v13.0.0` gets release v13.0.0. ### Dockerized Build @@ -245,18 +245,6 @@ DEBUG=1 ./build/teleport start -d Keep the server running in this mode, and make your UI changes in `/dist` directory. For instructions about how to update the Web UI, read [the `web` README](web#readme). -#### Updating Web UI assets - -After you commit a change to [the `webapps` -repo](https://github.com/gravitational/webapps), you need to update the Web UI -assets in the `webassets/` git submodule. - -Run `make update-webassets` to update the `webassets` repo and create a PR for -`teleport` to update its git submodule. - -You will need to have the `gh` utility installed on your system for the script -to work. For installation instructions, read the [GitHub CLI installation](https://github.com/cli/cli/releases/latest) documentation. - ### Managing dependencies All dependencies are managed using [Go modules](https://blog.golang.org/using-go-modules). Here are the instructions for some common tasks: @@ -306,6 +294,28 @@ Why is a specific version of a module imported? `go mod graph | grep $modname` +### Devbox Build (experimental) + +**Note**: Devbox support is still experimental. It's very possible things make not work as intended. + +Teleport can be built using [devbox](https://www.jetpack.io/devbox). To use devbox, follow +the instructions to install devbox [here](https://www.jetpack.io/devbox/docs/quickstart/) and +then run: + +`devbox shell` + +This will install Teleport's various build dependencies and drop you into a shell with these +dependencies. From here, you can build Teleport normally. + +#### flake.nix + +A nix flake is located in `build.assets/flake` that allows for installation of Teleport's less +common build tooling. If this flake is updated, run: + +`devbox install` + +in order to make sure the changes in the flake are reflected in the local devbox shell. + ## Why did We Build Teleport? The Teleport creators used to work together at Rackspace. We noticed that most cloud computing users struggle with setting up and configuring infrastructure security because popular tools, while flexible, are complex to understand and expensive to maintain. Additionally, most organizations use multiple infrastructure form factors such as several cloud providers, multiple cloud accounts, servers in colocation, and even smart devices. Some of those devices run on untrusted networks, behind third-party firewalls. This only magnifies complexity and increases operational overhead. @@ -345,4 +355,4 @@ You can see the list of companies who use Teleport in production on the Teleport Teleport was created by [Gravitational, Inc.](https://goteleport.com). We have built Teleport by borrowing from our previous experiences at Rackspace. [Learn more -about Teleport and our history](https://goteleport.com/about/). +about Teleport and our history](https://goteleport.com/about/). \ No newline at end of file diff --git a/api/client/alpn.go b/api/client/alpn.go index 4ccaa402f7e8d..4e94b35e7366c 100644 --- a/api/client/alpn.go +++ b/api/client/alpn.go @@ -63,8 +63,7 @@ type ALPNDialerConfig struct { // ALPNDialer is a ContextDialer that dials a connection to the Proxy Service // with ALPN and SNI configured in the provided TLSConfig. An ALPN connection // upgrade is also performed at the initial connection, if an upgrade is -// required. If the negotiated protocol is a Ping protocol, it will return the -// de-multiplexed connection without the Ping. +// required. type ALPNDialer struct { cfg ALPNDialerConfig } diff --git a/api/client/alpn_conn_upgrade.go b/api/client/alpn_conn_upgrade.go index 4ce254df95548..92c04ef3a0400 100644 --- a/api/client/alpn_conn_upgrade.go +++ b/api/client/alpn_conn_upgrade.go @@ -26,6 +26,7 @@ import ( "net/url" "os" "strings" + "time" "github.com/gravitational/trace" "github.com/sirupsen/logrus" @@ -48,19 +49,28 @@ import ( // In those cases, the Teleport client should make a HTTP "upgrade" call to the // Proxy Service to establish a tunnel for the originally planned traffic to // preserve the ALPN and SNI information. -func IsALPNConnUpgradeRequired(addr string, insecure bool) bool { +func IsALPNConnUpgradeRequired(ctx context.Context, addr string, insecure bool, opts ...DialOption) bool { if result, ok := OverwriteALPNConnUpgradeRequirementByEnv(addr); ok { return result } - netDialer := &net.Dialer{ - Timeout: defaults.DefaultIOTimeout, - } + // Use NewDialer which takes care of ProxyURL, and use a shorter I/O + // timeout to avoid blocking caller. + baseDialer := NewDialer( + ctx, + defaults.DefaultIdleTimeout, + 5*time.Second, + append(opts, + WithInsecureSkipVerify(insecure), + WithALPNConnUpgrade(false), + )..., + ) + tlsConfig := &tls.Config{ NextProtos: []string{string(constants.ALPNSNIProtocolReverseTunnel)}, InsecureSkipVerify: insecure, } - testConn, err := tls.DialWithDialer(netDialer, "tcp", addr, tlsConfig) + testConn, err := tlsutils.TLSDial(ctx, baseDialer, "tcp", addr, tlsConfig) if err != nil { if isRemoteNoALPNError(err) { logrus.Debugf("ALPN connection upgrade required for %q: %v. No ALPN protocol is negotiated by the server.", addr, true) diff --git a/api/client/alpn_conn_upgrade_test.go b/api/client/alpn_conn_upgrade_test.go index 56a5bce36a2c1..e51239019b179 100644 --- a/api/client/alpn_conn_upgrade_test.go +++ b/api/client/alpn_conn_upgrade_test.go @@ -32,6 +32,7 @@ import ( "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/api/fixtures" + "github.com/gravitational/teleport/api/testhelpers" "github.com/gravitational/teleport/api/utils/pingconn" ) @@ -70,10 +71,21 @@ func TestIsALPNConnUpgradeRequired(t *testing.T) { }, } + ctx := context.Background() + forwardProxy, forwardProxyURL := mustStartForwardProxy(t) + for _, test := range tests { t.Run(test.name, func(t *testing.T) { server := mustStartMockALPNServer(t, test.serverProtos) - require.Equal(t, test.expectedResult, IsALPNConnUpgradeRequired(server.Addr().String(), test.insecure)) + t.Run("direct", func(t *testing.T) { + require.Equal(t, test.expectedResult, IsALPNConnUpgradeRequired(ctx, server.Addr().String(), test.insecure)) + }) + + t.Run("with ProxyURL", func(t *testing.T) { + countBeforeTest := forwardProxy.Count() + require.Equal(t, test.expectedResult, IsALPNConnUpgradeRequired(ctx, server.Addr().String(), test.insecure, withProxyURL(forwardProxyURL))) + require.Equal(t, countBeforeTest+1, forwardProxy.Count()) + }) }) } } @@ -160,24 +172,50 @@ func TestALPNConnUpgradeDialer(t *testing.T) { pool.AddCert(server.Certificate()) tlsConfig := &tls.Config{RootCAs: pool} - preDialer := newDirectDialer(0, 5*time.Second) - dialer := newALPNConnUpgradeDialer(preDialer, tlsConfig, test.withPing) - conn, err := dialer.DialContext(ctx, "tcp", addr.Host) - if test.wantError { - require.Error(t, err) - return - } - require.NoError(t, err) - defer conn.Close() - - data := make([]byte, 100) - n, err := conn.Read(data) - require.NoError(t, err) - require.Equal(t, string(data[:n]), "hello") + directDialer := newDirectDialer(0, 5*time.Second) + + t.Run("direct", func(t *testing.T) { + dialer := newALPNConnUpgradeDialer(directDialer, tlsConfig, test.withPing) + conn, err := dialer.DialContext(ctx, "tcp", addr.Host) + if test.wantError { + require.Error(t, err) + return + } + require.NoError(t, err) + defer conn.Close() + + mustReadConnData(t, conn, "hello") + }) + + t.Run("with ProxyURL", func(t *testing.T) { + forwardProxy, forwardProxyURL := mustStartForwardProxy(t) + countBeforeTest := forwardProxy.Count() + + proxyURLDialer := newProxyURLDialer(forwardProxyURL, directDialer) + dialer := newALPNConnUpgradeDialer(proxyURLDialer, tlsConfig, test.withPing) + conn, err := dialer.DialContext(ctx, "tcp", addr.Host) + if test.wantError { + require.Error(t, err) + return + } + require.NoError(t, err) + defer conn.Close() + + mustReadConnData(t, conn, "hello") + require.Equal(t, countBeforeTest+1, forwardProxy.Count()) + }) }) } } +func mustReadConnData(t *testing.T, conn net.Conn, wantText string) { + data := make([]byte, len(wantText)*2) + n, err := conn.Read(data) + require.NoError(t, err) + require.Equal(t, len(wantText), n) + require.Equal(t, string(data[:n]), wantText) +} + type mockALPNServer struct { net.Listener cert tls.Certificate @@ -273,3 +311,20 @@ func mockConnUpgradeHandler(t *testing.T, upgradeType string, write []byte) http } }) } + +func mustStartForwardProxy(t *testing.T) (*testhelpers.ProxyHandler, *url.URL) { + t.Helper() + + listener, err := net.Listen("tcp", "localhost:0") + require.NoError(t, err) + t.Cleanup(func() { + listener.Close() + }) + + url, err := url.Parse("http://" + listener.Addr().String()) + require.NoError(t, err) + + handler := &testhelpers.ProxyHandler{} + go http.Serve(listener, handler) + return handler, url +} diff --git a/api/client/client.go b/api/client/client.go index 46ab883723ae2..41ac90e30bbdf 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -57,6 +57,7 @@ import ( pluginspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/plugins/v1" samlidppb "github.com/gravitational/teleport/api/gen/proto/go/teleport/samlidp/v1" trustpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/trust/v1" + userpreferencespb "github.com/gravitational/teleport/api/gen/proto/go/userpreferences/v1" "github.com/gravitational/teleport/api/internalutils/stream" "github.com/gravitational/teleport/api/metadata" "github.com/gravitational/teleport/api/observability/tracing" @@ -79,6 +80,7 @@ type AuthServiceClient struct { proto.AuthServiceClient assist.AssistServiceClient auditlogpb.AuditLogServiceClient + userpreferencespb.UserPreferencesServiceClient } // Client is a gRPC Client that connects to a Teleport Auth server either @@ -470,9 +472,10 @@ func (c *Client) dialGRPC(ctx context.Context, addr string) error { c.conn = conn c.grpc = AuthServiceClient{ - AuthServiceClient: proto.NewAuthServiceClient(c.conn), - AssistServiceClient: assist.NewAssistServiceClient(c.conn), - AuditLogServiceClient: auditlogpb.NewAuditLogServiceClient(c.conn), + AuthServiceClient: proto.NewAuthServiceClient(c.conn), + AssistServiceClient: assist.NewAssistServiceClient(c.conn), + AuditLogServiceClient: auditlogpb.NewAuditLogServiceClient(c.conn), + UserPreferencesServiceClient: userpreferencespb.NewUserPreferencesServiceClient(c.conn), } c.JoinServiceClient = NewJoinServiceClient(proto.NewJoinServiceClient(c.conn)) @@ -752,6 +755,12 @@ func (c *Client) TrustClient() trustpb.TrustServiceClient { return trustpb.NewTrustServiceClient(c.conn) } +// EmbeddingClient returns an unadorned Embedding client, using the underlying +// Auth gRPC connection. +func (c *Client) EmbeddingClient() assist.AssistEmbeddingServiceClient { + return assist.NewAssistEmbeddingServiceClient(c.conn) +} + // Ping gets basic info about the auth server. func (c *Client) Ping(ctx context.Context) (proto.PingResponse, error) { rsp, err := c.grpc.Ping(ctx, &proto.PingRequest{}) @@ -3903,6 +3912,24 @@ func (c *Client) GetHeadlessAuthentication(ctx context.Context, id string) (*typ return headlessAuthn, nil } +// WatchPendingHeadlessAuthentications creates a watcher for pending headless authentication for the current user. +func (c *Client) WatchPendingHeadlessAuthentications(ctx context.Context) (types.Watcher, error) { + cancelCtx, cancel := context.WithCancel(ctx) + stream, err := c.grpc.WatchPendingHeadlessAuthentications(cancelCtx, &emptypb.Empty{}) + if err != nil { + cancel() + return nil, trail.FromGRPC(err) + } + w := &streamWatcher{ + stream: stream, + ctx: cancelCtx, + cancel: cancel, + eventsC: make(chan types.Event), + } + go w.receiveEvents() + return w, nil +} + // CreateAssistantConversation creates a new conversation entry in the backend. func (c *Client) CreateAssistantConversation(ctx context.Context, req *assist.CreateAssistantConversationRequest) (*assist.CreateAssistantConversationResponse, error) { resp, err := c.grpc.CreateAssistantConversation(ctx, req) @@ -3966,3 +3993,29 @@ func (c *Client) UpdateAssistantConversationInfo(ctx context.Context, in *assist } return nil } + +func (c *Client) GetAssistantEmbeddings(ctx context.Context, in *assist.GetAssistantEmbeddingsRequest) (*assist.GetAssistantEmbeddingsResponse, error) { + result, err := c.EmbeddingClient().GetAssistantEmbeddings(ctx, in) + if err != nil { + return nil, trail.FromGRPC(err) + } + return result, nil +} + +// GetUserPreferences returns the user preferences for a given user. +func (c *Client) GetUserPreferences(ctx context.Context, in *userpreferencespb.GetUserPreferencesRequest) (*userpreferencespb.GetUserPreferencesResponse, error) { + resp, err := c.grpc.GetUserPreferences(ctx, in) + if err != nil { + return nil, trail.FromGRPC(err) + } + return resp, nil +} + +// UpsertUserPreferences creates or updates user preferences for a given username. +func (c *Client) UpsertUserPreferences(ctx context.Context, in *userpreferencespb.UpsertUserPreferencesRequest) error { + _, err := c.grpc.UpsertUserPreferences(ctx, in) + if err != nil { + return trail.FromGRPC(err) + } + return nil +} diff --git a/api/client/contextdialer.go b/api/client/contextdialer.go index 5dc11b63b74e6..e28227c98f9e5 100644 --- a/api/client/contextdialer.go +++ b/api/client/contextdialer.go @@ -48,6 +48,18 @@ type dialConfig struct { // proxyHeaderGetter is used if present to get signed PROXY headers to propagate client's IP. // Used by proxy's web server to make calls on behalf of connected clients. proxyHeaderGetter PROXYHeaderGetter + // proxyURLFunc is a function used to get ProxyURL. Defaults to + // utils.GetProxyURL if not specified. Currently only used in tests to + // overwrite the ProxyURL as httpproxy.FromEnvironment skips localhost + // proxies. + proxyURLFunc func(dialAddr string) *url.URL +} + +func (c *dialConfig) getProxyURL(dialAddr string) *url.URL { + if c.proxyURLFunc != nil { + return c.proxyURLFunc(dialAddr) + } + return utils.GetProxyURL(dialAddr) } // WithInsecureSkipVerify specifies if dialing insecure when using an HTTPS proxy. @@ -74,6 +86,14 @@ func WithALPNConnUpgradePing(alpnConnUpgradeWithPing bool) DialOption { } } +func withProxyURL(proxyURL *url.URL) DialProxyOption { + return func(cfg *dialProxyConfig) { + cfg.proxyURLFunc = func(_ string) *url.URL { + return proxyURL + } + } +} + // WithPROXYHeaderGetter provides PROXY headers signer so client's real IP could be propagated. // Used by proxy's web server to make calls on behalf of connected clients. func WithPROXYHeaderGetter(proxyHeaderGetter PROXYHeaderGetter) DialProxyOption { @@ -172,6 +192,12 @@ func NewDialer(ctx context.Context, keepAlivePeriod, dialTimeout time.Duration, // Base direct dialer. var dialer ContextDialer = netDialer + // Currently there is no use case where both cfg.proxyHeaderGetter and + // cfg.alpnConnUpgradeRequired are set. + if cfg.proxyHeaderGetter != nil && cfg.alpnConnUpgradeRequired { + return nil, trace.NotImplemented("ALPN connection upgrade does not support multiplexer header") + } + // Wrap with PROXY header dialer if getter is present. // Used by Proxy's web server to propagate real client IP when making calls on behalf of connected clients if cfg.proxyHeaderGetter != nil { @@ -179,7 +205,7 @@ func NewDialer(ctx context.Context, keepAlivePeriod, dialTimeout time.Duration, } // Wrap with proxy URL dialer if proxy URL is detected. - if proxyURL := utils.GetProxyURL(addr); proxyURL != nil { + if proxyURL := cfg.getProxyURL(addr); proxyURL != nil { dialer = newProxyURLDialer(proxyURL, dialer, opts...) } @@ -327,7 +353,7 @@ func newTLSRoutingWithConnUpgradeDialer(ssh ssh.ClientConfig, params connectPara InsecureSkipVerify: insecure, ServerName: host, }, - ALPNConnUpgradeRequired: IsALPNConnUpgradeRequired(params.addr, insecure), + ALPNConnUpgradeRequired: IsALPNConnUpgradeRequired(ctx, params.addr, insecure), GetClusterCAs: func(_ context.Context) (*x509.CertPool, error) { tlsConfig, err := params.cfg.Credentials[0].TLSConfig() if err != nil { diff --git a/api/client/events.go b/api/client/events.go index e4e838eb85473..de96aa411cf59 100644 --- a/api/client/events.go +++ b/api/client/events.go @@ -206,6 +206,10 @@ func EventToGRPC(in types.Event) (*proto.Event, error) { out.Resource = &proto.Event_Integration{ Integration: r, } + case *types.HeadlessAuthentication: + out.Resource = &proto.Event_HeadlessAuthentication{ + HeadlessAuthentication: r, + } default: return nil, trace.BadParameter("resource type %T is not supported", in.Resource) } @@ -358,6 +362,9 @@ func EventFromGRPC(in proto.Event) (*types.Event, error) { } else if r := in.GetIntegration(); r != nil { out.Resource = r return &out, nil + } else if r := in.GetHeadlessAuthentication(); r != nil { + out.Resource = r + return &out, nil } else { return nil, trace.BadParameter("received unsupported resource %T", in.Resource) } diff --git a/api/client/proto/authservice.pb.go b/api/client/proto/authservice.pb.go index cf0014eae5399..226968572086f 100644 --- a/api/client/proto/authservice.pb.go +++ b/api/client/proto/authservice.pb.go @@ -413,6 +413,7 @@ type Event struct { // *Event_OktaAssignment // *Event_Integration // *Event_WatchStatus + // *Event_HeadlessAuthentication Resource isEvent_Resource `protobuf_oneof:"Resource"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -581,6 +582,9 @@ type Event_Integration struct { type Event_WatchStatus struct { WatchStatus *types.WatchStatusV1 `protobuf:"bytes,43,opt,name=WatchStatus,proto3,oneof" json:"watch_status,omitempty"` } +type Event_HeadlessAuthentication struct { + HeadlessAuthentication *types.HeadlessAuthentication `protobuf:"bytes,44,opt,name=HeadlessAuthentication,proto3,oneof" json:"headless_authentication,omitempty"` +} func (*Event_ResourceHeader) isEvent_Resource() {} func (*Event_CertAuthority) isEvent_Resource() {} @@ -623,6 +627,7 @@ func (*Event_OktaImportRule) isEvent_Resource() {} func (*Event_OktaAssignment) isEvent_Resource() {} func (*Event_Integration) isEvent_Resource() {} func (*Event_WatchStatus) isEvent_Resource() {} +func (*Event_HeadlessAuthentication) isEvent_Resource() {} func (m *Event) GetResource() isEvent_Resource { if m != nil { @@ -925,6 +930,13 @@ func (m *Event) GetWatchStatus() *types.WatchStatusV1 { return nil } +func (m *Event) GetHeadlessAuthentication() *types.HeadlessAuthentication { + if x, ok := m.GetResource().(*Event_HeadlessAuthentication); ok { + return x.HeadlessAuthentication + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*Event) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -969,6 +981,7 @@ func (*Event) XXX_OneofWrappers() []interface{} { (*Event_OktaAssignment)(nil), (*Event_Integration)(nil), (*Event_WatchStatus)(nil), + (*Event_HeadlessAuthentication)(nil), } } @@ -14553,853 +14566,855 @@ func init() { } var fileDescriptor_0ffcffcda38ae159 = []byte{ - // 13522 bytes of a gzipped FileDescriptorProto + // 13568 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0xbd, 0x5d, 0x6c, 0x1c, 0x59, - 0x76, 0x18, 0xac, 0x6e, 0xfe, 0x1f, 0xfe, 0xb5, 0xae, 0xf8, 0xd3, 0x6a, 0x52, 0x6c, 0xa9, 0x34, - 0xd2, 0x68, 0xb4, 0x3b, 0xfa, 0xa1, 0xe6, 0x7f, 0x66, 0x67, 0xb6, 0x9b, 0xa4, 0x44, 0x4a, 0x14, - 0xc9, 0xa9, 0x26, 0x9b, 0xb3, 0xbb, 0xb3, 0xdb, 0x5b, 0xec, 0xbe, 0x22, 0xeb, 0x53, 0xb3, 0xab, - 0xb7, 0xaa, 0x28, 0x8d, 0x6c, 0xf8, 0xfb, 0x3e, 0xdb, 0xb1, 0x1f, 0x12, 0x24, 0x71, 0x00, 0x3b, - 0x88, 0xe1, 0x07, 0x07, 0x48, 0x5e, 0x12, 0x20, 0x40, 0x5e, 0x0c, 0xbf, 0x04, 0x08, 0x8c, 0x04, - 0xc8, 0x26, 0x80, 0x81, 0x00, 0xb1, 0x11, 0x20, 0x0f, 0x74, 0xbc, 0x0f, 0x79, 0x20, 0x90, 0x00, - 0x41, 0x90, 0x3c, 0x2c, 0x10, 0x20, 0xb8, 0xbf, 0x75, 0x6f, 0xd5, 0xad, 0x6a, 0x52, 0xe2, 0x4e, - 0x5e, 0x24, 0xf6, 0xbd, 0xe7, 0x9c, 0xfb, 0x7f, 0xea, 0x9c, 0x73, 0xcf, 0x3d, 0x07, 0xee, 0x84, - 0xb8, 0x8d, 0xbb, 0x9e, 0x1f, 0xde, 0x6d, 0xe3, 0x7d, 0xa7, 0xf9, 0xea, 0x6e, 0xb3, 0xed, 0xe2, - 0x4e, 0x78, 0xb7, 0xeb, 0x7b, 0xa1, 0x77, 0xd7, 0x39, 0x0a, 0x0f, 0x02, 0xec, 0xbf, 0x70, 0x9b, - 0xf8, 0x0e, 0x2d, 0x41, 0x03, 0xf4, 0xbf, 0xd2, 0xd4, 0xbe, 0xb7, 0xef, 0x31, 0x18, 0xf2, 0x17, - 0xab, 0x2c, 0xcd, 0xed, 0x7b, 0xde, 0x7e, 0x1b, 0x33, 0xe4, 0xbd, 0xa3, 0x67, 0x77, 0xf1, 0x61, - 0x37, 0x7c, 0xc5, 0x2b, 0xcb, 0xf1, 0xca, 0xd0, 0x3d, 0xc4, 0x41, 0xe8, 0x1c, 0x76, 0x39, 0xc0, - 0x3b, 0xb2, 0x2b, 0x4e, 0x18, 0x92, 0x9a, 0xd0, 0xf5, 0x3a, 0x77, 0x5f, 0xdc, 0x57, 0x7f, 0x72, - 0xd0, 0x5b, 0x99, 0xbd, 0x6e, 0x62, 0x3f, 0x0c, 0x12, 0x44, 0x39, 0x64, 0xf8, 0xaa, 0x8b, 0x83, - 0xbb, 0xf8, 0x05, 0xee, 0x84, 0xe2, 0x3f, 0x0e, 0x7a, 0xcd, 0x0c, 0x4a, 0xff, 0xe5, 0x20, 0xef, - 0x9a, 0x41, 0x5e, 0xe2, 0x3d, 0x32, 0x53, 0x1d, 0xf9, 0x47, 0x0f, 0x70, 0xdf, 0xe9, 0x76, 0xb1, - 0x1f, 0xfd, 0x91, 0xe8, 0xeb, 0x51, 0xe0, 0xec, 0x63, 0xde, 0xc7, 0x17, 0xf7, 0xd5, 0x9f, 0x0c, - 0xd4, 0xfa, 0xdd, 0x05, 0x18, 0x58, 0x21, 0x05, 0xe8, 0x23, 0xe8, 0xdf, 0x7e, 0xd5, 0xc5, 0xc5, - 0xdc, 0xd5, 0xdc, 0xad, 0x89, 0xc5, 0x02, 0xab, 0xbf, 0xb3, 0xd9, 0xc5, 0x3e, 0x9d, 0xb0, 0x2a, - 0x3a, 0x39, 0x2e, 0x4f, 0x90, 0x76, 0xbf, 0xeb, 0x1d, 0xba, 0x21, 0x5d, 0x10, 0x9b, 0x62, 0xa0, - 0x5d, 0x98, 0xb0, 0x71, 0xe0, 0x1d, 0xf9, 0x4d, 0xbc, 0x8a, 0x9d, 0x16, 0xf6, 0x8b, 0xf9, 0xab, - 0xb9, 0x5b, 0xa3, 0x8b, 0xd3, 0x77, 0xd8, 0x90, 0xf5, 0xca, 0xea, 0xcc, 0xc9, 0x71, 0x19, 0xf9, - 0xbc, 0x2c, 0x22, 0xb6, 0x7a, 0xc1, 0x8e, 0x91, 0x41, 0x5f, 0xc3, 0xf8, 0x12, 0xf6, 0xc3, 0xca, - 0x51, 0x78, 0xe0, 0xf9, 0x6e, 0xf8, 0xaa, 0xd8, 0x47, 0xe9, 0xce, 0x70, 0xba, 0x5a, 0x5d, 0x7d, - 0xb1, 0x3a, 0x7f, 0x72, 0x5c, 0x2e, 0x92, 0x35, 0x6b, 0x38, 0xa2, 0x54, 0x23, 0xaf, 0x13, 0x43, - 0x5f, 0xc1, 0x58, 0x8d, 0x6c, 0x86, 0xe6, 0xb6, 0xf7, 0x1c, 0x77, 0x82, 0x62, 0xbf, 0xd6, 0x69, - 0xb5, 0xaa, 0xbe, 0x58, 0x9d, 0x3b, 0x39, 0x2e, 0xcf, 0xd2, 0xbd, 0xd3, 0x6c, 0x84, 0xb4, 0x50, - 0x23, 0xad, 0x51, 0x42, 0x3f, 0x85, 0x89, 0x2d, 0xdf, 0x7b, 0xe1, 0x06, 0xae, 0xd7, 0xa1, 0x45, - 0xc5, 0x01, 0x4a, 0x7b, 0x96, 0xd3, 0xd6, 0x2b, 0xeb, 0x8b, 0xd5, 0x2b, 0x27, 0xc7, 0xe5, 0xcb, - 0x5d, 0x51, 0xca, 0x1a, 0xd0, 0x67, 0x46, 0x47, 0x41, 0xdb, 0x30, 0xba, 0xd4, 0x3e, 0x0a, 0x42, - 0xec, 0x6f, 0x38, 0x87, 0xb8, 0x38, 0x48, 0xc9, 0x4f, 0x89, 0x79, 0x89, 0x6a, 0xea, 0x8b, 0xd5, - 0xd2, 0xc9, 0x71, 0x79, 0xa6, 0xc9, 0x8a, 0x1a, 0x1d, 0xe7, 0x50, 0x9f, 0x72, 0x95, 0x0c, 0xfa, - 0x10, 0xfa, 0x77, 0x02, 0xec, 0x17, 0x87, 0x29, 0xb9, 0x71, 0x4e, 0x8e, 0x14, 0xd5, 0x17, 0xd9, - 0xfa, 0x1f, 0x05, 0xd8, 0xd7, 0xf0, 0x29, 0x02, 0x41, 0xb4, 0xbd, 0x36, 0x2e, 0x8e, 0x68, 0x88, - 0xa4, 0xa8, 0xfe, 0x01, 0x43, 0xf4, 0xbd, 0xb6, 0xde, 0x30, 0x45, 0x40, 0x6b, 0x30, 0x42, 0x5a, - 0x0e, 0xba, 0x4e, 0x13, 0x17, 0x81, 0x62, 0x17, 0x38, 0xb6, 0x2c, 0xaf, 0xce, 0x9e, 0x1c, 0x97, - 0x2f, 0x75, 0xc4, 0x4f, 0x8d, 0x4a, 0x84, 0x8d, 0xbe, 0x80, 0xc1, 0x1a, 0xf6, 0x5f, 0x60, 0xbf, - 0x38, 0x4a, 0xe9, 0x4c, 0x8a, 0x85, 0xa4, 0x85, 0xf5, 0xc5, 0xea, 0xd4, 0xc9, 0x71, 0xb9, 0x10, - 0xd0, 0x5f, 0x1a, 0x0d, 0x8e, 0x46, 0x76, 0x9b, 0x8d, 0x5f, 0x60, 0x3f, 0xc0, 0xdb, 0x47, 0x9d, - 0x0e, 0x6e, 0x17, 0xc7, 0xb4, 0xdd, 0xa6, 0xd5, 0x89, 0xdd, 0xe6, 0xb3, 0xc2, 0x46, 0x48, 0x4b, - 0xf5, 0xdd, 0xa6, 0x21, 0xa0, 0x03, 0x28, 0xb0, 0xbf, 0x96, 0xbc, 0x4e, 0x07, 0x37, 0xc9, 0x91, - 0x2a, 0x8e, 0xd3, 0x06, 0x2e, 0xf3, 0x06, 0xe2, 0xd5, 0xf5, 0xc5, 0x6a, 0xf9, 0xe4, 0xb8, 0x3c, - 0xc7, 0x68, 0x37, 0x9a, 0xb2, 0x42, 0x6b, 0x26, 0x41, 0x95, 0x8c, 0xa3, 0xd2, 0x6c, 0xe2, 0x20, - 0xb0, 0xf1, 0xcf, 0x8e, 0x70, 0x10, 0x16, 0x27, 0xb4, 0x71, 0x68, 0x75, 0xf5, 0x07, 0x6c, 0x1c, - 0x0e, 0x2d, 0x6c, 0xf8, 0xac, 0x54, 0x1f, 0x87, 0x86, 0x80, 0xb6, 0x00, 0x2a, 0xdd, 0x6e, 0x0d, - 0x07, 0x64, 0x33, 0x16, 0x27, 0x29, 0xe9, 0x4b, 0x9c, 0xf4, 0x2e, 0xde, 0xe3, 0x15, 0xf5, 0xc5, - 0xea, 0xe5, 0x93, 0xe3, 0xf2, 0xb4, 0xd3, 0xed, 0x36, 0x02, 0x56, 0xa4, 0x11, 0x55, 0x68, 0xb0, - 0x79, 0x3f, 0xf4, 0x42, 0xcc, 0xb7, 0x62, 0xb1, 0x10, 0x9b, 0x77, 0xa5, 0x4e, 0xf4, 0xd7, 0xa7, - 0x85, 0x0d, 0xbe, 0xad, 0xe3, 0xf3, 0xae, 0x20, 0x90, 0xb3, 0xb8, 0xec, 0x84, 0xce, 0x9e, 0x13, - 0x60, 0xbe, 0x3d, 0x2e, 0x6a, 0x67, 0x51, 0xaf, 0xac, 0x3f, 0x60, 0x67, 0xb1, 0xc5, 0x4b, 0x1b, - 0x86, 0xfd, 0x12, 0xa3, 0x47, 0x66, 0x24, 0x1a, 0x78, 0x11, 0xf5, 0x98, 0x91, 0x97, 0x78, 0xcf, - 0x3c, 0x23, 0x11, 0x28, 0x5a, 0x85, 0xe1, 0x5d, 0xbc, 0xc7, 0x38, 0xc7, 0x25, 0x4a, 0xef, 0x62, - 0x44, 0x8f, 0xf1, 0x8c, 0x07, 0xec, 0x54, 0x10, 0x6a, 0x49, 0x6e, 0x21, 0xb1, 0xd1, 0xef, 0xe4, - 0x60, 0x56, 0x9c, 0x70, 0x1c, 0xbe, 0xf4, 0xfc, 0xe7, 0x6e, 0x67, 0x7f, 0xc9, 0xeb, 0x3c, 0x73, - 0xf7, 0x8b, 0x53, 0x94, 0xf2, 0xd5, 0x18, 0xd3, 0x88, 0x41, 0xd5, 0x17, 0xab, 0x6f, 0x9f, 0x1c, - 0x97, 0xaf, 0x4b, 0x06, 0x22, 0xeb, 0xc9, 0x86, 0x7c, 0xe6, 0xee, 0x6b, 0x0d, 0xa7, 0xb5, 0x85, - 0x7e, 0x33, 0x07, 0x33, 0x7c, 0x74, 0x36, 0x6e, 0x7a, 0x7e, 0x2b, 0xea, 0xc6, 0x34, 0xed, 0x46, - 0x59, 0x9e, 0x56, 0x13, 0x50, 0x7d, 0xb1, 0x7a, 0xf3, 0xe4, 0xb8, 0x6c, 0xf1, 0x89, 0x6b, 0xf8, - 0xa2, 0xda, 0xd4, 0x89, 0x94, 0x86, 0xc8, 0x4e, 0x20, 0xcc, 0x7f, 0xcb, 0xc7, 0xcf, 0xb0, 0x8f, - 0x3b, 0x4d, 0x5c, 0x9c, 0xd1, 0x76, 0x82, 0x5e, 0x29, 0xb8, 0x32, 0xf9, 0x94, 0x34, 0xba, 0xb2, - 0x58, 0xdf, 0x09, 0x3a, 0x0a, 0xfa, 0x19, 0x20, 0x3e, 0x01, 0x95, 0xa3, 0x96, 0x1b, 0xf2, 0x01, - 0xce, 0xd2, 0x56, 0xe6, 0xf4, 0x79, 0x56, 0x00, 0xea, 0x8b, 0x55, 0xeb, 0xe4, 0xb8, 0xbc, 0x20, - 0xa6, 0xd8, 0x21, 0x55, 0xa6, 0x81, 0x19, 0x88, 0x13, 0xce, 0xbb, 0xee, 0x35, 0x9f, 0x17, 0x8b, - 0x1a, 0xe7, 0x25, 0x45, 0x82, 0x65, 0xb7, 0xbd, 0xe6, 0x73, 0x9d, 0xf3, 0x92, 0x5a, 0x14, 0xc2, - 0x25, 0xbe, 0x4a, 0x36, 0x0e, 0x42, 0xdf, 0xa5, 0xbc, 0x23, 0x28, 0x5e, 0xa6, 0x74, 0xe6, 0x05, - 0x0f, 0x4e, 0x42, 0xd4, 0xdf, 0x63, 0xbd, 0xe5, 0x1b, 0xa1, 0xe1, 0x2b, 0x75, 0x5a, 0x33, 0x26, - 0xf2, 0xe8, 0x37, 0x60, 0x7a, 0xd7, 0xed, 0xb4, 0xbc, 0x97, 0xc1, 0x32, 0x0e, 0x9e, 0x87, 0x5e, - 0xb7, 0xc6, 0x84, 0xc2, 0x62, 0x89, 0xb6, 0xbb, 0x20, 0xb6, 0xb9, 0x09, 0xa6, 0xfe, 0xa0, 0x7a, - 0xe3, 0xe4, 0xb8, 0x7c, 0xed, 0x25, 0xab, 0x6c, 0xb4, 0x58, 0x6d, 0x83, 0xcb, 0x95, 0x5a, 0xe3, - 0xe6, 0x56, 0xc8, 0x16, 0xd0, 0x2b, 0x8a, 0x73, 0xda, 0x16, 0xd0, 0x2b, 0x05, 0x33, 0x88, 0x35, - 0xa8, 0x6f, 0x01, 0x1d, 0x05, 0x3d, 0x82, 0x61, 0xc1, 0x1e, 0x8a, 0xf3, 0xda, 0xd1, 0x15, 0xc5, - 0xf5, 0x07, 0x4c, 0x02, 0x12, 0x2c, 0x46, 0x3f, 0xb9, 0x02, 0x0a, 0xad, 0xc3, 0x08, 0xe5, 0x91, - 0x94, 0x65, 0x5d, 0xa1, 0x94, 0x90, 0xd8, 0xa8, 0xa2, 0xbc, 0xfe, 0xa0, 0x5a, 0x3c, 0x39, 0x2e, - 0x4f, 0x31, 0x2e, 0x9b, 0x60, 0x54, 0x11, 0x01, 0xf4, 0x00, 0xfa, 0x2a, 0xdd, 0x6e, 0x71, 0x81, - 0xd2, 0x19, 0x8b, 0xe8, 0xd4, 0x1f, 0x54, 0x2f, 0x9e, 0x1c, 0x97, 0xc7, 0x9d, 0xae, 0x3e, 0x2c, - 0x02, 0x8d, 0xf6, 0xa0, 0x50, 0xeb, 0x78, 0x2f, 0x9f, 0xb5, 0x9d, 0xe7, 0x58, 0xb0, 0xb7, 0x72, - 0x3a, 0x7b, 0xa3, 0x1f, 0xab, 0x40, 0x20, 0x18, 0x99, 0x5c, 0x82, 0x1e, 0xf9, 0x2c, 0x3e, 0x39, - 0xda, 0xc3, 0x7e, 0x07, 0x87, 0x38, 0xe0, 0xa3, 0xbd, 0xaa, 0x7d, 0x16, 0xe3, 0xd5, 0xf5, 0x07, - 0xac, 0xa5, 0xe7, 0xb2, 0xdc, 0x34, 0xf6, 0x04, 0x55, 0xd4, 0x86, 0x8b, 0x51, 0x99, 0xf8, 0xd4, - 0x5c, 0xa3, 0x4d, 0x95, 0x12, 0x4d, 0x45, 0x9f, 0x9b, 0xab, 0x27, 0xc7, 0xe5, 0x79, 0xa5, 0x2d, - 0xd3, 0x27, 0x27, 0x49, 0x18, 0x3d, 0x81, 0x91, 0xb5, 0x4e, 0x10, 0x3a, 0xed, 0x36, 0xf6, 0x8b, - 0x96, 0xb6, 0x7c, 0xb2, 0xbc, 0x7e, 0x9f, 0x31, 0x71, 0x57, 0x14, 0xe8, 0xab, 0x27, 0xe1, 0x50, - 0x0b, 0x26, 0xd5, 0x6f, 0x0e, 0x39, 0x2f, 0xd7, 0x29, 0xc9, 0xa2, 0xe1, 0x23, 0x46, 0x4e, 0xca, - 0xfd, 0xea, 0xc2, 0xc9, 0x71, 0xb9, 0xa4, 0x7d, 0xc5, 0xe2, 0x47, 0x24, 0x4e, 0x12, 0xfd, 0x16, - 0xe1, 0xd1, 0x95, 0xa7, 0xeb, 0x6b, 0xad, 0x2d, 0x5e, 0x44, 0x85, 0x4e, 0x22, 0xcf, 0xbf, 0xa5, - 0xf3, 0x68, 0x23, 0x50, 0xfd, 0x3e, 0xfb, 0x52, 0x04, 0xce, 0x61, 0xbb, 0xe1, 0xb6, 0xe4, 0xb9, - 0x6c, 0x74, 0x39, 0x40, 0x8c, 0x49, 0x1b, 0x89, 0xa0, 0x1f, 0xc3, 0x84, 0xac, 0x61, 0x3b, 0xee, - 0x46, 0xfa, 0x8e, 0xa3, 0x83, 0x54, 0xda, 0x4b, 0x6e, 0xb8, 0x18, 0x31, 0x72, 0xaa, 0x88, 0xc0, - 0xfa, 0xc8, 0xf7, 0x8e, 0xba, 0xc5, 0x9b, 0xda, 0xb2, 0xc8, 0xf2, 0xfa, 0x7d, 0x76, 0xaa, 0x88, - 0xac, 0xdb, 0xd8, 0x27, 0x25, 0xfa, 0xba, 0x48, 0x40, 0xf2, 0x9d, 0xde, 0x59, 0xe3, 0x5c, 0xfe, - 0x6d, 0xed, 0xb0, 0x8b, 0x62, 0xb1, 0xc4, 0x47, 0xae, 0x89, 0xa1, 0x4b, 0x6c, 0xe4, 0xc0, 0xc4, - 0xe6, 0xf3, 0xd0, 0x59, 0x3b, 0x24, 0x5a, 0x9b, 0x7d, 0xd4, 0xc6, 0xc5, 0x5b, 0x1a, 0x63, 0xd2, - 0x2b, 0xc5, 0xfa, 0x7a, 0xcf, 0x43, 0xa7, 0xe1, 0xd2, 0xe2, 0x86, 0x7f, 0x14, 0x13, 0xb0, 0x63, - 0x04, 0x09, 0xef, 0x23, 0x25, 0x95, 0x20, 0x70, 0xf7, 0x3b, 0x87, 0xb8, 0x13, 0x16, 0xdf, 0x49, - 0x34, 0x11, 0x55, 0xd6, 0xef, 0x33, 0xde, 0x47, 0x9b, 0x70, 0x64, 0x71, 0xb2, 0x85, 0x08, 0x05, - 0xd5, 0x60, 0x74, 0xad, 0x13, 0xe2, 0x7d, 0xa6, 0x30, 0x16, 0x6f, 0x6b, 0x4a, 0x89, 0x52, 0x53, - 0xbf, 0xcf, 0x44, 0x21, 0x37, 0x2a, 0xd2, 0x75, 0x12, 0x05, 0x96, 0x68, 0x3a, 0xbb, 0x4e, 0xd8, - 0x3c, 0x20, 0x0a, 0xd6, 0x51, 0x50, 0xfc, 0x8e, 0x46, 0x54, 0xa9, 0xa9, 0xdf, 0x67, 0x9a, 0xce, - 0x4b, 0x52, 0xd4, 0x08, 0x68, 0x99, 0x4e, 0x55, 0x01, 0xae, 0x02, 0x0c, 0x0b, 0x5d, 0xf3, 0x71, - 0xff, 0xf0, 0x50, 0x61, 0xd8, 0xfa, 0xe3, 0x1c, 0x0c, 0x50, 0x08, 0xf4, 0x05, 0x0c, 0x3c, 0x71, - 0x3b, 0xad, 0xa0, 0x98, 0xbb, 0xda, 0xa7, 0xe8, 0x23, 0xb4, 0x92, 0x54, 0x54, 0x67, 0x7f, 0x7e, - 0x5c, 0xbe, 0x70, 0x72, 0x5c, 0x9e, 0x7c, 0x4e, 0xc0, 0x14, 0x75, 0x98, 0xe1, 0xa1, 0x1d, 0xb8, - 0x54, 0x69, 0xb7, 0xbd, 0x97, 0x5b, 0x8e, 0x1f, 0xba, 0x4e, 0xbb, 0x76, 0x44, 0x05, 0x68, 0xaa, - 0x14, 0x0f, 0x57, 0xaf, 0x9f, 0x1c, 0x97, 0xcb, 0x0e, 0xa9, 0x6e, 0x74, 0x59, 0x7d, 0x23, 0x60, - 0x00, 0x0a, 0x21, 0x13, 0xbe, 0xf5, 0x27, 0x83, 0x50, 0x58, 0xf5, 0x82, 0x90, 0x68, 0xb1, 0x52, - 0x1c, 0xbf, 0x0e, 0x83, 0xa4, 0x6c, 0x6d, 0x99, 0xea, 0xed, 0x23, 0xd5, 0xd1, 0x93, 0xe3, 0xf2, - 0xd0, 0x81, 0x17, 0x84, 0x0d, 0xb7, 0x65, 0xf3, 0x2a, 0xf4, 0x0e, 0x0c, 0x6f, 0x78, 0x2d, 0x4c, - 0x55, 0xc5, 0x3c, 0x05, 0x1b, 0x3f, 0x39, 0x2e, 0x8f, 0x74, 0xbc, 0x16, 0xa6, 0x1a, 0xa1, 0x2d, - 0xab, 0x51, 0x9d, 0x6b, 0x72, 0x7d, 0x14, 0xac, 0x7a, 0x72, 0x5c, 0xee, 0x27, 0xaa, 0xdb, 0x2f, - 0x8f, 0xcb, 0x1f, 0xec, 0xbb, 0xe1, 0xc1, 0xd1, 0xde, 0x9d, 0xa6, 0x77, 0x78, 0x77, 0xdf, 0x77, - 0x5e, 0xb8, 0xcc, 0x90, 0xe2, 0xb4, 0xef, 0x46, 0xe6, 0x96, 0xae, 0xcb, 0xad, 0x1c, 0xb5, 0x57, - 0x41, 0x88, 0x0f, 0x09, 0x25, 0xae, 0xe8, 0xed, 0xc2, 0x54, 0xa5, 0xd5, 0x72, 0x19, 0xc6, 0x96, - 0xef, 0x76, 0x9a, 0x6e, 0xd7, 0x69, 0x13, 0xa5, 0xbb, 0xef, 0xd6, 0x08, 0x9f, 0x14, 0x59, 0xdf, - 0xe8, 0x4a, 0x00, 0x65, 0x52, 0x8c, 0x04, 0xd0, 0x03, 0x18, 0x5e, 0xde, 0xa8, 0x51, 0x35, 0xb0, - 0x38, 0x40, 0x89, 0xd1, 0x03, 0xd7, 0xea, 0x04, 0x74, 0x68, 0x2a, 0x01, 0x09, 0x88, 0x3e, 0x80, - 0xb1, 0xad, 0xa3, 0xbd, 0xb6, 0xdb, 0xdc, 0x5e, 0xaf, 0x3d, 0xc1, 0xaf, 0xa8, 0xfe, 0x3c, 0xc6, - 0xc4, 0xa5, 0x2e, 0x2d, 0x6f, 0x84, 0xed, 0xa0, 0xf1, 0x1c, 0xbf, 0xb2, 0x35, 0xb8, 0x08, 0xaf, - 0x56, 0x5b, 0x25, 0x78, 0x43, 0x09, 0xbc, 0x20, 0x38, 0x50, 0xf1, 0x18, 0x1c, 0xba, 0x0b, 0xc0, - 0xb4, 0x92, 0x4a, 0xab, 0xc5, 0xd4, 0xeb, 0x91, 0xea, 0xe4, 0xc9, 0x71, 0x79, 0x94, 0xeb, 0x31, - 0x4e, 0xab, 0xe5, 0xdb, 0x0a, 0x08, 0x5a, 0x82, 0x61, 0xdb, 0x63, 0x13, 0xcc, 0x95, 0xea, 0x49, - 0xa9, 0x54, 0xb3, 0x62, 0x6e, 0x46, 0xe1, 0xbf, 0xd4, 0x51, 0x0a, 0x08, 0x54, 0x86, 0xa1, 0x0d, - 0x6f, 0xc9, 0x69, 0x1e, 0x30, 0xd5, 0x7a, 0xb8, 0x3a, 0x70, 0x72, 0x5c, 0xce, 0xbd, 0x6b, 0x8b, - 0x52, 0xf4, 0x02, 0x46, 0xa3, 0x85, 0x0a, 0x8a, 0xa3, 0x74, 0xfa, 0xb6, 0xc9, 0x29, 0x0a, 0x68, - 0x71, 0x83, 0x2c, 0xbd, 0x32, 0x83, 0x6f, 0xb0, 0x0b, 0xd4, 0x86, 0x50, 0x1b, 0xae, 0xec, 0x90, - 0x8f, 0xdb, 0x5e, 0x1b, 0x47, 0xc5, 0x95, 0x20, 0xc0, 0x3e, 0xa1, 0xb5, 0xb6, 0x4c, 0x35, 0xef, - 0x11, 0x2e, 0xf2, 0x47, 0x3d, 0x21, 0x7c, 0x88, 0x81, 0x34, 0xdc, 0x96, 0x32, 0xe2, 0x6c, 0x62, - 0xd6, 0xff, 0xce, 0x01, 0xda, 0xec, 0xe2, 0x4e, 0xad, 0xb6, 0x4a, 0x8e, 0x8e, 0x38, 0x39, 0xdf, - 0x85, 0x11, 0xb6, 0x46, 0x64, 0x21, 0xf3, 0x74, 0x21, 0x27, 0x4e, 0x8e, 0xcb, 0xc0, 0x17, 0x92, - 0x2c, 0x62, 0x04, 0x80, 0x6e, 0x40, 0xdf, 0xf6, 0xf6, 0x3a, 0x3d, 0x16, 0x7d, 0xd5, 0x4b, 0x27, - 0xc7, 0xe5, 0xbe, 0x30, 0x6c, 0xff, 0xf2, 0xb8, 0x3c, 0xbc, 0x7c, 0xc4, 0x18, 0x95, 0x4d, 0xea, - 0xd1, 0x0d, 0x18, 0x12, 0xa2, 0x45, 0x7f, 0x74, 0x1e, 0xb9, 0xcc, 0x60, 0x8b, 0x3a, 0xf4, 0x1d, - 0x6e, 0x68, 0x19, 0x30, 0x19, 0x5a, 0x86, 0xc9, 0xa1, 0x23, 0x1f, 0x1f, 0x6e, 0x5c, 0xb9, 0x03, - 0x03, 0x6c, 0x7d, 0x06, 0x29, 0x3f, 0x8a, 0x59, 0x57, 0x46, 0x4e, 0x8e, 0xcb, 0x03, 0x74, 0x9d, - 0x6c, 0x06, 0xf6, 0xb8, 0x7f, 0x38, 0x57, 0xc8, 0xdb, 0xc3, 0x04, 0x97, 0x9c, 0x00, 0xeb, 0x3b, - 0x30, 0xaa, 0x0c, 0x1f, 0xcd, 0x43, 0x3f, 0xf9, 0x9f, 0xf2, 0x8b, 0x31, 0xd6, 0x58, 0x93, 0x4c, - 0x0b, 0x2d, 0xb5, 0xfe, 0x64, 0x1c, 0x0a, 0x04, 0x53, 0x63, 0x32, 0xda, 0x54, 0xe5, 0x7a, 0x4d, - 0xd5, 0x2d, 0x90, 0x6d, 0x73, 0x6e, 0x33, 0x76, 0x72, 0x5c, 0x1e, 0x3e, 0xe2, 0x65, 0x51, 0xcf, - 0x50, 0x0d, 0x86, 0x56, 0xbe, 0xe9, 0xba, 0x3e, 0x0e, 0xb8, 0x65, 0xaf, 0x74, 0x87, 0xd9, 0x76, - 0xef, 0x08, 0xdb, 0xee, 0x9d, 0x6d, 0x61, 0xdb, 0xad, 0x5e, 0xe1, 0x5c, 0xf7, 0x22, 0x66, 0x28, - 0xd1, 0x06, 0xf8, 0xbd, 0xbf, 0x2a, 0xe7, 0x6c, 0x41, 0x09, 0x7d, 0x17, 0x06, 0x1f, 0x7a, 0xfe, - 0xa1, 0x13, 0xf2, 0x15, 0xa0, 0x66, 0x9f, 0x67, 0xb4, 0x44, 0xd9, 0x33, 0x1c, 0x06, 0x3d, 0x84, - 0x09, 0xdb, 0x3b, 0x0a, 0xf1, 0xb6, 0x27, 0xd6, 0x6d, 0x80, 0x62, 0xd1, 0xef, 0xab, 0x4f, 0x6a, - 0x1a, 0xa1, 0x97, 0x14, 0xfa, 0xec, 0x18, 0x16, 0x5a, 0x81, 0x09, 0xcd, 0x4e, 0xc2, 0x56, 0x6b, - 0x84, 0xeb, 0x90, 0x9a, 0x75, 0x45, 0x65, 0x49, 0x31, 0x24, 0xb4, 0x61, 0x12, 0x52, 0x87, 0x68, - 0x8f, 0x7a, 0x0a, 0xa2, 0x26, 0x31, 0x14, 0xc3, 0x24, 0xef, 0xa8, 0xd4, 0x4a, 0x86, 0xb9, 0x75, - 0x85, 0xd9, 0x77, 0x63, 0xb5, 0xd5, 0xeb, 0x7c, 0x96, 0xe7, 0xe4, 0xd8, 0x93, 0x7a, 0x8a, 0x1d, - 0xa7, 0x49, 0x98, 0xb0, 0xfc, 0xc0, 0x8c, 0xd0, 0xde, 0x32, 0x9b, 0x9d, 0xf8, 0xc0, 0xa8, 0xec, - 0x49, 0x7e, 0x6a, 0xd6, 0x61, 0x60, 0x27, 0x70, 0xf6, 0x19, 0x73, 0x9a, 0x58, 0xbc, 0xc6, 0x7b, - 0x14, 0xdf, 0x7d, 0xd4, 0xcc, 0x4b, 0x01, 0xe9, 0xb9, 0x9b, 0xa4, 0x36, 0x6c, 0xf5, 0xa3, 0x4b, - 0xeb, 0xd0, 0x97, 0x00, 0xbc, 0x57, 0x44, 0xd1, 0x19, 0xe5, 0xd2, 0x98, 0x36, 0xc8, 0x4a, 0xb7, - 0x5b, 0x5d, 0xe0, 0xe3, 0x9b, 0x91, 0xe3, 0xd3, 0x54, 0x1f, 0x5b, 0x21, 0x82, 0xbe, 0x80, 0x31, - 0xca, 0xbb, 0xc4, 0x8a, 0x8e, 0xd1, 0x15, 0xa5, 0x96, 0x60, 0xca, 0x8e, 0x0c, 0xeb, 0xa9, 0x21, - 0xa0, 0xff, 0x17, 0xa6, 0x39, 0xb9, 0x98, 0xd6, 0x39, 0xce, 0xb5, 0x6c, 0xad, 0x7b, 0x3a, 0x4c, - 0xf5, 0x36, 0xef, 0xa9, 0x25, 0x7b, 0x9a, 0xaa, 0x87, 0xda, 0xe6, 0x66, 0xd0, 0x1a, 0x4c, 0xee, - 0x04, 0x58, 0x1b, 0xc3, 0x04, 0xfd, 0x10, 0x50, 0x05, 0xea, 0x28, 0xc0, 0x8d, 0xb4, 0x71, 0xc4, - 0xf1, 0x90, 0x0d, 0x68, 0xd9, 0xf7, 0xba, 0xb1, 0x3d, 0x3e, 0x49, 0x67, 0x84, 0xda, 0x03, 0x5a, - 0xbe, 0xd7, 0x6d, 0xa4, 0x6f, 0x74, 0x03, 0x36, 0xfa, 0x09, 0xcc, 0x44, 0x66, 0xcb, 0x65, 0xd7, - 0xd9, 0xef, 0x78, 0x41, 0xe8, 0x36, 0xd7, 0x96, 0xa9, 0x05, 0x90, 0xf3, 0xff, 0xc8, 0xec, 0xd9, - 0x68, 0x49, 0x10, 0x9d, 0xff, 0xa7, 0x50, 0x41, 0x3f, 0x82, 0x71, 0xde, 0x16, 0x37, 0x93, 0x5f, - 0xcc, 0xde, 0x68, 0x12, 0x98, 0x9b, 0xac, 0xc5, 0x4f, 0x26, 0x23, 0xe9, 0xb4, 0xd0, 0xd7, 0x30, - 0xfa, 0xf4, 0x61, 0xc5, 0xc6, 0x41, 0xd7, 0xeb, 0x04, 0x98, 0x9b, 0xfd, 0x16, 0x38, 0xe9, 0xa7, - 0x0f, 0x2b, 0x95, 0xa3, 0xf0, 0x00, 0x77, 0x42, 0xb7, 0xe9, 0x84, 0x58, 0x40, 0x31, 0x09, 0xf5, - 0xf0, 0x99, 0xd3, 0xf0, 0x79, 0x89, 0x32, 0x0a, 0x95, 0x1c, 0x2a, 0xc1, 0x70, 0xad, 0xb6, 0xba, - 0xee, 0xed, 0xbb, 0xcc, 0x02, 0x38, 0x62, 0xcb, 0xdf, 0x68, 0x0f, 0xa6, 0x95, 0x8b, 0x2c, 0x2a, - 0xea, 0x62, 0x2a, 0xcf, 0x33, 0x83, 0xde, 0xbb, 0xf2, 0x26, 0xee, 0x8e, 0x7a, 0xdf, 0xf5, 0xe2, - 0xfe, 0x9d, 0x4a, 0xf4, 0xb3, 0x26, 0x90, 0xec, 0x29, 0xc7, 0x50, 0x6a, 0x7d, 0x05, 0x23, 0xf2, - 0xd8, 0xa1, 0x21, 0xe8, 0xab, 0xb4, 0xdb, 0x85, 0x0b, 0xe4, 0x8f, 0x5a, 0x6d, 0xb5, 0x90, 0x43, - 0x13, 0x00, 0x11, 0xaf, 0x29, 0xe4, 0xd1, 0x58, 0x64, 0xf5, 0x28, 0xf4, 0x51, 0xf8, 0x6e, 0xb7, - 0xd0, 0x8f, 0x50, 0xdc, 0xdc, 0x52, 0x18, 0xb0, 0x76, 0x60, 0x44, 0x4e, 0x24, 0x9a, 0x84, 0xd1, - 0x9d, 0x8d, 0xda, 0xd6, 0xca, 0xd2, 0xda, 0xc3, 0xb5, 0x95, 0xe5, 0xc2, 0x05, 0x74, 0x05, 0x2e, - 0x6f, 0xd7, 0x56, 0x1b, 0xcb, 0xd5, 0xc6, 0xfa, 0xe6, 0x52, 0x65, 0xbd, 0xb1, 0x65, 0x6f, 0x7e, - 0xf5, 0x83, 0xc6, 0xf6, 0xce, 0xc6, 0xc6, 0xca, 0x7a, 0x21, 0x87, 0x8a, 0x30, 0x45, 0xaa, 0x9f, - 0xec, 0x54, 0x57, 0x54, 0x80, 0x42, 0xde, 0xfa, 0x8f, 0xb9, 0x04, 0xa7, 0x43, 0x8b, 0x30, 0xca, - 0xd5, 0x4b, 0xba, 0xfa, 0x4c, 0x40, 0x2e, 0x9c, 0x1c, 0x97, 0xc7, 0x84, 0x6a, 0x4a, 0x17, 0x56, - 0x05, 0x22, 0x1f, 0xaf, 0x2d, 0xb2, 0x84, 0x4d, 0xaf, 0xad, 0x7e, 0xbc, 0xba, 0xbc, 0xcc, 0x96, - 0xb5, 0x68, 0x51, 0xf9, 0xcc, 0x31, 0x69, 0x99, 0x4a, 0x64, 0xe2, 0x33, 0xa7, 0xb2, 0x3c, 0xf9, - 0xc1, 0x5b, 0x54, 0xac, 0x43, 0xfd, 0x11, 0x8e, 0x81, 0xc5, 0x4a, 0x38, 0xeb, 0x28, 0x85, 0x89, - 0xa0, 0x4f, 0x13, 0xc6, 0x2c, 0x36, 0x42, 0xca, 0x25, 0x63, 0xbc, 0x22, 0x61, 0xa7, 0x2a, 0xc3, - 0x00, 0xdb, 0x5d, 0x6c, 0x90, 0x54, 0x8a, 0x68, 0x93, 0x02, 0x9b, 0x95, 0x5b, 0x7f, 0xa7, 0x4f, - 0x65, 0xa8, 0x44, 0x6a, 0x50, 0x26, 0x91, 0x4a, 0x0d, 0x74, 0xf2, 0x68, 0x29, 0x11, 0x10, 0xb8, - 0x86, 0xbd, 0xb6, 0xcc, 0x29, 0x52, 0x01, 0x41, 0xd8, 0x6b, 0xdd, 0x96, 0x1d, 0x01, 0x10, 0x69, - 0x98, 0x49, 0x0b, 0x54, 0x1a, 0xee, 0x8b, 0xa4, 0x61, 0x2e, 0x4f, 0x30, 0x69, 0x38, 0x02, 0x21, - 0x0b, 0xa9, 0xde, 0x76, 0xf5, 0x47, 0x0b, 0xa9, 0xde, 0x6b, 0xe9, 0x77, 0x59, 0x9f, 0x00, 0x54, - 0x76, 0x6b, 0x54, 0x16, 0xb4, 0x37, 0xf8, 0x47, 0x9d, 0x1e, 0x3f, 0xe7, 0x65, 0xc0, 0xa5, 0x49, - 0x5f, 0x15, 0x9b, 0x15, 0x68, 0x54, 0x85, 0xf1, 0xca, 0xaf, 0x1d, 0xf9, 0x78, 0xad, 0x45, 0x4e, - 0x70, 0xc8, 0xf4, 0x83, 0x11, 0x7e, 0x53, 0x42, 0x2a, 0x1a, 0x2e, 0xaf, 0x51, 0x08, 0xe8, 0x28, - 0x68, 0x13, 0x2e, 0x3e, 0x5a, 0x12, 0xe6, 0x8d, 0x4a, 0xb3, 0xe9, 0x1d, 0x75, 0x42, 0xfe, 0x25, - 0xbf, 0x76, 0x72, 0x5c, 0xbe, 0xb2, 0xdf, 0x8c, 0x2c, 0x24, 0x0e, 0xab, 0x56, 0x3f, 0xe5, 0x09, - 0x5c, 0xab, 0x0d, 0x13, 0x8f, 0x70, 0x48, 0xb6, 0x92, 0x10, 0xcb, 0xb2, 0xd7, 0xe4, 0x33, 0x18, - 0xdd, 0x75, 0xc3, 0x83, 0x1a, 0x6e, 0xfa, 0x38, 0x14, 0xda, 0x27, 0x53, 0x91, 0xdd, 0xf0, 0xa0, - 0x11, 0xb0, 0x72, 0x95, 0x01, 0x29, 0xe0, 0xd6, 0x0a, 0x4c, 0xf2, 0xd6, 0xa4, 0x14, 0xb8, 0xa8, - 0x13, 0xcc, 0x51, 0x82, 0x74, 0x15, 0x54, 0x82, 0x3a, 0x99, 0x3f, 0xc9, 0xc3, 0xf4, 0xd2, 0x81, - 0xd3, 0xd9, 0xc7, 0x5b, 0x4e, 0x10, 0xbc, 0xf4, 0xfc, 0x96, 0xd2, 0x79, 0x2a, 0x02, 0x27, 0x3a, - 0x4f, 0x65, 0xde, 0x45, 0x18, 0xdd, 0x6c, 0xb7, 0x04, 0x0e, 0x17, 0xcf, 0x69, 0x5b, 0x5e, 0xbb, - 0xd5, 0xe8, 0x0a, 0x5a, 0x2a, 0x10, 0xc1, 0xd9, 0xc0, 0x2f, 0x25, 0x4e, 0x5f, 0x84, 0xd3, 0xc1, - 0x2f, 0x15, 0x1c, 0x05, 0x08, 0xad, 0xc0, 0xc5, 0x1a, 0x6e, 0x7a, 0x9d, 0xd6, 0x43, 0xa7, 0x19, - 0x7a, 0x3e, 0xbb, 0x72, 0xe9, 0x8f, 0x24, 0x98, 0x80, 0x56, 0x36, 0x9e, 0xd1, 0x5a, 0x76, 0xd3, - 0x62, 0x27, 0x31, 0xd0, 0x26, 0xbd, 0xb0, 0xa1, 0x37, 0xf6, 0x5c, 0xa6, 0xbf, 0x71, 0x47, 0x5e, - 0xe1, 0x2f, 0xf9, 0x98, 0x6e, 0x0a, 0xa7, 0x2d, 0xb5, 0x12, 0xf9, 0x41, 0xa0, 0xcc, 0x45, 0x40, - 0xda, 0x92, 0x88, 0xb5, 0x03, 0xe3, 0x5b, 0xed, 0xa3, 0x7d, 0xb7, 0x43, 0xd8, 0x40, 0x0d, 0xff, - 0x0c, 0x2d, 0x03, 0x44, 0x05, 0xdc, 0x32, 0x21, 0x6c, 0x62, 0x51, 0x45, 0xfd, 0x01, 0x3f, 0x48, - 0xb4, 0x84, 0x8a, 0x6e, 0xb6, 0x82, 0x67, 0xfd, 0xcd, 0x3e, 0x40, 0x7c, 0x01, 0x28, 0xaf, 0xaf, - 0xe1, 0x90, 0xb0, 0xe1, 0x19, 0xc8, 0x4b, 0x03, 0xc2, 0xe0, 0xc9, 0x71, 0x39, 0xef, 0xb6, 0xec, - 0xfc, 0xda, 0x32, 0x7a, 0x0f, 0x06, 0x28, 0x18, 0x9d, 0xff, 0x09, 0xd9, 0x9e, 0x4a, 0x81, 0x71, - 0x0e, 0xfa, 0x0d, 0xb2, 0x19, 0x30, 0x7a, 0x1f, 0x46, 0x96, 0x71, 0x1b, 0xef, 0x3b, 0xa1, 0x27, - 0x4e, 0x37, 0x53, 0xc9, 0x45, 0xa1, 0xb2, 0xe7, 0x22, 0x48, 0x22, 0xb7, 0xdb, 0xd8, 0x09, 0xbc, - 0x8e, 0x2a, 0xb7, 0xfb, 0xb4, 0x44, 0x95, 0xdb, 0x19, 0x0c, 0xfa, 0x83, 0x1c, 0x8c, 0x56, 0x3a, - 0x1d, 0xae, 0xea, 0x06, 0x7c, 0xd6, 0xa7, 0xef, 0x48, 0x4f, 0x88, 0x75, 0x67, 0x0f, 0xb7, 0xeb, - 0x4e, 0xfb, 0x08, 0x07, 0xd5, 0xaf, 0x89, 0x28, 0xf5, 0x9f, 0x8e, 0xcb, 0x9f, 0x9e, 0x41, 0x79, - 0x8d, 0x7c, 0x2a, 0xb6, 0x7d, 0xc7, 0x0d, 0x03, 0x7a, 0x9b, 0x19, 0x35, 0xa8, 0x9e, 0x1b, 0xa5, - 0x1f, 0xe8, 0x1d, 0x55, 0x59, 0xe3, 0xbc, 0x38, 0xa6, 0x45, 0x73, 0x3d, 0xcd, 0xba, 0x2e, 0xbf, - 0x84, 0x6b, 0xcb, 0x69, 0x4b, 0x60, 0x2d, 0xc1, 0xfc, 0x23, 0x1c, 0xda, 0x38, 0xc0, 0xa1, 0xd8, - 0xb4, 0x74, 0xcb, 0x45, 0xf6, 0x9f, 0x21, 0xfa, 0x5b, 0x22, 0xd3, 0xf5, 0x60, 0x1b, 0x55, 0xd4, - 0x58, 0x7f, 0x23, 0x07, 0xe5, 0x25, 0x1f, 0x33, 0x49, 0x24, 0x85, 0x50, 0x36, 0x33, 0x99, 0xe7, - 0xce, 0x21, 0xf9, 0xa8, 0x96, 0xcc, 0x12, 0x77, 0x00, 0x39, 0x9d, 0x72, 0x6c, 0x3d, 0x83, 0x69, - 0x1b, 0x77, 0xf0, 0x4b, 0xa2, 0xaa, 0x6b, 0xfa, 0x65, 0x19, 0x06, 0xd8, 0xc9, 0x4b, 0x0c, 0x81, - 0x95, 0x9f, 0x4d, 0x57, 0xb7, 0xfe, 0x49, 0x1e, 0x0a, 0x6c, 0xb8, 0x55, 0x2f, 0x3c, 0xdd, 0xf8, - 0xf8, 0x08, 0xf2, 0x3d, 0xd4, 0xfb, 0x9b, 0xd1, 0x6c, 0xf7, 0x45, 0xc2, 0x01, 0xed, 0x2a, 0xf9, - 0xc6, 0x89, 0x4a, 0x32, 0x20, 0xb6, 0x0b, 0x98, 0x79, 0x2b, 0xa1, 0xa3, 0xa3, 0xdf, 0xcd, 0xc1, - 0x20, 0xdb, 0x57, 0xd9, 0x3b, 0x77, 0xf7, 0x7c, 0x76, 0x6e, 0x21, 0xa4, 0x7f, 0xa9, 0xe7, 0x88, - 0xd5, 0x59, 0xff, 0x2c, 0x0f, 0x17, 0x95, 0xb9, 0xe2, 0xe2, 0xe7, 0x3b, 0x4c, 0xb6, 0x51, 0x26, - 0x8c, 0x1a, 0x0c, 0xa9, 0x45, 0x3c, 0xd2, 0xe1, 0xe9, 0xcc, 0xbd, 0x03, 0xc3, 0x64, 0x48, 0x71, - 0xdb, 0x22, 0xfd, 0xc2, 0x32, 0x50, 0x51, 0x7d, 0xea, 0xd9, 0xbb, 0x0b, 0xc3, 0xf4, 0x4f, 0xb2, - 0x22, 0xfd, 0xe9, 0x2b, 0x22, 0x81, 0x90, 0x0b, 0xf0, 0xd8, 0x73, 0x3b, 0x4f, 0x71, 0x78, 0xe0, - 0xb5, 0xf8, 0xb7, 0x7e, 0x8d, 0xf0, 0xc1, 0xff, 0xc7, 0x73, 0x3b, 0x8d, 0x43, 0x5a, 0x7c, 0x56, - 0xdb, 0x55, 0x44, 0xd0, 0x56, 0x88, 0x5b, 0xf7, 0xa0, 0x40, 0x58, 0xd6, 0xe9, 0xb7, 0x96, 0x35, - 0x05, 0xe8, 0x11, 0x0e, 0xab, 0x9e, 0xf6, 0x31, 0xb5, 0xc6, 0x61, 0x74, 0xcb, 0xed, 0xec, 0x8b, - 0x9f, 0xff, 0xbc, 0x0f, 0xc6, 0xd8, 0x6f, 0xbe, 0x02, 0x31, 0x91, 0x27, 0x77, 0x1a, 0x91, 0xe7, - 0x23, 0x18, 0xe7, 0x57, 0x64, 0xd8, 0xa7, 0x57, 0x27, 0x6c, 0x3d, 0xa8, 0x32, 0xc3, 0xae, 0xc8, - 0x1a, 0x2f, 0x58, 0x8d, 0xad, 0x03, 0xa2, 0x75, 0x98, 0x60, 0x05, 0x0f, 0xb1, 0x13, 0x1e, 0x45, - 0xf6, 0x98, 0x49, 0xae, 0xcf, 0x88, 0x62, 0xc6, 0xcf, 0x38, 0xad, 0x67, 0xbc, 0xd0, 0x8e, 0xe1, - 0xa2, 0x2f, 0x60, 0x72, 0xcb, 0xf7, 0xbe, 0x79, 0xa5, 0x08, 0x79, 0x8c, 0xa5, 0x4f, 0x9f, 0x1c, - 0x97, 0x2f, 0x76, 0x49, 0x55, 0x43, 0x15, 0xf5, 0xe2, 0xd0, 0x64, 0x4f, 0xad, 0x05, 0x55, 0xcf, - 0x77, 0x3b, 0xfb, 0x74, 0x35, 0x87, 0xd9, 0x9e, 0x72, 0x83, 0xc6, 0x1e, 0x2d, 0xb4, 0x65, 0x75, - 0xcc, 0xb2, 0x3a, 0xd4, 0xdb, 0xb2, 0x7a, 0x0f, 0x60, 0xdd, 0x73, 0x5a, 0x95, 0x76, 0x7b, 0xa9, - 0x12, 0x50, 0x63, 0x08, 0x17, 0x62, 0xda, 0x9e, 0xd3, 0x6a, 0x38, 0xed, 0x76, 0xa3, 0xe9, 0x04, - 0xb6, 0x02, 0xf3, 0xb8, 0x7f, 0x78, 0xb0, 0x30, 0x64, 0x4f, 0xae, 0xbb, 0x4d, 0xdc, 0x09, 0xf0, - 0xae, 0xe3, 0x77, 0xdc, 0xce, 0x7e, 0x60, 0xfd, 0xe9, 0x00, 0x0c, 0xcb, 0x21, 0xdf, 0x51, 0x15, - 0x22, 0x2e, 0x1a, 0x51, 0x0e, 0x15, 0x19, 0x6c, 0x6c, 0x05, 0x02, 0x5d, 0x66, 0xf7, 0xb1, 0x4c, - 0x28, 0x1b, 0x22, 0xbb, 0xdb, 0xe9, 0x76, 0xd9, 0xad, 0xeb, 0x0c, 0xe4, 0x97, 0xab, 0x74, 0xfe, - 0x87, 0xd9, 0x97, 0xa0, 0xb5, 0x67, 0xe7, 0x97, 0xab, 0x64, 0x97, 0x6d, 0xae, 0x2d, 0x2f, 0xd1, - 0xa9, 0x1c, 0x66, 0xbb, 0xcc, 0x73, 0x5b, 0x4d, 0x9b, 0x96, 0x92, 0xda, 0x5a, 0xe5, 0xe9, 0x3a, - 0x9f, 0x2e, 0x5a, 0x1b, 0x38, 0x87, 0x6d, 0x9b, 0x96, 0x12, 0x55, 0x81, 0xe9, 0xde, 0x4b, 0x5e, - 0x27, 0xf4, 0xbd, 0x76, 0x40, 0x25, 0xda, 0x61, 0xb6, 0x9c, 0x5c, 0x69, 0x6f, 0xf2, 0x2a, 0x3b, - 0x06, 0x8a, 0x76, 0x61, 0xb6, 0xd2, 0x7a, 0xe1, 0x74, 0x9a, 0xb8, 0xc5, 0x6a, 0x76, 0x3d, 0xff, - 0xf9, 0xb3, 0xb6, 0xf7, 0x32, 0xa0, 0xf3, 0x3d, 0xcc, 0x6d, 0x5c, 0x1c, 0x44, 0xd8, 0x00, 0x5e, - 0x0a, 0x20, 0x3b, 0x0d, 0x9b, 0x70, 0xc9, 0xa5, 0xb6, 0x77, 0xd4, 0xe2, 0xab, 0x40, 0xb9, 0x64, - 0x93, 0x14, 0xd8, 0xac, 0x9c, 0xcc, 0xd2, 0x6a, 0xed, 0x29, 0xb5, 0x28, 0xf1, 0x59, 0x3a, 0x08, - 0x0e, 0x6d, 0x52, 0x86, 0x6e, 0xc0, 0x90, 0xd0, 0x7a, 0x98, 0x6d, 0x9b, 0x1a, 0x5a, 0x85, 0xb6, - 0x23, 0xea, 0xc8, 0x91, 0xb0, 0x71, 0xd3, 0x7b, 0x81, 0xfd, 0x57, 0x4b, 0x5e, 0x0b, 0x0b, 0xfb, - 0x07, 0xd7, 0xef, 0x59, 0x45, 0xa3, 0x49, 0x6a, 0x6c, 0x1d, 0x90, 0x34, 0xc0, 0x04, 0xa7, 0x80, - 0x3a, 0x39, 0xf1, 0x06, 0x98, 0x60, 0x15, 0xd8, 0xa2, 0x0e, 0x2d, 0xc3, 0xc5, 0xca, 0x51, 0xe8, - 0x1d, 0x3a, 0xa1, 0xdb, 0xdc, 0xe9, 0xee, 0xfb, 0x0e, 0x69, 0xa4, 0x40, 0x11, 0xa8, 0x6a, 0xe7, - 0x88, 0xca, 0xc6, 0x11, 0xaf, 0xb5, 0x93, 0x08, 0xe8, 0x03, 0x18, 0x5b, 0x0b, 0x98, 0x8d, 0xcb, - 0x09, 0x70, 0x8b, 0x1a, 0x2a, 0x78, 0x2f, 0xdd, 0xa0, 0x41, 0x2d, 0x5e, 0x0d, 0xa2, 0x0c, 0xb6, - 0x6c, 0x0d, 0x0e, 0x59, 0x30, 0x58, 0x09, 0x02, 0x37, 0x08, 0xa9, 0xfd, 0x61, 0xb8, 0x0a, 0x27, - 0xc7, 0xe5, 0x41, 0x87, 0x96, 0xd8, 0xbc, 0xe6, 0x71, 0xff, 0xf0, 0x68, 0x61, 0xec, 0x71, 0xff, - 0xf0, 0x58, 0x61, 0xfc, 0x71, 0xff, 0xf0, 0x78, 0x61, 0xc2, 0xba, 0x0f, 0x17, 0x19, 0x0f, 0x3b, - 0xb5, 0x32, 0x61, 0x6d, 0x01, 0xd4, 0xf0, 0xa1, 0xd3, 0x3d, 0xf0, 0xc8, 0x6e, 0xaf, 0xaa, 0xbf, - 0xb8, 0x30, 0x8a, 0xa4, 0x03, 0x0f, 0xaf, 0xa8, 0x3f, 0x10, 0x3a, 0xa0, 0x80, 0xb4, 0x15, 0x2c, - 0xeb, 0xcf, 0xf3, 0x80, 0xa8, 0x23, 0x4b, 0x2d, 0xf4, 0xb1, 0x73, 0x28, 0xba, 0xf1, 0x31, 0x8c, - 0xb1, 0xcf, 0x11, 0x2b, 0xa6, 0xdd, 0x21, 0x92, 0x2e, 0xe3, 0x43, 0x6a, 0xd5, 0xea, 0x05, 0x5b, - 0x03, 0x25, 0xa8, 0x36, 0x0e, 0x8e, 0x0e, 0x05, 0x6a, 0x5e, 0x43, 0x55, 0xab, 0x08, 0xaa, 0xfa, - 0x1b, 0x7d, 0x01, 0x13, 0x4b, 0xde, 0x61, 0x97, 0xcc, 0x09, 0x47, 0xee, 0xe3, 0x5f, 0x65, 0xde, - 0xae, 0x56, 0xb9, 0x7a, 0xc1, 0x8e, 0x81, 0xa3, 0x0d, 0xb8, 0xf4, 0xb0, 0x7d, 0x14, 0x1c, 0x54, - 0x3a, 0xad, 0xa5, 0xb6, 0x17, 0x08, 0x2a, 0xfd, 0xdc, 0xaa, 0xcd, 0xb9, 0x68, 0x12, 0x62, 0xf5, - 0x82, 0x6d, 0x42, 0x44, 0x37, 0xb8, 0x57, 0xae, 0xbc, 0x21, 0xe0, 0x4e, 0xbb, 0x9b, 0x1d, 0xbc, - 0xf9, 0x6c, 0xf5, 0x82, 0xcd, 0x6a, 0xab, 0x23, 0x30, 0x24, 0xbe, 0x20, 0x77, 0xc9, 0x46, 0x94, - 0xd3, 0xc9, 0xae, 0x39, 0x51, 0x09, 0x86, 0x77, 0xba, 0x84, 0xb1, 0x09, 0xf1, 0xd0, 0x96, 0xbf, - 0xad, 0xef, 0xea, 0x33, 0x8d, 0xe6, 0x55, 0x1d, 0x9e, 0x01, 0x47, 0x05, 0xd6, 0xaa, 0x3e, 0xb9, - 0xd9, 0xd0, 0x5a, 0xbb, 0xf9, 0x58, 0xbb, 0x85, 0xf8, 0x5c, 0x5b, 0xd3, 0xc6, 0xc9, 0xb3, 0xbe, - 0x82, 0x85, 0x9d, 0x2e, 0x51, 0x98, 0x2a, 0xdd, 0x6e, 0xdb, 0x6d, 0x32, 0x0b, 0x15, 0xfd, 0xd2, - 0x88, 0xcd, 0xf2, 0x81, 0x74, 0xf9, 0xcc, 0xa5, 0x3a, 0xc8, 0xd0, 0x23, 0xc1, 0xbe, 0x58, 0xc2, - 0xd3, 0xd3, 0xfa, 0xbd, 0x1c, 0x2c, 0xb0, 0x13, 0x90, 0x4a, 0xfa, 0x3b, 0xaa, 0x63, 0xaa, 0x22, - 0x02, 0x49, 0x37, 0x54, 0xd5, 0xf5, 0x34, 0xba, 0x84, 0xcd, 0xa7, 0x5f, 0xc2, 0x8a, 0x03, 0xd6, - 0x67, 0x3c, 0x60, 0x5f, 0x82, 0xc5, 0x7b, 0xd4, 0x6e, 0x27, 0x3a, 0x15, 0xbc, 0x4e, 0xaf, 0xac, - 0xff, 0x9a, 0x87, 0xd9, 0x47, 0xb8, 0x83, 0x7d, 0x87, 0x8e, 0x53, 0x93, 0xf6, 0xd5, 0x3b, 0x9a, - 0x5c, 0xe6, 0x1d, 0x8d, 0x14, 0x65, 0xf3, 0x29, 0xa2, 0xec, 0x65, 0xe8, 0xdb, 0xb1, 0xd7, 0xf8, - 0xb0, 0x28, 0x93, 0x3e, 0xf2, 0x5d, 0x9b, 0x94, 0xa1, 0xb5, 0xe8, 0x7e, 0xa7, 0xbf, 0xe7, 0xfd, - 0xce, 0x25, 0x6e, 0xef, 0x1e, 0xe2, 0xf7, 0x3b, 0xfa, 0xad, 0xce, 0x86, 0x22, 0x2f, 0x13, 0x76, - 0x73, 0x9b, 0x9f, 0xa9, 0x94, 0x01, 0x72, 0xd1, 0x77, 0xa5, 0x13, 0xfa, 0xaf, 0xd8, 0x16, 0x60, - 0x12, 0xb0, 0x90, 0x7b, 0x4b, 0x5f, 0xc2, 0xa8, 0x02, 0x82, 0x0a, 0xd0, 0xf7, 0x9c, 0xdf, 0x6d, - 0x8d, 0xd8, 0xe4, 0x4f, 0xf4, 0x5d, 0x18, 0x78, 0x41, 0x64, 0x70, 0xce, 0x46, 0x66, 0x22, 0xf9, - 0xbc, 0x16, 0x12, 0xc9, 0x83, 0x09, 0xe8, 0x36, 0x03, 0xfa, 0x24, 0xff, 0x51, 0xce, 0xfa, 0x14, - 0x8a, 0xc9, 0xde, 0x70, 0x71, 0xae, 0x97, 0x86, 0x63, 0x2d, 0xc3, 0xd4, 0x23, 0x1c, 0x46, 0x5e, - 0xb1, 0xca, 0xd5, 0x5b, 0xec, 0x9c, 0x65, 0x58, 0xd6, 0xac, 0x1a, 0x4c, 0xc7, 0xa8, 0xf0, 0xf6, - 0x3f, 0x81, 0x21, 0xe1, 0x4f, 0x93, 0x4b, 0xf7, 0xa7, 0xa1, 0xfb, 0x96, 0x53, 0xb6, 0x05, 0x82, - 0xb5, 0x0b, 0x33, 0x1a, 0xd1, 0x40, 0x52, 0xfd, 0x1e, 0x0c, 0x8b, 0xb2, 0x98, 0x49, 0x42, 0x23, - 0x4b, 0xb7, 0x56, 0x20, 0x90, 0x25, 0x8a, 0x75, 0x00, 0x33, 0xeb, 0x6e, 0xa0, 0x53, 0x66, 0xa3, - 0x9e, 0x83, 0x91, 0x2e, 0xf9, 0xe6, 0x05, 0xee, 0xaf, 0xb1, 0xfd, 0x39, 0x60, 0x0f, 0x93, 0x82, - 0x9a, 0xfb, 0x6b, 0x18, 0x5d, 0x01, 0xa0, 0x95, 0x74, 0xfe, 0x38, 0x7b, 0xa1, 0xe0, 0x4c, 0x57, - 0x44, 0x40, 0x2f, 0x4f, 0xd9, 0x86, 0xb4, 0xe9, 0xdf, 0x96, 0x0f, 0xb3, 0x89, 0x96, 0xf8, 0x18, - 0xee, 0x82, 0xec, 0x5a, 0xc6, 0x18, 0x6c, 0x09, 0x84, 0x6e, 0xc2, 0x64, 0x07, 0x7f, 0x13, 0x36, - 0x12, 0x7d, 0x18, 0x27, 0xc5, 0x5b, 0xa2, 0x1f, 0xd6, 0x8f, 0xa9, 0xe6, 0x1e, 0x77, 0x78, 0x3b, - 0xb7, 0xc9, 0x6b, 0x43, 0x89, 0x0c, 0x49, 0xf7, 0x6f, 0xfa, 0x95, 0x4d, 0xe0, 0x0b, 0x98, 0x33, - 0xb6, 0xf6, 0xab, 0x9e, 0xc4, 0xbf, 0xce, 0xc3, 0x2c, 0xfb, 0x4a, 0x25, 0x8f, 0xc6, 0xe9, 0x79, - 0xd8, 0xb7, 0x62, 0x70, 0xbe, 0x67, 0x30, 0x38, 0x53, 0x14, 0xd5, 0xe0, 0xac, 0x99, 0x99, 0x3f, - 0x32, 0x9b, 0x99, 0xa9, 0xd8, 0xa7, 0x9b, 0x99, 0xe3, 0xc6, 0xe5, 0x95, 0x74, 0xe3, 0x32, 0x35, - 0xb5, 0x19, 0x8c, 0xcb, 0x06, 0x93, 0xf2, 0xe3, 0xfe, 0xe1, 0x7c, 0xa1, 0xcf, 0xaa, 0x43, 0x31, - 0x39, 0xc5, 0xe7, 0xc0, 0x37, 0xfe, 0x34, 0x07, 0x57, 0xb8, 0x84, 0x11, 0x3b, 0x04, 0x67, 0x5f, - 0xc1, 0xf7, 0x61, 0x8c, 0xe3, 0x6e, 0x47, 0x9b, 0x85, 0xb9, 0xae, 0x0a, 0x4e, 0xc8, 0xd8, 0xa9, - 0x06, 0x86, 0xde, 0x57, 0x2c, 0x09, 0xcc, 0x3a, 0x75, 0x99, 0x7c, 0x2e, 0x99, 0xc9, 0x21, 0xd5, - 0x9e, 0x60, 0x7d, 0x0d, 0x0b, 0x69, 0x1d, 0x3f, 0x87, 0x79, 0xf9, 0xb3, 0x1c, 0xcc, 0x71, 0xf2, - 0xda, 0x71, 0x7a, 0x2d, 0x96, 0x7f, 0x06, 0x6f, 0x8b, 0xc7, 0x30, 0x4a, 0x1a, 0x14, 0xfd, 0xd6, - 0xdf, 0x52, 0x29, 0x35, 0xcb, 0x4e, 0xe8, 0xf0, 0x6b, 0x32, 0xe7, 0xb0, 0x2d, 0xdc, 0x2a, 0x6d, - 0x15, 0xd9, 0xfa, 0x21, 0xcc, 0x9b, 0x87, 0x70, 0x0e, 0xf3, 0xf3, 0x18, 0x4a, 0x06, 0xc6, 0xf9, - 0x7a, 0x1f, 0xc4, 0x1f, 0xc0, 0x9c, 0x91, 0xd6, 0x39, 0x74, 0x73, 0x95, 0x7c, 0xee, 0xc3, 0x73, - 0x58, 0x42, 0x6b, 0x17, 0x2e, 0x1b, 0x28, 0x9d, 0x43, 0x17, 0x1f, 0xc1, 0xac, 0x14, 0x73, 0xdf, - 0xa8, 0x87, 0x4f, 0xe1, 0x0a, 0x23, 0x74, 0x3e, 0xab, 0xf2, 0x04, 0xe6, 0x38, 0xb9, 0x73, 0x98, - 0xbd, 0x55, 0x98, 0x8f, 0xb4, 0x59, 0x83, 0x2c, 0x71, 0x6a, 0x26, 0x63, 0xad, 0xc3, 0xd5, 0x88, - 0x52, 0xca, 0x87, 0xf5, 0xf4, 0xd4, 0x98, 0x2c, 0x16, 0xad, 0xd2, 0x39, 0xca, 0x62, 0x11, 0xe0, - 0xb9, 0x89, 0x13, 0x6b, 0x70, 0x89, 0x11, 0xd6, 0xe5, 0xd6, 0x45, 0x55, 0x6e, 0x35, 0x3e, 0x43, - 0x4a, 0x8a, 0xb2, 0x4f, 0xa9, 0x28, 0x2b, 0x40, 0xa2, 0x1e, 0xbe, 0x0f, 0x83, 0xfc, 0xa5, 0x25, - 0xeb, 0x9f, 0x81, 0x18, 0x93, 0xd4, 0x19, 0x1a, 0x07, 0xb6, 0x7e, 0x02, 0x57, 0x98, 0x1a, 0x18, - 0xf7, 0xe8, 0x17, 0x4b, 0xf2, 0xbd, 0x98, 0x16, 0x98, 0xf1, 0x70, 0xc0, 0xa4, 0x0c, 0xee, 0x89, - 0xbd, 0x9d, 0x46, 0xff, 0x54, 0x2e, 0xb6, 0x42, 0xbb, 0xcb, 0x1b, 0xb5, 0xbb, 0xeb, 0x70, 0x4d, - 0x6a, 0x77, 0xf1, 0x66, 0xa4, 0x49, 0xf8, 0x87, 0x30, 0xc7, 0x06, 0xaa, 0xbf, 0x2f, 0x13, 0xdd, - 0xf8, 0x34, 0x36, 0xcc, 0xd4, 0x07, 0x6c, 0xa6, 0x41, 0xfe, 0xed, 0x9c, 0x38, 0x72, 0x66, 0xe2, - 0xdf, 0xb6, 0xba, 0xbb, 0x01, 0x65, 0x39, 0x21, 0x7a, 0x8f, 0x5e, 0x4f, 0xd7, 0x7d, 0x0a, 0xd3, - 0x89, 0x37, 0x10, 0x44, 0x60, 0x45, 0xef, 0x91, 0x63, 0x41, 0x0b, 0xc4, 0xb6, 0x4b, 0x7d, 0x33, - 0x61, 0x4b, 0x48, 0xab, 0x01, 0xf3, 0xc9, 0xa5, 0x70, 0x9b, 0xc2, 0x1d, 0x0a, 0x7d, 0x41, 0x8e, - 0x30, 0x7b, 0x88, 0x91, 0xeb, 0xf1, 0x10, 0x83, 0x9f, 0x63, 0x86, 0x2e, 0xb0, 0x2c, 0x4b, 0xb0, - 0x9a, 0xd8, 0xf8, 0x49, 0xeb, 0x62, 0x3f, 0xfc, 0x06, 0x20, 0x51, 0xb5, 0x54, 0xb3, 0x45, 0xd3, - 0x97, 0xa1, 0x6f, 0xa9, 0x66, 0x73, 0x2f, 0x4c, 0xaa, 0x6e, 0x37, 0x03, 0xdf, 0x26, 0x65, 0x71, - 0xa9, 0x35, 0x7f, 0x0a, 0xa9, 0xf5, 0x71, 0xff, 0x70, 0x5f, 0xa1, 0xdf, 0x46, 0x35, 0x77, 0xbf, - 0xb3, 0xeb, 0x86, 0x07, 0xb2, 0xc1, 0x8a, 0xf5, 0x23, 0xb8, 0xa4, 0x35, 0xcf, 0x4f, 0x71, 0xa6, - 0xfb, 0x28, 0xba, 0x09, 0x43, 0x4b, 0x15, 0x7a, 0xb7, 0x47, 0xed, 0x05, 0x63, 0x8c, 0xdf, 0x34, - 0x9d, 0x06, 0x7d, 0x4a, 0x6f, 0x8b, 0x4a, 0xeb, 0x1f, 0xf7, 0x2b, 0xd4, 0x15, 0xa7, 0xdc, 0x8c, - 0xd1, 0xdd, 0x07, 0x60, 0x3b, 0x44, 0x19, 0x1c, 0x11, 0x00, 0x47, 0xf9, 0x75, 0x04, 0x63, 0xc9, - 0xb6, 0x02, 0x74, 0x5a, 0xa7, 0x5d, 0xee, 0x27, 0xc4, 0x90, 0xc4, 0x9d, 0x9d, 0xf4, 0x13, 0xe2, - 0xa4, 0x03, 0x5b, 0x05, 0x42, 0x3f, 0x89, 0xfb, 0x96, 0x0d, 0xd0, 0x2b, 0xf2, 0xb7, 0xb8, 0x59, - 0xc2, 0x30, 0xb6, 0xb3, 0xb9, 0x97, 0xbd, 0x84, 0x69, 0x82, 0xeb, 0x3e, 0xa3, 0x0e, 0x64, 0x2b, - 0xdf, 0x84, 0xb8, 0xc3, 0x78, 0xfb, 0x20, 0x6d, 0xe7, 0x46, 0x46, 0x3b, 0x11, 0x30, 0x7f, 0xfb, - 0x1d, 0xd1, 0x69, 0x60, 0x59, 0x67, 0x9b, 0xe9, 0xd3, 0x4d, 0x64, 0xaf, 0xaf, 0x74, 0x5a, 0x5d, - 0xcf, 0x95, 0x4a, 0x05, 0xdb, 0x44, 0x7e, 0xbb, 0x81, 0x79, 0xb9, 0xad, 0x02, 0x59, 0x37, 0x33, - 0x7d, 0xba, 0x86, 0xa1, 0x7f, 0x7b, 0x69, 0x7b, 0xbd, 0x90, 0xb3, 0xee, 0x02, 0x28, 0x2d, 0x01, - 0x0c, 0x6e, 0x6c, 0xda, 0x4f, 0x2b, 0xeb, 0x85, 0x0b, 0x68, 0x1a, 0x2e, 0xee, 0xae, 0x6d, 0x2c, - 0x6f, 0xee, 0xd6, 0x1a, 0xb5, 0xa7, 0x15, 0x7b, 0x7b, 0xa9, 0x62, 0x2f, 0x17, 0x72, 0xd6, 0xd7, - 0x30, 0xa5, 0x8f, 0xf0, 0x5c, 0x37, 0x61, 0x08, 0x97, 0xa4, 0x3c, 0xf3, 0x78, 0x77, 0x5b, 0xf1, - 0x73, 0xe1, 0x0a, 0x52, 0xfc, 0xea, 0x8d, 0xab, 0x52, 0xfc, 0x18, 0x29, 0x40, 0xda, 0x85, 0x69, - 0x3e, 0xf3, 0xc2, 0xd4, 0xfa, 0x10, 0xa6, 0xf4, 0x56, 0x4f, 0x6b, 0x22, 0x7a, 0x8b, 0x3a, 0x00, - 0x29, 0x5e, 0x99, 0x44, 0x53, 0x8f, 0xba, 0xc8, 0x39, 0xeb, 0x87, 0x50, 0xe0, 0x50, 0xd1, 0x97, - 0xf7, 0xba, 0xb0, 0xe1, 0xe5, 0x0c, 0x1e, 0xe4, 0xc2, 0x1d, 0xe1, 0x6d, 0x71, 0x2b, 0xd0, 0xab, - 0x85, 0x3f, 0xcf, 0x41, 0x31, 0xe6, 0xe0, 0xb8, 0x74, 0xe0, 0xb4, 0xdb, 0xb8, 0xb3, 0x8f, 0xd1, - 0x2d, 0xe8, 0xdf, 0xde, 0xdc, 0xde, 0xe2, 0x56, 0xb3, 0x29, 0xbe, 0x4d, 0x49, 0x91, 0x84, 0xb1, - 0x29, 0x04, 0x7a, 0x02, 0x17, 0x85, 0xbb, 0x8b, 0xac, 0xe2, 0x4a, 0xc9, 0x95, 0x6c, 0xe7, 0x99, - 0x24, 0x1e, 0x7a, 0x8f, 0x7b, 0x63, 0xfe, 0xec, 0xc8, 0xf5, 0x71, 0x8b, 0x2a, 0xec, 0x13, 0x8b, - 0x28, 0xf2, 0xc6, 0x14, 0x35, 0xb6, 0x0a, 0xc6, 0x3c, 0xe5, 0xad, 0x3f, 0xc8, 0xc1, 0x6c, 0x8a, - 0xc3, 0x26, 0x7a, 0x47, 0x1b, 0xce, 0x25, 0x65, 0x38, 0x02, 0x64, 0xf5, 0x02, 0x1f, 0xcf, 0x92, - 0xe2, 0x03, 0xd4, 0x77, 0x06, 0x1f, 0x20, 0xfe, 0x5e, 0x9b, 0xc2, 0xf1, 0x77, 0x49, 0xb4, 0xdc, - 0x9a, 0x84, 0x71, 0x6d, 0xde, 0x2c, 0x0b, 0xc6, 0xd4, 0x96, 0xc9, 0xe2, 0x2c, 0x79, 0x2d, 0xb9, - 0x38, 0xe4, 0x6f, 0xeb, 0xef, 0xe5, 0x60, 0x8a, 0x0e, 0x71, 0xdf, 0x25, 0xa7, 0x31, 0x9a, 0xa1, - 0x45, 0x6d, 0x24, 0xf3, 0xda, 0x48, 0x62, 0xb0, 0x72, 0x48, 0x9f, 0x24, 0x86, 0x34, 0x6f, 0x1a, - 0x12, 0xd5, 0x04, 0x5d, 0xaf, 0xa3, 0x8d, 0x44, 0xb9, 0x9a, 0xf8, 0x07, 0x39, 0xb8, 0xa4, 0xf4, - 0x49, 0xf6, 0xff, 0xbe, 0xd6, 0xa5, 0x39, 0x43, 0x97, 0x12, 0x93, 0x5c, 0x4d, 0xf4, 0xe8, 0xad, - 0xac, 0x1e, 0xf5, 0x9c, 0xe3, 0xbf, 0xcc, 0xc1, 0xb4, 0x71, 0x0e, 0xd0, 0x0c, 0x11, 0xb7, 0x9a, - 0x3e, 0x0e, 0xf9, 0xf4, 0xf2, 0x5f, 0xa4, 0x7c, 0x2d, 0x08, 0x8e, 0x78, 0x90, 0x93, 0x11, 0x9b, - 0xff, 0x42, 0x6f, 0xc1, 0xf8, 0x16, 0xf6, 0x5d, 0xaf, 0xc5, 0xbc, 0xc3, 0xd8, 0x0d, 0xfa, 0xb8, - 0xad, 0x17, 0xa2, 0x79, 0x18, 0xa9, 0xb4, 0xf7, 0x3d, 0xdf, 0x0d, 0x0f, 0xd8, 0xed, 0xd0, 0x88, - 0x1d, 0x15, 0x10, 0xda, 0xcb, 0xee, 0xbe, 0x70, 0x0a, 0x19, 0xb7, 0xf9, 0x2f, 0x54, 0x84, 0x21, - 0x61, 0xe4, 0xa1, 0x26, 0x22, 0x5b, 0xfc, 0x24, 0x18, 0x5f, 0xda, 0x74, 0x13, 0xd0, 0xa7, 0x48, - 0x36, 0xff, 0x65, 0xdd, 0x86, 0x29, 0xd3, 0x3c, 0x1a, 0xb7, 0xcc, 0xff, 0x9f, 0x87, 0x4b, 0x95, - 0x56, 0xeb, 0xe9, 0xc3, 0xca, 0x32, 0x56, 0x85, 0x9c, 0xf7, 0xa0, 0x7f, 0xad, 0xe3, 0x86, 0x5c, - 0xc2, 0x11, 0xae, 0xcd, 0x06, 0x48, 0x02, 0x45, 0x56, 0x88, 0xfc, 0x8f, 0x6c, 0xb8, 0xb4, 0xf2, - 0x8d, 0x1b, 0x84, 0x6e, 0x67, 0x5f, 0xf5, 0x8f, 0xce, 0x9f, 0xc6, 0x3f, 0x7a, 0xf5, 0x82, 0x6d, - 0x42, 0x46, 0xdb, 0x30, 0xb3, 0x81, 0x5f, 0x1a, 0xb6, 0x90, 0x7c, 0x36, 0xa2, 0x1c, 0xf4, 0xc4, - 0xce, 0x49, 0xc1, 0x55, 0x77, 0xe8, 0xef, 0xe6, 0xe9, 0xf3, 0x34, 0x65, 0x60, 0xbc, 0xe5, 0x1d, - 0x98, 0x52, 0x3a, 0x14, 0xf1, 0xa9, 0x1c, 0x7f, 0x10, 0x6b, 0x1c, 0x8e, 0x7a, 0x90, 0x8c, 0xe8, - 0x68, 0x17, 0x66, 0xf5, 0x4e, 0x45, 0x94, 0xf5, 0xc3, 0x60, 0x02, 0x59, 0xbd, 0x60, 0xa7, 0x61, - 0xa3, 0x45, 0xe8, 0xab, 0x34, 0x9f, 0xf3, 0x69, 0x31, 0x2f, 0x19, 0x1b, 0x59, 0xa5, 0xf9, 0x9c, - 0x3e, 0xf3, 0x6e, 0x3e, 0xd7, 0xce, 0xc3, 0xbf, 0xce, 0xc1, 0x6c, 0xca, 0x0a, 0xa3, 0x05, 0x00, - 0x56, 0xa8, 0x7c, 0x11, 0x94, 0x12, 0x22, 0xa0, 0xb1, 0x5f, 0xd4, 0x53, 0xac, 0x8f, 0xb2, 0x60, - 0xf1, 0x02, 0x23, 0xaa, 0xb0, 0x15, 0x20, 0xb4, 0x05, 0xa3, 0xec, 0x17, 0x7b, 0x08, 0xa2, 0xb3, - 0x6d, 0xa5, 0x86, 0x09, 0x32, 0x2d, 0x5a, 0xd0, 0x88, 0x3f, 0x00, 0x51, 0x49, 0x70, 0x93, 0xe6, - 0x52, 0x7c, 0x14, 0x72, 0xd0, 0xe8, 0x16, 0x0c, 0xb2, 0x42, 0xbe, 0x86, 0xe2, 0x79, 0x67, 0x04, - 0xcc, 0xeb, 0xad, 0x7f, 0x98, 0x83, 0x19, 0xf6, 0x45, 0x4c, 0x1c, 0x8d, 0x0f, 0xb5, 0xa3, 0x71, - 0x4d, 0x76, 0xd8, 0x04, 0xac, 0x9d, 0x8e, 0xaa, 0xfe, 0x6a, 0xe0, 0xb4, 0xa7, 0x42, 0x45, 0x52, - 0xf7, 0xed, 0x3f, 0xca, 0x09, 0x0b, 0x4f, 0x72, 0xeb, 0xae, 0xc0, 0xd8, 0xeb, 0x6d, 0x59, 0x0d, - 0x0d, 0xbd, 0xcf, 0x76, 0x54, 0x3e, 0x7b, 0xa4, 0x99, 0x9b, 0xea, 0x33, 0x28, 0xa5, 0x4f, 0x4d, - 0xaf, 0x6d, 0x65, 0x3d, 0x34, 0x60, 0xbf, 0xce, 0x72, 0x1e, 0x25, 0xe8, 0xd4, 0x5e, 0x75, 0x9a, - 0x62, 0x45, 0x6f, 0xc6, 0xfd, 0x28, 0x53, 0x7d, 0xd3, 0xd4, 0xde, 0xe6, 0xa3, 0xab, 0x04, 0xbe, - 0x39, 0xa9, 0xb0, 0xa7, 0x76, 0xff, 0x5f, 0xe4, 0xf5, 0xbd, 0xf8, 0x3a, 0x8d, 0x2e, 0xc1, 0xf8, - 0x06, 0x7e, 0x99, 0x68, 0x97, 0xfa, 0xdd, 0x74, 0xf0, 0xcb, 0x86, 0xd2, 0xb6, 0xea, 0x90, 0xae, - 0xe1, 0xa0, 0x3d, 0x98, 0x10, 0x5c, 0xe3, 0xb4, 0xcc, 0x93, 0xbd, 0x82, 0x23, 0x2d, 0xa4, 0xbc, - 0x59, 0x89, 0x51, 0x3c, 0xff, 0xf3, 0x6c, 0x6d, 0x41, 0x31, 0x39, 0x7b, 0xbc, 0xb5, 0xf7, 0x7a, - 0xad, 0x3d, 0x33, 0x85, 0xb4, 0xf4, 0x7d, 0xb0, 0x4a, 0xcd, 0x53, 0x12, 0x46, 0xda, 0x1b, 0xee, - 0xc5, 0x17, 0x83, 0xfa, 0xef, 0x88, 0xc5, 0x50, 0xfa, 0x27, 0xdd, 0x6a, 0x97, 0xa8, 0x85, 0x4f, - 0xa5, 0xc4, 0x3b, 0x76, 0x1b, 0x86, 0x78, 0x51, 0xec, 0x0d, 0x79, 0xb4, 0x2b, 0x05, 0x80, 0xf5, - 0x87, 0x39, 0xb8, 0x4c, 0xed, 0x8d, 0x6e, 0x67, 0xbf, 0x8d, 0x77, 0x02, 0xdd, 0x33, 0xf6, 0x5d, - 0x8d, 0xd1, 0xcc, 0xa6, 0xbc, 0x5c, 0xfa, 0x55, 0xb1, 0x97, 0x3f, 0xce, 0x41, 0xc9, 0xd4, 0xb7, - 0xf3, 0xe5, 0x30, 0x77, 0xb8, 0x32, 0x97, 0xe7, 0x96, 0x14, 0x86, 0x2e, 0xdb, 0x14, 0x83, 0x25, - 0x83, 0x24, 0xff, 0x6b, 0xac, 0xe5, 0x7f, 0xe5, 0x60, 0x6a, 0x2d, 0x50, 0x05, 0x7c, 0x3e, 0x71, - 0x77, 0x4c, 0x0f, 0x29, 0xe9, 0xba, 0x9a, 0xe3, 0x75, 0xbc, 0xa7, 0xbc, 0xcc, 0xc9, 0x67, 0xbd, - 0x90, 0xd4, 0x82, 0xb4, 0xdc, 0x84, 0xfe, 0x0d, 0x22, 0x4e, 0xf5, 0xf1, 0xfd, 0xc7, 0x30, 0x48, - 0x11, 0x7d, 0x44, 0x43, 0xba, 0x4c, 0x7e, 0xa0, 0x87, 0x89, 0xa7, 0x3a, 0xfd, 0xbd, 0x5f, 0x00, - 0x26, 0xa3, 0xcb, 0x54, 0x87, 0x61, 0x70, 0xdb, 0xf1, 0xf7, 0x71, 0x68, 0xfd, 0x10, 0x4a, 0xdc, - 0xd3, 0x87, 0x59, 0x70, 0xa9, 0x3f, 0x50, 0x10, 0x39, 0x73, 0x65, 0x79, 0xe7, 0x2c, 0x00, 0xd4, - 0x42, 0xc7, 0x0f, 0xd7, 0x3a, 0x2d, 0xfc, 0x0d, 0x1d, 0xed, 0x80, 0xad, 0x94, 0x58, 0xef, 0xc3, - 0x88, 0x1c, 0x02, 0xd5, 0x00, 0x15, 0x89, 0x91, 0x0e, 0x67, 0x4a, 0x7b, 0x3c, 0x24, 0x5e, 0x0c, - 0x3d, 0x80, 0xe9, 0xd8, 0x52, 0x44, 0x8f, 0xd9, 0xa4, 0x66, 0x46, 0x5d, 0x23, 0x6d, 0xf9, 0xdb, - 0x5a, 0x82, 0x8b, 0x89, 0x95, 0x46, 0x88, 0xbe, 0x33, 0x63, 0xda, 0x3d, 0xf9, 0xa0, 0xd4, 0x6a, - 0xab, 0xa4, 0x6c, 0x7b, 0xbd, 0xc6, 0x9c, 0xbf, 0x49, 0xd9, 0xf6, 0x7a, 0xad, 0x3a, 0xc8, 0x76, - 0x8e, 0xf5, 0x4f, 0xf3, 0x54, 0xe9, 0x4d, 0xcc, 0x41, 0xcc, 0x7e, 0xa8, 0xda, 0x30, 0xab, 0x30, - 0x42, 0x47, 0xbc, 0x2c, 0x9e, 0x37, 0x64, 0x3b, 0xa7, 0x0c, 0xff, 0xfc, 0xb8, 0x7c, 0x81, 0x7a, - 0xa4, 0x44, 0x68, 0xe8, 0x73, 0x18, 0x5a, 0xe9, 0xb4, 0x28, 0x85, 0xbe, 0x33, 0x50, 0x10, 0x48, - 0x64, 0x1d, 0x68, 0x97, 0x89, 0x28, 0xc4, 0xcd, 0x4e, 0xb6, 0x52, 0x42, 0xa7, 0xd9, 0x3d, 0x74, - 0x99, 0x13, 0xd8, 0x80, 0xcd, 0x7e, 0xd0, 0xa7, 0x81, 0xa4, 0x0b, 0x22, 0x6e, 0xc1, 0x88, 0x2d, - 0x7f, 0x23, 0x0b, 0x06, 0x36, 0xfd, 0x16, 0x7f, 0x32, 0x3c, 0xb1, 0x38, 0x26, 0x82, 0x38, 0x92, - 0x32, 0x9b, 0x55, 0x59, 0xff, 0x23, 0x07, 0xb3, 0x8f, 0x70, 0x68, 0xdc, 0x37, 0xda, 0xac, 0xe4, - 0xde, 0x78, 0x56, 0xf2, 0xaf, 0x33, 0x2b, 0x72, 0xd4, 0x7d, 0x69, 0xa3, 0xee, 0x4f, 0x1b, 0xf5, - 0x40, 0xfa, 0xa8, 0x1f, 0xc1, 0x20, 0x1b, 0x2a, 0xba, 0x0e, 0x03, 0x6b, 0x21, 0x3e, 0x8c, 0x8c, - 0x21, 0xaa, 0x6b, 0x9d, 0xcd, 0xea, 0x88, 0xc6, 0xb5, 0xee, 0x04, 0xa1, 0x78, 0x6e, 0x30, 0x62, - 0x8b, 0x9f, 0xd6, 0x4f, 0xe9, 0xc3, 0xa8, 0x75, 0xaf, 0xf9, 0x5c, 0xb1, 0x54, 0x0f, 0xb1, 0x53, - 0x19, 0xbf, 0xd9, 0x20, 0x50, 0xac, 0xc6, 0x16, 0x10, 0xe8, 0x2a, 0x8c, 0xae, 0x75, 0x1e, 0x7a, - 0x7e, 0x13, 0x6f, 0x76, 0xda, 0x8c, 0xfa, 0xb0, 0xad, 0x16, 0x71, 0x0b, 0x0e, 0x6f, 0x21, 0xb2, - 0xe0, 0xd0, 0x82, 0x98, 0x05, 0x87, 0xc5, 0xf9, 0xb2, 0x59, 0x1d, 0x37, 0x10, 0x91, 0xbf, 0xb3, - 0xcc, 0x37, 0xd2, 0xce, 0xd3, 0x0b, 0x70, 0x0f, 0x2e, 0xdb, 0xb8, 0xdb, 0x76, 0x88, 0xc0, 0x75, - 0xe8, 0x31, 0x78, 0x39, 0xe6, 0xab, 0x06, 0xff, 0x74, 0xdd, 0x1f, 0x42, 0x76, 0x39, 0x9f, 0xd1, - 0xe5, 0x43, 0xb8, 0xf6, 0x08, 0x87, 0xc6, 0x60, 0x5d, 0xd1, 0xe0, 0x57, 0x61, 0x38, 0xd0, 0x6d, - 0xf8, 0xbd, 0xe2, 0x84, 0xf1, 0x5b, 0x2e, 0x4e, 0x47, 0xfe, 0x65, 0x7d, 0x01, 0xe5, 0xb4, 0xe6, - 0x4e, 0xe7, 0x07, 0xeb, 0xc2, 0xd5, 0x74, 0x02, 0xf2, 0xb3, 0x28, 0xec, 0xfd, 0x52, 0x75, 0xce, - 0xee, 0xad, 0x7e, 0x45, 0xc0, 0xff, 0xb0, 0xaa, 0xc2, 0x23, 0xf0, 0x0d, 0xba, 0xdb, 0xa0, 0x57, - 0xe9, 0x3a, 0x81, 0x68, 0x5e, 0x2b, 0x30, 0x2c, 0xca, 0xf8, 0xbc, 0xa6, 0xc6, 0x41, 0xa3, 0x13, - 0xda, 0x12, 0x04, 0x24, 0x9a, 0xf5, 0x53, 0x71, 0xad, 0xa4, 0x63, 0x9c, 0xee, 0xd1, 0xcd, 0x69, - 0xee, 0x91, 0x2c, 0x0f, 0x2e, 0xeb, 0xb4, 0xd5, 0xeb, 0x82, 0x82, 0x72, 0x5d, 0xc0, 0x6e, 0x09, - 0xae, 0xea, 0xe6, 0xeb, 0x3c, 0xdf, 0x97, 0x51, 0x11, 0x5a, 0x50, 0x2f, 0x05, 0xc6, 0x92, 0xaf, - 0x94, 0xee, 0x41, 0xc9, 0xd4, 0xa0, 0x62, 0x40, 0x91, 0x96, 0x67, 0x1e, 0x33, 0xe3, 0x37, 0x73, - 0x60, 0x69, 0xde, 0x51, 0x5a, 0x48, 0x2b, 0x79, 0x64, 0xde, 0x11, 0x8c, 0x8d, 0xfa, 0x63, 0x31, - 0xdf, 0xfb, 0x36, 0x29, 0x50, 0x9f, 0x86, 0x31, 0x6e, 0x77, 0x0f, 0x86, 0x36, 0xf0, 0x37, 0x11, - 0xfb, 0x61, 0xb2, 0x28, 0xf5, 0x98, 0x7a, 0x8e, 0xd5, 0x47, 0xa7, 0x02, 0x8c, 0x08, 0x42, 0xd7, - 0x33, 0xfb, 0xc0, 0xfb, 0xbf, 0x07, 0x85, 0x78, 0x1d, 0x5f, 0xfb, 0x9e, 0xd1, 0xbd, 0xe8, 0xeb, - 0x8d, 0x78, 0x50, 0xaf, 0xc0, 0x4e, 0xd0, 0x3b, 0x7b, 0xef, 0xd1, 0xc7, 0x00, 0xdb, 0x5e, 0xe8, - 0xb4, 0x97, 0xa8, 0x8d, 0x8b, 0x32, 0x7e, 0x16, 0x22, 0x2a, 0x24, 0xa5, 0x8d, 0xf8, 0xeb, 0x58, - 0x05, 0xd8, 0xfa, 0x3e, 0x3d, 0x91, 0xe6, 0x4e, 0x9f, 0xee, 0x90, 0x2c, 0xc1, 0xf5, 0x98, 0x37, - 0xc2, 0x6b, 0x10, 0x09, 0x61, 0x9a, 0x4c, 0xbf, 0x8c, 0x0d, 0xf6, 0xed, 0xac, 0xfa, 0xbf, 0xcb, - 0x31, 0x17, 0x4a, 0xb5, 0x59, 0xbe, 0xd0, 0x4b, 0x00, 0x51, 0x69, 0xcc, 0x47, 0x5f, 0x0d, 0x75, - 0x46, 0x95, 0xd7, 0x28, 0xd4, 0x59, 0x60, 0x2b, 0x68, 0xdf, 0xee, 0x4a, 0x3e, 0xa0, 0x2e, 0x08, - 0xb2, 0xf5, 0xd3, 0xcd, 0xfb, 0x07, 0xc2, 0x46, 0x73, 0x46, 0xbc, 0x03, 0x98, 0xd2, 0xa2, 0x41, - 0x47, 0xe1, 0x6d, 0xa3, 0x28, 0xd8, 0x23, 0xd5, 0xcf, 0x7e, 0x79, 0x5c, 0xfe, 0xe8, 0x2c, 0xaf, - 0xc6, 0x04, 0xcd, 0x6d, 0xf9, 0x38, 0xd2, 0x9a, 0x85, 0xbe, 0x25, 0x7b, 0x9d, 0xb2, 0x2a, 0x7b, - 0x5d, 0xb2, 0x2a, 0x7b, 0xdd, 0xfa, 0xef, 0x79, 0x28, 0xb3, 0xb7, 0xd1, 0xd4, 0x73, 0x25, 0xd2, - 0x95, 0x14, 0x57, 0x98, 0xd3, 0x5a, 0x08, 0x62, 0x6f, 0x9f, 0xf3, 0xa7, 0x79, 0xfb, 0xfc, 0xeb, - 0xaf, 0x6f, 0x55, 0x65, 0x91, 0xfe, 0x22, 0xc3, 0x00, 0xab, 0x35, 0x59, 0x08, 0x52, 0x9a, 0x48, - 0x9a, 0x34, 0xfa, 0x5f, 0xc3, 0xa4, 0x71, 0x0f, 0x86, 0xa8, 0xea, 0xb1, 0xb6, 0xc5, 0xfd, 0x2d, - 0xe9, 0xf6, 0xa4, 0x61, 0x0c, 0x1a, 0xae, 0x1a, 0x1f, 0x45, 0x80, 0x59, 0x7f, 0x3f, 0x0f, 0x57, - 0xd3, 0xe7, 0x9c, 0xf7, 0x6d, 0x59, 0x0b, 0xe8, 0x9b, 0xe1, 0xa3, 0x43, 0xcf, 0x8e, 0x12, 0xd0, - 0x37, 0x1e, 0xc4, 0x57, 0xbc, 0x28, 0x8a, 0xdd, 0x86, 0x69, 0x0f, 0x8d, 0x44, 0x38, 0x74, 0x56, - 0xa4, 0xc5, 0xf1, 0xe2, 0x65, 0x68, 0x0f, 0x66, 0xb7, 0x7c, 0xf7, 0x85, 0x13, 0xe2, 0x27, 0xf8, - 0xd5, 0x96, 0xd7, 0x76, 0x9b, 0xaf, 0x56, 0x3a, 0xce, 0x5e, 0x1b, 0xb7, 0xf8, 0x33, 0xb1, 0x5b, - 0x27, 0xc7, 0xe5, 0xb7, 0xba, 0x0c, 0x84, 0x1c, 0xcc, 0x46, 0x97, 0x02, 0x35, 0x30, 0x83, 0x52, - 0x88, 0xa6, 0x11, 0xb2, 0xfe, 0x6d, 0x0e, 0xe6, 0xa8, 0x40, 0xcd, 0x6f, 0x16, 0x44, 0xe3, 0xaf, - 0xe5, 0xaa, 0xa9, 0x0e, 0x90, 0xef, 0x45, 0xea, 0xaa, 0xa9, 0xbd, 0xb8, 0xb2, 0x35, 0x30, 0xb4, - 0x06, 0xa3, 0xfc, 0xb7, 0x62, 0x3e, 0x9e, 0x56, 0x18, 0x16, 0xdd, 0xea, 0xcc, 0x7a, 0x44, 0x37, - 0x36, 0x27, 0xd6, 0xa0, 0xef, 0x90, 0x55, 0x5c, 0xeb, 0x17, 0x79, 0x98, 0xaf, 0x63, 0xdf, 0x7d, - 0xf6, 0x2a, 0x65, 0x30, 0x9b, 0x30, 0x25, 0x8a, 0xe8, 0x98, 0xf5, 0x23, 0xc6, 0x02, 0xfc, 0x88, - 0xae, 0x06, 0x04, 0xa0, 0x21, 0x4f, 0x9c, 0x11, 0xf1, 0x0c, 0x4e, 0x98, 0xef, 0xc1, 0x70, 0x2c, - 0x42, 0x01, 0x5d, 0x7f, 0x71, 0x42, 0xf5, 0xf0, 0x90, 0xf2, 0xa8, 0xfe, 0x76, 0xfa, 0x15, 0x25, - 0xb7, 0x24, 0xf4, 0x8a, 0x3c, 0x43, 0x0f, 0x2c, 0x39, 0xac, 0x8e, 0x52, 0x6b, 0x38, 0xb0, 0xab, - 0x17, 0xec, 0xb4, 0x96, 0xaa, 0xa3, 0x30, 0x52, 0xa1, 0xd7, 0xae, 0x44, 0x71, 0xff, 0x9f, 0x79, - 0x58, 0x10, 0xef, 0x78, 0x52, 0xa6, 0xf9, 0x2b, 0x98, 0x15, 0x45, 0x95, 0x2e, 0x11, 0x18, 0x70, - 0x4b, 0x9f, 0x69, 0x16, 0x64, 0x4b, 0xcc, 0xb4, 0xc3, 0x61, 0xa2, 0xc9, 0x4e, 0x43, 0x3f, 0x1f, - 0x83, 0xe8, 0xe7, 0xa6, 0x78, 0x11, 0xd4, 0x30, 0xa9, 0xf2, 0x4c, 0x3d, 0x86, 0xa4, 0xca, 0x3f, - 0x5b, 0x09, 0x83, 0x6a, 0xff, 0x9b, 0x1a, 0x54, 0x57, 0x2f, 0xc4, 0x4d, 0xaa, 0xd5, 0x09, 0x18, - 0xdb, 0xc0, 0x2f, 0xa3, 0x79, 0xff, 0x9d, 0x5c, 0xec, 0x49, 0x23, 0x91, 0x30, 0xd8, 0xdb, 0xc6, - 0x5c, 0x14, 0x72, 0x80, 0x3e, 0x69, 0x54, 0x25, 0x0c, 0x06, 0xba, 0x06, 0x43, 0xcc, 0x6d, 0xb7, - 0x75, 0x0a, 0xdd, 0x5c, 0x3e, 0xc8, 0x69, 0x32, 0x14, 0xa6, 0xa6, 0x73, 0x7c, 0xeb, 0x09, 0x5c, - 0xe3, 0x5e, 0xe3, 0xfa, 0xe2, 0xd3, 0x86, 0xce, 0xf8, 0xf9, 0xb2, 0x1c, 0x58, 0x78, 0x84, 0xe3, - 0xac, 0x47, 0x7b, 0xb0, 0xf4, 0x05, 0x4c, 0x6a, 0xe5, 0x92, 0x22, 0x95, 0x4a, 0xe5, 0x1e, 0x92, - 0xa4, 0xe3, 0xd0, 0xd6, 0x55, 0x53, 0x13, 0x6a, 0x67, 0x2d, 0x4c, 0xa3, 0x65, 0xf9, 0xd1, 0x2d, - 0x72, 0x70, 0x06, 0xae, 0x77, 0x4b, 0x39, 0xd7, 0x8c, 0xe3, 0xb1, 0xb8, 0x41, 0xe2, 0xcb, 0x2b, - 0x6b, 0xad, 0x71, 0x18, 0x5d, 0xf2, 0x3a, 0x21, 0xfe, 0x86, 0x8a, 0x3a, 0xd6, 0x04, 0x8c, 0x89, - 0xaa, 0x36, 0x0e, 0x02, 0xeb, 0x8f, 0xfa, 0xc0, 0xe2, 0x13, 0x6b, 0xb2, 0x9e, 0x8a, 0xf9, 0xd8, - 0x4b, 0x74, 0x96, 0x7f, 0xa8, 0x66, 0x54, 0x1b, 0x71, 0x54, 0xcb, 0x76, 0x1e, 0x95, 0xf3, 0x9a, - 0x51, 0xa9, 0x1e, 0x10, 0x38, 0x3e, 0xfa, 0x1f, 0xa5, 0xb0, 0x49, 0x76, 0xd8, 0x68, 0x2c, 0xee, - 0x14, 0x36, 0xa9, 0xd1, 0x35, 0xb3, 0x4c, 0x5b, 0x9b, 0x06, 0x2e, 0x72, 0x20, 0xf9, 0xde, 0x52, - 0xd6, 0x70, 0x1f, 0x26, 0x56, 0xd0, 0x48, 0xe4, 0x9f, 0x50, 0x89, 0xa0, 0x1d, 0x7d, 0x2e, 0xf9, - 0x79, 0x14, 0x5e, 0x1b, 0x6a, 0x15, 0xa3, 0xda, 0x55, 0x4a, 0xf4, 0x74, 0x1e, 0x1a, 0xac, 0x62, - 0x11, 0xff, 0x7d, 0xe9, 0xbb, 0x4f, 0x3e, 0xa4, 0x6e, 0x1b, 0xf3, 0x87, 0x2a, 0x62, 0x59, 0x8e, - 0xcc, 0xb7, 0xdf, 0xb9, 0x53, 0xf1, 0x68, 0x1a, 0x05, 0x15, 0x73, 0xf4, 0xb4, 0x2b, 0x17, 0x13, - 0x7d, 0xeb, 0x38, 0x27, 0x5e, 0x2c, 0x24, 0xae, 0x84, 0xcf, 0x2a, 0x49, 0x56, 0xb5, 0x5b, 0xdc, - 0x7c, 0xca, 0x2d, 0xae, 0x76, 0xe7, 0x15, 0xf6, 0xb8, 0xd6, 0xed, 0x7b, 0xf3, 0x6b, 0xa0, 0x7f, - 0x39, 0x08, 0x17, 0xb7, 0x9c, 0x7d, 0xb7, 0x43, 0x78, 0x8f, 0x88, 0xdc, 0x8b, 0x2a, 0x89, 0xdc, - 0x0e, 0xd9, 0xae, 0xb1, 0x86, 0xe4, 0x0d, 0x8b, 0x6a, 0x98, 0xf5, 0x7c, 0xda, 0x2b, 0x52, 0x3d, - 0x98, 0xfa, 0xc7, 0x9a, 0xd5, 0x3f, 0x91, 0x67, 0x84, 0x7a, 0xf7, 0x75, 0xbc, 0x56, 0x2c, 0xdf, - 0x09, 0xb5, 0x9c, 0x27, 0x03, 0xd0, 0x0f, 0x9c, 0x73, 0x00, 0xfa, 0x1f, 0xc2, 0xe8, 0x93, 0xa3, - 0x3d, 0x99, 0x4b, 0x63, 0xb0, 0x67, 0x80, 0x73, 0xba, 0x06, 0xcf, 0x8f, 0xf6, 0xcc, 0xd9, 0x34, - 0x54, 0x62, 0xc6, 0x60, 0xed, 0x43, 0xbf, 0x92, 0x60, 0xed, 0xa9, 0x79, 0x02, 0x86, 0xbf, 0x95, - 0x3c, 0x01, 0x86, 0x80, 0xeb, 0x23, 0xe7, 0x1f, 0x70, 0x5d, 0x0b, 0x46, 0x0e, 0x6f, 0x18, 0x8c, - 0xbc, 0x0a, 0x30, 0xec, 0x47, 0x21, 0xad, 0xfb, 0x0b, 0x03, 0x6c, 0xed, 0x84, 0xc7, 0xf1, 0xbf, - 0x1a, 0x82, 0xa9, 0x75, 0x37, 0x08, 0xc5, 0xe1, 0x09, 0xa2, 0x2f, 0xeb, 0x98, 0x28, 0x53, 0x34, - 0x5f, 0x2e, 0x04, 0xb3, 0xf2, 0x46, 0x2c, 0xed, 0x93, 0x86, 0x80, 0xde, 0x57, 0x2f, 0x5a, 0xf2, - 0x4a, 0xf4, 0xcf, 0x64, 0xc6, 0x1e, 0xf5, 0x06, 0xe6, 0x1d, 0xcd, 0xce, 0x9f, 0x69, 0x18, 0x79, - 0x10, 0x37, 0xfe, 0xf3, 0xe0, 0x5c, 0xf4, 0x9b, 0xa3, 0x1b, 0x22, 0xa2, 0x5b, 0x81, 0x1d, 0x18, - 0xa4, 0x91, 0x74, 0xc4, 0x8b, 0xe1, 0xb7, 0x39, 0xff, 0x31, 0x4d, 0x02, 0x8b, 0xb9, 0xc3, 0x9f, - 0x0b, 0xd3, 0xc0, 0x53, 0x6d, 0x5a, 0xa0, 0x06, 0xcc, 0x61, 0x20, 0x68, 0x1b, 0x2e, 0x6d, 0xf9, - 0xb8, 0xc5, 0xdd, 0x66, 0xbb, 0x3e, 0xd7, 0x12, 0xd9, 0xd3, 0x3d, 0x1a, 0x09, 0xb3, 0x2b, 0xaa, - 0x1b, 0x58, 0xd6, 0xab, 0x0c, 0xdc, 0x80, 0x8e, 0x56, 0x60, 0xa2, 0x86, 0x1d, 0xbf, 0x79, 0xf0, - 0x04, 0xbf, 0x22, 0xdf, 0x9d, 0xa0, 0x38, 0x14, 0x85, 0x8f, 0x0d, 0x68, 0x0d, 0x19, 0x28, 0xad, - 0x52, 0xef, 0xdf, 0x75, 0x24, 0xf4, 0x7d, 0x18, 0xac, 0x79, 0x7e, 0x58, 0x7d, 0x15, 0x4b, 0xe1, - 0xc4, 0x0a, 0xab, 0x97, 0x45, 0x08, 0xdd, 0xc0, 0xf3, 0xc3, 0xc6, 0x9e, 0x3a, 0x6f, 0x1c, 0x0f, - 0x3d, 0x24, 0x42, 0x2d, 0x11, 0xb4, 0xa5, 0x0d, 0x87, 0x45, 0xdf, 0xe0, 0x82, 0x2b, 0x95, 0xce, - 0x4d, 0x86, 0x9c, 0x18, 0x16, 0x7a, 0x05, 0x53, 0xfa, 0xd1, 0x7a, 0xe8, 0xb6, 0x09, 0x3f, 0x02, - 0x2d, 0x19, 0x8a, 0x09, 0xa4, 0x7a, 0x8b, 0xf7, 0xf2, 0x6a, 0xfc, 0x00, 0x3f, 0xa3, 0xf5, 0x6a, - 0x44, 0x70, 0x13, 0x3e, 0x7a, 0x4a, 0x23, 0x18, 0xb3, 0x99, 0xa9, 0x04, 0x22, 0xb4, 0x35, 0x19, - 0x04, 0x0d, 0xbc, 0x77, 0x44, 0x8f, 0x27, 0x9d, 0x51, 0x27, 0x88, 0x47, 0xb8, 0xb6, 0x13, 0xa8, - 0x68, 0x0b, 0x2e, 0xee, 0x04, 0x78, 0xcb, 0xc7, 0x2f, 0x5c, 0xfc, 0x52, 0xd0, 0x1b, 0xa3, 0xf4, - 0xe8, 0x72, 0x13, 0x7a, 0x5d, 0x56, 0x6b, 0x22, 0x98, 0x44, 0x2e, 0x7d, 0x0c, 0xa3, 0xca, 0x7e, - 0x33, 0xbc, 0x3d, 0x9f, 0x52, 0xdf, 0x9e, 0x8f, 0xa8, 0x6f, 0xcc, 0xff, 0x32, 0xc7, 0xec, 0x8c, - 0xca, 0x06, 0xe6, 0x46, 0x8b, 0x4d, 0x18, 0x91, 0x85, 0xf2, 0xa5, 0x83, 0x10, 0x7c, 0x62, 0x1f, - 0x4e, 0x76, 0x7c, 0xc4, 0xe9, 0x56, 0x7b, 0x1b, 0xd1, 0xf8, 0x76, 0x6d, 0x7f, 0xbf, 0x1d, 0xbd, - 0x89, 0xe4, 0xef, 0x37, 0x7d, 0xa7, 0xf9, 0x3c, 0x32, 0xbe, 0xfe, 0x84, 0x9c, 0x0f, 0xb5, 0x82, - 0x67, 0x9e, 0x9a, 0xd5, 0xd3, 0x06, 0xf1, 0x4a, 0x91, 0xbc, 0x40, 0x3e, 0x0d, 0x65, 0xc5, 0xfa, - 0xc1, 0x51, 0x11, 0xa8, 0x27, 0xf0, 0xa4, 0x65, 0xb3, 0x27, 0x7d, 0xc6, 0x1e, 0x7c, 0x90, 0x7c, - 0x94, 0x46, 0x19, 0x73, 0xf4, 0x28, 0x4d, 0x9d, 0xc6, 0xe8, 0x79, 0xda, 0x0e, 0xcc, 0xd9, 0xf8, - 0xd0, 0x7b, 0x81, 0xcf, 0x97, 0xec, 0x8f, 0xe0, 0xb2, 0x4e, 0x70, 0xa7, 0xdb, 0xa2, 0xb1, 0x3c, - 0xd8, 0x15, 0xac, 0x31, 0x6e, 0x1f, 0x47, 0x60, 0x71, 0xfb, 0x58, 0x24, 0x27, 0xf2, 0xa7, 0xca, - 0x6f, 0x69, 0x9d, 0xe5, 0xc1, 0xbc, 0x4e, 0xbc, 0xd2, 0x6a, 0xd1, 0x64, 0x04, 0x4d, 0xb7, 0xeb, - 0x74, 0x42, 0xb4, 0x09, 0xa3, 0xca, 0xcf, 0x98, 0xd8, 0xa4, 0xd4, 0xb0, 0xd5, 0xef, 0x46, 0x05, - 0xaa, 0x78, 0xa7, 0xc0, 0x59, 0x18, 0xca, 0xf1, 0xe9, 0x21, 0x53, 0xa6, 0xb6, 0x59, 0x85, 0x71, - 0xe5, 0xa7, 0xd4, 0x42, 0x68, 0x4c, 0x4e, 0xa5, 0x05, 0x7d, 0xc2, 0x74, 0x14, 0xab, 0x09, 0x25, - 0xd3, 0xa4, 0xd1, 0x18, 0x13, 0xaf, 0xd0, 0x4a, 0x14, 0xad, 0xa2, 0xf7, 0xd5, 0xf7, 0x64, 0x5a, - 0xa4, 0x0a, 0xeb, 0xef, 0xf6, 0xc3, 0x1c, 0x5f, 0x8c, 0xf3, 0x5c, 0x71, 0xf4, 0x53, 0x18, 0x55, - 0xd6, 0x98, 0x4f, 0xfa, 0x55, 0xe1, 0x2d, 0x93, 0xb6, 0x17, 0x98, 0x78, 0x77, 0x44, 0x0b, 0x1a, - 0xb1, 0xe5, 0x26, 0xe2, 0x9d, 0xba, 0x6d, 0xda, 0x30, 0xa1, 0x2f, 0x34, 0x97, 0x70, 0xaf, 0x1b, - 0x1b, 0xd1, 0x41, 0x45, 0x10, 0xa8, 0x56, 0xc3, 0xb8, 0xdc, 0x34, 0x59, 0x96, 0xbe, 0x89, 0xbe, - 0x81, 0x8b, 0x89, 0x55, 0xe6, 0x1a, 0xdb, 0x4d, 0x63, 0x83, 0x09, 0x68, 0x16, 0x12, 0xdd, 0xa7, - 0xc5, 0xa9, 0xcd, 0x26, 0x1b, 0x41, 0x2d, 0x18, 0x53, 0x17, 0x9e, 0x8b, 0xe0, 0xd7, 0x32, 0xa6, - 0x92, 0x01, 0x32, 0xa1, 0x88, 0xcf, 0x25, 0x5d, 0x7b, 0x3d, 0xbf, 0xa4, 0x46, 0xb5, 0x3a, 0x0c, - 0x83, 0xec, 0x37, 0x61, 0x01, 0x5b, 0x3e, 0x0e, 0x70, 0xa7, 0x89, 0x55, 0xc7, 0xa7, 0x37, 0x65, - 0x01, 0xff, 0x26, 0x07, 0x45, 0x13, 0xdd, 0x1a, 0xee, 0xb4, 0xd0, 0x16, 0x14, 0xe2, 0x0d, 0xf1, - 0x5d, 0x6d, 0x89, 0xaf, 0x42, 0x7a, 0x97, 0x88, 0x48, 0x9e, 0xe8, 0xe6, 0x06, 0x5c, 0x54, 0xca, - 0xce, 0xe8, 0x61, 0x96, 0x44, 0x55, 0xb5, 0xea, 0x55, 0xea, 0x48, 0xb7, 0xec, 0x1d, 0x3a, 0x6e, - 0x87, 0x08, 0x88, 0x4a, 0x5c, 0x09, 0x88, 0x4a, 0xf9, 0xdc, 0x30, 0xcd, 0x93, 0x96, 0x0a, 0x6f, - 0x4b, 0x09, 0x62, 0x7d, 0x46, 0x39, 0x38, 0xd7, 0x57, 0xd8, 0x3b, 0x1f, 0x49, 0xec, 0x2a, 0x0c, - 0x6c, 0xaf, 0xd7, 0x96, 0x2a, 0xfc, 0xd5, 0x10, 0x7b, 0x6b, 0xda, 0x0e, 0x1a, 0x4d, 0xc7, 0x66, - 0x15, 0xd6, 0xa7, 0x34, 0x54, 0x1f, 0x0f, 0xf4, 0x26, 0xf1, 0x6e, 0xc0, 0x10, 0x2f, 0xe2, 0x98, - 0xf4, 0x9e, 0xba, 0xcd, 0xa1, 0x44, 0x9d, 0xb5, 0x25, 0xe4, 0xeb, 0x36, 0x76, 0x02, 0xe5, 0xc3, - 0xfc, 0x11, 0x91, 0xcb, 0x59, 0x19, 0xff, 0x2e, 0x4f, 0xc8, 0x38, 0xaa, 0xb4, 0x98, 0x69, 0xe2, - 0x02, 0xc6, 0x96, 0x7f, 0x59, 0x7f, 0x96, 0x87, 0x29, 0x11, 0x51, 0x46, 0xb3, 0x32, 0xf4, 0x8c, - 0x97, 0xf9, 0x03, 0x3d, 0x68, 0xcf, 0x92, 0x0c, 0xda, 0xf3, 0x06, 0x19, 0x3c, 0x78, 0xb8, 0x9f, - 0x53, 0xbe, 0xa9, 0x7b, 0x22, 0xa5, 0xef, 0x7e, 0x4d, 0xfa, 0x36, 0x8d, 0x47, 0x93, 0xbe, 0xe9, - 0xb2, 0x30, 0xe9, 0x5b, 0xc8, 0xdc, 0x6f, 0x22, 0x30, 0x7d, 0x44, 0xb6, 0x96, 0xd6, 0xe4, 0x69, - 0x9f, 0x5b, 0xad, 0xd3, 0x57, 0xf9, 0x9b, 0x6b, 0xcb, 0x4b, 0x64, 0x4f, 0xf3, 0xae, 0x8a, 0x15, - 0xb8, 0x4b, 0x5d, 0xe8, 0x38, 0x4d, 0x75, 0x63, 0x52, 0x16, 0xcb, 0x63, 0x51, 0x28, 0x20, 0xd6, - 0x03, 0xf9, 0xc6, 0xdf, 0x40, 0x2d, 0x2d, 0xf8, 0xeb, 0x06, 0x8d, 0x5e, 0xf0, 0x88, 0xae, 0xd7, - 0x79, 0x74, 0xe2, 0x0f, 0x73, 0x2c, 0x1c, 0x42, 0x6d, 0x53, 0x89, 0x93, 0xdf, 0x79, 0xe6, 0x29, - 0x46, 0x56, 0xa5, 0x99, 0x27, 0x6e, 0xa7, 0xa5, 0x1a, 0x59, 0x69, 0x26, 0x44, 0xfe, 0x6a, 0xb1, - 0xf1, 0xdc, 0xed, 0xb4, 0xec, 0x38, 0x34, 0xfa, 0x18, 0xc6, 0x95, 0x22, 0xf9, 0x91, 0x66, 0x61, - 0x06, 0x55, 0x74, 0xb7, 0x65, 0xeb, 0x90, 0xd6, 0xef, 0xe4, 0x61, 0x2e, 0x23, 0x8f, 0x0b, 0xd5, - 0x01, 0xa9, 0x6d, 0x40, 0xce, 0x14, 0x0f, 0xd0, 0x4c, 0x5f, 0x68, 0x6a, 0x3c, 0x52, 0x02, 0xa2, - 0xcf, 0x60, 0x54, 0x4d, 0x2b, 0x93, 0x57, 0xa2, 0x80, 0x9b, 0x53, 0xc9, 0xa8, 0xe0, 0x28, 0x00, - 0x88, 0x7a, 0xc2, 0x1f, 0x32, 0xd7, 0x88, 0x44, 0xa3, 0xe4, 0xa4, 0x39, 0x97, 0xe4, 0x38, 0x4a, - 0x33, 0xd6, 0xdf, 0xca, 0xc3, 0x42, 0xc6, 0x3c, 0xd4, 0x70, 0xf8, 0x7f, 0x63, 0x2a, 0x62, 0x99, - 0x82, 0xfa, 0xbe, 0xa5, 0x4c, 0x41, 0xd6, 0xef, 0xe7, 0x61, 0x66, 0xa7, 0x1b, 0x50, 0x4f, 0xd7, - 0xb5, 0xce, 0x0b, 0xdc, 0x09, 0x3d, 0xff, 0x15, 0xf5, 0xd4, 0x43, 0xef, 0xc3, 0xc0, 0x2a, 0x6e, - 0xb7, 0x3d, 0xfe, 0x59, 0xbb, 0x22, 0xec, 0xde, 0x71, 0x68, 0x0a, 0xb4, 0x7a, 0xc1, 0x66, 0xd0, - 0xe8, 0x63, 0x18, 0x59, 0xc5, 0x8e, 0x1f, 0xee, 0x61, 0x47, 0x48, 0xae, 0x97, 0x39, 0xaa, 0x82, - 0xc2, 0x01, 0x56, 0x2f, 0xd8, 0x11, 0x34, 0x5a, 0x84, 0xfe, 0x2d, 0xaf, 0xb3, 0x2f, 0x9f, 0xc2, - 0xa5, 0x34, 0x48, 0x60, 0x56, 0x2f, 0xd8, 0x14, 0x16, 0x3d, 0x85, 0xf1, 0xca, 0x3e, 0xee, 0x84, - 0x4f, 0x71, 0xe8, 0xb4, 0x9c, 0xd0, 0xe1, 0x12, 0xce, 0x8d, 0x34, 0x64, 0x0d, 0x98, 0x66, 0xdf, - 0x55, 0x0b, 0xaa, 0x03, 0xd0, 0xf7, 0x34, 0xd8, 0xb7, 0x8e, 0x73, 0x50, 0x5c, 0xf6, 0x5e, 0x76, - 0x8c, 0x13, 0xf3, 0xa1, 0x3e, 0x31, 0xc2, 0x1f, 0xdb, 0x00, 0x1f, 0x9b, 0x9a, 0xf7, 0xa0, 0x7f, - 0xcb, 0xed, 0xec, 0xc7, 0x3e, 0xea, 0x06, 0x3c, 0x02, 0x45, 0x47, 0xe8, 0x76, 0xf6, 0xd1, 0xba, - 0x90, 0xa6, 0x38, 0xbf, 0xef, 0xd3, 0x44, 0x38, 0x03, 0xb6, 0x0a, 0x1d, 0x49, 0x4d, 0xec, 0xb7, - 0x18, 0xe0, 0x3b, 0x30, 0x9b, 0xd2, 0x2e, 0x9a, 0x90, 0xcc, 0xb2, 0x9f, 0x32, 0xc9, 0xb7, 0x61, - 0xda, 0xb8, 0x04, 0x09, 0xc0, 0xff, 0x96, 0x33, 0xec, 0x25, 0x36, 0xf2, 0x22, 0x0c, 0x89, 0x98, - 0xb9, 0xec, 0xab, 0x22, 0x7e, 0x52, 0xbf, 0x53, 0x71, 0xd6, 0x78, 0x24, 0x43, 0x79, 0xa4, 0xea, - 0x4a, 0x6c, 0x01, 0x76, 0x22, 0x3e, 0x79, 0x83, 0x7d, 0x2f, 0x69, 0x91, 0x36, 0x57, 0xbd, 0x20, - 0xec, 0x48, 0xb7, 0x08, 0x5b, 0xfe, 0x46, 0xb7, 0xa1, 0xb0, 0xf2, 0x4d, 0x88, 0xfd, 0x8e, 0xd3, - 0xe6, 0xd1, 0x43, 0x79, 0xc6, 0x22, 0x3b, 0x51, 0x6e, 0xfd, 0x45, 0x9e, 0x46, 0x50, 0xcc, 0xd8, - 0x60, 0x64, 0x8e, 0x36, 0x6b, 0x7c, 0xcc, 0xf9, 0xcd, 0x1a, 0x9a, 0x87, 0x91, 0xcd, 0x9a, 0x16, - 0x3e, 0xd8, 0x8e, 0x0a, 0x48, 0xe3, 0xa4, 0x23, 0x15, 0xbf, 0x79, 0xe0, 0x86, 0xb8, 0x19, 0x1e, - 0xf9, 0x9c, 0x2d, 0xda, 0x89, 0x72, 0x64, 0xc1, 0xd8, 0xa3, 0xb6, 0xbb, 0xd7, 0x14, 0xc4, 0xd8, - 0x40, 0xb4, 0x32, 0x74, 0x13, 0x26, 0x78, 0x92, 0x4b, 0x16, 0x5d, 0x99, 0x67, 0x70, 0xb3, 0x63, - 0xa5, 0xa4, 0xdd, 0x25, 0xaf, 0x13, 0x3a, 0x6e, 0x07, 0xfb, 0xf6, 0x51, 0x27, 0x74, 0x79, 0xca, - 0xf3, 0x11, 0x3b, 0x51, 0x8e, 0xde, 0x83, 0x69, 0x59, 0xb6, 0xe9, 0x37, 0x0f, 0x70, 0x10, 0xfa, - 0x34, 0x12, 0x3d, 0x7d, 0xc9, 0x6e, 0x9b, 0x2b, 0x69, 0x0b, 0x6d, 0xef, 0xa8, 0xb5, 0xd2, 0x79, - 0xe1, 0xfa, 0x1e, 0x4b, 0x8f, 0x38, 0xcc, 0x5b, 0x88, 0x95, 0x5b, 0x5b, 0xc6, 0xb3, 0xf7, 0x06, - 0x1b, 0xc9, 0x3a, 0xc9, 0xc1, 0xbc, 0xf1, 0x78, 0x88, 0x0f, 0x73, 0x29, 0xce, 0xf1, 0x95, 0x5d, - 0x78, 0x1b, 0xfa, 0xe9, 0x97, 0x9a, 0xe9, 0xfa, 0xe2, 0xfa, 0x8f, 0xe2, 0x33, 0x52, 0xa4, 0xd6, - 0xa6, 0x30, 0xe8, 0x91, 0x94, 0xca, 0xfa, 0xa8, 0x54, 0x76, 0x37, 0xce, 0xf9, 0x0c, 0x8d, 0xab, - 0xd2, 0xd9, 0x79, 0x48, 0x64, 0x7f, 0x91, 0x83, 0x72, 0x0f, 0xae, 0x20, 0xc7, 0x94, 0x3b, 0xc5, - 0x98, 0x1e, 0xcb, 0x31, 0x31, 0x47, 0xe3, 0xc5, 0xd3, 0x71, 0x9e, 0xf3, 0x1e, 0xd6, 0x12, 0xa0, - 0xe4, 0xf7, 0x03, 0xbd, 0x0b, 0x23, 0xb5, 0xda, 0xaa, 0x76, 0x39, 0x15, 0xbf, 0x2f, 0xb2, 0x23, - 0x08, 0xeb, 0x03, 0x98, 0x91, 0x44, 0x58, 0x08, 0x57, 0xe5, 0x35, 0x03, 0xcf, 0x72, 0x24, 0x1f, - 0x51, 0x44, 0x05, 0xd6, 0x8f, 0x12, 0x78, 0xb5, 0xa3, 0xc3, 0x43, 0xc7, 0x7f, 0x85, 0x2a, 0x3a, - 0x5e, 0x5f, 0xcf, 0x2f, 0x65, 0xb5, 0xff, 0xe7, 0xc7, 0xe5, 0x0b, 0x2a, 0xf1, 0x5b, 0x70, 0x53, - 0x82, 0xc8, 0x52, 0xce, 0xac, 0xa8, 0xf5, 0x4e, 0xde, 0xa0, 0xff, 0x66, 0x1e, 0xca, 0x3d, 0x40, - 0xd1, 0x1f, 0xe5, 0x58, 0x94, 0x72, 0x59, 0xc2, 0x7b, 0xf5, 0x71, 0x7c, 0x2b, 0x9a, 0xf1, 0xef, - 0x68, 0xbf, 0x98, 0xca, 0xf0, 0xc9, 0x6f, 0xfd, 0xd5, 0x6b, 0x73, 0x5d, 0xbd, 0x2f, 0xa5, 0xef, - 0x03, 0x4a, 0x36, 0xd0, 0x6b, 0x1f, 0xf4, 0xab, 0xfb, 0xc0, 0x86, 0x29, 0xed, 0x7b, 0x75, 0x9a, - 0x23, 0xbc, 0x00, 0xc0, 0xa3, 0x6d, 0xaf, 0x7b, 0xfb, 0xfc, 0x49, 0x80, 0x52, 0x62, 0x3d, 0x84, - 0xe9, 0x18, 0x4d, 0xae, 0xc4, 0xbc, 0x0b, 0x52, 0xed, 0xa2, 0x44, 0xfb, 0xaa, 0x17, 0x7f, 0x79, - 0x5c, 0x1e, 0x27, 0x8c, 0xf0, 0x4e, 0x14, 0xd7, 0x4e, 0xfc, 0x65, 0x3d, 0x55, 0xb5, 0xe3, 0x4a, - 0x5b, 0x7b, 0xcc, 0x75, 0x1f, 0x06, 0x59, 0x49, 0x2c, 0x7a, 0x94, 0x0a, 0xcd, 0xf7, 0x06, 0x07, - 0xb4, 0xa6, 0xa9, 0xc3, 0x26, 0xfd, 0x51, 0x89, 0x9e, 0x06, 0x58, 0x3b, 0x2c, 0x94, 0x69, 0x54, - 0x2c, 0x23, 0x54, 0xf5, 0x57, 0xa2, 0x27, 0x0c, 0xe2, 0x0a, 0x40, 0xc0, 0x75, 0xbc, 0x97, 0x6d, - 0xdc, 0xda, 0xa7, 0xe9, 0xa7, 0xaa, 0x63, 0xfc, 0x0a, 0xa0, 0xdf, 0x21, 0x04, 0x28, 0x9a, 0xf5, - 0x05, 0x4c, 0x2f, 0xb5, 0xb1, 0xe3, 0xc7, 0xdb, 0x43, 0x37, 0x61, 0x88, 0x96, 0xe9, 0x37, 0xdb, - 0x0e, 0x29, 0xa2, 0x37, 0xdb, 0xbc, 0x92, 0x28, 0x74, 0x2c, 0xa8, 0x8f, 0x3a, 0xa4, 0x48, 0x97, - 0x1a, 0xa0, 0xbf, 0x63, 0xee, 0x7e, 0x86, 0xd1, 0x33, 0x38, 0xeb, 0x73, 0xea, 0x4f, 0x62, 0xca, - 0x3c, 0x76, 0x3a, 0x07, 0xd4, 0xff, 0x0f, 0xe6, 0x2b, 0xdd, 0x2e, 0xee, 0xb4, 0x22, 0xc4, 0x6d, - 0xdf, 0x39, 0xa5, 0x63, 0x3f, 0xaa, 0xc0, 0x00, 0x85, 0x96, 0x66, 0x40, 0xde, 0x5d, 0x43, 0x77, - 0x28, 0x1c, 0xd7, 0x6f, 0x69, 0x03, 0x0c, 0xd3, 0x6a, 0xc1, 0x6c, 0xed, 0x68, 0xef, 0xd0, 0x65, - 0x49, 0xbe, 0xe8, 0xe3, 0x18, 0xd1, 0xf6, 0x9a, 0x88, 0x3e, 0xcd, 0x26, 0xe3, 0x56, 0x94, 0x51, - 0x8c, 0x5e, 0xd2, 0xf3, 0x07, 0x33, 0x2f, 0xee, 0xdf, 0x89, 0x50, 0xa9, 0xe8, 0xc9, 0x5a, 0xa1, - 0xd5, 0x3c, 0x42, 0xb5, 0x75, 0x09, 0x2e, 0xaa, 0x26, 0x15, 0xb6, 0x43, 0xa6, 0xe1, 0x92, 0x6e, - 0x2a, 0x61, 0xc5, 0x5f, 0xc3, 0x14, 0xbb, 0x03, 0x60, 0xe1, 0xc0, 0x16, 0xa3, 0xc8, 0x57, 0xf9, - 0xfa, 0x62, 0xec, 0x6a, 0x9f, 0x7a, 0x67, 0xcb, 0x40, 0x8f, 0xf5, 0x45, 0xe6, 0x13, 0xf8, 0x62, - 0x51, 0x33, 0xc8, 0xe5, 0xeb, 0x8b, 0xd5, 0x21, 0xae, 0xe7, 0x13, 0xea, 0x6c, 0xf9, 0x7f, 0x25, - 0xd4, 0x17, 0xa9, 0x1b, 0xfa, 0x2a, 0x76, 0xa8, 0xcb, 0x88, 0xd9, 0x99, 0x77, 0x02, 0xf2, 0x6e, - 0x4b, 0x08, 0x5b, 0x6e, 0xcb, 0xfa, 0xd3, 0x1c, 0xdc, 0x62, 0x9f, 0x24, 0x33, 0x1e, 0xd5, 0xdc, - 0x53, 0x90, 0xd1, 0x47, 0xc0, 0xb2, 0xee, 0xf0, 0xef, 0xbe, 0xc5, 0x7b, 0x9e, 0x45, 0x89, 0x21, - 0xa0, 0x0a, 0x8c, 0xa9, 0xbe, 0x25, 0xb1, 0x60, 0x01, 0x29, 0x36, 0x3c, 0x7b, 0xf4, 0xf0, 0x99, - 0x23, 0xfd, 0x4d, 0x9e, 0xc3, 0xdc, 0xca, 0x37, 0x64, 0x43, 0x70, 0x59, 0x93, 0xdf, 0xc3, 0x45, - 0xce, 0xa2, 0x93, 0xdb, 0x7c, 0xc7, 0xe8, 0xd2, 0x50, 0xbc, 0x98, 0x48, 0x89, 0x42, 0x5c, 0x95, - 0x42, 0xcc, 0x88, 0xad, 0x95, 0x59, 0xff, 0x21, 0x07, 0xf3, 0xe6, 0xd6, 0x38, 0x63, 0x59, 0x83, - 0x8b, 0x4b, 0x4e, 0xc7, 0xeb, 0xb8, 0x4d, 0xa7, 0x5d, 0x6b, 0x1e, 0xe0, 0xd6, 0x51, 0x5b, 0xb8, - 0xdc, 0x48, 0x2e, 0x43, 0xa4, 0x5e, 0x8e, 0x2e, 0x40, 0xec, 0x24, 0x16, 0xfa, 0x00, 0x66, 0xa8, - 0xc3, 0x03, 0xe3, 0xbd, 0x6d, 0xec, 0x4b, 0x7a, 0xac, 0x67, 0x29, 0xb5, 0xe8, 0x1e, 0x5c, 0x62, - 0x1f, 0x95, 0xd6, 0x4e, 0xc7, 0x0d, 0x25, 0x12, 0x13, 0x8e, 0x4d, 0x55, 0xb7, 0x6f, 0xc3, 0xc8, - 0x66, 0x17, 0xf3, 0x24, 0xd7, 0xc3, 0xd0, 0xbf, 0xb6, 0xb1, 0xb6, 0xcd, 0x52, 0xec, 0x6d, 0xed, - 0x6c, 0x17, 0x72, 0x08, 0x60, 0x70, 0x79, 0x65, 0x7d, 0x65, 0x7b, 0xa5, 0x90, 0xbf, 0xdd, 0x50, - 0x7d, 0x72, 0xd0, 0x1c, 0xcc, 0x2e, 0xaf, 0xd4, 0xd7, 0x96, 0x56, 0x1a, 0xdb, 0x3f, 0xd8, 0x5a, - 0x69, 0xe8, 0xc1, 0x96, 0xa6, 0xa0, 0xa0, 0x56, 0x6e, 0x6f, 0x6e, 0x6f, 0xb1, 0xbc, 0x79, 0x6a, - 0xe9, 0xee, 0x4a, 0xb5, 0xb2, 0xb3, 0xbd, 0xba, 0x51, 0xe8, 0xb3, 0xfa, 0x87, 0xf3, 0x85, 0xfc, - 0xed, 0x9f, 0x6a, 0x0e, 0x3b, 0x68, 0x1e, 0x8a, 0x1c, 0x7c, 0xa7, 0x56, 0x79, 0x94, 0xde, 0x04, - 0xab, 0x7d, 0xfa, 0xb0, 0x52, 0xc8, 0xa1, 0x2b, 0x70, 0x59, 0x2b, 0xdd, 0xaa, 0xd4, 0x6a, 0xbb, - 0x9b, 0xf6, 0xf2, 0xfa, 0x4a, 0xad, 0x56, 0xc8, 0xdf, 0xae, 0x6b, 0x01, 0x7a, 0x48, 0x0b, 0x4f, - 0x1f, 0x56, 0x1a, 0xf6, 0xca, 0x97, 0x3b, 0x6b, 0xf6, 0xca, 0x72, 0xb2, 0x05, 0xad, 0xf6, 0x07, - 0x2b, 0xb5, 0x42, 0x0e, 0x5d, 0x82, 0x49, 0xad, 0x74, 0x63, 0xb3, 0x90, 0xbf, 0x7d, 0x93, 0xbf, - 0xfd, 0x43, 0x13, 0x00, 0xcb, 0x2b, 0xb5, 0xa5, 0x95, 0x8d, 0xe5, 0xb5, 0x8d, 0x47, 0x85, 0x0b, - 0x68, 0x1c, 0x46, 0x2a, 0xf2, 0x67, 0xee, 0xf6, 0x55, 0x98, 0x8c, 0x89, 0x8f, 0x04, 0x42, 0x4a, - 0x5e, 0x85, 0x0b, 0x8b, 0xff, 0xe5, 0xf7, 0x72, 0x30, 0x4a, 0xb6, 0xbe, 0x70, 0xcf, 0xf8, 0x5a, - 0x11, 0xaa, 0xf8, 0x92, 0xf3, 0xe0, 0xf7, 0xa9, 0x12, 0x14, 0xe5, 0x82, 0xa5, 0x0c, 0x8d, 0x9b, - 0x02, 0xdc, 0xca, 0xdd, 0xcb, 0x21, 0x9b, 0xda, 0x9a, 0x63, 0x52, 0x9b, 0xa4, 0x6c, 0x96, 0x02, - 0x4b, 0x29, 0xd5, 0x42, 0xd8, 0xfb, 0x75, 0xb0, 0x54, 0x9a, 0x29, 0x12, 0xd8, 0xbb, 0xa7, 0x93, - 0xb4, 0x44, 0x9b, 0x37, 0x4f, 0x07, 0x8e, 0x1e, 0xc3, 0x38, 0x91, 0x4d, 0x24, 0x18, 0x9a, 0x8b, - 0x23, 0x2a, 0xe2, 0x50, 0x69, 0xde, 0x5c, 0x29, 0x43, 0x64, 0x8e, 0xd1, 0x81, 0x04, 0xa1, 0xd3, - 0x21, 0x1a, 0xf1, 0xb4, 0x4c, 0x22, 0xcf, 0x4a, 0xd8, 0x4d, 0x7f, 0xe9, 0x62, 0xac, 0xb8, 0x7e, - 0xff, 0x5e, 0x0e, 0xd5, 0xe8, 0xf3, 0x49, 0x4d, 0xc8, 0x41, 0xc2, 0x5f, 0x28, 0x29, 0xfd, 0xb0, - 0xde, 0x94, 0xa5, 0x75, 0x3a, 0x45, 0x3a, 0xda, 0x00, 0x94, 0x94, 0x1d, 0xd0, 0xd5, 0x68, 0x1f, - 0x98, 0xc5, 0x8a, 0xd2, 0x4c, 0xe2, 0x0a, 0x71, 0x85, 0x7c, 0x3d, 0xd0, 0x0a, 0x4c, 0x70, 0x27, - 0x4f, 0x2e, 0xcd, 0xa0, 0x2c, 0x79, 0x28, 0x95, 0xcc, 0x23, 0x3a, 0x4f, 0x52, 0x22, 0x42, 0xa5, - 0x68, 0x1c, 0x71, 0x31, 0xa9, 0x34, 0x67, 0xac, 0xe3, 0xe3, 0x7b, 0x08, 0x13, 0xba, 0x70, 0x85, - 0xc4, 0x02, 0x19, 0x65, 0xae, 0xd4, 0x0e, 0x35, 0x60, 0xf6, 0xa9, 0xe3, 0x52, 0x0d, 0x9b, 0x5f, - 0x54, 0x89, 0x6b, 0x26, 0x54, 0xce, 0xb8, 0x77, 0xaa, 0xe1, 0x4e, 0xab, 0xd4, 0x2b, 0x70, 0x00, - 0x3d, 0x36, 0x35, 0x21, 0x23, 0xe8, 0xd7, 0x74, 0xc8, 0xd2, 0x33, 0x84, 0x98, 0x6e, 0x5e, 0x4b, - 0x69, 0xce, 0x02, 0xe8, 0x29, 0x15, 0x52, 0x62, 0x14, 0x95, 0x3d, 0x71, 0x66, 0x72, 0x45, 0xea, - 0x6a, 0x1c, 0xba, 0xf1, 0x5b, 0xff, 0x00, 0xa5, 0x4c, 0x5c, 0x2a, 0xb1, 0x7b, 0x39, 0xf4, 0x35, - 0x3d, 0xd5, 0x46, 0x72, 0xbb, 0x6e, 0x78, 0xc0, 0xbd, 0x5e, 0xe6, 0x8c, 0x04, 0xf8, 0x41, 0xc9, - 0xa0, 0x6e, 0xc3, 0x94, 0xc9, 0x3f, 0x41, 0x4e, 0x68, 0x86, 0xf3, 0x42, 0xea, 0x2e, 0xb0, 0x89, - 0xa8, 0xd5, 0x4a, 0x5f, 0xa4, 0x8c, 0xeb, 0xf1, 0x54, 0x9a, 0x9f, 0xc1, 0x04, 0xd9, 0x25, 0x4f, - 0x30, 0xee, 0x56, 0xda, 0xee, 0x0b, 0x1c, 0x20, 0x11, 0x54, 0x43, 0x16, 0xa5, 0xe1, 0xde, 0xca, - 0xa1, 0xef, 0xc0, 0xe8, 0xae, 0x13, 0x36, 0x0f, 0xf8, 0x1b, 0x70, 0xf1, 0x44, 0x9c, 0x96, 0x95, - 0xc4, 0x2f, 0x5a, 0x79, 0x2f, 0x87, 0xbe, 0x07, 0x43, 0x8f, 0x70, 0x48, 0xfd, 0x35, 0xaf, 0xc9, - 0xab, 0x3a, 0xe6, 0x16, 0xb3, 0xd6, 0x91, 0x0e, 0x6c, 0xa2, 0xc3, 0x71, 0x7d, 0x1e, 0xdd, 0x05, - 0x60, 0x0c, 0x81, 0x52, 0x88, 0x57, 0x97, 0x12, 0xdd, 0x46, 0x8f, 0xc8, 0xe7, 0xbd, 0x8d, 0x43, - 0x7c, 0xda, 0x26, 0xd3, 0xe6, 0x68, 0x1d, 0x26, 0x64, 0x54, 0xd1, 0x0d, 0xea, 0xf0, 0x6f, 0xc5, - 0x88, 0x05, 0x67, 0xa0, 0xf6, 0x09, 0x39, 0x15, 0xec, 0xea, 0x4c, 0x06, 0x1c, 0x41, 0x69, 0x21, - 0x48, 0xe4, 0x24, 0x32, 0x30, 0x05, 0x77, 0xd5, 0x0b, 0x42, 0x1d, 0x57, 0x96, 0x98, 0x71, 0x31, - 0x94, 0xd4, 0x76, 0xf5, 0xe0, 0x23, 0x11, 0xcf, 0x4d, 0x8b, 0x99, 0x52, 0xba, 0x96, 0x01, 0xc1, - 0xd8, 0x1d, 0xe5, 0x24, 0xcb, 0x44, 0x7b, 0x65, 0xcd, 0xa8, 0xe9, 0xf1, 0xc5, 0x65, 0x80, 0x52, - 0x26, 0x08, 0xa3, 0x64, 0x15, 0xf9, 0xea, 0x69, 0x41, 0x2f, 0xa2, 0xaf, 0x9e, 0x21, 0x2a, 0x49, - 0xf4, 0xd5, 0x33, 0xc6, 0xc9, 0x78, 0xc2, 0xf4, 0x69, 0x2d, 0x49, 0x76, 0x7d, 0x11, 0x09, 0xe7, - 0x5d, 0xad, 0x82, 0x1f, 0xec, 0x19, 0x53, 0x5d, 0xfd, 0xc1, 0xbd, 0x1c, 0x5a, 0x81, 0x4b, 0xf2, - 0x7d, 0x46, 0x54, 0x85, 0x52, 0x10, 0x52, 0x37, 0xc1, 0x17, 0x70, 0x89, 0x6f, 0x29, 0x8d, 0x4c, - 0x41, 0x72, 0x07, 0x7e, 0x7f, 0x97, 0x4a, 0xe0, 0x31, 0x4c, 0xd7, 0x62, 0x83, 0x62, 0xde, 0x26, - 0x97, 0x75, 0x12, 0x4a, 0x3e, 0xd2, 0x54, 0x5a, 0x4f, 0x00, 0x31, 0x95, 0x55, 0x90, 0x7b, 0xe1, - 0xe2, 0x97, 0xe8, 0x4a, 0x6c, 0x48, 0xa4, 0x90, 0x82, 0x51, 0xf6, 0x92, 0x36, 0x45, 0x68, 0x9b, - 0xe5, 0x4a, 0x61, 0xb9, 0xce, 0x9c, 0xae, 0xb3, 0xe7, 0xb6, 0xdd, 0xd0, 0xc5, 0x64, 0x87, 0xa9, - 0x08, 0x6a, 0x95, 0x58, 0xc6, 0xcb, 0xa9, 0x10, 0xe8, 0x73, 0x18, 0x7f, 0x84, 0xc3, 0x28, 0xe5, - 0x2a, 0x9a, 0x4d, 0x24, 0x69, 0xe5, 0x4b, 0x27, 0x5e, 0x03, 0xea, 0x79, 0x5e, 0xd7, 0xa0, 0xc0, - 0xb8, 0xa3, 0x42, 0xe2, 0x4a, 0x82, 0x04, 0x07, 0x71, 0x7c, 0xe7, 0x30, 0x48, 0x9d, 0xad, 0xbb, - 0xec, 0x3a, 0x07, 0x89, 0x6d, 0xab, 0x8a, 0x5f, 0x97, 0xb4, 0x32, 0x19, 0xbd, 0x69, 0xda, 0x98, - 0x6b, 0x14, 0x5d, 0x8f, 0x3e, 0x85, 0xa9, 0x09, 0x44, 0x4b, 0x28, 0xfe, 0x56, 0xaf, 0xfe, 0x00, - 0xc9, 0xd4, 0x12, 0x06, 0xa2, 0x37, 0xb5, 0x2f, 0xf6, 0xd9, 0xe8, 0x7e, 0x0e, 0x23, 0x32, 0x69, - 0xa5, 0x64, 0x2b, 0xf1, 0x94, 0x9f, 0xa5, 0x62, 0xb2, 0x82, 0x8f, 0xf4, 0x33, 0x96, 0xa2, 0x56, - 0xc7, 0x8f, 0xe7, 0x75, 0x4c, 0x9d, 0xd8, 0x8f, 0x61, 0x54, 0xc9, 0xe8, 0x28, 0x37, 0x72, 0x32, - 0xcb, 0x63, 0x69, 0x5c, 0xe9, 0x7b, 0x7d, 0xf1, 0x5e, 0x0e, 0xdd, 0xa5, 0x9f, 0x16, 0xfa, 0x58, - 0x65, 0x3a, 0x42, 0x53, 0xf2, 0xb0, 0xc5, 0x50, 0xd0, 0x87, 0x34, 0xa6, 0xc7, 0xd2, 0x91, 0xef, - 0x13, 0x05, 0x96, 0xe0, 0xa5, 0x49, 0x10, 0x31, 0xc4, 0xcf, 0x29, 0x33, 0x51, 0x10, 0x99, 0xfb, - 0x46, 0x2f, 0x6c, 0x16, 0x13, 0xf6, 0x5e, 0x0e, 0x3d, 0x80, 0x61, 0x91, 0x00, 0x1a, 0xcd, 0xe8, - 0x5d, 0x4d, 0x1f, 0xde, 0x03, 0x00, 0x36, 0xd9, 0xb4, 0xa7, 0x7a, 0x75, 0xea, 0x74, 0x3e, 0x20, - 0xdf, 0xcb, 0xd6, 0x19, 0x91, 0x3e, 0x17, 0xdf, 0x4c, 0x8a, 0x54, 0xd4, 0x96, 0x50, 0x9d, 0xce, - 0x34, 0x7c, 0x22, 0xf0, 0x6a, 0x79, 0xa9, 0x23, 0x81, 0xd7, 0x94, 0xae, 0x3a, 0x95, 0xce, 0x1a, - 0x14, 0x2a, 0x4d, 0xca, 0xc7, 0x65, 0x6e, 0x3b, 0xa9, 0x6d, 0xc4, 0x2b, 0x04, 0xad, 0xe9, 0x78, - 0xaa, 0xbc, 0x75, 0xec, 0xd0, 0x30, 0x27, 0xb3, 0x52, 0x26, 0x88, 0x55, 0x99, 0x31, 0x32, 0xb4, - 0x8b, 0xa9, 0x25, 0xa2, 0x0f, 0xb5, 0xdf, 0x8c, 0xcc, 0x27, 0x94, 0x97, 0x29, 0x79, 0xff, 0x66, - 0xe2, 0xf8, 0x52, 0x0f, 0x13, 0xae, 0x73, 0x12, 0xb4, 0x02, 0x93, 0x3c, 0xa8, 0x82, 0x9c, 0x96, - 0x34, 0xec, 0xb4, 0xe6, 0x3f, 0x84, 0x89, 0x15, 0xc2, 0xeb, 0x8f, 0x5a, 0x2e, 0x0b, 0xed, 0x84, - 0xf4, 0x58, 0x3d, 0xa9, 0x88, 0xab, 0x22, 0xa5, 0xad, 0x92, 0x10, 0x4f, 0x9e, 0xd2, 0x64, 0xce, - 0xc1, 0xd2, 0x94, 0x20, 0xab, 0xe6, 0xce, 0xe3, 0x4a, 0xfa, 0x6c, 0x4a, 0x0a, 0x3a, 0x74, 0x43, - 0xd3, 0xfd, 0xd2, 0xf2, 0xc8, 0x19, 0xa4, 0xbd, 0xaf, 0x94, 0xa4, 0x1c, 0x29, 0x34, 0xb3, 0x73, - 0xd3, 0xa5, 0x8e, 0x5b, 0x06, 0x63, 0x31, 0xe6, 0x90, 0x43, 0xef, 0xe8, 0xd4, 0x33, 0xf2, 0xcc, - 0xa5, 0xb6, 0x40, 0x75, 0x6b, 0x3d, 0xc5, 0x19, 0x5a, 0xc8, 0xce, 0xc4, 0xa6, 0xe8, 0xd6, 0x29, - 0xb9, 0xd1, 0x1e, 0xd3, 0x6d, 0x16, 0x65, 0xee, 0x40, 0xaa, 0xa6, 0x1a, 0x4f, 0x5c, 0x22, 0x45, - 0x28, 0x73, 0x9e, 0xb3, 0x47, 0x94, 0x5d, 0x2a, 0x59, 0x40, 0x52, 0x19, 0xde, 0x15, 0x13, 0x9d, - 0x40, 0xf9, 0x16, 0x4e, 0xc6, 0x32, 0x86, 0x49, 0xdb, 0x8c, 0x39, 0x67, 0x59, 0x69, 0x21, 0xad, - 0x9a, 0x53, 0xac, 0x89, 0xa4, 0xd4, 0xca, 0x48, 0x17, 0xb4, 0x2f, 0x54, 0x72, 0xb0, 0xe5, 0xd4, - 0x7a, 0x39, 0x77, 0x85, 0x78, 0x86, 0x17, 0x49, 0x34, 0x25, 0xf5, 0x4b, 0x06, 0x4b, 0x9c, 0x52, - 0xb7, 0x46, 0xcf, 0x19, 0x4c, 0xa3, 0xb3, 0x0d, 0xd3, 0xc6, 0x84, 0x2c, 0x52, 0x8c, 0xc8, 0x4a, - 0xd7, 0x92, 0x4a, 0x15, 0xc3, 0x8c, 0x39, 0x27, 0x13, 0x7a, 0x4b, 0x57, 0xfd, 0xcd, 0x19, 0x6a, - 0x4a, 0x37, 0x7a, 0x40, 0xf1, 0x09, 0xfd, 0x9a, 0x7e, 0x36, 0x13, 0x6d, 0x5c, 0x53, 0x8c, 0x01, - 0x29, 0x0d, 0x58, 0x59, 0x20, 0x72, 0x0f, 0x4c, 0x99, 0x72, 0xc2, 0xa5, 0x4e, 0xf1, 0xf5, 0x74, - 0x9a, 0xd1, 0xc6, 0xaa, 0x8b, 0x10, 0x28, 0xa9, 0x33, 0x93, 0x99, 0xbb, 0x27, 0x43, 0x9b, 0x2c, - 0xc9, 0xfd, 0x70, 0xfa, 0x2e, 0xa7, 0x5b, 0x86, 0xa6, 0x4c, 0x19, 0xa3, 0xe2, 0x86, 0x1b, 0x53, - 0x42, 0x20, 0x39, 0x0d, 0x99, 0x29, 0xa7, 0xea, 0xcc, 0x88, 0xa3, 0x53, 0x57, 0x8d, 0x38, 0x46, - 0xd2, 0x57, 0xd3, 0x01, 0xa2, 0x1d, 0x61, 0x48, 0x7d, 0x27, 0x77, 0x44, 0x7a, 0x12, 0x3e, 0xb9, - 0x23, 0xb2, 0x32, 0xe7, 0xd9, 0xe2, 0xd0, 0xa5, 0x4c, 0x4b, 0x46, 0x9e, 0xa4, 0x0c, 0x95, 0xab, - 0x18, 0x2d, 0x5c, 0xac, 0xdb, 0x67, 0x5d, 0xb6, 0xaf, 0xe1, 0x72, 0x6a, 0x4e, 0x24, 0xf4, 0x76, - 0xe2, 0x40, 0xa7, 0xcc, 0x44, 0x7a, 0x4f, 0xc7, 0xb5, 0x74, 0x46, 0xd2, 0x8a, 0x15, 0xcb, 0x9c, - 0x94, 0x60, 0xfd, 0x86, 0xb4, 0x4a, 0x8c, 0xf5, 0x2b, 0xa9, 0x91, 0x4e, 0xc3, 0xfa, 0x4d, 0x99, - 0x94, 0x24, 0x4f, 0x55, 0xfa, 0x25, 0x44, 0xba, 0x78, 0xc5, 0x59, 0x78, 0xea, 0x69, 0xba, 0x96, - 0x46, 0x67, 0x99, 0xaa, 0x1c, 0x22, 0x53, 0x12, 0xba, 0xac, 0x4d, 0x93, 0xf6, 0xb9, 0x2d, 0x69, - 0x83, 0xd3, 0xbf, 0xb4, 0x4b, 0xd4, 0x5c, 0x2c, 0x33, 0x33, 0xa5, 0xf6, 0x62, 0x2e, 0x49, 0x43, - 0x33, 0x15, 0xcb, 0x59, 0x60, 0xbd, 0x99, 0x8f, 0x4f, 0x8e, 0xd6, 0xa1, 0xf4, 0x21, 0x21, 0x75, - 0x6a, 0x7a, 0x74, 0x29, 0x5d, 0xd4, 0xbd, 0xc4, 0x94, 0x07, 0x16, 0xa3, 0x50, 0xbc, 0x54, 0x9e, - 0x91, 0x76, 0x2f, 0xa5, 0x34, 0xc3, 0xcc, 0xb1, 0x45, 0x5d, 0x03, 0x0d, 0x49, 0xa6, 0x24, 0x0f, - 0xcd, 0xcc, 0x41, 0x65, 0x10, 0xf3, 0x24, 0x57, 0x4e, 0xa5, 0x98, 0x99, 0x75, 0x2a, 0xb5, 0xa7, - 0x3f, 0x51, 0xb8, 0x72, 0x22, 0x95, 0x14, 0xba, 0x15, 0x97, 0xf1, 0xd2, 0xb2, 0x4d, 0x65, 0x70, - 0xfd, 0x29, 0x53, 0x16, 0x2a, 0xc5, 0x76, 0x9b, 0x9a, 0xa2, 0xca, 0x30, 0x0b, 0x92, 0xbd, 0xa5, - 0x50, 0xcb, 0xc8, 0x49, 0x95, 0xda, 0xc3, 0x1f, 0x2a, 0xec, 0x2d, 0x96, 0x3b, 0x4a, 0x1a, 0x15, - 0x7a, 0x24, 0x97, 0x4a, 0xa5, 0xbd, 0x41, 0x9d, 0x49, 0x93, 0x89, 0x9f, 0xa4, 0xec, 0x92, 0x95, - 0x16, 0xca, 0x68, 0xda, 0x9d, 0x4e, 0x0e, 0x91, 0xd0, 0x9b, 0x89, 0x19, 0x66, 0x7b, 0x75, 0x4c, - 0xf2, 0x61, 0x43, 0xc2, 0xa8, 0x18, 0x1f, 0x4e, 0x4f, 0x29, 0x95, 0xa1, 0x31, 0x4d, 0xd6, 0xdc, - 0xfd, 0x8e, 0x92, 0xef, 0x49, 0xea, 0x4b, 0xc9, 0x14, 0x54, 0x92, 0xc5, 0x98, 0xd2, 0x43, 0x6d, - 0x46, 0x4f, 0x56, 0xd4, 0xcc, 0x3d, 0xa8, 0x94, 0x9e, 0xb0, 0x48, 0xb2, 0x1b, 0x63, 0xaa, 0x1f, - 0x85, 0xa0, 0x9a, 0x36, 0x47, 0x12, 0x34, 0x64, 0xf0, 0x91, 0x04, 0x8d, 0x79, 0x76, 0x98, 0x09, - 0xc6, 0xf6, 0xda, 0x58, 0x35, 0xc1, 0x28, 0x49, 0x6f, 0x62, 0xb6, 0x10, 0xf4, 0x29, 0xb5, 0x84, - 0x64, 0x9b, 0x4f, 0x66, 0x75, 0x4a, 0x11, 0xb7, 0x7c, 0x20, 0x2e, 0x03, 0x68, 0x83, 0x3a, 0xe5, - 0xde, 0xc6, 0x0d, 0x8a, 0xa4, 0x1b, 0x37, 0xd4, 0x8e, 0xa6, 0xdb, 0x49, 0xc7, 0xd4, 0xa0, 0xe9, - 0x72, 0xae, 0x0c, 0x99, 0x1d, 0xe4, 0x5c, 0x99, 0xf2, 0x25, 0x50, 0x1d, 0x78, 0x5b, 0x68, 0xf2, - 0x11, 0xbd, 0x2b, 0x99, 0x09, 0x0f, 0x4a, 0x0b, 0xd9, 0x59, 0x02, 0xf8, 0x3d, 0x5e, 0x21, 0x1e, - 0xd7, 0x1d, 0x99, 0xf2, 0x55, 0x28, 0xe1, 0xf2, 0xa5, 0x36, 0x94, 0x1a, 0x10, 0x7e, 0x4b, 0x18, - 0xab, 0x75, 0xba, 0x29, 0x59, 0x0b, 0x54, 0xd2, 0xd9, 0x02, 0x4a, 0x14, 0xe2, 0x5d, 0xd5, 0x4d, - 0x13, 0x21, 0xe4, 0x55, 0x01, 0xc5, 0x10, 0x15, 0xde, 0x15, 0x4f, 0x9c, 0xcd, 0x99, 0x93, 0xde, - 0xd1, 0x75, 0xbd, 0x8c, 0xe0, 0x3f, 0x3d, 0x6f, 0x4a, 0xd1, 0x8f, 0x45, 0xd6, 0xe4, 0x64, 0x86, - 0x90, 0x1b, 0x31, 0xb3, 0xab, 0x39, 0x5c, 0x4c, 0x29, 0x2b, 0x01, 0x09, 0x7a, 0x4a, 0xaf, 0xd8, - 0x37, 0xd7, 0x96, 0x97, 0xb8, 0x2f, 0x80, 0xe7, 0x27, 0xae, 0xad, 0x76, 0xdd, 0xf0, 0x80, 0xa5, - 0xcc, 0x51, 0xb8, 0x0f, 0x03, 0xd1, 0x10, 0xeb, 0x0f, 0x50, 0x8d, 0x4a, 0xee, 0x5a, 0xa9, 0xe1, - 0xe6, 0xca, 0x40, 0xb0, 0x64, 0x26, 0x48, 0x13, 0xff, 0x51, 0xc1, 0x80, 0x1c, 0x3c, 0xbd, 0x9b, - 0x29, 0x7d, 0xc8, 0x92, 0x2f, 0xd8, 0xb6, 0x31, 0x93, 0x39, 0x2d, 0xfb, 0x7e, 0x04, 0xd3, 0x6c, - 0xc2, 0x63, 0xef, 0xc9, 0xb4, 0xfe, 0x28, 0xe5, 0xa5, 0x94, 0x72, 0xb4, 0x41, 0xdd, 0x46, 0xe2, - 0xa5, 0x8a, 0x16, 0x63, 0x7e, 0xb0, 0x96, 0x4a, 0x8f, 0x2d, 0x25, 0x11, 0xdb, 0x5f, 0x6b, 0x29, - 0x35, 0xc4, 0xfa, 0x22, 0x5f, 0x4a, 0xad, 0xf4, 0x6c, 0x4b, 0x19, 0x23, 0xa8, 0x2f, 0xa5, 0xde, - 0xcd, 0x94, 0x3e, 0xf4, 0x5e, 0x4a, 0x33, 0x99, 0x33, 0x2f, 0x65, 0xec, 0x31, 0x9f, 0xd6, 0x1f, - 0xd3, 0x52, 0xc6, 0xe1, 0xd9, 0x52, 0xc6, 0x4b, 0x63, 0x0a, 0x69, 0xc6, 0x52, 0xc6, 0x31, 0xbf, - 0xa4, 0xf4, 0xd8, 0x6b, 0xc1, 0x33, 0x2d, 0xa6, 0x08, 0x6a, 0x13, 0x43, 0xad, 0x3f, 0x40, 0xbb, - 0xd4, 0x1a, 0x12, 0x2b, 0x3f, 0xdd, 0x82, 0xce, 0xa7, 0x11, 0xa5, 0x4b, 0xba, 0x26, 0xe4, 0xac, - 0x78, 0x77, 0x53, 0xfb, 0x92, 0xb5, 0x1e, 0x6c, 0x59, 0xe3, 0xa4, 0xce, 0xba, 0xb0, 0x4f, 0x05, - 0xd3, 0x4c, 0x3c, 0xb8, 0x8c, 0xf5, 0x4a, 0x5d, 0xdc, 0xd4, 0x1a, 0xb4, 0x4d, 0x6d, 0x3d, 0xc9, - 0x72, 0xc5, 0x4e, 0x94, 0xf6, 0xb2, 0xb3, 0x27, 0xd5, 0xc4, 0x0b, 0x4e, 0x95, 0x6a, 0xda, 0xf3, - 0x4e, 0x49, 0x35, 0x89, 0xfd, 0x05, 0xd5, 0x9d, 0xb9, 0x3f, 0x7a, 0xe7, 0x99, 0x97, 0x2e, 0xe8, - 0x5c, 0xd2, 0xdc, 0x19, 0x08, 0x2c, 0xf5, 0x22, 0xf9, 0x8c, 0x5f, 0x15, 0x88, 0xc2, 0xd4, 0xc9, - 0x37, 0xe1, 0xa3, 0x2f, 0xa0, 0xc0, 0x0f, 0x78, 0x44, 0xc0, 0x04, 0x98, 0xba, 0x74, 0x55, 0xa1, - 0xb2, 0x9f, 0xa2, 0x07, 0xa7, 0x51, 0xd5, 0x4f, 0x33, 0x13, 0xe9, 0x7a, 0x2d, 0x61, 0x81, 0xdb, - 0x3e, 0x51, 0x39, 0x5b, 0x49, 0x7d, 0x54, 0xef, 0x8c, 0xb8, 0x1d, 0xd6, 0xc1, 0xeb, 0x8b, 0x68, - 0x8d, 0x1e, 0x66, 0xbd, 0x38, 0x4b, 0x61, 0x37, 0x93, 0xa1, 0x67, 0x6d, 0x55, 0x3a, 0x3e, 0xeb, - 0x7d, 0x4a, 0x6b, 0x3b, 0xbd, 0x53, 0x72, 0x8a, 0x4e, 0x39, 0xba, 0xb4, 0x29, 0x62, 0x12, 0x35, - 0x33, 0x1e, 0xf4, 0x9a, 0x99, 0xb8, 0x2b, 0x36, 0xfa, 0x3e, 0x8c, 0x08, 0xe4, 0xde, 0x13, 0x12, - 0xc7, 0xa6, 0x13, 0xf2, 0x39, 0x8c, 0x2a, 0x9e, 0xe0, 0x28, 0xad, 0xa5, 0x0c, 0xf1, 0x7c, 0x54, - 0xf1, 0x53, 0x3f, 0x3b, 0xfe, 0x32, 0x8c, 0x6b, 0x7e, 0xee, 0x52, 0xa8, 0x34, 0x79, 0xbf, 0x67, - 0x51, 0xd1, 0xfc, 0xd9, 0x25, 0x15, 0x93, 0x97, 0x7b, 0xb6, 0x80, 0xab, 0xbc, 0x8f, 0x57, 0x04, - 0xdc, 0xe4, 0x43, 0x7d, 0x45, 0xc0, 0x35, 0x3d, 0xa9, 0xff, 0x1e, 0x8c, 0xf2, 0xed, 0x91, 0xb9, - 0xb2, 0xe9, 0x96, 0x87, 0x69, 0xc5, 0xff, 0xf2, 0xa8, 0xe5, 0x86, 0x4b, 0x5e, 0xe7, 0x99, 0xbb, - 0xdf, 0x73, 0x91, 0x93, 0x28, 0xf5, 0x45, 0x54, 0xa7, 0xa9, 0x0f, 0x44, 0x42, 0x0a, 0x1c, 0xbe, - 0xf4, 0xfc, 0xe7, 0x6e, 0x67, 0xbf, 0x07, 0xc9, 0xab, 0x3a, 0xc9, 0x38, 0x1e, 0xa3, 0x5b, 0x4b, - 0xa7, 0xdb, 0x13, 0x3f, 0xc3, 0xf2, 0x30, 0x4f, 0x7d, 0x20, 0xce, 0xda, 0xe3, 0xf4, 0x5b, 0x98, - 0xcb, 0x91, 0xe7, 0xa2, 0x8d, 0x9b, 0x9e, 0xdf, 0xea, 0x4d, 0xac, 0xac, 0xfb, 0x09, 0xc6, 0xd0, - 0xea, 0x8b, 0x84, 0x6a, 0x2d, 0x95, 0x6a, 0x2f, 0xec, 0x8c, 0x2f, 0xef, 0x1c, 0x1d, 0xfb, 0x19, - 0x7b, 0x9b, 0xcd, 0x81, 0xc9, 0x57, 0x73, 0xcb, 0xc7, 0xcf, 0xb0, 0x4f, 0xdd, 0x4f, 0x7b, 0x39, - 0x5e, 0xea, 0xe0, 0xf5, 0x45, 0x42, 0xa5, 0x96, 0xa0, 0x92, 0x06, 0x9d, 0x25, 0x74, 0xd2, 0xa1, - 0x9d, 0xb2, 0x37, 0x69, 0x64, 0x3e, 0xa2, 0xf6, 0xdf, 0x9d, 0xb5, 0x1e, 0x33, 0x22, 0x1c, 0xa2, - 0x05, 0x60, 0xfd, 0x3e, 0xc1, 0xac, 0x29, 0x98, 0x49, 0x88, 0xd4, 0x36, 0xbf, 0x2f, 0x0c, 0xbd, - 0x3d, 0x9b, 0x4d, 0xf7, 0xec, 0x18, 0x91, 0x69, 0x99, 0x90, 0x62, 0x22, 0xd1, 0x92, 0x0e, 0x95, - 0xc6, 0x55, 0xf7, 0xcb, 0x00, 0x55, 0x98, 0x46, 0xa2, 0xa6, 0x27, 0x52, 0xee, 0x98, 0x8d, 0x79, - 0x8b, 0xe2, 0x24, 0x98, 0x89, 0x67, 0xdd, 0x6b, 0x3e, 0x57, 0x4d, 0x3c, 0x4a, 0xbe, 0x9b, 0x92, - 0x9e, 0x8d, 0x86, 0x7f, 0x90, 0x68, 0x4a, 0x1a, 0xd5, 0xd9, 0x45, 0xcd, 0x78, 0xa3, 0x9a, 0x78, - 0xf4, 0xdc, 0x3c, 0xd2, 0xc4, 0x43, 0x1b, 0xd4, 0x29, 0xf7, 0x36, 0xf1, 0x50, 0x24, 0xdd, 0xc4, - 0xa3, 0x76, 0x34, 0x9d, 0x5d, 0xa0, 0x64, 0x72, 0x1e, 0xa9, 0x3c, 0xa4, 0xe6, 0xed, 0xc9, 0xf0, - 0x63, 0xb9, 0x64, 0xc8, 0x27, 0x26, 0x4d, 0x27, 0xe9, 0xb9, 0xc6, 0x4a, 0xba, 0x53, 0xc6, 0xbd, - 0x1c, 0xda, 0x80, 0x99, 0x47, 0x38, 0xe4, 0x0c, 0xcc, 0xc6, 0x41, 0xe8, 0xbb, 0xf4, 0x49, 0x5a, - 0xfa, 0xd7, 0x5a, 0xe8, 0x0a, 0x06, 0x9c, 0xfa, 0x7b, 0x84, 0x5e, 0xcd, 0x4c, 0x2f, 0x13, 0x2f, - 0xc3, 0x3a, 0xc6, 0x4d, 0xa9, 0x67, 0xe9, 0x62, 0xfa, 0x16, 0x1f, 0x62, 0x1e, 0x04, 0xe9, 0xa8, - 0x85, 0x28, 0x9e, 0x2c, 0xd7, 0x7e, 0xee, 0xc0, 0x20, 0x43, 0x4a, 0xfd, 0x46, 0x8e, 0xa9, 0x38, - 0xe8, 0xbe, 0x70, 0x77, 0x23, 0x28, 0x5a, 0x55, 0x6a, 0xbf, 0xee, 0xc3, 0x08, 0xbb, 0x17, 0x39, - 0x3d, 0xca, 0xa7, 0xc2, 0x29, 0x2e, 0xab, 0x63, 0xe9, 0x7e, 0xa2, 0xe3, 0xaa, 0xf3, 0xc0, 0xd9, - 0x27, 0xf2, 0x7b, 0xf4, 0x6e, 0x4a, 0x98, 0x80, 0xd3, 0xf1, 0xa7, 0x63, 0x11, 0x58, 0xf9, 0x94, - 0x32, 0x06, 0x29, 0x13, 0xf3, 0xa5, 0x75, 0xff, 0x62, 0x02, 0x1b, 0x7d, 0x2a, 0x9e, 0x62, 0x48, - 0xe4, 0x24, 0x50, 0xc6, 0x9c, 0x4d, 0xb0, 0x69, 0x7e, 0x1d, 0x64, 0xc9, 0x60, 0x7b, 0x76, 0xfb, - 0x34, 0x77, 0x68, 0xbd, 0xa7, 0x2e, 0x8d, 0xca, 0x26, 0x15, 0xbc, 0x12, 0xb1, 0x81, 0xd3, 0x09, - 0x2d, 0xa4, 0x87, 0x13, 0xa6, 0x8b, 0xf1, 0x98, 0x2a, 0xa9, 0xc9, 0x24, 0x8b, 0x69, 0xc3, 0xcb, - 0x08, 0x4f, 0x1c, 0x69, 0xe5, 0x49, 0x72, 0x19, 0x68, 0x59, 0x4a, 0x3e, 0x7f, 0x02, 0x76, 0x2e, - 0xe4, 0xd6, 0x84, 0x33, 0xd7, 0xe9, 0x07, 0x9b, 0x21, 0x04, 0x19, 0x6e, 0xed, 0x7a, 0xae, 0x45, - 0x1a, 0xb9, 0x1f, 0x53, 0xf9, 0xcf, 0x9c, 0x59, 0x2d, 0x95, 0xd8, 0x2d, 0xe5, 0xe2, 0x37, 0x3b, - 0x27, 0xdb, 0x73, 0xfa, 0xc6, 0xc5, 0x1c, 0x3d, 0xf9, 0x66, 0x0f, 0x2a, 0x62, 0x26, 0xde, 0xee, - 0x09, 0x27, 0xef, 0x80, 0xe6, 0xd8, 0x17, 0xd6, 0xdc, 0x5e, 0x8f, 0x68, 0xd0, 0x86, 0x6b, 0xb9, - 0x94, 0xb4, 0x65, 0x82, 0xa0, 0xee, 0x29, 0x97, 0x39, 0x86, 0xb4, 0xe9, 0xff, 0x12, 0xca, 0xd1, - 0xed, 0xf6, 0xd9, 0x16, 0x21, 0x5d, 0xa2, 0x47, 0xc9, 0x64, 0x6e, 0x28, 0x2b, 0x94, 0x6e, 0xe9, - 0x5a, 0xda, 0x0c, 0x07, 0x8a, 0xdb, 0x04, 0xf7, 0xcb, 0x89, 0xc5, 0x11, 0x4f, 0x8b, 0x48, 0x9e, - 0x61, 0x87, 0xe3, 0x8f, 0x7e, 0xce, 0x85, 0x50, 0x72, 0xb5, 0xcf, 0x4e, 0x48, 0x5e, 0x3e, 0xc7, - 0x08, 0x59, 0x19, 0xcb, 0x7b, 0x16, 0xdf, 0x9a, 0xf8, 0x52, 0x9c, 0x75, 0x41, 0x9d, 0xe8, 0xa1, - 0x4b, 0x32, 0xe3, 0x9c, 0x94, 0xe5, 0x52, 0xb3, 0xdf, 0xc9, 0xd5, 0xcd, 0x48, 0x57, 0xb7, 0x44, - 0x8e, 0x29, 0x6b, 0x42, 0x4b, 0x77, 0xb5, 0x64, 0xaf, 0x47, 0x56, 0x07, 0x43, 0x1e, 0xac, 0x12, - 0x88, 0x4a, 0x7b, 0x1d, 0xd5, 0xa0, 0xc4, 0xb6, 0x88, 0x29, 0xbc, 0x80, 0x7c, 0x9d, 0x60, 0xaa, - 0xcc, 0xd0, 0x2e, 0x6a, 0x50, 0x62, 0xdb, 0xe5, 0x3c, 0x89, 0x36, 0x68, 0x6a, 0x53, 0x23, 0xc5, - 0x1b, 0xca, 0x13, 0xcf, 0xf4, 0xa0, 0x0d, 0xa5, 0xec, 0x86, 0xd1, 0x8f, 0x60, 0xda, 0x18, 0xb5, - 0x41, 0xfa, 0x07, 0x64, 0xc5, 0x74, 0xe8, 0x45, 0xfc, 0x39, 0x14, 0xd3, 0x72, 0x53, 0x45, 0xaf, - 0x25, 0xb2, 0x13, 0x86, 0x49, 0x9e, 0xda, 0x33, 0xc9, 0xd5, 0x06, 0x4c, 0x99, 0xf2, 0x3d, 0xc9, - 0xc3, 0x91, 0x91, 0x0c, 0xca, 0xf8, 0x24, 0x63, 0x0b, 0xa6, 0x8d, 0x39, 0x97, 0xe4, 0xcc, 0x64, - 0x65, 0x64, 0x32, 0x52, 0xfc, 0x0a, 0x66, 0x53, 0x12, 0x0c, 0x45, 0x97, 0x98, 0x99, 0x09, 0x88, - 0x32, 0x9c, 0x29, 0x4a, 0xe9, 0xb9, 0x6b, 0xa4, 0x0f, 0x4d, 0xcf, 0xf4, 0x36, 0x25, 0x63, 0x42, - 0x2f, 0xb4, 0x4d, 0x37, 0xa1, 0x29, 0x99, 0x8d, 0xba, 0x09, 0x33, 0x92, 0xdd, 0xa4, 0x3c, 0xa5, - 0x99, 0x4d, 0xc9, 0x5f, 0x93, 0x41, 0xf5, 0x14, 0xbd, 0xdd, 0x10, 0xfc, 0x5f, 0x4f, 0x68, 0x12, - 0xf3, 0xcb, 0x34, 0x66, 0x3b, 0x31, 0xf6, 0x53, 0x79, 0xba, 0xdd, 0x6e, 0x67, 0x88, 0x41, 0x48, - 0x7d, 0xbb, 0x4d, 0x20, 0xe9, 0x3d, 0xc0, 0xb8, 0x8a, 0x9b, 0xc5, 0x51, 0x13, 0xc8, 0x54, 0xf0, - 0xfc, 0x04, 0xc6, 0x6a, 0x6a, 0xe3, 0x86, 0x46, 0x52, 0x37, 0x85, 0x7c, 0xb1, 0xd0, 0xbb, 0xef, - 0x3d, 0x6f, 0x18, 0x2b, 0xed, 0xf6, 0xa9, 0x46, 0x91, 0x6a, 0x93, 0xd5, 0x62, 0xbc, 0x4b, 0x4e, - 0x6d, 0x4a, 0x5d, 0x20, 0x6d, 0xb2, 0xe6, 0xb0, 0xf0, 0x2b, 0x74, 0x4a, 0xa3, 0x08, 0xb9, 0x19, - 0x3a, 0xb8, 0xdc, 0x44, 0x86, 0x40, 0xbc, 0x4f, 0xd4, 0x47, 0xf5, 0x2c, 0xae, 0x6e, 0x86, 0x11, - 0x31, 0xfe, 0x98, 0x3e, 0x16, 0x88, 0xb7, 0x0e, 0x45, 0x11, 0xe1, 0x92, 0xc5, 0x98, 0x8c, 0xe2, - 0x31, 0x45, 0x6e, 0x66, 0xe9, 0x21, 0x30, 0x33, 0xe6, 0xad, 0x10, 0x8f, 0x68, 0x23, 0x2d, 0x47, - 0x29, 0xa1, 0x6e, 0x32, 0x76, 0x03, 0x44, 0x71, 0x6b, 0xa4, 0x7d, 0x26, 0x11, 0xca, 0xa6, 0x74, - 0xd9, 0x50, 0x23, 0x25, 0xab, 0x31, 0x35, 0xca, 0x8d, 0xf4, 0xc2, 0x31, 0x84, 0xbe, 0x29, 0xcd, - 0x19, 0xeb, 0x38, 0xa1, 0x10, 0xe6, 0x32, 0x52, 0xbb, 0x4a, 0x69, 0xb5, 0x77, 0x0a, 0xda, 0xd2, - 0xed, 0xd3, 0x80, 0xf2, 0x56, 0xb1, 0x8c, 0x58, 0x9b, 0x84, 0x42, 0x6f, 0x1b, 0xdc, 0xa6, 0x4d, - 0x59, 0x53, 0x4b, 0xbd, 0xb2, 0xca, 0xa2, 0x5d, 0x98, 0x8f, 0xb9, 0x75, 0xeb, 0x2d, 0xf5, 0x22, - 0x90, 0xba, 0x82, 0xbb, 0x30, 0xcf, 0xdf, 0x99, 0x9f, 0x33, 0xe1, 0x3d, 0x98, 0xcf, 0xca, 0x17, - 0x8b, 0x6e, 0x9b, 0x5d, 0xb7, 0x8d, 0xd3, 0x93, 0x2e, 0xba, 0x5e, 0x4d, 0xba, 0x70, 0xc7, 0xd6, - 0xfd, 0xac, 0x6c, 0xe5, 0x29, 0x4c, 0xe8, 0xb9, 0x62, 0x91, 0xca, 0x3a, 0x12, 0x99, 0x6b, 0x4b, - 0x57, 0x52, 0x6a, 0xf9, 0xfe, 0xf8, 0x9c, 0x32, 0x7a, 0x59, 0xa1, 0xc6, 0x9e, 0x88, 0xe7, 0x62, - 0x2d, 0x19, 0xd2, 0xda, 0xa0, 0xef, 0xc1, 0x64, 0xf4, 0x56, 0x90, 0x91, 0x30, 0x80, 0x65, 0xd8, - 0x8b, 0x26, 0xa3, 0x57, 0x83, 0x67, 0x47, 0x5f, 0x15, 0xdc, 0x3e, 0x42, 0xbf, 0x92, 0xf0, 0x66, - 0xd7, 0xc6, 0x70, 0x1a, 0xa6, 0xaf, 0xcc, 0xed, 0x59, 0x57, 0xa7, 0x49, 0x8f, 0x9b, 0x39, 0x7c, - 0x93, 0x7a, 0xdc, 0x32, 0x43, 0x4c, 0x49, 0x09, 0x33, 0x85, 0x4e, 0x1b, 0xae, 0xf5, 0x0c, 0x38, - 0x85, 0xee, 0x6a, 0x51, 0x1a, 0x7a, 0x87, 0xa6, 0xca, 0x7a, 0xf2, 0x61, 0x8a, 0xdb, 0x24, 0x79, - 0x7c, 0x46, 0x08, 0x29, 0xf9, 0xe4, 0x23, 0x33, 0xf0, 0xd3, 0x57, 0x34, 0x9c, 0x35, 0xff, 0xc8, - 0xd0, 0xb8, 0x23, 0xb8, 0xe3, 0x74, 0x9a, 0xb8, 0xc7, 0x75, 0xc5, 0x35, 0xfd, 0x92, 0x2e, 0x81, - 0x48, 0xe5, 0xfc, 0x05, 0xae, 0x9d, 0xa4, 0x11, 0xef, 0x4d, 0x24, 0x6d, 0x5e, 0xaa, 0xcb, 0x3f, - 0xff, 0xeb, 0x85, 0xdc, 0xcf, 0x7f, 0xb1, 0x90, 0xfb, 0xf7, 0xbf, 0x58, 0xc8, 0xfd, 0xe7, 0x5f, - 0x2c, 0xe4, 0x7e, 0xb8, 0x78, 0xba, 0xe8, 0x85, 0xcd, 0xb6, 0x8b, 0x3b, 0xe1, 0x5d, 0x46, 0x6e, - 0x90, 0xfe, 0xf7, 0xe0, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x1a, 0x2f, 0xd9, 0x79, 0xd5, - 0x00, 0x00, + 0x76, 0x18, 0xac, 0x6e, 0x92, 0x22, 0x79, 0xf8, 0xd7, 0xba, 0xe2, 0x4f, 0xab, 0x45, 0xa9, 0xa5, + 0xd2, 0x4a, 0xa3, 0xd1, 0xee, 0xea, 0x87, 0x9a, 0x99, 0x9d, 0xbf, 0x9d, 0xd9, 0x6e, 0x92, 0x12, + 0x29, 0x51, 0x24, 0xa7, 0x9a, 0x6c, 0xce, 0xee, 0xce, 0x6e, 0x6f, 0xb1, 0xfb, 0x8a, 0xac, 0x4f, + 0xcd, 0xaa, 0xde, 0xaa, 0xa2, 0x34, 0xb2, 0x61, 0x7f, 0xb1, 0x1d, 0xfb, 0x21, 0x41, 0x12, 0x1b, + 0xb0, 0x83, 0x18, 0x7e, 0x70, 0x80, 0xe4, 0x25, 0x01, 0x02, 0xe4, 0x65, 0xe1, 0x97, 0x00, 0x81, + 0x91, 0x00, 0xd9, 0x04, 0x30, 0x10, 0x20, 0x36, 0x02, 0xe4, 0x81, 0x8e, 0xf7, 0x91, 0x40, 0x02, + 0x04, 0x41, 0xf2, 0xb0, 0x40, 0x80, 0xe0, 0xfe, 0xd6, 0xbd, 0x55, 0xb7, 0xaa, 0x49, 0x0d, 0x77, + 0xf2, 0x22, 0xb1, 0xef, 0x3d, 0xe7, 0xdc, 0xff, 0x53, 0xe7, 0x9c, 0x7b, 0xee, 0x39, 0x70, 0x37, + 0xc2, 0x5d, 0xdc, 0xf3, 0x83, 0xe8, 0x5e, 0x17, 0xef, 0x39, 0xed, 0xd7, 0xf7, 0xda, 0x5d, 0x17, + 0x7b, 0xd1, 0xbd, 0x5e, 0xe0, 0x47, 0xfe, 0x3d, 0xe7, 0x30, 0xda, 0x0f, 0x71, 0xf0, 0xd2, 0x6d, + 0xe3, 0xbb, 0xb4, 0x04, 0x0d, 0xd1, 0xff, 0x2a, 0xd3, 0x7b, 0xfe, 0x9e, 0xcf, 0x60, 0xc8, 0x5f, + 0xac, 0xb2, 0x72, 0x79, 0xcf, 0xf7, 0xf7, 0xba, 0x98, 0x21, 0xef, 0x1e, 0x3e, 0xbf, 0x87, 0x0f, + 0x7a, 0xd1, 0x6b, 0x5e, 0x59, 0x4d, 0x56, 0x46, 0xee, 0x01, 0x0e, 0x23, 0xe7, 0xa0, 0xc7, 0x01, + 0xde, 0x96, 0x5d, 0x71, 0xa2, 0x88, 0xd4, 0x44, 0xae, 0xef, 0xdd, 0x7b, 0xf9, 0x40, 0xfd, 0xc9, + 0x41, 0x6f, 0xe7, 0xf6, 0xba, 0x8d, 0x83, 0x28, 0x4c, 0x11, 0xe5, 0x90, 0xd1, 0xeb, 0x1e, 0x0e, + 0xef, 0xe1, 0x97, 0xd8, 0x8b, 0xc4, 0x7f, 0x1c, 0xf4, 0xba, 0x19, 0x94, 0xfe, 0xcb, 0x41, 0xbe, + 0x6d, 0x06, 0x79, 0x85, 0x77, 0xc9, 0x4c, 0x79, 0xf2, 0x8f, 0x3e, 0xe0, 0x81, 0xd3, 0xeb, 0xe1, + 0x20, 0xfe, 0x23, 0xd5, 0xd7, 0xc3, 0xd0, 0xd9, 0xc3, 0xbc, 0x8f, 0x2f, 0x1f, 0xa8, 0x3f, 0x19, + 0xa8, 0xf5, 0x7b, 0x55, 0x18, 0x5a, 0x26, 0x05, 0xe8, 0x7d, 0x18, 0xdc, 0x7a, 0xdd, 0xc3, 0xe5, + 0xc2, 0xb5, 0xc2, 0xed, 0xc9, 0x85, 0x12, 0xab, 0xbf, 0xbb, 0xd1, 0xc3, 0x01, 0x9d, 0xb0, 0x3a, + 0x3a, 0x3e, 0xaa, 0x4e, 0x92, 0x76, 0xbf, 0xe5, 0x1f, 0xb8, 0x11, 0x5d, 0x10, 0x9b, 0x62, 0xa0, + 0x1d, 0x98, 0xb4, 0x71, 0xe8, 0x1f, 0x06, 0x6d, 0xbc, 0x82, 0x9d, 0x0e, 0x0e, 0xca, 0xc5, 0x6b, + 0x85, 0xdb, 0x63, 0x0b, 0x33, 0x77, 0xd9, 0x90, 0xf5, 0xca, 0xfa, 0xec, 0xf1, 0x51, 0x15, 0x05, + 0xbc, 0x2c, 0x26, 0xb6, 0x72, 0xce, 0x4e, 0x90, 0x41, 0x5f, 0xc0, 0xc4, 0x22, 0x0e, 0xa2, 0xda, + 0x61, 0xb4, 0xef, 0x07, 0x6e, 0xf4, 0xba, 0x3c, 0x40, 0xe9, 0xce, 0x72, 0xba, 0x5a, 0x5d, 0x73, + 0xa1, 0x3e, 0x7f, 0x7c, 0x54, 0x2d, 0x93, 0x35, 0x6b, 0x39, 0xa2, 0x54, 0x23, 0xaf, 0x13, 0x43, + 0x9f, 0xc3, 0x78, 0x83, 0x6c, 0x86, 0xf6, 0x96, 0xff, 0x02, 0x7b, 0x61, 0x79, 0x50, 0xeb, 0xb4, + 0x5a, 0xd5, 0x5c, 0xa8, 0x5f, 0x3e, 0x3e, 0xaa, 0xce, 0xd1, 0xbd, 0xd3, 0x6e, 0x45, 0xb4, 0x50, + 0x23, 0xad, 0x51, 0x42, 0x3f, 0x81, 0xc9, 0xcd, 0xc0, 0x7f, 0xe9, 0x86, 0xae, 0xef, 0xd1, 0xa2, + 0xf2, 0x10, 0xa5, 0x3d, 0xc7, 0x69, 0xeb, 0x95, 0xcd, 0x85, 0xfa, 0x95, 0xe3, 0xa3, 0xea, 0xa5, + 0x9e, 0x28, 0x65, 0x0d, 0xe8, 0x33, 0xa3, 0xa3, 0xa0, 0x2d, 0x18, 0x5b, 0xec, 0x1e, 0x86, 0x11, + 0x0e, 0xd6, 0x9d, 0x03, 0x5c, 0x3e, 0x4f, 0xc9, 0x4f, 0x8b, 0x79, 0x89, 0x6b, 0x9a, 0x0b, 0xf5, + 0xca, 0xf1, 0x51, 0x75, 0xb6, 0xcd, 0x8a, 0x5a, 0x9e, 0x73, 0xa0, 0x4f, 0xb9, 0x4a, 0x06, 0x7d, + 0x07, 0x06, 0xb7, 0x43, 0x1c, 0x94, 0x47, 0x28, 0xb9, 0x09, 0x4e, 0x8e, 0x14, 0x35, 0x17, 0xd8, + 0xfa, 0x1f, 0x86, 0x38, 0xd0, 0xf0, 0x29, 0x02, 0x41, 0xb4, 0xfd, 0x2e, 0x2e, 0x8f, 0x6a, 0x88, + 0xa4, 0xa8, 0xf9, 0x1e, 0x43, 0x0c, 0xfc, 0xae, 0xde, 0x30, 0x45, 0x40, 0xab, 0x30, 0x4a, 0x5a, + 0x0e, 0x7b, 0x4e, 0x1b, 0x97, 0x81, 0x62, 0x97, 0x38, 0xb6, 0x2c, 0xaf, 0xcf, 0x1d, 0x1f, 0x55, + 0x2f, 0x7a, 0xe2, 0xa7, 0x46, 0x25, 0xc6, 0x46, 0x9f, 0xc2, 0xf9, 0x06, 0x0e, 0x5e, 0xe2, 0xa0, + 0x3c, 0x46, 0xe9, 0x4c, 0x89, 0x85, 0xa4, 0x85, 0xcd, 0x85, 0xfa, 0xf4, 0xf1, 0x51, 0xb5, 0x14, + 0xd2, 0x5f, 0x1a, 0x0d, 0x8e, 0x46, 0x76, 0x9b, 0x8d, 0x5f, 0xe2, 0x20, 0xc4, 0x5b, 0x87, 0x9e, + 0x87, 0xbb, 0xe5, 0x71, 0x6d, 0xb7, 0x69, 0x75, 0x62, 0xb7, 0x05, 0xac, 0xb0, 0x15, 0xd1, 0x52, + 0x7d, 0xb7, 0x69, 0x08, 0x68, 0x1f, 0x4a, 0xec, 0xaf, 0x45, 0xdf, 0xf3, 0x70, 0x9b, 0x1c, 0xa9, + 0xf2, 0x04, 0x6d, 0xe0, 0x12, 0x6f, 0x20, 0x59, 0xdd, 0x5c, 0xa8, 0x57, 0x8f, 0x8f, 0xaa, 0x97, + 0x19, 0xed, 0x56, 0x5b, 0x56, 0x68, 0xcd, 0xa4, 0xa8, 0x92, 0x71, 0xd4, 0xda, 0x6d, 0x1c, 0x86, + 0x36, 0xfe, 0xe9, 0x21, 0x0e, 0xa3, 0xf2, 0xa4, 0x36, 0x0e, 0xad, 0xae, 0xf9, 0x90, 0x8d, 0xc3, + 0xa1, 0x85, 0xad, 0x80, 0x95, 0xea, 0xe3, 0xd0, 0x10, 0xd0, 0x26, 0x40, 0xad, 0xd7, 0x6b, 0xe0, + 0x90, 0x6c, 0xc6, 0xf2, 0x14, 0x25, 0x7d, 0x91, 0x93, 0xde, 0xc1, 0xbb, 0xbc, 0xa2, 0xb9, 0x50, + 0xbf, 0x74, 0x7c, 0x54, 0x9d, 0x71, 0x7a, 0xbd, 0x56, 0xc8, 0x8a, 0x34, 0xa2, 0x0a, 0x0d, 0x36, + 0xef, 0x07, 0x7e, 0x84, 0xf9, 0x56, 0x2c, 0x97, 0x12, 0xf3, 0xae, 0xd4, 0x89, 0xfe, 0x06, 0xb4, + 0xb0, 0xc5, 0xb7, 0x75, 0x72, 0xde, 0x15, 0x04, 0x72, 0x16, 0x97, 0x9c, 0xc8, 0xd9, 0x75, 0x42, + 0xcc, 0xb7, 0xc7, 0x05, 0xed, 0x2c, 0xea, 0x95, 0xcd, 0x87, 0xec, 0x2c, 0x76, 0x78, 0x69, 0xcb, + 0xb0, 0x5f, 0x12, 0xf4, 0xc8, 0x8c, 0xc4, 0x03, 0x2f, 0xa3, 0x3e, 0x33, 0xf2, 0x0a, 0xef, 0x9a, + 0x67, 0x24, 0x06, 0x45, 0x2b, 0x30, 0xb2, 0x83, 0x77, 0x19, 0xe7, 0xb8, 0x48, 0xe9, 0x5d, 0x88, + 0xe9, 0x31, 0x9e, 0xf1, 0x90, 0x9d, 0x0a, 0x42, 0x2d, 0xcd, 0x2d, 0x24, 0x36, 0xfa, 0xdd, 0x02, + 0xcc, 0x89, 0x13, 0x8e, 0xa3, 0x57, 0x7e, 0xf0, 0xc2, 0xf5, 0xf6, 0x16, 0x7d, 0xef, 0xb9, 0xbb, + 0x57, 0x9e, 0xa6, 0x94, 0xaf, 0x25, 0x98, 0x46, 0x02, 0xaa, 0xb9, 0x50, 0x7f, 0xeb, 0xf8, 0xa8, + 0x7a, 0x43, 0x32, 0x10, 0x59, 0x4f, 0x36, 0xe4, 0x73, 0x77, 0x4f, 0x6b, 0x38, 0xab, 0x2d, 0xf4, + 0x5b, 0x05, 0x98, 0xe5, 0xa3, 0xb3, 0x71, 0xdb, 0x0f, 0x3a, 0x71, 0x37, 0x66, 0x68, 0x37, 0xaa, + 0xf2, 0xb4, 0x9a, 0x80, 0x9a, 0x0b, 0xf5, 0x5b, 0xc7, 0x47, 0x55, 0x8b, 0x4f, 0x5c, 0x2b, 0x10, + 0xd5, 0xa6, 0x4e, 0x64, 0x34, 0x44, 0x76, 0x02, 0x61, 0xfe, 0x9b, 0x01, 0x7e, 0x8e, 0x03, 0xec, + 0xb5, 0x71, 0x79, 0x56, 0xdb, 0x09, 0x7a, 0xa5, 0xe0, 0xca, 0xe4, 0x53, 0xd2, 0xea, 0xc9, 0x62, + 0x7d, 0x27, 0xe8, 0x28, 0xe8, 0xa7, 0x80, 0xf8, 0x04, 0xd4, 0x0e, 0x3b, 0x6e, 0xc4, 0x07, 0x38, + 0x47, 0x5b, 0xb9, 0xac, 0xcf, 0xb3, 0x02, 0xd0, 0x5c, 0xa8, 0x5b, 0xc7, 0x47, 0xd5, 0xab, 0x62, + 0x8a, 0x1d, 0x52, 0x65, 0x1a, 0x98, 0x81, 0x38, 0xe1, 0xbc, 0x6b, 0x7e, 0xfb, 0x45, 0xb9, 0xac, + 0x71, 0x5e, 0x52, 0x24, 0x58, 0x76, 0xd7, 0x6f, 0xbf, 0xd0, 0x39, 0x2f, 0xa9, 0x45, 0x11, 0x5c, + 0xe4, 0xab, 0x64, 0xe3, 0x30, 0x0a, 0x5c, 0xca, 0x3b, 0xc2, 0xf2, 0x25, 0x4a, 0x67, 0x5e, 0xf0, + 0xe0, 0x34, 0x44, 0xf3, 0x1d, 0xd6, 0x5b, 0xbe, 0x11, 0x5a, 0x81, 0x52, 0xa7, 0x35, 0x63, 0x22, + 0x8f, 0x7e, 0x03, 0x66, 0x76, 0x5c, 0xaf, 0xe3, 0xbf, 0x0a, 0x97, 0x70, 0xf8, 0x22, 0xf2, 0x7b, + 0x0d, 0x26, 0x14, 0x96, 0x2b, 0xb4, 0xdd, 0xab, 0x62, 0x9b, 0x9b, 0x60, 0x9a, 0x0f, 0xeb, 0x37, + 0x8f, 0x8f, 0xaa, 0xd7, 0x5f, 0xb1, 0xca, 0x56, 0x87, 0xd5, 0xb6, 0xb8, 0x5c, 0xa9, 0x35, 0x6e, + 0x6e, 0x85, 0x6c, 0x01, 0xbd, 0xa2, 0x7c, 0x59, 0xdb, 0x02, 0x7a, 0xa5, 0x60, 0x06, 0x89, 0x06, + 0xf5, 0x2d, 0xa0, 0xa3, 0xa0, 0xc7, 0x30, 0x22, 0xd8, 0x43, 0x79, 0x5e, 0x3b, 0xba, 0xa2, 0xb8, + 0xf9, 0x90, 0x49, 0x40, 0x82, 0xc5, 0xe8, 0x27, 0x57, 0x40, 0xa1, 0x35, 0x18, 0xa5, 0x3c, 0x92, + 0xb2, 0xac, 0x2b, 0x94, 0x12, 0x12, 0x1b, 0x55, 0x94, 0x37, 0x1f, 0xd6, 0xcb, 0xc7, 0x47, 0xd5, + 0x69, 0xc6, 0x65, 0x53, 0x8c, 0x2a, 0x26, 0x80, 0x1e, 0xc2, 0x40, 0xad, 0xd7, 0x2b, 0x5f, 0xa5, + 0x74, 0xc6, 0x63, 0x3a, 0xcd, 0x87, 0xf5, 0x0b, 0xc7, 0x47, 0xd5, 0x09, 0xa7, 0xa7, 0x0f, 0x8b, + 0x40, 0xa3, 0x5d, 0x28, 0x35, 0x3c, 0xff, 0xd5, 0xf3, 0xae, 0xf3, 0x02, 0x0b, 0xf6, 0x56, 0xcd, + 0x66, 0x6f, 0xf4, 0x63, 0x15, 0x0a, 0x04, 0x23, 0x93, 0x4b, 0xd1, 0x23, 0x9f, 0xc5, 0xa7, 0x87, + 0xbb, 0x38, 0xf0, 0x70, 0x84, 0x43, 0x3e, 0xda, 0x6b, 0xda, 0x67, 0x31, 0x59, 0xdd, 0x7c, 0xc8, + 0x5a, 0x7a, 0x21, 0xcb, 0x4d, 0x63, 0x4f, 0x51, 0x45, 0x5d, 0xb8, 0x10, 0x97, 0x89, 0x4f, 0xcd, + 0x75, 0xda, 0x54, 0x25, 0xd5, 0x54, 0xfc, 0xb9, 0xb9, 0x76, 0x7c, 0x54, 0x9d, 0x57, 0xda, 0x32, + 0x7d, 0x72, 0xd2, 0x84, 0xd1, 0x53, 0x18, 0x5d, 0xf5, 0xc2, 0xc8, 0xe9, 0x76, 0x71, 0x50, 0xb6, + 0xb4, 0xe5, 0x93, 0xe5, 0xcd, 0x07, 0x8c, 0x89, 0xbb, 0xa2, 0x40, 0x5f, 0x3d, 0x09, 0x87, 0x3a, + 0x30, 0xa5, 0x7e, 0x73, 0xc8, 0x79, 0xb9, 0x41, 0x49, 0x96, 0x0d, 0x1f, 0x31, 0x72, 0x52, 0x1e, + 0xd4, 0xaf, 0x1e, 0x1f, 0x55, 0x2b, 0xda, 0x57, 0x2c, 0x79, 0x44, 0x92, 0x24, 0xd1, 0x6f, 0x13, + 0x1e, 0x5d, 0x7b, 0xb6, 0xb6, 0xda, 0xd9, 0xe4, 0x45, 0x54, 0xe8, 0x24, 0xf2, 0xfc, 0x37, 0x74, + 0x1e, 0x6d, 0x04, 0x6a, 0x3e, 0x60, 0x5f, 0x8a, 0xd0, 0x39, 0xe8, 0xb6, 0xdc, 0x8e, 0x3c, 0x97, + 0xad, 0x1e, 0x07, 0x48, 0x30, 0x69, 0x23, 0x11, 0xf4, 0x23, 0x98, 0x94, 0x35, 0x6c, 0xc7, 0xdd, + 0xcc, 0xde, 0x71, 0x74, 0x90, 0x4a, 0x7b, 0xe9, 0x0d, 0x97, 0x20, 0x46, 0x4e, 0x15, 0x11, 0x58, + 0x1f, 0x07, 0xfe, 0x61, 0xaf, 0x7c, 0x4b, 0x5b, 0x16, 0x59, 0xde, 0x7c, 0xc0, 0x4e, 0x15, 0x91, + 0x75, 0x5b, 0x7b, 0xa4, 0x44, 0x5f, 0x17, 0x09, 0x48, 0xbe, 0xd3, 0xdb, 0xab, 0x9c, 0xcb, 0xbf, + 0xa5, 0x1d, 0x76, 0x51, 0x2c, 0x96, 0xf8, 0xd0, 0x35, 0x31, 0x74, 0x89, 0x8d, 0x1c, 0x98, 0xdc, + 0x78, 0x11, 0x39, 0xab, 0x07, 0x44, 0x6b, 0xb3, 0x0f, 0xbb, 0xb8, 0x7c, 0x5b, 0x63, 0x4c, 0x7a, + 0xa5, 0x58, 0x5f, 0xff, 0x45, 0xe4, 0xb4, 0x5c, 0x5a, 0xdc, 0x0a, 0x0e, 0x13, 0x02, 0x76, 0x82, + 0x20, 0xe1, 0x7d, 0xa4, 0xa4, 0x16, 0x86, 0xee, 0x9e, 0x77, 0x80, 0xbd, 0xa8, 0xfc, 0x76, 0xaa, + 0x89, 0xb8, 0xb2, 0xf9, 0x80, 0xf1, 0x3e, 0xda, 0x84, 0x23, 0x8b, 0xd3, 0x2d, 0xc4, 0x28, 0xa8, + 0x01, 0x63, 0xab, 0x5e, 0x84, 0xf7, 0x98, 0xc2, 0x58, 0xbe, 0xa3, 0x29, 0x25, 0x4a, 0x4d, 0xf3, + 0x01, 0x13, 0x85, 0xdc, 0xb8, 0x48, 0xd7, 0x49, 0x14, 0x58, 0xa2, 0xe9, 0xec, 0x38, 0x51, 0x7b, + 0x9f, 0x28, 0x58, 0x87, 0x61, 0xf9, 0x9b, 0x1a, 0x51, 0xa5, 0xa6, 0xf9, 0x80, 0x69, 0x3a, 0xaf, + 0x48, 0x51, 0x2b, 0xa4, 0x65, 0x3a, 0x55, 0x05, 0x18, 0xfd, 0x26, 0xcc, 0x12, 0x1d, 0xb3, 0x8b, + 0xc3, 0x90, 0x7c, 0xc3, 0xb1, 0x17, 0xb9, 0x6d, 0xd6, 0xeb, 0x6f, 0xd1, 0x06, 0xae, 0xf0, 0x06, + 0xcc, 0x40, 0xec, 0x3b, 0xb4, 0xcf, 0xeb, 0xa8, 0xb6, 0x19, 0x57, 0xea, 0xdb, 0x3c, 0x83, 0x00, + 0xc0, 0x88, 0xd0, 0x75, 0x9f, 0x0c, 0x8e, 0x0c, 0x97, 0x46, 0xac, 0x3f, 0x2d, 0xc0, 0x10, 0xed, + 0x21, 0xfa, 0x14, 0x86, 0x9e, 0xba, 0x5e, 0x27, 0x2c, 0x17, 0xae, 0x0d, 0x28, 0xfa, 0x10, 0xad, + 0x24, 0x15, 0xf5, 0xb9, 0x9f, 0x1f, 0x55, 0xcf, 0x1d, 0x1f, 0x55, 0xa7, 0x5e, 0x10, 0x30, 0x45, + 0x1d, 0x67, 0x78, 0x68, 0x1b, 0x2e, 0xd6, 0xba, 0x5d, 0xff, 0xd5, 0xa6, 0x13, 0x44, 0xae, 0xd3, + 0x6d, 0x1c, 0x52, 0x01, 0x9e, 0x2a, 0xe5, 0x23, 0xf5, 0x1b, 0xc7, 0x47, 0xd5, 0xaa, 0x43, 0xaa, + 0x5b, 0x3d, 0x56, 0xdf, 0x0a, 0x19, 0x80, 0x42, 0xc8, 0x84, 0x6f, 0xfd, 0xec, 0x3c, 0x94, 0x56, + 0xfc, 0x30, 0x22, 0x5a, 0xb4, 0x54, 0x07, 0x6e, 0xc0, 0x79, 0x52, 0xb6, 0xba, 0x44, 0xed, 0x06, + 0xa3, 0xf5, 0xb1, 0xe3, 0xa3, 0xea, 0xf0, 0xbe, 0x1f, 0x46, 0x2d, 0xb7, 0x63, 0xf3, 0x2a, 0xf4, + 0x36, 0x8c, 0xac, 0xfb, 0x1d, 0x4c, 0x55, 0xd5, 0x22, 0x05, 0x9b, 0x38, 0x3e, 0xaa, 0x8e, 0x7a, + 0x7e, 0x07, 0x53, 0x8d, 0xd4, 0x96, 0xd5, 0xa8, 0xc9, 0x35, 0xc9, 0x01, 0x0a, 0x56, 0x3f, 0x3e, + 0xaa, 0x0e, 0x12, 0xd5, 0xf1, 0x97, 0x47, 0xd5, 0xf7, 0xf6, 0xdc, 0x68, 0xff, 0x70, 0xf7, 0x6e, + 0xdb, 0x3f, 0xb8, 0xb7, 0x17, 0x38, 0x2f, 0x5d, 0x66, 0xc8, 0x71, 0xba, 0xf7, 0x62, 0x73, 0x4f, + 0xcf, 0xe5, 0x56, 0x96, 0xc6, 0xeb, 0x30, 0xc2, 0x07, 0x84, 0x12, 0x57, 0x34, 0x77, 0x60, 0xba, + 0xd6, 0xe9, 0xb8, 0x0c, 0x63, 0x33, 0x70, 0xbd, 0xb6, 0xdb, 0x73, 0xba, 0x44, 0xe9, 0x1f, 0xb8, + 0x3d, 0xca, 0x27, 0x45, 0xd6, 0xb7, 0x7a, 0x12, 0x40, 0x99, 0x14, 0x23, 0x01, 0xf4, 0x10, 0x46, + 0x96, 0xd6, 0x1b, 0x54, 0x0d, 0x2d, 0x0f, 0x51, 0x62, 0xf4, 0xc0, 0x77, 0xbc, 0x90, 0x0e, 0x4d, + 0x25, 0x20, 0x01, 0xd1, 0x7b, 0x30, 0xbe, 0x79, 0xb8, 0xdb, 0x75, 0xdb, 0x5b, 0x6b, 0x8d, 0xa7, + 0xf8, 0x35, 0xd5, 0xdf, 0xc7, 0x99, 0xb8, 0xd6, 0xa3, 0xe5, 0xad, 0xa8, 0x1b, 0xb6, 0x5e, 0xe0, + 0xd7, 0xb6, 0x06, 0x17, 0xe3, 0x35, 0x1a, 0x2b, 0x04, 0x6f, 0x38, 0x85, 0x17, 0x86, 0xfb, 0x2a, + 0x1e, 0x83, 0x43, 0xf7, 0x00, 0x98, 0x56, 0x54, 0xeb, 0x74, 0x98, 0x7a, 0x3f, 0x5a, 0x9f, 0x3a, + 0x3e, 0xaa, 0x8e, 0x71, 0x3d, 0xca, 0xe9, 0x74, 0x02, 0x5b, 0x01, 0x41, 0x8b, 0x30, 0x62, 0xfb, + 0x6c, 0x82, 0xb9, 0x52, 0x3f, 0x25, 0x95, 0x7a, 0x56, 0xcc, 0xcd, 0x38, 0xfc, 0x97, 0x3a, 0x4a, + 0x01, 0x81, 0xaa, 0x30, 0xbc, 0xee, 0x2f, 0x3a, 0xed, 0x7d, 0xa6, 0xda, 0x8f, 0xd4, 0x87, 0x8e, + 0x8f, 0xaa, 0x85, 0x6f, 0xdb, 0xa2, 0x14, 0xbd, 0x84, 0xb1, 0x78, 0xa1, 0xc2, 0xf2, 0x18, 0x9d, + 0xbe, 0x2d, 0x72, 0x8a, 0x43, 0x5a, 0xdc, 0x22, 0x4b, 0xaf, 0xcc, 0xe0, 0x57, 0xd8, 0x05, 0x6a, + 0x43, 0xa8, 0x0b, 0x57, 0xb6, 0xc9, 0xc7, 0x75, 0xb7, 0x8b, 0xe3, 0xe2, 0x5a, 0x18, 0xe2, 0x80, + 0xd0, 0x5a, 0x5d, 0xa2, 0x9a, 0xff, 0x28, 0x57, 0x39, 0xe2, 0x9e, 0x10, 0x3e, 0xc8, 0x40, 0x5a, + 0x6e, 0x47, 0x19, 0x71, 0x3e, 0x31, 0xeb, 0xff, 0x14, 0x00, 0x6d, 0xf4, 0xb0, 0xd7, 0x68, 0xac, + 0x90, 0xa3, 0x23, 0x4e, 0xce, 0xb7, 0x60, 0x94, 0xad, 0x11, 0x59, 0xc8, 0x22, 0x5d, 0xc8, 0xc9, + 0xe3, 0xa3, 0x2a, 0xf0, 0x85, 0x24, 0x8b, 0x18, 0x03, 0xa0, 0x9b, 0x30, 0xb0, 0xb5, 0xb5, 0x46, + 0x8f, 0xc5, 0x40, 0xfd, 0xe2, 0xf1, 0x51, 0x75, 0x20, 0x8a, 0xba, 0xbf, 0x3c, 0xaa, 0x8e, 0x2c, + 0x1d, 0x32, 0x46, 0x69, 0x93, 0x7a, 0x74, 0x13, 0x86, 0x85, 0x68, 0x33, 0x18, 0x9f, 0x47, 0x2e, + 0xb3, 0xd8, 0xa2, 0x0e, 0x7d, 0x93, 0x1b, 0x7a, 0x86, 0x4c, 0x86, 0x9e, 0x11, 0x72, 0xe8, 0xc8, + 0xc7, 0x8f, 0x1b, 0x77, 0xee, 0xc2, 0x10, 0x5b, 0x9f, 0xf3, 0x94, 0x1f, 0x25, 0xac, 0x3b, 0xa3, + 0xc7, 0x47, 0xd5, 0x21, 0xba, 0x4e, 0x36, 0x03, 0x7b, 0x32, 0x38, 0x52, 0x28, 0x15, 0xed, 0x11, + 0x82, 0x4b, 0x4e, 0x80, 0xf5, 0x4d, 0x18, 0x53, 0x86, 0x8f, 0xe6, 0x61, 0x90, 0xfc, 0x4f, 0xf9, + 0xc5, 0x38, 0x6b, 0xac, 0x4d, 0xa6, 0x85, 0x96, 0x5a, 0x3f, 0x9b, 0x80, 0x12, 0xc1, 0xd4, 0x98, + 0x8c, 0x36, 0x55, 0x85, 0x7e, 0x53, 0x75, 0x1b, 0x64, 0xdb, 0x9c, 0xdb, 0x8c, 0x1f, 0x1f, 0x55, + 0x47, 0x0e, 0x79, 0x59, 0xdc, 0x33, 0xd4, 0x80, 0xe1, 0xe5, 0x2f, 0x7b, 0x6e, 0x80, 0x43, 0x6e, + 0x59, 0xac, 0xdc, 0x65, 0xb6, 0xe5, 0xbb, 0xc2, 0xb6, 0x7c, 0x77, 0x4b, 0xd8, 0x96, 0xeb, 0x57, + 0x38, 0xd7, 0xbd, 0x80, 0x19, 0x4a, 0xbc, 0x01, 0x7e, 0xff, 0xaf, 0xab, 0x05, 0x5b, 0x50, 0x42, + 0xdf, 0x82, 0xf3, 0x8f, 0xfc, 0xe0, 0xc0, 0x89, 0xf8, 0x0a, 0x50, 0xb3, 0xd3, 0x73, 0x5a, 0xa2, + 0xec, 0x19, 0x0e, 0x83, 0x1e, 0xc1, 0xa4, 0xed, 0x1f, 0x46, 0x78, 0xcb, 0x17, 0xeb, 0x36, 0x44, + 0xb1, 0xe8, 0xf7, 0x3d, 0x20, 0x35, 0xad, 0xc8, 0x4f, 0x0b, 0x9d, 0x76, 0x02, 0x0b, 0x2d, 0xc3, + 0xa4, 0x66, 0xa7, 0x61, 0xab, 0x35, 0xca, 0x75, 0x58, 0xcd, 0xba, 0xa3, 0xb2, 0xa4, 0x04, 0x12, + 0x5a, 0x37, 0x09, 0xc9, 0xc3, 0xb4, 0x47, 0x7d, 0x05, 0x61, 0x93, 0x18, 0x8c, 0x61, 0x8a, 0x77, + 0x54, 0x6a, 0x45, 0x23, 0xdc, 0xba, 0xc3, 0xec, 0xcb, 0x89, 0xda, 0xfa, 0x0d, 0x3e, 0xcb, 0x97, + 0xe5, 0xd8, 0xd3, 0x7a, 0x92, 0x9d, 0xa4, 0x49, 0x98, 0xb0, 0xfc, 0xc0, 0x8c, 0xd2, 0xde, 0x32, + 0x9b, 0xa1, 0xf8, 0xc0, 0xa8, 0xec, 0x49, 0x7e, 0x6a, 0xd6, 0x60, 0x68, 0x3b, 0x74, 0xf6, 0x18, + 0x73, 0x9a, 0x5c, 0xb8, 0xce, 0x7b, 0x94, 0xdc, 0x7d, 0xd4, 0xcc, 0x4c, 0x01, 0xe9, 0xb9, 0x9b, + 0xa2, 0x36, 0x74, 0xf5, 0xa3, 0x4b, 0xeb, 0xd0, 0x67, 0x00, 0xbc, 0x57, 0x44, 0xd1, 0x1a, 0xe3, + 0xd2, 0xa0, 0x36, 0xc8, 0x5a, 0xaf, 0x57, 0xbf, 0xca, 0xc7, 0x37, 0x2b, 0xc7, 0xa7, 0xa9, 0x5e, + 0xb6, 0x42, 0x04, 0x7d, 0x0a, 0xe3, 0x94, 0x77, 0x89, 0x15, 0x1d, 0xa7, 0x2b, 0x4a, 0x2d, 0xd1, + 0x94, 0x1d, 0x19, 0xd6, 0x53, 0x43, 0x40, 0xbf, 0x09, 0x33, 0x9c, 0x5c, 0x42, 0xeb, 0x9d, 0xe0, + 0x5a, 0xbe, 0xd6, 0x3d, 0x1d, 0xa6, 0x7e, 0x87, 0xf7, 0xd4, 0x92, 0x3d, 0xcd, 0xd4, 0x83, 0x6d, + 0x73, 0x33, 0x68, 0x15, 0xa6, 0xb6, 0x43, 0xac, 0x8d, 0x61, 0x92, 0x7e, 0x08, 0xa8, 0x02, 0x77, + 0x18, 0xe2, 0x56, 0xd6, 0x38, 0x92, 0x78, 0xc8, 0x06, 0xb4, 0x14, 0xf8, 0xbd, 0xc4, 0x1e, 0x9f, + 0xa2, 0x33, 0x42, 0xed, 0x11, 0x9d, 0xc0, 0xef, 0xb5, 0xb2, 0x37, 0xba, 0x01, 0x1b, 0xfd, 0x18, + 0x66, 0x63, 0xb3, 0xe9, 0x92, 0xeb, 0xec, 0x79, 0x7e, 0x18, 0xb9, 0xed, 0xd5, 0x25, 0x6a, 0x81, + 0xe4, 0xfc, 0x3f, 0x36, 0xbb, 0xb6, 0x3a, 0x12, 0x44, 0xe7, 0xff, 0x19, 0x54, 0xd0, 0x0f, 0x61, + 0x82, 0xb7, 0xc5, 0xcd, 0xf4, 0x17, 0xf2, 0x37, 0x9a, 0x04, 0xe6, 0x26, 0x73, 0xf1, 0x93, 0xc9, + 0x48, 0x3a, 0x2d, 0xf4, 0x05, 0x8c, 0x3d, 0x7b, 0x54, 0xb3, 0x71, 0xd8, 0xf3, 0xbd, 0x10, 0x73, + 0xb3, 0xe3, 0x55, 0x4e, 0xfa, 0xd9, 0xa3, 0x9a, 0x22, 0x70, 0x62, 0x01, 0xc5, 0x24, 0xe4, 0x83, + 0xe7, 0x4e, 0x2b, 0xe0, 0x25, 0xca, 0x28, 0x54, 0x72, 0xa8, 0x02, 0x23, 0x8d, 0xc6, 0xca, 0x9a, + 0xbf, 0xe7, 0x32, 0x0b, 0xe4, 0xa8, 0x2d, 0x7f, 0xa3, 0x5d, 0x98, 0x51, 0x2e, 0xd2, 0xa8, 0xa8, + 0x8d, 0xa9, 0x3e, 0xc1, 0x0c, 0x8a, 0xdf, 0x96, 0x37, 0x81, 0x77, 0xd5, 0xfb, 0xb6, 0x97, 0x0f, + 0xee, 0xd6, 0xe2, 0x9f, 0x0d, 0x81, 0x64, 0x4f, 0x3b, 0x86, 0x52, 0xeb, 0x73, 0x18, 0x95, 0xc7, + 0x0e, 0x0d, 0xc3, 0x40, 0xad, 0xdb, 0x2d, 0x9d, 0x23, 0x7f, 0x34, 0x1a, 0x2b, 0xa5, 0x02, 0x9a, + 0x04, 0x88, 0x79, 0x4d, 0xa9, 0x88, 0xc6, 0x63, 0xab, 0x4b, 0x69, 0x80, 0xc2, 0xf7, 0x7a, 0xa5, + 0x41, 0x84, 0x92, 0xe6, 0x9e, 0xd2, 0x90, 0xb5, 0x0d, 0xa3, 0x72, 0x22, 0xd1, 0x14, 0x8c, 0x6d, + 0xaf, 0x37, 0x36, 0x97, 0x17, 0x57, 0x1f, 0xad, 0x2e, 0x2f, 0x95, 0xce, 0xa1, 0x2b, 0x70, 0x69, + 0xab, 0xb1, 0xd2, 0x5a, 0xaa, 0xb7, 0xd6, 0x36, 0x16, 0x6b, 0x6b, 0xad, 0x4d, 0x7b, 0xe3, 0xf3, + 0xef, 0xb7, 0xb6, 0xb6, 0xd7, 0xd7, 0x97, 0xd7, 0x4a, 0x05, 0x54, 0x86, 0x69, 0x52, 0xfd, 0x74, + 0xbb, 0xbe, 0xac, 0x02, 0x94, 0x8a, 0xd6, 0x7f, 0x2e, 0xa4, 0x38, 0x1d, 0x5a, 0x80, 0x31, 0xae, + 0xde, 0xd2, 0xd5, 0x67, 0x02, 0x72, 0xe9, 0xf8, 0xa8, 0x3a, 0x2e, 0x54, 0x63, 0xba, 0xb0, 0x2a, + 0x10, 0xf9, 0x78, 0x6d, 0x92, 0x25, 0x6c, 0xfb, 0x5d, 0xf5, 0xe3, 0xd5, 0xe3, 0x65, 0xb6, 0xac, + 0x45, 0x0b, 0xca, 0x67, 0x8e, 0x49, 0xcb, 0x54, 0x22, 0x13, 0x9f, 0x39, 0x95, 0xe5, 0xc9, 0x0f, + 0xde, 0x82, 0x62, 0x9d, 0x1a, 0x8c, 0x71, 0x0c, 0x2c, 0x56, 0xc2, 0x59, 0x87, 0x19, 0x4c, 0x04, + 0x7d, 0x94, 0x32, 0xa6, 0xb1, 0x11, 0x52, 0x2e, 0x99, 0xe0, 0x15, 0x29, 0x3b, 0x59, 0x15, 0x86, + 0xd8, 0xee, 0x62, 0x83, 0xa4, 0x52, 0x44, 0x97, 0x14, 0xd8, 0xac, 0xdc, 0xfa, 0xfb, 0x03, 0x2a, + 0x43, 0x25, 0x52, 0x83, 0x32, 0x89, 0x54, 0x6a, 0xa0, 0x93, 0x47, 0x4b, 0x89, 0x80, 0xc0, 0x35, + 0xfc, 0xd5, 0x25, 0x4e, 0x91, 0x0a, 0x08, 0xc2, 0x5e, 0xec, 0x76, 0xec, 0x18, 0x80, 0x48, 0xc3, + 0x4c, 0x5a, 0xa0, 0xd2, 0xf0, 0x40, 0x2c, 0x0d, 0x73, 0x79, 0x82, 0x49, 0xc3, 0x31, 0x08, 0x59, + 0x48, 0xf5, 0xb6, 0x6d, 0x30, 0x5e, 0x48, 0xf5, 0x5e, 0x4d, 0xbf, 0x4b, 0xfb, 0x10, 0xa0, 0xb6, + 0xd3, 0xa0, 0xb2, 0xa0, 0xbd, 0xce, 0x3f, 0xea, 0xf4, 0xf8, 0x39, 0xaf, 0x42, 0x2e, 0x4d, 0x06, + 0xaa, 0xd8, 0xac, 0x40, 0xa3, 0x3a, 0x4c, 0xd4, 0x7e, 0xed, 0x30, 0xc0, 0xab, 0x1d, 0x72, 0x82, + 0x23, 0xa6, 0x1f, 0x8c, 0xf2, 0x9b, 0x1a, 0x52, 0xd1, 0x72, 0x79, 0x8d, 0x42, 0x40, 0x47, 0x41, + 0x1b, 0x70, 0xe1, 0xf1, 0xa2, 0x30, 0xaf, 0xd4, 0xda, 0x6d, 0xff, 0xd0, 0x8b, 0xf8, 0x97, 0xfc, + 0xfa, 0xf1, 0x51, 0xf5, 0xca, 0x5e, 0x3b, 0xb6, 0xd0, 0x38, 0xac, 0x5a, 0xfd, 0x94, 0xa7, 0x70, + 0xad, 0x2e, 0x4c, 0x3e, 0xc6, 0x11, 0xd9, 0x4a, 0x42, 0x2c, 0xcb, 0x5f, 0x93, 0x8f, 0x61, 0x6c, + 0xc7, 0x8d, 0xf6, 0x1b, 0xb8, 0x1d, 0xe0, 0x48, 0x68, 0x9f, 0x4c, 0x45, 0x77, 0xa3, 0xfd, 0x56, + 0xc8, 0xca, 0x55, 0x06, 0xa4, 0x80, 0x5b, 0xcb, 0x30, 0xc5, 0x5b, 0x93, 0x52, 0xe0, 0x82, 0x4e, + 0xb0, 0x40, 0x09, 0xd2, 0x55, 0x50, 0x09, 0xea, 0x64, 0x7e, 0x56, 0x84, 0x99, 0xc5, 0x7d, 0xc7, + 0xdb, 0xc3, 0x9b, 0x4e, 0x18, 0xbe, 0xf2, 0x83, 0x8e, 0xd2, 0x79, 0x2a, 0x02, 0xa7, 0x3a, 0x4f, + 0x65, 0xde, 0x05, 0x18, 0xdb, 0xe8, 0x76, 0x04, 0x0e, 0x17, 0xcf, 0x69, 0x5b, 0x7e, 0xb7, 0xd3, + 0xea, 0x09, 0x5a, 0x2a, 0x10, 0xc1, 0x59, 0xc7, 0xaf, 0x24, 0xce, 0x40, 0x8c, 0xe3, 0xe1, 0x57, + 0x0a, 0x8e, 0x02, 0x84, 0x96, 0xe1, 0x42, 0x03, 0xb7, 0x7d, 0xaf, 0xf3, 0xc8, 0x69, 0x47, 0x7e, + 0xc0, 0xae, 0x7c, 0x06, 0x63, 0x09, 0x26, 0xa4, 0x95, 0xad, 0xe7, 0xb4, 0x96, 0xdd, 0xf4, 0xd8, + 0x69, 0x0c, 0xb4, 0x41, 0x2f, 0x8c, 0xa8, 0xc7, 0x00, 0x97, 0xe9, 0x6f, 0xde, 0x95, 0x2e, 0x04, + 0x8b, 0x01, 0xa6, 0x9b, 0xc2, 0xe9, 0x4a, 0xad, 0x44, 0x7e, 0x10, 0x28, 0x73, 0x11, 0x90, 0xb6, + 0x24, 0x62, 0x6d, 0xc3, 0xc4, 0x66, 0xf7, 0x70, 0xcf, 0xf5, 0x08, 0x1b, 0x68, 0xe0, 0x9f, 0xa2, + 0x25, 0x80, 0xb8, 0x80, 0x5b, 0x26, 0x84, 0x4d, 0x2e, 0xae, 0x68, 0x3e, 0xe4, 0x07, 0x89, 0x96, + 0x50, 0xd1, 0xcd, 0x56, 0xf0, 0xac, 0xbf, 0x33, 0x00, 0x88, 0x2f, 0x00, 0xe5, 0xf5, 0x0d, 0x1c, + 0x11, 0x36, 0x3c, 0x0b, 0x45, 0x69, 0x40, 0x38, 0x7f, 0x7c, 0x54, 0x2d, 0xba, 0x1d, 0xbb, 0xb8, + 0xba, 0x84, 0xde, 0x81, 0x21, 0x0a, 0x46, 0xe7, 0x7f, 0x52, 0xb6, 0xa7, 0x52, 0x60, 0x9c, 0x83, + 0x7e, 0x83, 0x6c, 0x06, 0x8c, 0xde, 0x85, 0xd1, 0x25, 0xdc, 0xc5, 0x7b, 0x4e, 0xe4, 0x8b, 0xd3, + 0xcd, 0x54, 0x72, 0x51, 0xa8, 0xec, 0xb9, 0x18, 0x92, 0xc8, 0xed, 0x36, 0x76, 0x42, 0xdf, 0x53, + 0xe5, 0xf6, 0x80, 0x96, 0xa8, 0x72, 0x3b, 0x83, 0x41, 0x7f, 0x54, 0x80, 0xb1, 0x9a, 0xe7, 0x71, + 0x55, 0x37, 0xe4, 0xb3, 0x3e, 0x73, 0x57, 0x7a, 0x62, 0xac, 0x39, 0xbb, 0xb8, 0xdb, 0x74, 0xba, + 0x87, 0x38, 0xac, 0x7f, 0x41, 0x44, 0xa9, 0xff, 0x72, 0x54, 0xfd, 0xe8, 0x14, 0xca, 0x6b, 0xec, + 0xd3, 0xb1, 0x15, 0x38, 0x6e, 0x14, 0xd2, 0xdb, 0xd4, 0xb8, 0x41, 0xf5, 0xdc, 0x28, 0xfd, 0x40, + 0x6f, 0xab, 0xca, 0x1a, 0xe7, 0xc5, 0x09, 0x2d, 0x9a, 0xeb, 0x69, 0xd6, 0x0d, 0xf9, 0x25, 0x5c, + 0x5d, 0xca, 0x5a, 0x02, 0x6b, 0x11, 0xe6, 0x1f, 0xe3, 0xc8, 0xc6, 0x21, 0x8e, 0xc4, 0xa6, 0xa5, + 0x5b, 0x2e, 0xb6, 0xff, 0x0c, 0xd3, 0xdf, 0x12, 0x99, 0xae, 0x07, 0xdb, 0xa8, 0xa2, 0xc6, 0xfa, + 0xdb, 0x05, 0xa8, 0x2e, 0x06, 0x98, 0x49, 0x22, 0x19, 0x84, 0xf2, 0x99, 0xc9, 0x3c, 0x77, 0x4e, + 0x29, 0xc6, 0xb5, 0x64, 0x96, 0xb8, 0x03, 0xca, 0xc9, 0x94, 0x63, 0xeb, 0x39, 0xcc, 0xd8, 0xd8, + 0xc3, 0xaf, 0x88, 0xaa, 0xae, 0xe9, 0x97, 0x55, 0x18, 0x62, 0x27, 0x2f, 0x35, 0x04, 0x56, 0x7e, + 0x3a, 0x5d, 0xdd, 0xfa, 0x67, 0x45, 0x28, 0xb1, 0xe1, 0xd6, 0xfd, 0xe8, 0x64, 0xe3, 0xe3, 0x23, + 0x28, 0xf6, 0x51, 0xef, 0x6f, 0xc5, 0xb3, 0x3d, 0x10, 0x0b, 0x07, 0xb4, 0xab, 0xe4, 0x1b, 0x27, + 0x2a, 0xc9, 0x80, 0xd8, 0x2e, 0x60, 0xe6, 0xad, 0x94, 0x8e, 0x8e, 0x7e, 0xaf, 0x00, 0xe7, 0xd9, + 0xbe, 0xca, 0xdf, 0xb9, 0x3b, 0x67, 0xb3, 0x73, 0x4b, 0x11, 0xfd, 0x4b, 0x3d, 0x47, 0xac, 0xce, + 0xfa, 0x17, 0x45, 0xb8, 0xa0, 0xcc, 0x15, 0x17, 0x3f, 0xdf, 0x66, 0xb2, 0x8d, 0x32, 0x61, 0xd4, + 0x60, 0x48, 0x2d, 0xf2, 0xb1, 0x0e, 0x4f, 0x67, 0xee, 0x6d, 0x18, 0x21, 0x43, 0x4a, 0xda, 0x16, + 0xe9, 0x17, 0x96, 0x81, 0x8a, 0xea, 0x13, 0xcf, 0xde, 0x3d, 0x18, 0xa1, 0x7f, 0x92, 0x15, 0x19, + 0xcc, 0x5e, 0x11, 0x09, 0x84, 0x5c, 0x80, 0x27, 0xbe, 0xeb, 0x3d, 0xc3, 0xd1, 0xbe, 0xdf, 0xe1, + 0xdf, 0xfa, 0x55, 0xc2, 0x07, 0xff, 0x3f, 0xdf, 0xf5, 0x5a, 0x07, 0xb4, 0xf8, 0xb4, 0xb6, 0xab, + 0x98, 0xa0, 0xad, 0x10, 0xb7, 0xee, 0x43, 0x89, 0xb0, 0xac, 0x93, 0x6f, 0x2d, 0x6b, 0x1a, 0xd0, + 0x63, 0x1c, 0xd5, 0x7d, 0xed, 0x63, 0x6a, 0x4d, 0xc0, 0xd8, 0xa6, 0xeb, 0xed, 0x89, 0x9f, 0xff, + 0x72, 0x00, 0xc6, 0xd9, 0x6f, 0xbe, 0x02, 0x09, 0x91, 0xa7, 0x70, 0x12, 0x91, 0xe7, 0x7d, 0x98, + 0xe0, 0x57, 0x74, 0x38, 0xa0, 0x57, 0x37, 0x6c, 0x3d, 0xa8, 0x32, 0xc3, 0xae, 0xe8, 0x5a, 0x2f, + 0x59, 0x8d, 0xad, 0x03, 0xa2, 0x35, 0x98, 0x64, 0x05, 0x8f, 0xb0, 0x13, 0x1d, 0xc6, 0xf6, 0x98, + 0x29, 0xae, 0xcf, 0x88, 0x62, 0xc6, 0xcf, 0x38, 0xad, 0xe7, 0xbc, 0xd0, 0x4e, 0xe0, 0xa2, 0x4f, + 0x61, 0x6a, 0x33, 0xf0, 0xbf, 0x7c, 0xad, 0x08, 0x79, 0x8c, 0xa5, 0xcf, 0x1c, 0x1f, 0x55, 0x2f, + 0xf4, 0x48, 0x55, 0x4b, 0x15, 0xf5, 0x92, 0xd0, 0x64, 0x4f, 0xad, 0x86, 0x75, 0x3f, 0x70, 0xbd, + 0x3d, 0xba, 0x9a, 0x23, 0x6c, 0x4f, 0xb9, 0x61, 0x6b, 0x97, 0x16, 0xda, 0xb2, 0x3a, 0x61, 0x59, + 0x1d, 0xee, 0x6f, 0x59, 0xbd, 0x0f, 0xb0, 0xe6, 0x3b, 0x9d, 0x5a, 0xb7, 0xbb, 0x58, 0x0b, 0xa9, + 0x31, 0x84, 0x0b, 0x31, 0x5d, 0xdf, 0xe9, 0xb4, 0x9c, 0x6e, 0xb7, 0xd5, 0x76, 0x42, 0x5b, 0x81, + 0x79, 0x32, 0x38, 0x72, 0xbe, 0x34, 0x6c, 0x4f, 0xad, 0xb9, 0x6d, 0xec, 0x85, 0x78, 0xc7, 0x09, + 0x3c, 0xd7, 0xdb, 0x0b, 0xad, 0x3f, 0x1b, 0x82, 0x11, 0x39, 0xe4, 0xbb, 0xaa, 0x42, 0xc4, 0x45, + 0x23, 0xca, 0xa1, 0x62, 0x83, 0x8d, 0xad, 0x40, 0xa0, 0x4b, 0xec, 0x3e, 0x98, 0x09, 0x65, 0xc3, + 0x64, 0x77, 0x3b, 0xbd, 0x1e, 0xbb, 0xf5, 0x9d, 0x85, 0xe2, 0x52, 0x9d, 0xce, 0xff, 0x08, 0xfb, + 0x12, 0x74, 0x76, 0xed, 0xe2, 0x52, 0x9d, 0xec, 0xb2, 0x8d, 0xd5, 0xa5, 0x45, 0x3a, 0x95, 0x23, + 0x6c, 0x97, 0xf9, 0x6e, 0xa7, 0x6d, 0xd3, 0x52, 0x52, 0xdb, 0xa8, 0x3d, 0x5b, 0xe3, 0xd3, 0x45, + 0x6b, 0x43, 0xe7, 0xa0, 0x6b, 0xd3, 0x52, 0xa2, 0x2a, 0x30, 0xdd, 0x7b, 0xd1, 0xf7, 0xa2, 0xc0, + 0xef, 0x86, 0x54, 0xa2, 0x1d, 0x61, 0xcb, 0xc9, 0x95, 0xf6, 0x36, 0xaf, 0xb2, 0x13, 0xa0, 0x68, + 0x07, 0xe6, 0x6a, 0x9d, 0x97, 0x8e, 0xd7, 0xc6, 0x1d, 0x56, 0xb3, 0xe3, 0x07, 0x2f, 0x9e, 0x77, + 0xfd, 0x57, 0x21, 0x9d, 0xef, 0x11, 0x6e, 0xe3, 0xe2, 0x20, 0xc2, 0x06, 0xf0, 0x4a, 0x00, 0xd9, + 0x59, 0xd8, 0x84, 0x4b, 0x2e, 0x76, 0xfd, 0xc3, 0x0e, 0x5f, 0x05, 0xca, 0x25, 0xdb, 0xa4, 0xc0, + 0x66, 0xe5, 0x64, 0x96, 0x56, 0x1a, 0xcf, 0xa8, 0x45, 0x89, 0xcf, 0xd2, 0x7e, 0x78, 0x60, 0x93, + 0x32, 0x74, 0x13, 0x86, 0x85, 0xd6, 0xc3, 0x6c, 0xdb, 0xd4, 0xd0, 0x2a, 0xb4, 0x1d, 0x51, 0x47, + 0x8e, 0x84, 0x8d, 0xdb, 0xfe, 0x4b, 0x1c, 0xbc, 0x5e, 0xf4, 0x3b, 0x58, 0xd8, 0x3f, 0xb8, 0x7e, + 0xcf, 0x2a, 0x5a, 0x6d, 0x52, 0x63, 0xeb, 0x80, 0xa4, 0x01, 0x26, 0x38, 0x85, 0xd4, 0xc9, 0x8a, + 0x37, 0xc0, 0x04, 0xab, 0xd0, 0x16, 0x75, 0x68, 0x09, 0x2e, 0xd4, 0x0e, 0x23, 0xff, 0xc0, 0x89, + 0xdc, 0xf6, 0x76, 0x6f, 0x2f, 0x70, 0x48, 0x23, 0x25, 0x8a, 0x40, 0x55, 0x3b, 0x47, 0x54, 0xb6, + 0x0e, 0x79, 0xad, 0x9d, 0x46, 0x40, 0xef, 0xc1, 0xf8, 0x6a, 0xc8, 0x6c, 0x5c, 0x4e, 0x88, 0x3b, + 0xd4, 0x50, 0xc1, 0x7b, 0xe9, 0x86, 0x2d, 0x6a, 0xf1, 0x6a, 0x11, 0x65, 0xb0, 0x63, 0x6b, 0x70, + 0xc8, 0x82, 0xf3, 0xb5, 0x30, 0x74, 0xc3, 0x88, 0xda, 0x1f, 0x46, 0xea, 0x70, 0x7c, 0x54, 0x3d, + 0xef, 0xd0, 0x12, 0x9b, 0xd7, 0x3c, 0x19, 0x1c, 0x19, 0x2b, 0x8d, 0x3f, 0x19, 0x1c, 0x19, 0x2f, + 0x4d, 0x3c, 0x19, 0x1c, 0x99, 0x28, 0x4d, 0x5a, 0x0f, 0xe0, 0x02, 0xe3, 0x61, 0x27, 0x56, 0x26, + 0xac, 0x4d, 0x80, 0x06, 0x3e, 0x70, 0x7a, 0xfb, 0x3e, 0xd9, 0xed, 0x75, 0xf5, 0x17, 0x17, 0x46, + 0x91, 0x74, 0x20, 0xe2, 0x15, 0xcd, 0x87, 0x42, 0x07, 0x14, 0x90, 0xb6, 0x82, 0x65, 0xfd, 0x45, + 0x11, 0x10, 0x75, 0xa4, 0x69, 0x44, 0x01, 0x76, 0x0e, 0x44, 0x37, 0x3e, 0x80, 0x71, 0xf6, 0x39, + 0x62, 0xc5, 0xb4, 0x3b, 0x44, 0xd2, 0x65, 0x7c, 0x48, 0xad, 0x5a, 0x39, 0x67, 0x6b, 0xa0, 0x04, + 0xd5, 0xc6, 0xe1, 0xe1, 0x81, 0x40, 0x2d, 0x6a, 0xa8, 0x6a, 0x15, 0x41, 0x55, 0x7f, 0xa3, 0x4f, + 0x61, 0x72, 0xd1, 0x3f, 0xe8, 0x91, 0x39, 0xe1, 0xc8, 0x03, 0xfc, 0xab, 0xcc, 0xdb, 0xd5, 0x2a, + 0x57, 0xce, 0xd9, 0x09, 0x70, 0xb4, 0x0e, 0x17, 0x1f, 0x75, 0x0f, 0xc3, 0xfd, 0x9a, 0xd7, 0x59, + 0xec, 0xfa, 0xa1, 0xa0, 0x32, 0xc8, 0xad, 0xda, 0x9c, 0x8b, 0xa6, 0x21, 0x56, 0xce, 0xd9, 0x26, + 0x44, 0x74, 0x93, 0x7b, 0x05, 0xcb, 0x1b, 0x02, 0xee, 0x34, 0xbc, 0xe1, 0xe1, 0x8d, 0xe7, 0x2b, + 0xe7, 0x6c, 0x56, 0x5b, 0x1f, 0x85, 0x61, 0xf1, 0x05, 0xb9, 0x47, 0x36, 0xa2, 0x9c, 0x4e, 0x7e, + 0xcd, 0x5a, 0x81, 0x91, 0xed, 0x1e, 0x61, 0x6c, 0x42, 0x3c, 0xb4, 0xe5, 0x6f, 0xeb, 0x5b, 0xfa, + 0x4c, 0xa3, 0x79, 0x55, 0x87, 0x67, 0xc0, 0x71, 0x81, 0xb5, 0xa2, 0x4f, 0x6e, 0x3e, 0xb4, 0xd6, + 0x6e, 0x31, 0xd1, 0x6e, 0x29, 0x39, 0xd7, 0xd6, 0x8c, 0x71, 0xf2, 0xac, 0xcf, 0xe1, 0xea, 0x76, + 0x8f, 0x28, 0x4c, 0xb5, 0x5e, 0xaf, 0xcb, 0x2f, 0x6e, 0xd9, 0x97, 0x46, 0x6c, 0x96, 0xf7, 0xa4, + 0xcb, 0x69, 0x21, 0xd3, 0x41, 0x87, 0x1e, 0x09, 0xf6, 0xc5, 0x12, 0x9e, 0xa6, 0xd6, 0xef, 0x17, + 0xe0, 0x2a, 0x3b, 0x01, 0x99, 0xa4, 0xbf, 0xa9, 0x3a, 0xc6, 0x2a, 0x22, 0x90, 0x74, 0x83, 0x55, + 0x5d, 0x5f, 0xe3, 0x4b, 0xd8, 0x62, 0xf6, 0x25, 0xac, 0x38, 0x60, 0x03, 0xc6, 0x03, 0xf6, 0x19, + 0x58, 0xbc, 0x47, 0xdd, 0x6e, 0xaa, 0x53, 0xe1, 0x9b, 0xf4, 0xca, 0xfa, 0x6f, 0x45, 0x98, 0x7b, + 0x8c, 0x3d, 0x1c, 0x38, 0x74, 0x9c, 0x9a, 0xb4, 0xaf, 0xde, 0xd1, 0x14, 0x72, 0xef, 0x68, 0xa4, + 0x28, 0x5b, 0xcc, 0x10, 0x65, 0x2f, 0xc1, 0xc0, 0xb6, 0xbd, 0xca, 0x87, 0x45, 0x99, 0xf4, 0x61, + 0xe0, 0xda, 0xa4, 0x0c, 0xad, 0xc6, 0xf7, 0x3b, 0x83, 0x7d, 0xef, 0x77, 0x2e, 0x72, 0x7b, 0xf7, + 0x30, 0xbf, 0xdf, 0xd1, 0x6f, 0x75, 0xd6, 0x15, 0x79, 0x99, 0xb0, 0x9b, 0x3b, 0xfc, 0x4c, 0x65, + 0x0c, 0x90, 0x8b, 0xbe, 0xcb, 0x5e, 0x14, 0xbc, 0x66, 0x5b, 0x80, 0x49, 0xc0, 0x42, 0xee, 0xad, + 0x7c, 0x06, 0x63, 0x0a, 0x08, 0x2a, 0xc1, 0xc0, 0x0b, 0x7e, 0xb7, 0x35, 0x6a, 0x93, 0x3f, 0xd1, + 0xb7, 0x60, 0xe8, 0x25, 0x91, 0xc1, 0x39, 0x1b, 0x99, 0x8d, 0xe5, 0xf3, 0x46, 0x44, 0x24, 0x0f, + 0x26, 0xa0, 0xdb, 0x0c, 0xe8, 0xc3, 0xe2, 0xfb, 0x05, 0xeb, 0x23, 0x28, 0xa7, 0x7b, 0xc3, 0xc5, + 0xb9, 0x7e, 0x1a, 0x8e, 0xb5, 0x04, 0xd3, 0x8f, 0x71, 0x14, 0x7b, 0xe5, 0x2a, 0x57, 0x6f, 0x89, + 0x73, 0x96, 0x63, 0x59, 0xb3, 0x1a, 0x30, 0x93, 0xa0, 0xc2, 0xdb, 0xff, 0x10, 0x86, 0x85, 0x3f, + 0x4f, 0x21, 0xdb, 0x9f, 0x87, 0xee, 0x5b, 0x4e, 0xd9, 0x16, 0x08, 0xd6, 0x0e, 0xcc, 0x6a, 0x44, + 0x43, 0x49, 0xf5, 0xbb, 0x30, 0x22, 0xca, 0x12, 0x26, 0x09, 0x8d, 0x2c, 0xdd, 0x5a, 0xa1, 0x40, + 0x96, 0x28, 0xd6, 0x3e, 0xcc, 0xae, 0xb9, 0xa1, 0x4e, 0x99, 0x8d, 0xfa, 0x32, 0x8c, 0xf6, 0xc8, + 0x37, 0x2f, 0x74, 0x7f, 0x8d, 0xed, 0xcf, 0x21, 0x7b, 0x84, 0x14, 0x34, 0xdc, 0x5f, 0xc3, 0xe8, + 0x0a, 0x00, 0xad, 0xa4, 0xf3, 0xc7, 0xd9, 0x0b, 0x05, 0x67, 0xba, 0x22, 0x02, 0x7a, 0x79, 0xca, + 0x36, 0xa4, 0x4d, 0xff, 0xb6, 0x02, 0x98, 0x4b, 0xb5, 0xc4, 0xc7, 0x70, 0x0f, 0x64, 0xd7, 0x72, + 0xc6, 0x60, 0x4b, 0x20, 0x74, 0x0b, 0xa6, 0x3c, 0xfc, 0x65, 0xd4, 0x4a, 0xf5, 0x61, 0x82, 0x14, + 0x6f, 0x8a, 0x7e, 0x58, 0x3f, 0xa2, 0x9a, 0x7b, 0xd2, 0xe1, 0xee, 0xcc, 0x26, 0xaf, 0x0b, 0x15, + 0x32, 0x24, 0xdd, 0xbf, 0xea, 0x57, 0x36, 0x81, 0x2f, 0xe1, 0xb2, 0xb1, 0xb5, 0x5f, 0xf5, 0x24, + 0xfe, 0x4d, 0x11, 0xe6, 0xd8, 0x57, 0x2a, 0x7d, 0x34, 0x4e, 0xce, 0xc3, 0xbe, 0x16, 0x83, 0xf3, + 0x7d, 0x83, 0xc1, 0x99, 0xa2, 0xa8, 0x06, 0x67, 0xcd, 0xcc, 0xfc, 0xbe, 0xd9, 0xcc, 0x4c, 0xc5, + 0x3e, 0xdd, 0xcc, 0x9c, 0x34, 0x2e, 0x2f, 0x67, 0x1b, 0x97, 0xa9, 0xa9, 0xcd, 0x60, 0x5c, 0x36, + 0x98, 0x94, 0x9f, 0x0c, 0x8e, 0x14, 0x4b, 0x03, 0x56, 0x13, 0xca, 0xe9, 0x29, 0x3e, 0x03, 0xbe, + 0xf1, 0x67, 0x05, 0xb8, 0xc2, 0x25, 0x8c, 0xc4, 0x21, 0x38, 0xfd, 0x0a, 0xbe, 0x0b, 0xe3, 0x1c, + 0x77, 0x2b, 0xde, 0x2c, 0xcc, 0x75, 0x56, 0x70, 0x42, 0xc6, 0x4e, 0x35, 0x30, 0xf4, 0xae, 0x62, + 0x49, 0x60, 0xd6, 0xa9, 0x4b, 0xe4, 0x73, 0xc9, 0x4c, 0x0e, 0x99, 0xf6, 0x04, 0xeb, 0x0b, 0xb8, + 0x9a, 0xd5, 0xf1, 0x33, 0x98, 0x97, 0x3f, 0x2f, 0xc0, 0x65, 0x4e, 0x5e, 0x3b, 0x4e, 0x6f, 0xc4, + 0xf2, 0x4f, 0xe1, 0x6d, 0xf1, 0x04, 0xc6, 0x48, 0x83, 0xa2, 0xdf, 0xfa, 0x5b, 0x2e, 0xa5, 0x66, + 0xc9, 0x89, 0x1c, 0x7e, 0x4d, 0xe6, 0x1c, 0x74, 0x85, 0x5b, 0xa7, 0xad, 0x22, 0x5b, 0x3f, 0x80, + 0x79, 0xf3, 0x10, 0xce, 0x60, 0x7e, 0x9e, 0x40, 0xc5, 0xc0, 0x38, 0xdf, 0xec, 0x83, 0xf8, 0x7d, + 0xb8, 0x6c, 0xa4, 0x75, 0x06, 0xdd, 0x5c, 0x21, 0x9f, 0xfb, 0xe8, 0x0c, 0x96, 0xd0, 0xda, 0x81, + 0x4b, 0x06, 0x4a, 0x67, 0xd0, 0xc5, 0xc7, 0x30, 0x27, 0xc5, 0xdc, 0xaf, 0xd4, 0xc3, 0x67, 0x70, + 0x85, 0x11, 0x3a, 0x9b, 0x55, 0x79, 0x0a, 0x97, 0x39, 0xb9, 0x33, 0x98, 0xbd, 0x15, 0x98, 0x8f, + 0xb5, 0x59, 0x83, 0x2c, 0x71, 0x62, 0x26, 0x63, 0xad, 0xc1, 0xb5, 0x98, 0x52, 0xc6, 0x87, 0xf5, + 0xe4, 0xd4, 0x98, 0x2c, 0x16, 0xaf, 0xd2, 0x19, 0xca, 0x62, 0x31, 0xe0, 0x99, 0x89, 0x13, 0xab, + 0x70, 0x91, 0x11, 0xd6, 0xe5, 0xd6, 0x05, 0x55, 0x6e, 0x35, 0x3e, 0x83, 0x4a, 0x8b, 0xb2, 0xcf, + 0xa8, 0x28, 0x2b, 0x40, 0xe2, 0x1e, 0xbe, 0x0b, 0xe7, 0xf9, 0x4b, 0x4f, 0xd6, 0x3f, 0x03, 0x31, + 0x26, 0xa9, 0x33, 0x34, 0x0e, 0x6c, 0xfd, 0x18, 0xae, 0x30, 0x35, 0x30, 0xf9, 0xa2, 0x40, 0x2c, + 0xc9, 0x77, 0x13, 0x5a, 0x60, 0xce, 0xc3, 0x05, 0x93, 0x32, 0xb8, 0x2b, 0xf6, 0x76, 0x16, 0xfd, + 0x13, 0xb9, 0xd8, 0x0a, 0xed, 0xae, 0x68, 0xd4, 0xee, 0x6e, 0xc0, 0x75, 0xa9, 0xdd, 0x25, 0x9b, + 0x91, 0x26, 0xe1, 0x1f, 0xc0, 0x65, 0x36, 0x50, 0xfd, 0x7d, 0x9b, 0xe8, 0xc6, 0x47, 0x89, 0x61, + 0x66, 0x3e, 0xa0, 0x33, 0x0d, 0xf2, 0xef, 0x15, 0xc4, 0x91, 0x33, 0x13, 0xff, 0xba, 0xd5, 0xdd, + 0x75, 0xa8, 0xca, 0x09, 0xd1, 0x7b, 0xf4, 0x66, 0xba, 0xee, 0x33, 0x98, 0x49, 0xbd, 0xc1, 0x20, + 0x02, 0x2b, 0x7a, 0x87, 0x1c, 0x0b, 0x5a, 0x20, 0xb6, 0x5d, 0xe6, 0x9b, 0x0d, 0x5b, 0x42, 0x5a, + 0x2d, 0x98, 0x4f, 0x2f, 0x85, 0xdb, 0x16, 0xee, 0x50, 0xe8, 0x53, 0x72, 0x84, 0xd9, 0x43, 0x90, + 0x42, 0x9f, 0x87, 0x20, 0xfc, 0x1c, 0x33, 0x74, 0x81, 0x65, 0x59, 0x82, 0xd5, 0x24, 0xc6, 0x4f, + 0x5a, 0x17, 0xfb, 0xe1, 0x37, 0x00, 0x89, 0xaa, 0xc5, 0x86, 0x2d, 0x9a, 0xbe, 0x04, 0x03, 0x8b, + 0x0d, 0x9b, 0x7b, 0x61, 0x52, 0x75, 0xbb, 0x1d, 0x06, 0x36, 0x29, 0x4b, 0x4a, 0xad, 0xc5, 0x13, + 0x48, 0xad, 0x4f, 0x06, 0x47, 0x06, 0x4a, 0x83, 0x36, 0x6a, 0xb8, 0x7b, 0xde, 0x8e, 0x1b, 0xed, + 0xcb, 0x06, 0x6b, 0xd6, 0x0f, 0xe1, 0xa2, 0xd6, 0x3c, 0x3f, 0xc5, 0xb9, 0xee, 0xa3, 0xe8, 0x16, + 0x0c, 0x2f, 0xd6, 0xe8, 0xdd, 0x1e, 0xb5, 0x17, 0x8c, 0x33, 0x7e, 0xd3, 0x76, 0x5a, 0xf4, 0x29, + 0xbf, 0x2d, 0x2a, 0xad, 0x7f, 0x3a, 0xa8, 0x50, 0x57, 0x9c, 0x72, 0x73, 0x46, 0xf7, 0x00, 0x80, + 0xed, 0x10, 0x65, 0x70, 0x44, 0x00, 0x1c, 0xe3, 0xd7, 0x11, 0x8c, 0x25, 0xdb, 0x0a, 0xd0, 0x49, + 0x9d, 0x76, 0xb9, 0x9f, 0x10, 0x43, 0x12, 0x77, 0x76, 0xd2, 0x4f, 0x88, 0x93, 0x0e, 0x6d, 0x15, + 0x08, 0xfd, 0x38, 0xe9, 0x5b, 0x36, 0x44, 0xaf, 0xc8, 0xbf, 0xc1, 0xcd, 0x12, 0x86, 0xb1, 0x9d, + 0xce, 0xbd, 0xec, 0x15, 0xcc, 0x10, 0x5c, 0xf7, 0x39, 0x75, 0x20, 0x5b, 0xfe, 0x32, 0xc2, 0x1e, + 0xe3, 0xed, 0xe7, 0x69, 0x3b, 0x37, 0x73, 0xda, 0x89, 0x81, 0xf9, 0xdb, 0xf3, 0x98, 0x4e, 0x0b, + 0xcb, 0x3a, 0xdb, 0x4c, 0x9f, 0x6e, 0x22, 0x7b, 0x6d, 0xd9, 0xeb, 0xf4, 0x7c, 0x57, 0x2a, 0x15, + 0x6c, 0x13, 0x05, 0xdd, 0x16, 0xe6, 0xe5, 0xb6, 0x0a, 0x64, 0xdd, 0xca, 0xf5, 0xe9, 0x1a, 0x81, + 0xc1, 0xad, 0xc5, 0xad, 0xb5, 0x52, 0xc1, 0xba, 0x07, 0xa0, 0xb4, 0x04, 0x70, 0x7e, 0x7d, 0xc3, + 0x7e, 0x56, 0x5b, 0x2b, 0x9d, 0x43, 0x33, 0x70, 0x61, 0x67, 0x75, 0x7d, 0x69, 0x63, 0xa7, 0xd1, + 0x6a, 0x3c, 0xab, 0xd9, 0x5b, 0x8b, 0x35, 0x7b, 0xa9, 0x54, 0xb0, 0xbe, 0x80, 0x69, 0x7d, 0x84, + 0x67, 0xba, 0x09, 0x23, 0xb8, 0x28, 0xe5, 0x99, 0x27, 0x3b, 0x5b, 0x8a, 0x9f, 0x0b, 0x57, 0x90, + 0x92, 0x57, 0x6f, 0x5c, 0x95, 0xe2, 0xc7, 0x48, 0x01, 0xd2, 0x2e, 0x4c, 0x8b, 0xb9, 0x17, 0xa6, + 0xd6, 0x77, 0x60, 0x5a, 0x6f, 0xf5, 0xa4, 0x26, 0xa2, 0x6f, 0x50, 0x07, 0x20, 0xc5, 0x2b, 0x93, + 0x68, 0xea, 0x71, 0x17, 0x39, 0x67, 0xfd, 0x0e, 0x94, 0x38, 0x54, 0xfc, 0xe5, 0xbd, 0x21, 0x6c, + 0x78, 0x05, 0x83, 0x07, 0xb9, 0x70, 0x47, 0x78, 0x4b, 0xdc, 0x0a, 0xf4, 0x6b, 0xe1, 0x2f, 0x0a, + 0x50, 0x4e, 0x38, 0x38, 0x2e, 0xee, 0x3b, 0xdd, 0x2e, 0xf6, 0xf6, 0x30, 0xba, 0x0d, 0x83, 0x5b, + 0x1b, 0x5b, 0x9b, 0xdc, 0x6a, 0x36, 0xcd, 0xb7, 0x29, 0x29, 0x92, 0x30, 0x36, 0x85, 0x40, 0x4f, + 0xe1, 0x82, 0x70, 0x77, 0x91, 0x55, 0x5c, 0x29, 0xb9, 0x92, 0xef, 0x3c, 0x93, 0xc6, 0x43, 0xef, + 0x70, 0x6f, 0xcc, 0x9f, 0x1e, 0xba, 0x01, 0xee, 0x50, 0x85, 0x7d, 0x72, 0x01, 0xc5, 0xde, 0x98, + 0xa2, 0xc6, 0x56, 0xc1, 0x98, 0xa7, 0xbc, 0xf5, 0x47, 0x05, 0x98, 0xcb, 0x70, 0xd8, 0x44, 0x6f, + 0x6b, 0xc3, 0xb9, 0xa8, 0x0c, 0x47, 0x80, 0xac, 0x9c, 0xe3, 0xe3, 0x59, 0x54, 0x7c, 0x80, 0x06, + 0x4e, 0xe1, 0x03, 0xc4, 0xdf, 0x8b, 0x53, 0x38, 0xfe, 0x2e, 0x89, 0x96, 0x5b, 0x53, 0x30, 0xa1, + 0xcd, 0x9b, 0x65, 0xc1, 0xb8, 0xda, 0x32, 0x59, 0x9c, 0x45, 0xbf, 0x23, 0x17, 0x87, 0xfc, 0x6d, + 0xfd, 0x41, 0x01, 0xa6, 0xe9, 0x10, 0xf7, 0x5c, 0x72, 0x1a, 0xe3, 0x19, 0x5a, 0xd0, 0x46, 0x32, + 0xaf, 0x8d, 0x24, 0x01, 0x2b, 0x87, 0xf4, 0x61, 0x6a, 0x48, 0xf3, 0xa6, 0x21, 0x51, 0x4d, 0xd0, + 0xf5, 0x3d, 0x6d, 0x24, 0xca, 0xd5, 0xc4, 0x3f, 0x2a, 0xc0, 0x45, 0xa5, 0x4f, 0xb2, 0xff, 0x0f, + 0xb4, 0x2e, 0x5d, 0x36, 0x74, 0x29, 0x35, 0xc9, 0xf5, 0x54, 0x8f, 0xbe, 0x91, 0xd7, 0xa3, 0xbe, + 0x73, 0xfc, 0x57, 0x05, 0x98, 0x31, 0xce, 0x01, 0x9a, 0x25, 0xe2, 0x56, 0x3b, 0xc0, 0x11, 0x9f, + 0x5e, 0xfe, 0x8b, 0x94, 0xaf, 0x86, 0xe1, 0x21, 0x0f, 0xb2, 0x32, 0x6a, 0xf3, 0x5f, 0xe8, 0x1b, + 0x30, 0xb1, 0x89, 0x03, 0xd7, 0xef, 0x30, 0xef, 0x30, 0x76, 0x83, 0x3e, 0x61, 0xeb, 0x85, 0x68, + 0x1e, 0x46, 0x6b, 0xdd, 0x3d, 0x3f, 0x70, 0xa3, 0x7d, 0x76, 0x3b, 0x34, 0x6a, 0xc7, 0x05, 0x84, + 0xf6, 0x92, 0xbb, 0x27, 0x9c, 0x42, 0x26, 0x6c, 0xfe, 0x0b, 0x95, 0x61, 0x58, 0x18, 0x79, 0xa8, + 0x89, 0xc8, 0x16, 0x3f, 0x09, 0xc6, 0x67, 0x36, 0xdd, 0x04, 0xf4, 0x29, 0x92, 0xcd, 0x7f, 0x59, + 0x77, 0x60, 0xda, 0x34, 0x8f, 0xc6, 0x2d, 0xf3, 0xb7, 0x8a, 0x70, 0xb1, 0xd6, 0xe9, 0x3c, 0x7b, + 0x54, 0x5b, 0xc2, 0xaa, 0x90, 0xf3, 0x0e, 0x0c, 0xae, 0x7a, 0x6e, 0xc4, 0x25, 0x1c, 0xe1, 0xda, + 0x6c, 0x80, 0x24, 0x50, 0x64, 0x85, 0xc8, 0xff, 0xc8, 0x86, 0x8b, 0xcb, 0x5f, 0xba, 0x61, 0xe4, + 0x7a, 0x7b, 0xaa, 0x7f, 0x74, 0xf1, 0x24, 0xfe, 0xd1, 0x2b, 0xe7, 0x6c, 0x13, 0x32, 0xda, 0x82, + 0xd9, 0x75, 0xfc, 0xca, 0xb0, 0x85, 0xe4, 0xb3, 0x11, 0xe5, 0xa0, 0xa7, 0x76, 0x4e, 0x06, 0xae, + 0xba, 0x43, 0x7f, 0xaf, 0x48, 0x9f, 0xa7, 0x29, 0x03, 0xe3, 0x2d, 0x6f, 0xc3, 0xb4, 0xd2, 0xa1, + 0x98, 0x4f, 0x15, 0xf8, 0x83, 0x5c, 0xe3, 0x70, 0xd4, 0x83, 0x64, 0x44, 0x47, 0x3b, 0x30, 0xa7, + 0x77, 0x2a, 0xa6, 0xac, 0x1f, 0x06, 0x13, 0xc8, 0xca, 0x39, 0x3b, 0x0b, 0x1b, 0x2d, 0xc0, 0x40, + 0xad, 0xfd, 0x82, 0x4f, 0x8b, 0x79, 0xc9, 0xd8, 0xc8, 0x6a, 0xed, 0x17, 0xf4, 0x99, 0x79, 0xfb, + 0x85, 0x76, 0x1e, 0xfe, 0x6d, 0x01, 0xe6, 0x32, 0x56, 0x18, 0x5d, 0x05, 0x60, 0x85, 0xca, 0x17, + 0x41, 0x29, 0x21, 0x02, 0x1a, 0xfb, 0x45, 0x3d, 0xc5, 0x06, 0x28, 0x0b, 0x16, 0x2f, 0x30, 0xe2, + 0x0a, 0x5b, 0x01, 0x42, 0x9b, 0x30, 0xc6, 0x7e, 0xb1, 0x87, 0x20, 0x3a, 0xdb, 0x56, 0x6a, 0x98, + 0x20, 0xd3, 0xa1, 0x05, 0xad, 0xe4, 0x03, 0x10, 0x95, 0x04, 0x37, 0x69, 0x2e, 0x26, 0x47, 0x21, + 0x07, 0x8d, 0x6e, 0xc3, 0x79, 0x56, 0xc8, 0xd7, 0x50, 0x3c, 0xef, 0x8c, 0x81, 0x79, 0xbd, 0xf5, + 0x8f, 0x0b, 0x30, 0xcb, 0xbe, 0x88, 0xa9, 0xa3, 0xf1, 0x1d, 0xed, 0x68, 0x5c, 0x97, 0x1d, 0x36, + 0x01, 0x6b, 0xa7, 0xa3, 0xae, 0xbf, 0x1a, 0x38, 0xe9, 0xa9, 0x50, 0x91, 0xd4, 0x7d, 0xfb, 0x4f, + 0x0a, 0xc2, 0xc2, 0x93, 0xde, 0xba, 0xcb, 0x30, 0xfe, 0x66, 0x5b, 0x56, 0x43, 0x43, 0xef, 0xb2, + 0x1d, 0x55, 0xcc, 0x1f, 0x69, 0xee, 0xa6, 0xfa, 0x18, 0x2a, 0xd9, 0x53, 0xd3, 0x6f, 0x5b, 0x59, + 0x8f, 0x0c, 0xd8, 0x6f, 0xb2, 0x9c, 0x87, 0x29, 0x3a, 0x8d, 0xd7, 0x5e, 0x5b, 0xac, 0xe8, 0xad, + 0xa4, 0x1f, 0x65, 0xa6, 0x6f, 0x9a, 0xda, 0xdb, 0x62, 0x7c, 0x95, 0xc0, 0x37, 0x27, 0x15, 0xf6, + 0xd4, 0xee, 0xff, 0xab, 0xa2, 0xbe, 0x17, 0xdf, 0xa4, 0xd1, 0x45, 0x98, 0x58, 0xc7, 0xaf, 0x52, + 0xed, 0x52, 0xbf, 0x1b, 0x0f, 0xbf, 0x6a, 0x29, 0x6d, 0xab, 0x0e, 0xe9, 0x1a, 0x0e, 0xda, 0x85, + 0x49, 0xc1, 0x35, 0x4e, 0xca, 0x3c, 0xd9, 0x2b, 0x38, 0xd2, 0x42, 0xc6, 0x9b, 0x95, 0x04, 0xc5, + 0xb3, 0x3f, 0xcf, 0xd6, 0x26, 0x94, 0xd3, 0xb3, 0xc7, 0x5b, 0x7b, 0xa7, 0xdf, 0xda, 0x33, 0x53, + 0x48, 0x47, 0xdf, 0x07, 0x2b, 0xd4, 0x3c, 0x25, 0x61, 0xa4, 0xbd, 0xe1, 0x7e, 0x72, 0x31, 0xa8, + 0xff, 0x8e, 0x58, 0x0c, 0xa5, 0x7f, 0xd2, 0xad, 0x76, 0x91, 0x5a, 0xf8, 0x54, 0x4a, 0xbc, 0x63, + 0x77, 0x60, 0x98, 0x17, 0x25, 0xde, 0x90, 0xc7, 0xbb, 0x52, 0x00, 0x58, 0x7f, 0x5c, 0x80, 0x4b, + 0xd4, 0xde, 0xe8, 0x7a, 0x7b, 0x5d, 0xbc, 0x1d, 0xea, 0x9e, 0xb1, 0xdf, 0xd6, 0x18, 0xcd, 0x5c, + 0xc6, 0xcb, 0xa5, 0x5f, 0x15, 0x7b, 0xf9, 0xd3, 0x02, 0x54, 0x4c, 0x7d, 0x3b, 0x5b, 0x0e, 0x73, + 0x97, 0x2b, 0x73, 0x45, 0x6e, 0x49, 0x61, 0xe8, 0xb2, 0x4d, 0x31, 0x58, 0x32, 0x48, 0xf2, 0xbf, + 0xc6, 0x5a, 0xfe, 0x77, 0x01, 0xa6, 0x57, 0x43, 0x55, 0xc0, 0xe7, 0x13, 0x77, 0xd7, 0xf4, 0x90, + 0x92, 0xae, 0xab, 0x39, 0x5e, 0xc8, 0x3b, 0xca, 0xcb, 0x9c, 0x62, 0xde, 0x0b, 0x49, 0x2d, 0x48, + 0xcc, 0x2d, 0x18, 0x5c, 0x27, 0xe2, 0xd4, 0x00, 0xdf, 0x7f, 0x0c, 0x83, 0x14, 0xd1, 0x47, 0x34, + 0xa4, 0xcb, 0xe4, 0x07, 0x7a, 0x94, 0x7a, 0xaa, 0x33, 0xd8, 0xff, 0x05, 0x60, 0x3a, 0xba, 0x4d, + 0x7d, 0x04, 0xce, 0x6f, 0x39, 0xc1, 0x1e, 0x8e, 0xac, 0x1f, 0x40, 0x85, 0x7b, 0xfa, 0x30, 0x0b, + 0x2e, 0xf5, 0x07, 0x0a, 0x63, 0x67, 0xae, 0x3c, 0xef, 0x9c, 0xab, 0x00, 0x8d, 0xc8, 0x09, 0xa2, + 0x55, 0xaf, 0x83, 0xbf, 0xa4, 0xa3, 0x1d, 0xb2, 0x95, 0x12, 0xeb, 0x5d, 0x18, 0x95, 0x43, 0xa0, + 0x1a, 0xa0, 0x22, 0x31, 0xd2, 0xe1, 0x4c, 0x6b, 0x8f, 0x87, 0xc4, 0x8b, 0xa1, 0x87, 0x30, 0x93, + 0x58, 0x8a, 0xf8, 0x31, 0x9b, 0xd4, 0xcc, 0xa8, 0x6b, 0xa4, 0x2d, 0x7f, 0x5b, 0x8b, 0x70, 0x21, + 0xb5, 0xd2, 0x08, 0xd1, 0x77, 0x66, 0x4c, 0xbb, 0x27, 0x1f, 0x94, 0x46, 0x63, 0x85, 0x94, 0x6d, + 0xad, 0x35, 0x98, 0xf3, 0x37, 0x29, 0xdb, 0x5a, 0x6b, 0xd4, 0xcf, 0xb3, 0x9d, 0x63, 0xfd, 0xf3, + 0x22, 0x55, 0x7a, 0x53, 0x73, 0x90, 0xb0, 0x1f, 0xaa, 0x36, 0xcc, 0x3a, 0x8c, 0xd2, 0x11, 0x2f, + 0x89, 0xe7, 0x0d, 0xf9, 0xce, 0x29, 0x23, 0x3f, 0x3f, 0xaa, 0x9e, 0xa3, 0x1e, 0x29, 0x31, 0x1a, + 0xfa, 0x04, 0x86, 0x97, 0xbd, 0x0e, 0xa5, 0x30, 0x70, 0x0a, 0x0a, 0x02, 0x89, 0xac, 0x03, 0xed, + 0x32, 0x11, 0x85, 0xb8, 0xd9, 0xc9, 0x56, 0x4a, 0xe8, 0x34, 0xbb, 0x07, 0x2e, 0x73, 0x02, 0x1b, + 0xb2, 0xd9, 0x0f, 0xfa, 0x34, 0x90, 0x74, 0x41, 0xc4, 0x2d, 0x18, 0xb5, 0xe5, 0x6f, 0x64, 0xc1, + 0xd0, 0x46, 0xd0, 0xe1, 0x4f, 0x86, 0x27, 0x17, 0xc6, 0x45, 0x10, 0x49, 0x52, 0x66, 0xb3, 0x2a, + 0xeb, 0x7f, 0x16, 0x60, 0xee, 0x31, 0x8e, 0x8c, 0xfb, 0x46, 0x9b, 0x95, 0xc2, 0x57, 0x9e, 0x95, + 0xe2, 0x9b, 0xcc, 0x8a, 0x1c, 0xf5, 0x40, 0xd6, 0xa8, 0x07, 0xb3, 0x46, 0x3d, 0x94, 0x3d, 0xea, + 0xc7, 0x70, 0x9e, 0x0d, 0x15, 0xdd, 0x80, 0xa1, 0xd5, 0x08, 0x1f, 0xc4, 0xc6, 0x10, 0xd5, 0xb5, + 0xce, 0x66, 0x75, 0x44, 0xe3, 0x5a, 0x73, 0xc2, 0x48, 0x3c, 0x37, 0x18, 0xb5, 0xc5, 0x4f, 0xeb, + 0x27, 0xf4, 0x61, 0xd4, 0x9a, 0xdf, 0x7e, 0xa1, 0x58, 0xaa, 0x87, 0xd9, 0xa9, 0x4c, 0xde, 0x6c, + 0x10, 0x28, 0x56, 0x63, 0x0b, 0x08, 0x74, 0x0d, 0xc6, 0x56, 0xbd, 0x47, 0x7e, 0xd0, 0xc6, 0x1b, + 0x5e, 0x97, 0x51, 0x1f, 0xb1, 0xd5, 0x22, 0x6e, 0xc1, 0xe1, 0x2d, 0xc4, 0x16, 0x1c, 0x5a, 0x90, + 0xb0, 0xe0, 0xb0, 0x38, 0x63, 0x36, 0xab, 0xe3, 0x06, 0x22, 0xf2, 0x77, 0x9e, 0xf9, 0x46, 0xda, + 0x79, 0xfa, 0x01, 0xee, 0xc2, 0x25, 0x1b, 0xf7, 0xba, 0x0e, 0x11, 0xb8, 0x0e, 0x7c, 0x06, 0x2f, + 0xc7, 0x7c, 0xcd, 0xe0, 0x9f, 0xae, 0xfb, 0x43, 0xc8, 0x2e, 0x17, 0x73, 0xba, 0x7c, 0x00, 0xd7, + 0x1f, 0xe3, 0xc8, 0x18, 0x2c, 0x2c, 0x1e, 0xfc, 0x0a, 0x8c, 0x84, 0xba, 0x0d, 0xbf, 0x5f, 0x9c, + 0x32, 0x7e, 0xcb, 0xc5, 0xe9, 0xc8, 0xbf, 0xac, 0x4f, 0xa1, 0x9a, 0xd5, 0xdc, 0xc9, 0xfc, 0x60, + 0x5d, 0xb8, 0x96, 0x4d, 0x40, 0x7e, 0x16, 0x85, 0xbd, 0x5f, 0xaa, 0xce, 0xf9, 0xbd, 0xd5, 0xaf, + 0x08, 0xf8, 0x1f, 0x56, 0x5d, 0x78, 0x04, 0x7e, 0x85, 0xee, 0xb6, 0xe8, 0x55, 0xba, 0x4e, 0x20, + 0x9e, 0xd7, 0x1a, 0x8c, 0x88, 0x32, 0x3e, 0xaf, 0x99, 0x71, 0xd8, 0xe8, 0x84, 0x76, 0x04, 0x01, + 0x89, 0x66, 0xfd, 0x44, 0x5c, 0x2b, 0xe9, 0x18, 0x27, 0x7b, 0x74, 0x73, 0x92, 0x7b, 0x24, 0xcb, + 0x87, 0x4b, 0x3a, 0x6d, 0xf5, 0xba, 0xa0, 0xa4, 0x5c, 0x17, 0xb0, 0x5b, 0x82, 0x6b, 0xba, 0xf9, + 0xba, 0xc8, 0xf7, 0x65, 0x5c, 0x84, 0xae, 0xaa, 0x97, 0x02, 0xe3, 0xe9, 0x57, 0x4a, 0xf7, 0xa1, + 0x62, 0x6a, 0x50, 0x31, 0xa0, 0x48, 0xcb, 0x33, 0x8f, 0x99, 0xf1, 0x5b, 0x05, 0xb0, 0x34, 0xef, + 0x28, 0x2d, 0xa4, 0x96, 0x3c, 0x32, 0x6f, 0x0b, 0xc6, 0x46, 0xfd, 0xb1, 0x98, 0xef, 0x7d, 0x97, + 0x14, 0xa8, 0x4f, 0xc3, 0x18, 0xb7, 0xbb, 0x0f, 0xc3, 0xeb, 0xf8, 0xcb, 0x98, 0xfd, 0x30, 0x59, + 0x94, 0x7a, 0x4c, 0xbd, 0xc0, 0xea, 0xa3, 0x53, 0x01, 0x46, 0x04, 0xa1, 0x1b, 0xb9, 0x7d, 0xe0, + 0xfd, 0xdf, 0x85, 0x52, 0xb2, 0x8e, 0xaf, 0x7d, 0xdf, 0xe8, 0x62, 0xf4, 0xf5, 0x46, 0x32, 0xa8, + 0x58, 0x68, 0xa7, 0xe8, 0x9d, 0xbe, 0xf7, 0xe8, 0x03, 0x80, 0x2d, 0x3f, 0x72, 0xba, 0x8b, 0xd4, + 0xc6, 0x45, 0x19, 0x3f, 0x0b, 0x51, 0x15, 0x91, 0xd2, 0x56, 0xf2, 0x75, 0xac, 0x02, 0x6c, 0x7d, + 0x8f, 0x9e, 0x48, 0x73, 0xa7, 0x4f, 0x76, 0x48, 0x16, 0xe1, 0x46, 0xc2, 0x1b, 0xe1, 0x0d, 0x88, + 0x44, 0x30, 0x43, 0xa6, 0x5f, 0xc6, 0x26, 0xfb, 0x7a, 0x56, 0xfd, 0x3f, 0x14, 0x98, 0x0b, 0xa5, + 0xda, 0x2c, 0x5f, 0xe8, 0x45, 0x80, 0xb8, 0x34, 0xe1, 0xa3, 0xaf, 0x86, 0x5a, 0xa3, 0xca, 0x6b, + 0x1c, 0x6a, 0x2d, 0xb4, 0x15, 0xb4, 0xaf, 0x77, 0x25, 0x1f, 0x52, 0x17, 0x04, 0xd9, 0xfa, 0xc9, + 0xe6, 0xfd, 0x3d, 0x61, 0xa3, 0x39, 0x25, 0xde, 0x3e, 0x4c, 0x6b, 0xd1, 0xa8, 0xe3, 0xf0, 0xba, + 0x71, 0x14, 0xee, 0xd1, 0xfa, 0xc7, 0xbf, 0x3c, 0xaa, 0xbe, 0x7f, 0x9a, 0x57, 0x63, 0x82, 0xe6, + 0x96, 0x7c, 0x1c, 0x69, 0xcd, 0xc1, 0xc0, 0xa2, 0xbd, 0x46, 0x59, 0x95, 0xbd, 0x26, 0x59, 0x95, + 0xbd, 0x66, 0xfd, 0x8f, 0x22, 0x54, 0xd9, 0xdb, 0x68, 0xea, 0xb9, 0xa2, 0x05, 0x28, 0x3b, 0xad, + 0x85, 0x20, 0xf1, 0xf6, 0xb9, 0x78, 0x92, 0xb7, 0xcf, 0xbf, 0xfe, 0xe6, 0x56, 0x55, 0x16, 0x69, + 0x30, 0x36, 0x0c, 0xb0, 0x5a, 0x93, 0x85, 0x20, 0xa3, 0x89, 0xb4, 0x49, 0x63, 0xf0, 0x0d, 0x4c, + 0x1a, 0xf7, 0x61, 0x98, 0xaa, 0x1e, 0xab, 0x9b, 0xdc, 0xdf, 0x92, 0x6e, 0x4f, 0x1a, 0xc6, 0xa0, + 0xe5, 0xaa, 0xf1, 0x51, 0x04, 0x98, 0xf5, 0x0f, 0x8b, 0x70, 0x2d, 0x7b, 0xce, 0x79, 0xdf, 0x96, + 0xb4, 0x80, 0xc2, 0x39, 0x3e, 0x3a, 0xf4, 0xec, 0x28, 0x01, 0x85, 0x93, 0x41, 0x84, 0xc5, 0x8b, + 0xa2, 0xc4, 0x6d, 0x98, 0xf6, 0xd0, 0x48, 0x84, 0x63, 0x67, 0x45, 0x5a, 0x1c, 0x2f, 0x5e, 0x86, + 0x76, 0x61, 0x6e, 0x33, 0x70, 0x5f, 0x3a, 0x11, 0x7e, 0x8a, 0x5f, 0x6f, 0xfa, 0x5d, 0xb7, 0xfd, + 0x7a, 0xd9, 0x73, 0x76, 0xbb, 0xb8, 0xc3, 0x9f, 0x89, 0xdd, 0x3e, 0x3e, 0xaa, 0x7e, 0xa3, 0xc7, + 0x40, 0xc8, 0xc1, 0x6c, 0xf5, 0x28, 0x50, 0x0b, 0x33, 0x28, 0x85, 0x68, 0x16, 0x21, 0xeb, 0xdf, + 0x17, 0xe0, 0x32, 0x15, 0xa8, 0xf9, 0xcd, 0x82, 0x68, 0xfc, 0x8d, 0x5c, 0x35, 0xd5, 0x01, 0xf2, + 0xbd, 0x48, 0x5d, 0x35, 0xb5, 0x17, 0x57, 0xb6, 0x06, 0x86, 0x56, 0x61, 0x8c, 0xff, 0x56, 0xcc, + 0xc7, 0x33, 0x0a, 0xc3, 0xa2, 0x5b, 0x9d, 0x59, 0x8f, 0xe8, 0xc6, 0xe6, 0xc4, 0x5a, 0xf4, 0x1d, + 0xb2, 0x8a, 0x6b, 0xfd, 0xa2, 0x08, 0xf3, 0x4d, 0x1c, 0xb8, 0xcf, 0x5f, 0x67, 0x0c, 0x66, 0x03, + 0xa6, 0x45, 0x11, 0x1d, 0xb3, 0x7e, 0xc4, 0x58, 0x80, 0x1f, 0xd1, 0xd5, 0x90, 0x00, 0xb4, 0xe4, + 0x89, 0x33, 0x22, 0x9e, 0xc2, 0x09, 0xf3, 0x1d, 0x18, 0x49, 0x44, 0x28, 0xa0, 0xeb, 0x2f, 0x4e, + 0xa8, 0x1e, 0x9e, 0x52, 0x1e, 0xd5, 0xdf, 0xc9, 0xbe, 0xa2, 0xe4, 0x96, 0x84, 0x7e, 0x91, 0x67, + 0xe8, 0x81, 0x25, 0x87, 0x55, 0x09, 0x96, 0x88, 0x0d, 0x07, 0x76, 0xe5, 0x9c, 0x9d, 0xd5, 0x52, + 0x7d, 0x0c, 0x46, 0x6b, 0xf4, 0xda, 0x95, 0x28, 0xee, 0xff, 0xab, 0x08, 0x57, 0xc5, 0x3b, 0x9e, + 0x8c, 0x69, 0xfe, 0x1c, 0xe6, 0x44, 0x51, 0xad, 0x47, 0x04, 0x06, 0xdc, 0xd1, 0x67, 0x9a, 0x05, + 0xd9, 0x12, 0x33, 0xed, 0x70, 0x98, 0x78, 0xb2, 0xb3, 0xd0, 0xcf, 0xc6, 0x20, 0xfa, 0x89, 0x29, + 0x5e, 0x04, 0x35, 0x4c, 0xaa, 0x3c, 0x53, 0x8f, 0x61, 0xa9, 0xf2, 0xcf, 0x4e, 0xca, 0xa0, 0x3a, + 0xf8, 0x55, 0x0d, 0xaa, 0x2b, 0xe7, 0x92, 0x26, 0xd5, 0xfa, 0x24, 0x8c, 0xaf, 0xe3, 0x57, 0xf1, + 0xbc, 0xff, 0x6e, 0x21, 0xf1, 0xa4, 0x91, 0x48, 0x18, 0xec, 0x6d, 0x63, 0x21, 0x0e, 0x39, 0x40, + 0x9f, 0x34, 0xaa, 0x12, 0x06, 0x03, 0x5d, 0x85, 0x61, 0xe6, 0xb6, 0xdb, 0x39, 0x81, 0x6e, 0x2e, + 0x1f, 0xe4, 0xb4, 0x19, 0x0a, 0x53, 0xd3, 0x39, 0xbe, 0xf5, 0x14, 0xae, 0x73, 0xaf, 0x71, 0x7d, + 0xf1, 0x69, 0x43, 0xa7, 0xfc, 0x7c, 0x59, 0x0e, 0x5c, 0x7d, 0x8c, 0x93, 0xac, 0x47, 0x7b, 0xb0, + 0xf4, 0x29, 0x4c, 0x69, 0xe5, 0x92, 0x22, 0x95, 0x4a, 0xe5, 0x1e, 0x92, 0xa4, 0x93, 0xd0, 0xd6, + 0x35, 0x53, 0x13, 0x6a, 0x67, 0x2d, 0x4c, 0xa3, 0x65, 0x05, 0xf1, 0x2d, 0x72, 0x78, 0x0a, 0xae, + 0x77, 0x5b, 0x39, 0xd7, 0x8c, 0xe3, 0xb1, 0xb8, 0x41, 0xe2, 0xcb, 0x2b, 0x6b, 0xad, 0x09, 0x18, + 0x5b, 0xf4, 0xbd, 0x08, 0x7f, 0x49, 0x45, 0x1d, 0x6b, 0x12, 0xc6, 0x45, 0x55, 0x17, 0x87, 0xa1, + 0xf5, 0x27, 0x03, 0x60, 0xf1, 0x89, 0x35, 0x59, 0x4f, 0xc5, 0x7c, 0xec, 0xa6, 0x3a, 0xcb, 0x3f, + 0x54, 0xb3, 0xaa, 0x8d, 0x38, 0xae, 0x65, 0x3b, 0x8f, 0xca, 0x79, 0xed, 0xb8, 0x54, 0x0f, 0x48, + 0x9c, 0x1c, 0xfd, 0x0f, 0x33, 0xd8, 0x24, 0x3b, 0x6c, 0x34, 0x06, 0x6b, 0x06, 0x9b, 0xd4, 0xe8, + 0x9a, 0x59, 0xa6, 0xad, 0x4d, 0x03, 0x17, 0x39, 0x90, 0x7c, 0x6f, 0x29, 0x6b, 0xb8, 0x0f, 0x13, + 0x2b, 0x68, 0xa5, 0xf2, 0x5f, 0xa8, 0x44, 0xd0, 0xb6, 0x3e, 0x97, 0xfc, 0x3c, 0x0a, 0xaf, 0x0d, + 0xb5, 0x8a, 0x51, 0xed, 0x29, 0x25, 0x7a, 0x3a, 0x11, 0x0d, 0x56, 0xb1, 0x88, 0xff, 0xa1, 0xf4, + 0xdd, 0x27, 0x1f, 0x52, 0xb7, 0x8b, 0xf9, 0x43, 0x15, 0xb1, 0x2c, 0x87, 0xe6, 0xdb, 0xef, 0xc2, + 0x89, 0x78, 0x34, 0x8d, 0x82, 0x8a, 0x39, 0x7a, 0xd6, 0x95, 0x8b, 0x89, 0xbe, 0x75, 0x54, 0x10, + 0x2f, 0x16, 0x52, 0x57, 0xc2, 0xa7, 0x95, 0x24, 0xeb, 0xda, 0x2d, 0x6e, 0x31, 0xe3, 0x16, 0x57, + 0xbb, 0xf3, 0x8a, 0xfa, 0x5c, 0xeb, 0x0e, 0x7c, 0xf5, 0x6b, 0xa0, 0x7f, 0x7d, 0x1e, 0x2e, 0x6c, + 0x3a, 0x7b, 0xae, 0x47, 0x78, 0x8f, 0x88, 0xdc, 0x8b, 0x6a, 0xa9, 0xdc, 0x12, 0xf9, 0xae, 0xb1, + 0x86, 0xe4, 0x11, 0x0b, 0x6a, 0x98, 0xf7, 0x62, 0xd6, 0x2b, 0x52, 0x3d, 0x98, 0xfb, 0x07, 0x9a, + 0xd5, 0x3f, 0x95, 0xe7, 0x84, 0x7a, 0xf7, 0x79, 0x7e, 0x27, 0x91, 0x6f, 0x85, 0x5a, 0xce, 0xd3, + 0x01, 0xf0, 0x87, 0xce, 0x38, 0x00, 0xfe, 0x0f, 0x60, 0xec, 0xe9, 0xe1, 0xae, 0xcc, 0xe5, 0x71, + 0xbe, 0x6f, 0x80, 0x75, 0xba, 0x06, 0x2f, 0x0e, 0x77, 0xcd, 0xd9, 0x3c, 0x54, 0x62, 0xc6, 0x60, + 0xf1, 0xc3, 0xbf, 0x92, 0x60, 0xf1, 0x99, 0x79, 0x0a, 0x46, 0xbe, 0x96, 0x3c, 0x05, 0x86, 0x80, + 0xef, 0xa3, 0x67, 0x1f, 0xf0, 0x5d, 0x0b, 0x86, 0x0e, 0x5f, 0x31, 0x18, 0x7a, 0x1d, 0x60, 0x24, + 0x88, 0x43, 0x5a, 0x0f, 0x96, 0x86, 0xd8, 0xda, 0x09, 0x8f, 0xe3, 0x7f, 0x33, 0x0c, 0xd3, 0x6b, + 0x6e, 0x18, 0x89, 0xc3, 0x13, 0xc6, 0x5f, 0xd6, 0x71, 0x51, 0xa6, 0x68, 0xbe, 0x5c, 0x08, 0x66, + 0xe5, 0xad, 0x44, 0xda, 0x29, 0x0d, 0x01, 0xbd, 0xab, 0x5e, 0xb4, 0x14, 0x95, 0xe8, 0x9f, 0xe9, + 0x8c, 0x41, 0xea, 0x0d, 0xcc, 0xdb, 0x9a, 0x9d, 0x3f, 0xd7, 0x30, 0xf2, 0x30, 0x69, 0xfc, 0xe7, + 0xc1, 0xb9, 0xe8, 0x37, 0x47, 0x37, 0x44, 0xc4, 0xb7, 0x02, 0xdb, 0x70, 0x9e, 0x46, 0xd2, 0x11, + 0x2f, 0x86, 0xdf, 0xe2, 0xfc, 0xc7, 0x34, 0x09, 0x2c, 0xe6, 0x0e, 0x7f, 0x2e, 0x4c, 0x03, 0x4f, + 0x75, 0x69, 0x81, 0x1a, 0x30, 0x87, 0x81, 0xa0, 0x2d, 0xb8, 0xb8, 0x19, 0xe0, 0x0e, 0x77, 0x9b, + 0xed, 0x05, 0x5c, 0x4b, 0x64, 0x4f, 0xf7, 0x68, 0x24, 0xcc, 0x9e, 0xa8, 0x6e, 0x61, 0x59, 0xaf, + 0x32, 0x70, 0x03, 0x3a, 0x5a, 0x86, 0xc9, 0x06, 0x76, 0x82, 0xf6, 0xfe, 0x53, 0xfc, 0x9a, 0x7c, + 0x77, 0xc2, 0xf2, 0x70, 0x1c, 0x3e, 0x36, 0xa4, 0x35, 0x64, 0xa0, 0xb4, 0x4a, 0xbd, 0x7f, 0xd7, + 0x91, 0xd0, 0xf7, 0xe0, 0x7c, 0xc3, 0x0f, 0xa2, 0xfa, 0xeb, 0x44, 0x0a, 0x29, 0x56, 0x58, 0xbf, + 0x24, 0x42, 0xe8, 0x86, 0x7e, 0x10, 0xb5, 0x76, 0xd5, 0x79, 0xe3, 0x78, 0xe8, 0x11, 0x11, 0x6a, + 0x89, 0xa0, 0x2d, 0x6d, 0x38, 0x2c, 0xfa, 0x06, 0x17, 0x5c, 0xa9, 0x74, 0x6e, 0x32, 0xe4, 0x24, + 0xb0, 0xd0, 0x6b, 0x98, 0xd6, 0x8f, 0xd6, 0x23, 0xb7, 0x4b, 0xf8, 0x11, 0x68, 0xc9, 0x58, 0x4c, + 0x20, 0xf5, 0xdb, 0xbc, 0x97, 0xd7, 0x92, 0x07, 0xf8, 0x39, 0xad, 0x57, 0x23, 0x82, 0x9b, 0xf0, + 0xd1, 0x33, 0x1a, 0xc1, 0x98, 0xcd, 0x4c, 0x2d, 0x14, 0xa1, 0xad, 0xc9, 0x20, 0x68, 0xe0, 0xbd, + 0x43, 0x7a, 0x3c, 0xe9, 0x8c, 0x3a, 0x61, 0x32, 0xc2, 0xb5, 0x9d, 0x42, 0x45, 0x9b, 0x70, 0x61, + 0x3b, 0xc4, 0x9b, 0x01, 0x7e, 0xe9, 0xe2, 0x57, 0x82, 0xde, 0x38, 0xa5, 0x47, 0x97, 0x9b, 0xd0, + 0xeb, 0xb1, 0x5a, 0x13, 0xc1, 0x34, 0x72, 0xe5, 0x03, 0x18, 0x53, 0xf6, 0x9b, 0xe1, 0xed, 0xf9, + 0xb4, 0xfa, 0xf6, 0x7c, 0x54, 0x7d, 0x63, 0xfe, 0x57, 0x05, 0x66, 0x67, 0x54, 0x36, 0x30, 0x37, + 0x5a, 0x6c, 0xc0, 0xa8, 0x2c, 0x94, 0x2f, 0x1d, 0x84, 0xe0, 0x93, 0xf8, 0x70, 0xb2, 0xe3, 0x23, + 0x4e, 0xb7, 0xda, 0xdb, 0x98, 0xc6, 0xd7, 0x6b, 0xfb, 0xfb, 0x9d, 0xf8, 0x4d, 0x24, 0x7f, 0xbf, + 0x19, 0x38, 0xed, 0x17, 0xb1, 0xf1, 0xf5, 0xc7, 0xe4, 0x7c, 0xa8, 0x15, 0x3c, 0xf3, 0xd5, 0x9c, + 0x9e, 0xb6, 0x88, 0x57, 0x8a, 0xe4, 0x09, 0xf2, 0x69, 0x28, 0x2b, 0xd6, 0x0f, 0x8e, 0x8a, 0x40, + 0x3d, 0x81, 0xa7, 0x2c, 0x9b, 0x3d, 0xe9, 0x33, 0xf6, 0xe0, 0xbd, 0xf4, 0xa3, 0x34, 0xca, 0x98, + 0xe3, 0x47, 0x69, 0xea, 0x34, 0xc6, 0xcf, 0xd3, 0xb6, 0xe1, 0xb2, 0x8d, 0x0f, 0xfc, 0x97, 0xf8, + 0x6c, 0xc9, 0xfe, 0x10, 0x2e, 0xe9, 0x04, 0xb7, 0x7b, 0x1d, 0x1a, 0xcb, 0x83, 0x5d, 0xc1, 0x1a, + 0xe3, 0xf6, 0x71, 0x04, 0x16, 0xb7, 0x8f, 0x45, 0x72, 0x22, 0x7f, 0xaa, 0xfc, 0x96, 0xd6, 0x59, + 0x3e, 0xcc, 0xeb, 0xc4, 0x6b, 0x9d, 0x0e, 0x4d, 0x46, 0xd0, 0x76, 0x7b, 0x8e, 0x17, 0xa1, 0x0d, + 0x18, 0x53, 0x7e, 0x26, 0xc4, 0x26, 0xa5, 0x86, 0xad, 0x7e, 0x2f, 0x2e, 0x50, 0xc5, 0x3b, 0x05, + 0xce, 0xc2, 0x50, 0x4d, 0x4e, 0x0f, 0x99, 0x32, 0xb5, 0xcd, 0x3a, 0x4c, 0x28, 0x3f, 0xa5, 0x16, + 0x42, 0x63, 0x72, 0x2a, 0x2d, 0xe8, 0x13, 0xa6, 0xa3, 0x58, 0x6d, 0xa8, 0x98, 0x26, 0x8d, 0xc6, + 0x98, 0x78, 0x8d, 0x96, 0xe3, 0x68, 0x15, 0xfd, 0xaf, 0xbe, 0xa7, 0xb2, 0x22, 0x55, 0x58, 0xff, + 0x60, 0x10, 0x2e, 0xf3, 0xc5, 0x38, 0xcb, 0x15, 0x47, 0x3f, 0x81, 0x31, 0x65, 0x8d, 0xf9, 0xa4, + 0x5f, 0x13, 0xde, 0x32, 0x59, 0x7b, 0x81, 0x89, 0x77, 0x87, 0xb4, 0xa0, 0x95, 0x58, 0x6e, 0x22, + 0xde, 0xa9, 0xdb, 0xa6, 0x0b, 0x93, 0xfa, 0x42, 0x73, 0x09, 0xf7, 0x86, 0xb1, 0x11, 0x1d, 0x54, + 0x04, 0x81, 0xea, 0xb4, 0x8c, 0xcb, 0x4d, 0x93, 0x75, 0xe9, 0x9b, 0xe8, 0x4b, 0xb8, 0x90, 0x5a, + 0x65, 0xae, 0xb1, 0xdd, 0x32, 0x36, 0x98, 0x82, 0x66, 0x21, 0xd1, 0x03, 0x5a, 0x9c, 0xd9, 0x6c, + 0xba, 0x11, 0xd4, 0x81, 0x71, 0x75, 0xe1, 0xb9, 0x08, 0x7e, 0x3d, 0x67, 0x2a, 0x19, 0x20, 0x13, + 0x8a, 0xf8, 0x5c, 0xd2, 0xb5, 0xd7, 0xf3, 0x5b, 0x6a, 0x54, 0xeb, 0x23, 0x70, 0x9e, 0xfd, 0x26, + 0x2c, 0x60, 0x33, 0xc0, 0x21, 0xf6, 0xda, 0x58, 0x75, 0x7c, 0xfa, 0xaa, 0x2c, 0xe0, 0xdf, 0x15, + 0xa0, 0x6c, 0xa2, 0xdb, 0xc0, 0x5e, 0x07, 0x6d, 0x42, 0x29, 0xd9, 0x10, 0xdf, 0xd5, 0x96, 0xf8, + 0x2a, 0x64, 0x77, 0x89, 0x88, 0xe4, 0xa9, 0x6e, 0xae, 0xc3, 0x05, 0xa5, 0xec, 0x94, 0x1e, 0x66, + 0x69, 0x54, 0x55, 0xab, 0x5e, 0xa1, 0x8e, 0x74, 0x4b, 0xfe, 0x81, 0xe3, 0x7a, 0x44, 0x40, 0x54, + 0xe2, 0x4a, 0x40, 0x5c, 0xca, 0xe7, 0x86, 0x69, 0x9e, 0xb4, 0x54, 0x78, 0x5b, 0x4a, 0x10, 0xeb, + 0x63, 0xca, 0xc1, 0xb9, 0xbe, 0xc2, 0xde, 0xf9, 0x48, 0x62, 0xd7, 0x60, 0x68, 0x6b, 0xad, 0xb1, + 0x58, 0xe3, 0xaf, 0x86, 0xd8, 0x5b, 0xd3, 0x6e, 0xd8, 0x6a, 0x3b, 0x36, 0xab, 0xb0, 0x3e, 0xa2, + 0xa1, 0xfa, 0x78, 0xa0, 0x37, 0x89, 0x77, 0x13, 0x86, 0x79, 0x11, 0xc7, 0xa4, 0xf7, 0xd4, 0x5d, + 0x0e, 0x25, 0xea, 0xac, 0x4d, 0x21, 0x5f, 0x77, 0xb1, 0x13, 0x2a, 0x1f, 0xe6, 0xf7, 0x89, 0x5c, + 0xce, 0xca, 0xf8, 0x77, 0x79, 0x52, 0xc6, 0x51, 0xa5, 0xc5, 0x4c, 0x13, 0x17, 0x30, 0xb6, 0xfc, + 0xcb, 0xfa, 0xf3, 0x22, 0x4c, 0x8b, 0x88, 0x32, 0x9a, 0x95, 0xa1, 0x6f, 0xbc, 0xcc, 0xef, 0xeb, + 0x41, 0x7b, 0x16, 0x65, 0xd0, 0x9e, 0xaf, 0x90, 0xc1, 0x83, 0x87, 0xfb, 0x39, 0xe1, 0x9b, 0xba, + 0xa7, 0x52, 0xfa, 0x1e, 0xd4, 0xa4, 0x6f, 0xd3, 0x78, 0x34, 0xe9, 0x9b, 0x2e, 0x0b, 0x93, 0xbe, + 0x85, 0xcc, 0xfd, 0x55, 0x04, 0xa6, 0xf7, 0xc9, 0xd6, 0xd2, 0x9a, 0x3c, 0xe9, 0x73, 0xab, 0x35, + 0xfa, 0x2a, 0x7f, 0x63, 0x75, 0x69, 0x91, 0xec, 0x69, 0xde, 0x55, 0xb1, 0x02, 0xf7, 0xa8, 0x0b, + 0x1d, 0xa7, 0xa9, 0x6e, 0x4c, 0xca, 0x62, 0x79, 0x2c, 0x0a, 0x05, 0xc4, 0x7a, 0x28, 0xdf, 0xf8, + 0x1b, 0xa8, 0x65, 0x05, 0x7f, 0x5d, 0xa7, 0xd1, 0x0b, 0x1e, 0xd3, 0xf5, 0x3a, 0x8b, 0x4e, 0xfc, + 0x71, 0x81, 0x85, 0x43, 0x68, 0x6c, 0x28, 0x71, 0xf2, 0xbd, 0xe7, 0xbe, 0x62, 0x64, 0x55, 0x9a, + 0x79, 0xea, 0x7a, 0x1d, 0xd5, 0xc8, 0x4a, 0x33, 0x31, 0xf2, 0x57, 0x8b, 0xad, 0x17, 0xae, 0xd7, + 0xb1, 0x93, 0xd0, 0xe8, 0x03, 0x98, 0x50, 0x8a, 0xe4, 0x47, 0x9a, 0x85, 0x19, 0x54, 0xd1, 0xdd, + 0x8e, 0xad, 0x43, 0x5a, 0xbf, 0x5b, 0x84, 0xcb, 0x39, 0x79, 0x5c, 0xa8, 0x0e, 0x48, 0x6d, 0x03, + 0x72, 0xa6, 0x78, 0x80, 0x66, 0xfa, 0x42, 0x53, 0xe3, 0x91, 0x12, 0x10, 0x7d, 0x0c, 0x63, 0x6a, + 0x5a, 0x99, 0xa2, 0x12, 0x05, 0xdc, 0x9c, 0x4a, 0x46, 0x05, 0x47, 0x21, 0x40, 0xdc, 0x13, 0xfe, + 0x90, 0xb9, 0x41, 0x24, 0x1a, 0x25, 0x27, 0xcd, 0x99, 0x24, 0xc7, 0x51, 0x9a, 0xb1, 0xfe, 0x6e, + 0x11, 0xae, 0xe6, 0xcc, 0x43, 0x03, 0x47, 0xff, 0x2f, 0xa6, 0x22, 0x91, 0x29, 0x68, 0xe0, 0x6b, + 0xca, 0x14, 0x64, 0xfd, 0x61, 0x11, 0x66, 0xb7, 0x7b, 0x21, 0xf5, 0x74, 0x5d, 0xf5, 0x5e, 0x62, + 0x2f, 0xf2, 0x83, 0xd7, 0xd4, 0x53, 0x0f, 0xbd, 0x0b, 0x43, 0x2b, 0xb8, 0xdb, 0xf5, 0xf9, 0x67, + 0xed, 0x8a, 0xb0, 0x7b, 0x27, 0xa1, 0x29, 0xd0, 0xca, 0x39, 0x9b, 0x41, 0xa3, 0x0f, 0x60, 0x74, + 0x05, 0x3b, 0x41, 0xb4, 0x8b, 0x1d, 0x21, 0xb9, 0x5e, 0xe2, 0xa8, 0x0a, 0x0a, 0x07, 0x58, 0x39, + 0x67, 0xc7, 0xd0, 0x68, 0x01, 0x06, 0x37, 0x7d, 0x6f, 0x4f, 0x3e, 0x85, 0xcb, 0x68, 0x90, 0xc0, + 0xac, 0x9c, 0xb3, 0x29, 0x2c, 0x7a, 0x06, 0x13, 0xb5, 0x3d, 0xec, 0x45, 0xcf, 0x70, 0xe4, 0x74, + 0x9c, 0xc8, 0xe1, 0x12, 0xce, 0xcd, 0x2c, 0x64, 0x0d, 0x98, 0x66, 0xff, 0x55, 0x0b, 0xea, 0x43, + 0x30, 0xf0, 0x2c, 0xdc, 0xb3, 0x8e, 0x0a, 0x50, 0x5e, 0xf2, 0x5f, 0x79, 0xc6, 0x89, 0xf9, 0x8e, + 0x3e, 0x31, 0xc2, 0x1f, 0xdb, 0x00, 0x9f, 0x98, 0x9a, 0x77, 0x60, 0x70, 0xd3, 0xf5, 0xf6, 0x12, + 0x1f, 0x75, 0x03, 0x1e, 0x81, 0xa2, 0x23, 0x74, 0xbd, 0x3d, 0xb4, 0x26, 0xa4, 0x29, 0xce, 0xef, + 0x07, 0x34, 0x11, 0xce, 0x80, 0xad, 0x42, 0xc7, 0x52, 0x13, 0xfb, 0x2d, 0x06, 0xf8, 0x36, 0xcc, + 0x65, 0xb4, 0x8b, 0x26, 0x25, 0xb3, 0x1c, 0xa4, 0x4c, 0xf2, 0x2d, 0x98, 0x31, 0x2e, 0x41, 0x0a, + 0xf0, 0xbf, 0x17, 0x0c, 0x7b, 0x89, 0x8d, 0xbc, 0x0c, 0xc3, 0x22, 0x66, 0x2e, 0xfb, 0xaa, 0x88, + 0x9f, 0xd4, 0xef, 0x54, 0x9c, 0x35, 0x1e, 0xc9, 0x50, 0x1e, 0xa9, 0xa6, 0x12, 0x5b, 0x80, 0x9d, + 0x88, 0x0f, 0xbf, 0xc2, 0xbe, 0x97, 0xb4, 0x48, 0x9b, 0x2b, 0x7e, 0x18, 0x79, 0xd2, 0x2d, 0xc2, + 0x96, 0xbf, 0xd1, 0x1d, 0x28, 0x2d, 0x7f, 0x19, 0xe1, 0xc0, 0x73, 0xba, 0x3c, 0x7a, 0x28, 0xcf, + 0x58, 0x64, 0xa7, 0xca, 0xad, 0xbf, 0x2c, 0xd2, 0x08, 0x8a, 0x39, 0x1b, 0x8c, 0xcc, 0xd1, 0x46, + 0x83, 0x8f, 0xb9, 0xb8, 0xd1, 0x40, 0xf3, 0x30, 0xba, 0xd1, 0xd0, 0xc2, 0x07, 0xdb, 0x71, 0x01, + 0x69, 0x9c, 0x74, 0xa4, 0x16, 0xb4, 0xf7, 0xdd, 0x08, 0xb7, 0xa3, 0xc3, 0x80, 0xb3, 0x45, 0x3b, + 0x55, 0x8e, 0x2c, 0x18, 0x7f, 0xdc, 0x75, 0x77, 0xdb, 0x82, 0x18, 0x1b, 0x88, 0x56, 0x86, 0x6e, + 0xc1, 0x24, 0x4f, 0xb2, 0xc9, 0xa2, 0x2b, 0xf3, 0x0c, 0x6e, 0x76, 0xa2, 0x94, 0xb4, 0xbb, 0xe8, + 0x7b, 0x91, 0xe3, 0x7a, 0x38, 0xb0, 0x0f, 0xbd, 0xc8, 0xe5, 0x29, 0xd7, 0x47, 0xed, 0x54, 0x39, + 0x7a, 0x07, 0x66, 0x64, 0xd9, 0x46, 0xd0, 0xde, 0xc7, 0x61, 0x14, 0xd0, 0x48, 0xf4, 0xf4, 0x25, + 0xbb, 0x6d, 0xae, 0xa4, 0x2d, 0x74, 0xfd, 0xc3, 0xce, 0xb2, 0xf7, 0xd2, 0x0d, 0x7c, 0x96, 0x9e, + 0x71, 0x84, 0xb7, 0x90, 0x28, 0xb7, 0x36, 0x8d, 0x67, 0xef, 0x2b, 0x6c, 0x24, 0xeb, 0xb8, 0x00, + 0xf3, 0xc6, 0xe3, 0x21, 0x3e, 0xcc, 0x95, 0x24, 0xc7, 0x57, 0x76, 0xe1, 0x1d, 0x18, 0xa4, 0x5f, + 0x6a, 0xa6, 0xeb, 0x8b, 0xeb, 0x3f, 0x8a, 0xcf, 0x48, 0x91, 0x5a, 0x9b, 0xc2, 0xa0, 0xc7, 0x52, + 0x2a, 0x1b, 0xa0, 0x52, 0xd9, 0xbd, 0x24, 0xe7, 0x33, 0x34, 0xae, 0x4a, 0x67, 0x67, 0x21, 0x91, + 0xfd, 0x65, 0x01, 0xaa, 0x7d, 0xb8, 0x82, 0x1c, 0x53, 0xe1, 0x04, 0x63, 0x7a, 0x22, 0xc7, 0xc4, + 0x1c, 0x8d, 0x17, 0x4e, 0xc6, 0x79, 0xce, 0x7a, 0x58, 0x8b, 0x80, 0xd2, 0xdf, 0x0f, 0xf4, 0x6d, + 0x18, 0x6d, 0x34, 0x56, 0xb4, 0xcb, 0xa9, 0xe4, 0x7d, 0x91, 0x1d, 0x43, 0x58, 0xef, 0xc1, 0xac, + 0x24, 0xc2, 0x42, 0xb8, 0x2a, 0xaf, 0x19, 0x78, 0x96, 0x23, 0xf9, 0x88, 0x22, 0x2e, 0xb0, 0x7e, + 0x98, 0xc2, 0x6b, 0x1c, 0x1e, 0x1c, 0x38, 0xc1, 0x6b, 0x54, 0xd3, 0xf1, 0x06, 0xfa, 0x7e, 0x29, + 0xeb, 0x83, 0x3f, 0x3f, 0xaa, 0x9e, 0x53, 0x89, 0xdf, 0x86, 0x5b, 0x12, 0x44, 0x96, 0x72, 0x66, + 0x45, 0xad, 0x77, 0xf2, 0x06, 0xfd, 0xb7, 0x8a, 0x50, 0xed, 0x03, 0x8a, 0xfe, 0xa4, 0xc0, 0xa2, + 0x94, 0xcb, 0x12, 0xde, 0xab, 0x0f, 0x92, 0x5b, 0xd1, 0x8c, 0x7f, 0x57, 0xfb, 0xc5, 0x54, 0x86, + 0x0f, 0x7f, 0xfb, 0xaf, 0xdf, 0x98, 0xeb, 0xea, 0x7d, 0xa9, 0x7c, 0x0f, 0x50, 0xba, 0x81, 0x7e, + 0xfb, 0x60, 0x50, 0xdd, 0x07, 0x36, 0x4c, 0x6b, 0xdf, 0xab, 0x93, 0x1c, 0xe1, 0xab, 0x00, 0x3c, + 0xda, 0xf6, 0x9a, 0xbf, 0xc7, 0x9f, 0x04, 0x28, 0x25, 0xd6, 0x23, 0x98, 0x49, 0xd0, 0xe4, 0x4a, + 0xcc, 0xb7, 0x41, 0xaa, 0x5d, 0x94, 0xe8, 0x40, 0xfd, 0xc2, 0x2f, 0x8f, 0xaa, 0x13, 0x84, 0x11, + 0xde, 0x8d, 0xe3, 0xda, 0x89, 0xbf, 0xac, 0x67, 0xaa, 0x76, 0x5c, 0xeb, 0x6a, 0x8f, 0xb9, 0x1e, + 0xc0, 0x79, 0x56, 0x92, 0x88, 0x1e, 0xa5, 0x42, 0xf3, 0xbd, 0xc1, 0x01, 0xad, 0x19, 0xea, 0xb0, + 0x49, 0x7f, 0xd4, 0xe2, 0xa7, 0x01, 0xd6, 0x36, 0x0b, 0x65, 0x1a, 0x17, 0xcb, 0x08, 0x55, 0x83, + 0xb5, 0xf8, 0x09, 0x83, 0xb8, 0x02, 0x10, 0x70, 0x9e, 0xff, 0xaa, 0x8b, 0x3b, 0x7b, 0x34, 0xfd, + 0x54, 0x7d, 0x9c, 0x5f, 0x01, 0x0c, 0x3a, 0x84, 0x00, 0x45, 0xb3, 0x3e, 0x85, 0x99, 0xc5, 0x2e, + 0x76, 0x82, 0x64, 0x7b, 0xe8, 0x16, 0x0c, 0xd3, 0x32, 0xfd, 0x66, 0xdb, 0x21, 0x45, 0xf4, 0x66, + 0x9b, 0x57, 0x12, 0x85, 0x8e, 0x05, 0xf5, 0x51, 0x87, 0x14, 0xeb, 0x52, 0x43, 0xf4, 0x77, 0xc2, + 0xdd, 0xcf, 0x30, 0x7a, 0x06, 0x67, 0x7d, 0x42, 0xfd, 0x49, 0x4c, 0x99, 0xc7, 0x4e, 0xe6, 0x80, + 0xfa, 0xff, 0xc3, 0x7c, 0xad, 0xd7, 0xc3, 0x5e, 0x27, 0x46, 0xdc, 0x0a, 0x9c, 0x13, 0x3a, 0xf6, + 0xa3, 0x1a, 0x0c, 0x51, 0x68, 0x69, 0x06, 0xe4, 0xdd, 0x35, 0x74, 0x87, 0xc2, 0x71, 0xfd, 0x96, + 0x36, 0xc0, 0x30, 0xad, 0x0e, 0xcc, 0x35, 0x0e, 0x77, 0x0f, 0x5c, 0x96, 0xe4, 0x8b, 0x3e, 0x8e, + 0x11, 0x6d, 0xaf, 0x8a, 0xe8, 0xd3, 0x6c, 0x32, 0x6e, 0xc7, 0x19, 0xc5, 0xe8, 0x25, 0x3d, 0x7f, + 0x30, 0xf3, 0xf2, 0xc1, 0xdd, 0x18, 0x95, 0x8a, 0x9e, 0xac, 0x15, 0x5a, 0xcd, 0x23, 0x54, 0x5b, + 0x17, 0xe1, 0x82, 0x6a, 0x52, 0x61, 0x3b, 0x64, 0x06, 0x2e, 0xea, 0xa6, 0x12, 0x56, 0xfc, 0x05, + 0x4c, 0xb3, 0x3b, 0x00, 0x16, 0x0e, 0x6c, 0x21, 0x8e, 0x7c, 0x55, 0x6c, 0x2e, 0x24, 0xae, 0xf6, + 0xa9, 0x77, 0xb6, 0x0c, 0xf4, 0xd8, 0x5c, 0x60, 0x3e, 0x81, 0x2f, 0x17, 0x34, 0x83, 0x5c, 0xb1, + 0xb9, 0x50, 0x1f, 0xe6, 0x7a, 0x3e, 0xa1, 0xce, 0x96, 0xff, 0x57, 0x42, 0x7d, 0x81, 0xba, 0xa1, + 0x9b, 0xb3, 0x0d, 0x8b, 0x96, 0x26, 0xa1, 0xe8, 0x76, 0x84, 0xb0, 0xe5, 0x76, 0xac, 0x3f, 0x2b, + 0xc0, 0x6d, 0xf6, 0x49, 0x32, 0xe3, 0x51, 0xcd, 0x3d, 0x03, 0x19, 0xbd, 0x0f, 0x2c, 0xeb, 0x0e, + 0xff, 0xee, 0x5b, 0xb9, 0x09, 0x93, 0x19, 0x25, 0x86, 0x80, 0x6a, 0x30, 0xae, 0xfa, 0x96, 0x24, + 0x82, 0x05, 0x64, 0xd8, 0xf0, 0xec, 0xb1, 0x83, 0xe7, 0x8e, 0xf4, 0x37, 0x79, 0x01, 0x97, 0x97, + 0xbf, 0x24, 0x1b, 0x82, 0xcb, 0x9a, 0xfc, 0x1e, 0x2e, 0x76, 0x16, 0x9d, 0xda, 0xe2, 0x3b, 0x46, + 0x97, 0x86, 0x92, 0xc5, 0x44, 0x4a, 0x14, 0xe2, 0xaa, 0x14, 0x62, 0x46, 0x6d, 0xad, 0xcc, 0xfa, + 0x4f, 0x05, 0x98, 0x37, 0xb7, 0xc6, 0x19, 0xcb, 0x2a, 0x5c, 0x58, 0x74, 0x3c, 0xdf, 0x73, 0xdb, + 0x4e, 0xb7, 0xd1, 0xde, 0xc7, 0x9d, 0xc3, 0xae, 0x70, 0xb9, 0x91, 0x5c, 0x86, 0x48, 0xbd, 0x1c, + 0x5d, 0x80, 0xd8, 0x69, 0x2c, 0xf4, 0x1e, 0xcc, 0x52, 0x87, 0x07, 0xc6, 0x7b, 0xbb, 0x38, 0x90, + 0xf4, 0x58, 0xcf, 0x32, 0x6a, 0xd1, 0x7d, 0xb8, 0xc8, 0x3e, 0x2a, 0x9d, 0x6d, 0xcf, 0x8d, 0x24, + 0x12, 0x13, 0x8e, 0x4d, 0x55, 0x77, 0xee, 0xc0, 0xe8, 0x46, 0x0f, 0xf3, 0x24, 0xdb, 0x23, 0x30, + 0xb8, 0xba, 0xbe, 0xba, 0xc5, 0x52, 0xec, 0x6d, 0x6e, 0x6f, 0x95, 0x0a, 0x08, 0xe0, 0xfc, 0xd2, + 0xf2, 0xda, 0xf2, 0xd6, 0x72, 0xa9, 0x78, 0xa7, 0xa5, 0xfa, 0xe4, 0xa0, 0xcb, 0x30, 0xb7, 0xb4, + 0xdc, 0x5c, 0x5d, 0x5c, 0x6e, 0x6d, 0x7d, 0x7f, 0x73, 0xb9, 0xa5, 0x07, 0x5b, 0x9a, 0x86, 0x92, + 0x5a, 0xb9, 0xb5, 0xb1, 0xb5, 0xc9, 0xf2, 0xe6, 0xa9, 0xa5, 0x3b, 0xcb, 0xf5, 0xda, 0xf6, 0xd6, + 0xca, 0x7a, 0x69, 0xc0, 0x1a, 0x1c, 0x29, 0x96, 0x8a, 0x77, 0x7e, 0xa2, 0x39, 0xec, 0xa0, 0x79, + 0x28, 0x73, 0xf0, 0xed, 0x46, 0xed, 0x71, 0x76, 0x13, 0xac, 0xf6, 0xd9, 0xa3, 0x5a, 0xa9, 0x80, + 0xae, 0xc0, 0x25, 0xad, 0x74, 0xb3, 0xd6, 0x68, 0xec, 0x6c, 0xd8, 0x4b, 0x6b, 0xcb, 0x8d, 0x46, + 0xa9, 0x78, 0xa7, 0xa9, 0x05, 0xe8, 0x21, 0x2d, 0x3c, 0x7b, 0x54, 0x6b, 0xd9, 0xcb, 0x9f, 0x6d, + 0xaf, 0xda, 0xcb, 0x4b, 0xe9, 0x16, 0xb4, 0xda, 0xef, 0x2f, 0x37, 0x4a, 0x05, 0x74, 0x11, 0xa6, + 0xb4, 0xd2, 0xf5, 0x8d, 0x52, 0xf1, 0xce, 0x2d, 0xfe, 0xf6, 0x0f, 0x4d, 0x02, 0x2c, 0x2d, 0x37, + 0x16, 0x97, 0xd7, 0x97, 0x56, 0xd7, 0x1f, 0x97, 0xce, 0xa1, 0x09, 0x18, 0xad, 0xc9, 0x9f, 0x85, + 0x3b, 0xd7, 0x60, 0x2a, 0x21, 0x3e, 0x12, 0x08, 0x29, 0x79, 0x95, 0xce, 0x2d, 0xfc, 0xec, 0x0f, + 0x0a, 0x30, 0x46, 0xb6, 0xbe, 0x70, 0xcf, 0xf8, 0x42, 0x11, 0xaa, 0xf8, 0x92, 0xf3, 0xe0, 0xf7, + 0x99, 0x12, 0x14, 0xe5, 0x82, 0x95, 0x1c, 0x8d, 0x9b, 0x02, 0xdc, 0x2e, 0xdc, 0x2f, 0x20, 0x9b, + 0xda, 0x9a, 0x13, 0x52, 0x9b, 0xa4, 0x6c, 0x96, 0x02, 0x2b, 0x19, 0xd5, 0x42, 0xd8, 0xfb, 0x75, + 0xb0, 0x54, 0x9a, 0x19, 0x12, 0xd8, 0xb7, 0x4f, 0x26, 0x69, 0x89, 0x36, 0x6f, 0x9d, 0x0c, 0x1c, + 0x3d, 0x81, 0x09, 0x22, 0x9b, 0x48, 0x30, 0x74, 0x39, 0x89, 0xa8, 0x88, 0x43, 0x95, 0x79, 0x73, + 0xa5, 0x0c, 0x91, 0x39, 0x4e, 0x07, 0x12, 0x46, 0x8e, 0x47, 0x34, 0xe2, 0x19, 0x99, 0xc4, 0x9e, + 0x95, 0xb0, 0x9b, 0xfe, 0xca, 0x85, 0x44, 0x71, 0xf3, 0xc1, 0xfd, 0x02, 0x6a, 0xd0, 0xe7, 0x93, + 0x9a, 0x90, 0x83, 0x84, 0xbf, 0x50, 0x5a, 0xfa, 0x61, 0xbd, 0xa9, 0x4a, 0xeb, 0x74, 0x86, 0x74, + 0xb4, 0x0e, 0x28, 0x2d, 0x3b, 0xa0, 0x6b, 0xf1, 0x3e, 0x30, 0x8b, 0x15, 0x95, 0xd9, 0xd4, 0x15, + 0xe2, 0x32, 0xf9, 0x7a, 0xa0, 0x65, 0x98, 0xe4, 0x4e, 0x9e, 0x5c, 0x9a, 0x41, 0x79, 0xf2, 0x50, + 0x26, 0x99, 0xc7, 0x74, 0x9e, 0xa4, 0x44, 0x84, 0x2a, 0xf1, 0x38, 0x92, 0x62, 0x52, 0xe5, 0xb2, + 0xb1, 0x8e, 0x8f, 0xef, 0x11, 0x4c, 0xea, 0xc2, 0x15, 0x12, 0x0b, 0x64, 0x94, 0xb9, 0x32, 0x3b, + 0xd4, 0x82, 0xb9, 0x67, 0x8e, 0x4b, 0x35, 0x6c, 0x7e, 0x51, 0x25, 0xae, 0x99, 0x50, 0x35, 0xe7, + 0xde, 0xa9, 0x81, 0xbd, 0x4e, 0xa5, 0x5f, 0xe0, 0x00, 0x7a, 0x6c, 0x1a, 0x42, 0x46, 0xd0, 0xaf, + 0xe9, 0x90, 0xa5, 0x67, 0x08, 0x31, 0xdd, 0xbc, 0x56, 0xb2, 0x9c, 0x05, 0xd0, 0x33, 0x2a, 0xa4, + 0x24, 0x28, 0x2a, 0x7b, 0xe2, 0xd4, 0xe4, 0xca, 0xd4, 0xd5, 0x38, 0x72, 0x93, 0xb7, 0xfe, 0x21, + 0xca, 0x98, 0xb8, 0x4c, 0x62, 0xf7, 0x0b, 0xe8, 0x0b, 0x7a, 0xaa, 0x8d, 0xe4, 0x76, 0xdc, 0x68, + 0x9f, 0x7b, 0xbd, 0x5c, 0x36, 0x12, 0xe0, 0x07, 0x25, 0x87, 0xba, 0x0d, 0xd3, 0x26, 0xff, 0x04, + 0x39, 0xa1, 0x39, 0xce, 0x0b, 0x99, 0xbb, 0xc0, 0x26, 0xa2, 0x56, 0x27, 0x7b, 0x91, 0x72, 0xae, + 0xc7, 0x33, 0x69, 0x7e, 0x0c, 0x93, 0x64, 0x97, 0x3c, 0xc5, 0xb8, 0x57, 0xeb, 0xba, 0x2f, 0x71, + 0x88, 0x44, 0x50, 0x0d, 0x59, 0x94, 0x85, 0x7b, 0xbb, 0x80, 0xbe, 0x09, 0x63, 0x3b, 0x4e, 0xd4, + 0xde, 0xe7, 0x6f, 0xc0, 0xc5, 0x13, 0x71, 0x5a, 0x56, 0x11, 0xbf, 0x68, 0xe5, 0xfd, 0x02, 0xfa, + 0x2e, 0x0c, 0x3f, 0xc6, 0x11, 0xf5, 0xd7, 0xbc, 0x2e, 0xaf, 0xea, 0x98, 0x5b, 0xcc, 0xaa, 0x27, + 0x1d, 0xd8, 0x44, 0x87, 0x93, 0xfa, 0x3c, 0xba, 0x07, 0xc0, 0x18, 0x02, 0xa5, 0x90, 0xac, 0xae, + 0xa4, 0xba, 0x8d, 0x1e, 0x93, 0xcf, 0x7b, 0x17, 0x47, 0xf8, 0xa4, 0x4d, 0x66, 0xcd, 0xd1, 0x1a, + 0x4c, 0xca, 0xa8, 0xa2, 0xeb, 0xd4, 0xe1, 0xdf, 0x4a, 0x10, 0x0b, 0x4f, 0x41, 0xed, 0x43, 0x72, + 0x2a, 0xd8, 0xd5, 0x99, 0x0c, 0x38, 0x82, 0xb2, 0x42, 0x90, 0xc8, 0x49, 0x64, 0x60, 0x0a, 0xee, + 0x8a, 0x1f, 0x46, 0x3a, 0xae, 0x2c, 0x31, 0xe3, 0x62, 0xa8, 0xa8, 0xed, 0xea, 0xc1, 0x47, 0x62, + 0x9e, 0x9b, 0x15, 0x33, 0xa5, 0x72, 0x3d, 0x07, 0x82, 0xb1, 0x3b, 0xca, 0x49, 0x96, 0x88, 0xf6, + 0xca, 0x9a, 0x51, 0xd3, 0xe3, 0x8b, 0xcb, 0x00, 0xa5, 0x4c, 0x10, 0x46, 0xe9, 0x2a, 0xf2, 0xd5, + 0xd3, 0x82, 0x5e, 0xc4, 0x5f, 0x3d, 0x43, 0x54, 0x92, 0xf8, 0xab, 0x67, 0x8c, 0x93, 0xf1, 0x94, + 0xe9, 0xd3, 0x5a, 0x92, 0xec, 0xe6, 0x02, 0x12, 0xce, 0xbb, 0x5a, 0x05, 0x3f, 0xd8, 0xb3, 0xa6, + 0xba, 0xe6, 0xc3, 0xfb, 0x05, 0xb4, 0x0c, 0x17, 0xe5, 0xfb, 0x8c, 0xb8, 0x0a, 0x65, 0x20, 0x64, + 0x6e, 0x82, 0x4f, 0xe1, 0x22, 0xdf, 0x52, 0x1a, 0x99, 0x92, 0xe4, 0x0e, 0xfc, 0xfe, 0x2e, 0x93, + 0xc0, 0x13, 0x98, 0x69, 0x24, 0x06, 0xc5, 0xbc, 0x4d, 0x2e, 0xe9, 0x24, 0x94, 0x7c, 0xa4, 0x99, + 0xb4, 0x9e, 0x02, 0x62, 0x2a, 0xab, 0x20, 0xf7, 0xd2, 0xc5, 0xaf, 0xd0, 0x95, 0xc4, 0x90, 0x48, + 0x21, 0x05, 0xa3, 0xec, 0x25, 0x6b, 0x8a, 0xd0, 0x16, 0xcb, 0x95, 0xc2, 0x72, 0x9d, 0x39, 0x3d, + 0x67, 0xd7, 0xed, 0xba, 0x91, 0x8b, 0xc9, 0x0e, 0x53, 0x11, 0xd4, 0x2a, 0xb1, 0x8c, 0x97, 0x32, + 0x21, 0xd0, 0x27, 0x30, 0xf1, 0x18, 0x47, 0x71, 0xca, 0x55, 0x34, 0x97, 0x4a, 0xd2, 0xca, 0x97, + 0x4e, 0xbc, 0x06, 0xd4, 0xf3, 0xbc, 0xae, 0x42, 0x89, 0x71, 0x47, 0x85, 0xc4, 0x95, 0x14, 0x09, + 0x0e, 0xe2, 0x04, 0xce, 0x41, 0x98, 0x39, 0x5b, 0xf7, 0xd8, 0x75, 0x0e, 0x12, 0xdb, 0x56, 0x15, + 0xbf, 0x2e, 0x6a, 0x65, 0x32, 0x7a, 0xd3, 0x8c, 0x31, 0xd7, 0x28, 0xba, 0x11, 0x7f, 0x0a, 0x33, + 0x13, 0x88, 0x56, 0x50, 0xf2, 0xad, 0x5e, 0xf3, 0x21, 0x92, 0xa9, 0x25, 0x0c, 0x44, 0x6f, 0x69, + 0x5f, 0xec, 0xd3, 0xd1, 0xfd, 0x04, 0x46, 0x65, 0xd2, 0x4a, 0xc9, 0x56, 0x92, 0x29, 0x3f, 0x2b, + 0xe5, 0x74, 0x05, 0x1f, 0xe9, 0xc7, 0x2c, 0x45, 0xad, 0x8e, 0x9f, 0xcc, 0xeb, 0x98, 0x39, 0xb1, + 0x1f, 0xc0, 0x98, 0x92, 0xd1, 0x51, 0x6e, 0xe4, 0x74, 0x96, 0xc7, 0xca, 0x84, 0xd2, 0xf7, 0xe6, + 0xc2, 0xfd, 0x02, 0xba, 0x47, 0x3f, 0x2d, 0xf4, 0xb1, 0xca, 0x4c, 0x8c, 0xa6, 0xe4, 0x61, 0x4b, + 0xa0, 0xa0, 0xef, 0xd0, 0x98, 0x1e, 0x8b, 0x87, 0x41, 0x40, 0x14, 0x58, 0x82, 0x97, 0x25, 0x41, + 0x24, 0x10, 0x3f, 0xa1, 0xcc, 0x44, 0x41, 0x64, 0xee, 0x1b, 0xfd, 0xb0, 0x59, 0x4c, 0xd8, 0xfb, + 0x05, 0xf4, 0x10, 0x46, 0x44, 0x02, 0x68, 0x34, 0xab, 0x77, 0x35, 0x7b, 0x78, 0x0f, 0x01, 0xd8, + 0x64, 0xd3, 0x9e, 0xea, 0xd5, 0x99, 0xd3, 0xf9, 0x90, 0x7c, 0x2f, 0x3b, 0xa7, 0x44, 0xfa, 0x44, + 0x7c, 0x33, 0x29, 0x52, 0x59, 0x5b, 0x42, 0x75, 0x3a, 0xb3, 0xf0, 0x89, 0xc0, 0xab, 0xe5, 0xa5, + 0x8e, 0x05, 0x5e, 0x53, 0xba, 0xea, 0x4c, 0x3a, 0xab, 0x50, 0xaa, 0xb5, 0x29, 0x1f, 0x97, 0xb9, + 0xed, 0xa4, 0xb6, 0x91, 0xac, 0x10, 0xb4, 0x66, 0x92, 0xa9, 0xf2, 0xd6, 0xb0, 0x43, 0xc3, 0x9c, + 0xcc, 0x49, 0x99, 0x20, 0x51, 0x65, 0xc6, 0xc8, 0xd1, 0x2e, 0xa6, 0x17, 0x89, 0x3e, 0xd4, 0xfd, + 0x6a, 0x64, 0x3e, 0xa4, 0xbc, 0x4c, 0xc9, 0xfb, 0x37, 0x9b, 0xc4, 0x97, 0x7a, 0x98, 0x70, 0x9d, + 0x93, 0xa0, 0x35, 0x98, 0xe2, 0x41, 0x15, 0xe4, 0xb4, 0x64, 0x61, 0x67, 0x35, 0xff, 0x1d, 0x98, + 0x5c, 0x26, 0xbc, 0xfe, 0xb0, 0xe3, 0xb2, 0xd0, 0x4e, 0x48, 0x8f, 0xd5, 0x93, 0x89, 0xb8, 0x22, + 0x52, 0xda, 0x2a, 0x09, 0xf1, 0xe4, 0x29, 0x4d, 0xe7, 0x1c, 0xac, 0x4c, 0x0b, 0xb2, 0x6a, 0xee, + 0x3c, 0xae, 0xa4, 0xcf, 0x65, 0xa4, 0xa0, 0x43, 0x37, 0x35, 0xdd, 0x2f, 0x2b, 0x8f, 0x9c, 0x41, + 0xda, 0xfb, 0x5c, 0x49, 0xca, 0x91, 0x41, 0x33, 0x3f, 0x37, 0x5d, 0xe6, 0xb8, 0x65, 0x30, 0x16, + 0x63, 0x0e, 0x39, 0xf4, 0xb6, 0x4e, 0x3d, 0x27, 0xcf, 0x5c, 0x66, 0x0b, 0x54, 0xb7, 0xd6, 0x53, + 0x9c, 0xa1, 0xab, 0xf9, 0x99, 0xd8, 0x14, 0xdd, 0x3a, 0x23, 0x37, 0xda, 0x13, 0xba, 0xcd, 0xe2, + 0xcc, 0x1d, 0x48, 0xd5, 0x54, 0x93, 0x89, 0x4b, 0xa4, 0x08, 0x65, 0xce, 0x73, 0xf6, 0x98, 0xb2, + 0x4b, 0x25, 0x0b, 0x48, 0x26, 0xc3, 0xbb, 0x62, 0xa2, 0x13, 0x2a, 0xdf, 0xc2, 0xa9, 0x44, 0xc6, + 0x30, 0x69, 0x9b, 0x31, 0xe7, 0x2c, 0xab, 0x5c, 0xcd, 0xaa, 0xe6, 0x14, 0x1b, 0x22, 0x29, 0xb5, + 0x32, 0xd2, 0xab, 0xda, 0x17, 0x2a, 0x3d, 0xd8, 0x6a, 0x66, 0xbd, 0x9c, 0xbb, 0x52, 0x32, 0xc3, + 0x8b, 0x24, 0x9a, 0x91, 0xfa, 0x25, 0x87, 0x25, 0x4e, 0xab, 0x5b, 0xa3, 0xef, 0x0c, 0x66, 0xd1, + 0xd9, 0x82, 0x19, 0x63, 0x42, 0x16, 0x29, 0x46, 0xe4, 0xa5, 0x6b, 0xc9, 0xa4, 0x8a, 0x61, 0xd6, + 0x9c, 0x93, 0x09, 0x7d, 0x43, 0x57, 0xfd, 0xcd, 0x19, 0x6a, 0x2a, 0x37, 0xfb, 0x40, 0xf1, 0x09, + 0xfd, 0x82, 0x7e, 0x36, 0x53, 0x6d, 0x5c, 0x57, 0x8c, 0x01, 0x19, 0x0d, 0x58, 0x79, 0x20, 0x72, + 0x0f, 0x4c, 0x9b, 0x72, 0xc2, 0x65, 0x4e, 0xf1, 0x8d, 0x6c, 0x9a, 0xf1, 0xc6, 0x6a, 0x8a, 0x10, + 0x28, 0x99, 0x33, 0x93, 0x9b, 0xbb, 0x27, 0x47, 0x9b, 0xac, 0xc8, 0xfd, 0x70, 0xf2, 0x2e, 0x67, + 0x5b, 0x86, 0xa6, 0x4d, 0x19, 0xa3, 0x92, 0x86, 0x1b, 0x53, 0x42, 0x20, 0x39, 0x0d, 0xb9, 0x29, + 0xa7, 0x9a, 0xcc, 0x88, 0xa3, 0x53, 0x57, 0x8d, 0x38, 0x46, 0xd2, 0xd7, 0xb2, 0x01, 0xe2, 0x1d, + 0x61, 0x48, 0x7d, 0x27, 0x77, 0x44, 0x76, 0x12, 0x3e, 0xb9, 0x23, 0xf2, 0x32, 0xe7, 0xd9, 0xe2, + 0xd0, 0x65, 0x4c, 0x4b, 0x4e, 0x9e, 0xa4, 0x1c, 0x95, 0xab, 0x1c, 0x2f, 0x5c, 0xa2, 0xdb, 0xa7, + 0x5d, 0xb6, 0x2f, 0xe0, 0x52, 0x66, 0x4e, 0x24, 0xf4, 0x56, 0xea, 0x40, 0x67, 0xcc, 0x44, 0x76, + 0x4f, 0x27, 0xb4, 0x74, 0x46, 0xd2, 0x8a, 0x95, 0xc8, 0x9c, 0x94, 0x62, 0xfd, 0x86, 0xb4, 0x4a, + 0x8c, 0xf5, 0x2b, 0xa9, 0x91, 0x4e, 0xc2, 0xfa, 0x4d, 0x99, 0x94, 0x24, 0x4f, 0x55, 0xfa, 0x25, + 0x44, 0xba, 0x64, 0xc5, 0x69, 0x78, 0xea, 0x49, 0xba, 0x96, 0x45, 0x67, 0x89, 0xaa, 0x1c, 0x22, + 0x53, 0x12, 0xba, 0xa4, 0x4d, 0x93, 0xf6, 0xb9, 0xad, 0x68, 0x83, 0xd3, 0xbf, 0xb4, 0x8b, 0xd4, + 0x5c, 0x2c, 0x33, 0x33, 0x65, 0xf6, 0xe2, 0x72, 0x9a, 0x86, 0x66, 0x2a, 0x96, 0xb3, 0xc0, 0x7a, + 0x33, 0x9f, 0x9c, 0x1c, 0xad, 0x43, 0xd9, 0x43, 0x42, 0xea, 0xd4, 0xf4, 0xe9, 0x52, 0xb6, 0xa8, + 0x7b, 0x91, 0x29, 0x0f, 0x2c, 0x46, 0xa1, 0x78, 0xa9, 0x3c, 0x2b, 0xed, 0x5e, 0x4a, 0x69, 0x8e, + 0x99, 0x63, 0x93, 0xba, 0x06, 0x1a, 0x92, 0x4c, 0x49, 0x1e, 0x9a, 0x9b, 0x83, 0xca, 0x20, 0xe6, + 0x49, 0xae, 0x9c, 0x49, 0x31, 0x37, 0xeb, 0x54, 0x66, 0x4f, 0x7f, 0xac, 0x70, 0xe5, 0x54, 0x2a, + 0x29, 0x74, 0x3b, 0x29, 0xe3, 0x65, 0x65, 0x9b, 0xca, 0xe1, 0xfa, 0xd3, 0xa6, 0x2c, 0x54, 0x8a, + 0xed, 0x36, 0x33, 0x45, 0x95, 0x61, 0x16, 0x24, 0x7b, 0xcb, 0xa0, 0x96, 0x93, 0x93, 0x2a, 0xb3, + 0x87, 0x3f, 0x50, 0xd8, 0x5b, 0x22, 0x77, 0x94, 0x34, 0x2a, 0xf4, 0x49, 0x2e, 0x95, 0x49, 0x7b, + 0x9d, 0x3a, 0x93, 0xa6, 0x13, 0x3f, 0x49, 0xd9, 0x25, 0x2f, 0x2d, 0x94, 0xd1, 0xb4, 0x3b, 0x93, + 0x1e, 0x22, 0xa1, 0x37, 0x9b, 0x30, 0xcc, 0xf6, 0xeb, 0x98, 0xe4, 0xc3, 0x86, 0x84, 0x51, 0x09, + 0x3e, 0x9c, 0x9d, 0x52, 0x2a, 0x47, 0x63, 0x9a, 0x6a, 0xb8, 0x7b, 0x9e, 0x92, 0xef, 0x49, 0xea, + 0x4b, 0xe9, 0x14, 0x54, 0x92, 0xc5, 0x98, 0xd2, 0x43, 0x6d, 0xc4, 0x4f, 0x56, 0xd4, 0xcc, 0x3d, + 0xa8, 0x92, 0x9d, 0xb0, 0x48, 0xb2, 0x1b, 0x63, 0xaa, 0x1f, 0x85, 0xa0, 0x9a, 0x36, 0x47, 0x12, + 0x34, 0x64, 0xf0, 0x91, 0x04, 0x8d, 0x79, 0x76, 0x98, 0x09, 0xc6, 0xf6, 0xbb, 0x58, 0x35, 0xc1, + 0x28, 0x49, 0x6f, 0x12, 0xb6, 0x10, 0xf4, 0x11, 0xb5, 0x84, 0xe4, 0x9b, 0x4f, 0xe6, 0x74, 0x4a, + 0x31, 0xb7, 0x7c, 0x28, 0x2e, 0x03, 0x68, 0x83, 0x3a, 0xe5, 0xfe, 0xc6, 0x0d, 0x8a, 0xa4, 0x1b, + 0x37, 0xd4, 0x8e, 0x66, 0xdb, 0x49, 0xc7, 0xd5, 0xa0, 0xe9, 0x72, 0xae, 0x0c, 0x99, 0x1d, 0xe4, + 0x5c, 0x99, 0xf2, 0x25, 0x50, 0x1d, 0x78, 0x4b, 0x68, 0xf2, 0x31, 0xbd, 0x2b, 0xb9, 0x09, 0x0f, + 0x2a, 0x57, 0xf3, 0xb3, 0x04, 0xf0, 0x7b, 0xbc, 0x52, 0x32, 0xae, 0x3b, 0x32, 0xe5, 0xab, 0x50, + 0xc2, 0xe5, 0x4b, 0x6d, 0x28, 0x33, 0x20, 0xfc, 0xa6, 0x30, 0x56, 0xeb, 0x74, 0x33, 0xb2, 0x16, + 0xa8, 0xa4, 0xf3, 0x05, 0x94, 0x38, 0xc4, 0xbb, 0xaa, 0x9b, 0xa6, 0x42, 0xc8, 0xab, 0x02, 0x8a, + 0x21, 0x2a, 0xbc, 0x2b, 0x9e, 0x38, 0x9b, 0x33, 0x27, 0xbd, 0xad, 0xeb, 0x7a, 0x39, 0xc1, 0x7f, + 0xfa, 0xde, 0x94, 0xa2, 0x1f, 0x89, 0xac, 0xc9, 0xe9, 0x0c, 0x21, 0x37, 0x13, 0x66, 0x57, 0x73, + 0xb8, 0x98, 0x4a, 0x5e, 0x02, 0x12, 0xf4, 0x8c, 0x5e, 0xb1, 0x6f, 0xac, 0x2e, 0x2d, 0x72, 0x5f, + 0x00, 0x3f, 0x48, 0x5d, 0x5b, 0xed, 0xb8, 0xd1, 0x3e, 0x4b, 0x99, 0xa3, 0x70, 0x1f, 0x06, 0xa2, + 0x21, 0x36, 0x1f, 0xa2, 0x06, 0x95, 0xdc, 0xb5, 0x52, 0xc3, 0xcd, 0x95, 0x81, 0x60, 0xc5, 0x4c, + 0x90, 0x26, 0xfe, 0xa3, 0x82, 0x01, 0x39, 0x78, 0x7a, 0x37, 0x33, 0xfa, 0x90, 0x27, 0x5f, 0xb0, + 0x6d, 0x63, 0x26, 0x73, 0x52, 0xf6, 0xfd, 0x18, 0x66, 0xd8, 0x84, 0x27, 0xde, 0x93, 0x69, 0xfd, + 0x51, 0xca, 0x2b, 0x19, 0xe5, 0x68, 0x9d, 0xba, 0x8d, 0x24, 0x4b, 0x15, 0x2d, 0xc6, 0xfc, 0x60, + 0x2d, 0x93, 0x1e, 0x5b, 0x4a, 0x22, 0xb6, 0xbf, 0xd1, 0x52, 0x6a, 0x88, 0xcd, 0x05, 0xbe, 0x94, + 0x5a, 0xe9, 0xe9, 0x96, 0x32, 0x41, 0x50, 0x5f, 0x4a, 0xbd, 0x9b, 0x19, 0x7d, 0xe8, 0xbf, 0x94, + 0x66, 0x32, 0xa7, 0x5e, 0xca, 0xc4, 0x63, 0x3e, 0xad, 0x3f, 0xa6, 0xa5, 0x4c, 0xc2, 0xb3, 0xa5, + 0x4c, 0x96, 0x26, 0x14, 0xd2, 0x9c, 0xa5, 0x4c, 0x62, 0x7e, 0x46, 0xe9, 0xb1, 0xd7, 0x82, 0xa7, + 0x5a, 0x4c, 0x11, 0xd4, 0x26, 0x81, 0xda, 0x7c, 0x88, 0x76, 0xa8, 0x35, 0x24, 0x51, 0x7e, 0xb2, + 0x05, 0x9d, 0xcf, 0x22, 0x4a, 0x97, 0x74, 0x55, 0xc8, 0x59, 0xc9, 0xee, 0x66, 0xf6, 0x25, 0x6f, + 0x3d, 0xd8, 0xb2, 0x26, 0x49, 0x9d, 0x76, 0x61, 0x9f, 0x09, 0xa6, 0x99, 0x7a, 0x70, 0x99, 0xe8, + 0x95, 0xba, 0xb8, 0x99, 0x35, 0x68, 0x8b, 0xda, 0x7a, 0xd2, 0xe5, 0x8a, 0x9d, 0x28, 0xeb, 0x65, + 0x67, 0x5f, 0xaa, 0xa9, 0x17, 0x9c, 0x2a, 0xd5, 0xac, 0xe7, 0x9d, 0x92, 0x6a, 0x1a, 0xfb, 0x53, + 0xaa, 0x3b, 0x73, 0x7f, 0x74, 0xef, 0xb9, 0x9f, 0x2d, 0xe8, 0x5c, 0xd4, 0xdc, 0x19, 0x08, 0x2c, + 0xf5, 0x22, 0xf9, 0x98, 0x5f, 0x15, 0x88, 0xc2, 0xcc, 0xc9, 0x37, 0xe1, 0xa3, 0x4f, 0xa1, 0xc4, + 0x0f, 0x78, 0x4c, 0xc0, 0x04, 0x98, 0xb9, 0x74, 0x75, 0xa1, 0xb2, 0x9f, 0xa0, 0x07, 0x27, 0x51, + 0xd5, 0x4f, 0x32, 0x13, 0xd9, 0x7a, 0x2d, 0x61, 0x81, 0x5b, 0x01, 0x51, 0x39, 0x3b, 0x69, 0x7d, + 0x54, 0xef, 0x8c, 0xb8, 0x1d, 0xd6, 0xc1, 0x9b, 0x0b, 0x68, 0x95, 0x1e, 0x66, 0xbd, 0x38, 0x4f, + 0x61, 0x37, 0x93, 0xa1, 0x67, 0x6d, 0x45, 0x3a, 0x3e, 0xeb, 0x7d, 0xca, 0x6a, 0x3b, 0xbb, 0x53, + 0x72, 0x8a, 0x4e, 0x38, 0xba, 0xac, 0x29, 0x62, 0x12, 0x35, 0x33, 0x1e, 0xf4, 0x9b, 0x99, 0xa4, + 0x2b, 0x36, 0xfa, 0x1e, 0x8c, 0x0a, 0xe4, 0xfe, 0x13, 0x92, 0xc4, 0xa6, 0x13, 0xf2, 0x09, 0x8c, + 0x29, 0x9e, 0xe0, 0x28, 0xab, 0xa5, 0x1c, 0xf1, 0x7c, 0x4c, 0xf1, 0x53, 0x3f, 0x3d, 0xfe, 0x12, + 0x4c, 0x68, 0x7e, 0xee, 0x52, 0xa8, 0x34, 0x79, 0xbf, 0xe7, 0x51, 0xd1, 0xfc, 0xd9, 0x25, 0x15, + 0x93, 0x97, 0x7b, 0xbe, 0x80, 0xab, 0xbc, 0x8f, 0x57, 0x04, 0xdc, 0xf4, 0x43, 0x7d, 0x45, 0xc0, + 0x35, 0x3d, 0xa9, 0xff, 0x2e, 0x8c, 0xf1, 0xed, 0x91, 0xbb, 0xb2, 0xd9, 0x96, 0x87, 0x19, 0xc5, + 0xff, 0xf2, 0xb0, 0xe3, 0x46, 0x8b, 0xbe, 0xf7, 0xdc, 0xdd, 0xeb, 0xbb, 0xc8, 0x69, 0x94, 0xe6, + 0x02, 0x6a, 0xd2, 0xd4, 0x07, 0x22, 0x21, 0x05, 0x8e, 0x5e, 0xf9, 0xc1, 0x0b, 0xd7, 0xdb, 0xeb, + 0x43, 0xf2, 0x9a, 0x4e, 0x32, 0x89, 0xc7, 0xe8, 0x36, 0xb2, 0xe9, 0xf6, 0xc5, 0xcf, 0xb1, 0x3c, + 0xcc, 0x53, 0x1f, 0x88, 0xd3, 0xf6, 0x38, 0xfb, 0x16, 0xe6, 0x52, 0xec, 0xb9, 0x68, 0xe3, 0xb6, + 0x1f, 0x74, 0xfa, 0x13, 0xab, 0xea, 0x7e, 0x82, 0x09, 0xb4, 0xe6, 0x02, 0xa1, 0xda, 0xc8, 0xa4, + 0xda, 0x0f, 0x3b, 0xe7, 0xcb, 0x7b, 0x99, 0x8e, 0xfd, 0x94, 0xbd, 0xcd, 0xe7, 0xc0, 0xe4, 0xab, + 0xb9, 0x19, 0xe0, 0xe7, 0x38, 0xa0, 0xee, 0xa7, 0xfd, 0x1c, 0x2f, 0x75, 0xf0, 0xe6, 0x02, 0xa1, + 0xd2, 0x48, 0x51, 0xc9, 0x82, 0xce, 0x13, 0x3a, 0xe9, 0xd0, 0x4e, 0xd8, 0x9b, 0x2c, 0x32, 0xef, + 0x53, 0xfb, 0xef, 0xf6, 0x6a, 0x9f, 0x19, 0x11, 0x0e, 0xd1, 0x02, 0xb0, 0xf9, 0x80, 0x60, 0x36, + 0x14, 0xcc, 0x34, 0x44, 0x66, 0x9b, 0xdf, 0x13, 0x86, 0xde, 0xbe, 0xcd, 0x66, 0x7b, 0x76, 0x8c, + 0xca, 0xb4, 0x4c, 0x48, 0x31, 0x91, 0x68, 0x49, 0x87, 0x2a, 0x13, 0xaa, 0xfb, 0x65, 0x88, 0x6a, + 0x4c, 0x23, 0x51, 0xd3, 0x13, 0x29, 0x77, 0xcc, 0xc6, 0xbc, 0x45, 0x49, 0x12, 0xcc, 0xc4, 0xb3, + 0xe6, 0xb7, 0x5f, 0xa8, 0x26, 0x1e, 0x25, 0xdf, 0x4d, 0x45, 0xcf, 0x46, 0xc3, 0x3f, 0x48, 0x34, + 0x25, 0x8d, 0xea, 0xec, 0xa2, 0x66, 0xbc, 0x51, 0x4d, 0x3c, 0x7a, 0x6e, 0x1e, 0x69, 0xe2, 0xa1, + 0x0d, 0xea, 0x94, 0xfb, 0x9b, 0x78, 0x28, 0x92, 0x6e, 0xe2, 0x51, 0x3b, 0x9a, 0xcd, 0x2e, 0x50, + 0x3a, 0x39, 0x8f, 0x54, 0x1e, 0x32, 0xf3, 0xf6, 0xe4, 0xf8, 0xb1, 0x5c, 0x34, 0xe4, 0x13, 0x93, + 0xa6, 0x93, 0xec, 0x5c, 0x63, 0x15, 0xdd, 0x29, 0xe3, 0x7e, 0x01, 0xad, 0xc3, 0xec, 0x63, 0x1c, + 0x71, 0x06, 0x66, 0xe3, 0x30, 0x0a, 0x5c, 0xfa, 0x24, 0x2d, 0xfb, 0x6b, 0x2d, 0x74, 0x05, 0x03, + 0x4e, 0xf3, 0x1d, 0x42, 0xaf, 0x61, 0xa6, 0x97, 0x8b, 0x97, 0x63, 0x1d, 0xe3, 0xa6, 0xd4, 0xd3, + 0x74, 0x31, 0x7b, 0x8b, 0x0f, 0x33, 0x0f, 0x82, 0x6c, 0xd4, 0x52, 0x1c, 0x4f, 0x96, 0x6b, 0x3f, + 0x77, 0xe1, 0x3c, 0x43, 0xca, 0xfc, 0x46, 0x8e, 0xab, 0x38, 0xe8, 0x81, 0x70, 0x77, 0x23, 0x28, + 0x5a, 0x55, 0x66, 0xbf, 0x1e, 0xc0, 0x28, 0xbb, 0x17, 0x39, 0x39, 0xca, 0x47, 0xc2, 0x29, 0x2e, + 0xaf, 0x63, 0xd9, 0x7e, 0xa2, 0x13, 0xaa, 0xf3, 0xc0, 0xe9, 0x27, 0xf2, 0xbb, 0xf4, 0x6e, 0x4a, + 0x98, 0x80, 0xb3, 0xf1, 0x67, 0x12, 0x11, 0x58, 0xf9, 0x94, 0x32, 0x06, 0x29, 0x13, 0xf3, 0x65, + 0x75, 0xff, 0x42, 0x0a, 0x1b, 0x7d, 0x24, 0x9e, 0x62, 0x48, 0xe4, 0x34, 0x50, 0xce, 0x9c, 0x4d, + 0xb2, 0x69, 0x7e, 0x13, 0x64, 0xc9, 0x60, 0xfb, 0x76, 0xfb, 0x24, 0x77, 0x68, 0xfd, 0xa7, 0x2e, + 0x8b, 0xca, 0x06, 0x15, 0xbc, 0x52, 0xb1, 0x81, 0xb3, 0x09, 0x5d, 0xcd, 0x0e, 0x27, 0x4c, 0x17, + 0xe3, 0x09, 0x55, 0x52, 0xd3, 0x49, 0x16, 0xb3, 0x86, 0x97, 0x13, 0x9e, 0x38, 0xd6, 0xca, 0xd3, + 0xe4, 0x72, 0xd0, 0xf2, 0x94, 0x7c, 0xfe, 0x04, 0xec, 0x4c, 0xc8, 0xad, 0x0a, 0x67, 0xae, 0x93, + 0x0f, 0x36, 0x47, 0x08, 0x32, 0xdc, 0xda, 0xf5, 0x5d, 0x8b, 0x2c, 0x72, 0x3f, 0xa2, 0xf2, 0x9f, + 0x39, 0xb3, 0x5a, 0x26, 0xb1, 0xdb, 0xca, 0xc5, 0x6f, 0x7e, 0x4e, 0xb6, 0x17, 0xf4, 0x8d, 0x8b, + 0x39, 0x7a, 0xf2, 0xad, 0x3e, 0x54, 0xc4, 0x4c, 0xbc, 0xd5, 0x17, 0x4e, 0xde, 0x01, 0x5d, 0x66, + 0x5f, 0x58, 0x73, 0x7b, 0x7d, 0xa2, 0x41, 0x1b, 0xae, 0xe5, 0x32, 0xd2, 0x96, 0x09, 0x82, 0xba, + 0xa7, 0x5c, 0xee, 0x18, 0xb2, 0xa6, 0xff, 0x33, 0xa8, 0xc6, 0xb7, 0xdb, 0xa7, 0x5b, 0x84, 0x6c, + 0x89, 0x1e, 0xa5, 0x93, 0xb9, 0xa1, 0xbc, 0x50, 0xba, 0x95, 0xeb, 0x59, 0x33, 0x1c, 0x2a, 0x6e, + 0x13, 0xdc, 0x2f, 0x27, 0x11, 0x47, 0x3c, 0x2b, 0x22, 0x79, 0x8e, 0x1d, 0x8e, 0x3f, 0xfa, 0x39, + 0x13, 0x42, 0xe9, 0xd5, 0x3e, 0x3d, 0x21, 0x79, 0xf9, 0x9c, 0x20, 0x64, 0xe5, 0x2c, 0xef, 0x69, + 0x7c, 0x6b, 0x92, 0x4b, 0x71, 0xda, 0x05, 0x75, 0xe2, 0x87, 0x2e, 0xe9, 0x8c, 0x73, 0x52, 0x96, + 0xcb, 0xcc, 0x7e, 0x27, 0x57, 0x37, 0x27, 0x5d, 0xdd, 0x22, 0x39, 0xa6, 0xac, 0x09, 0x2d, 0xdd, + 0xd5, 0xa2, 0xbd, 0x16, 0x5b, 0x1d, 0x0c, 0x79, 0xb0, 0x2a, 0x20, 0x2a, 0xed, 0x35, 0xd4, 0x80, + 0x0a, 0xdb, 0x22, 0xa6, 0xf0, 0x02, 0xf2, 0x75, 0x82, 0xa9, 0x32, 0x47, 0xbb, 0x68, 0x40, 0x85, + 0x6d, 0x97, 0xb3, 0x24, 0xda, 0xa2, 0xa9, 0x4d, 0x8d, 0x14, 0x6f, 0x2a, 0x4f, 0x3c, 0xb3, 0x83, + 0x36, 0x54, 0xf2, 0x1b, 0x46, 0x3f, 0x84, 0x19, 0x63, 0xd4, 0x06, 0xe9, 0x1f, 0x90, 0x17, 0xd3, + 0xa1, 0x1f, 0xf1, 0x17, 0x50, 0xce, 0xca, 0x4d, 0x15, 0xbf, 0x96, 0xc8, 0x4f, 0x18, 0x26, 0x79, + 0x6a, 0xdf, 0x24, 0x57, 0xeb, 0x30, 0x6d, 0xca, 0xf7, 0x24, 0x0f, 0x47, 0x4e, 0x32, 0x28, 0xe3, + 0x93, 0x8c, 0x4d, 0x98, 0x31, 0xe6, 0x5c, 0x92, 0x33, 0x93, 0x97, 0x91, 0xc9, 0x48, 0xf1, 0x73, + 0x98, 0xcb, 0x48, 0x30, 0x14, 0x5f, 0x62, 0xe6, 0x26, 0x20, 0xca, 0x71, 0xa6, 0xa8, 0x64, 0xe7, + 0xae, 0x91, 0x3e, 0x34, 0x7d, 0xd3, 0xdb, 0x54, 0x8c, 0x09, 0xbd, 0xd0, 0x16, 0xdd, 0x84, 0xa6, + 0x64, 0x36, 0xea, 0x26, 0xcc, 0x49, 0x76, 0x93, 0xf1, 0x94, 0x66, 0x2e, 0x23, 0x7f, 0x4d, 0x0e, + 0xd5, 0x13, 0xf4, 0x76, 0x5d, 0xf0, 0x7f, 0x3d, 0xa1, 0x49, 0xc2, 0x2f, 0xd3, 0x98, 0xed, 0xc4, + 0xd8, 0x4f, 0xe5, 0xe9, 0x76, 0xb7, 0x9b, 0x23, 0x06, 0x21, 0xf5, 0xed, 0x36, 0x81, 0xa4, 0xf7, + 0x00, 0x13, 0x2a, 0x6e, 0x1e, 0x47, 0x4d, 0x21, 0x53, 0xc1, 0xf3, 0x43, 0x18, 0x6f, 0xa8, 0x8d, + 0x1b, 0x1a, 0xc9, 0xdc, 0x14, 0xf2, 0xc5, 0x42, 0xff, 0xbe, 0xf7, 0xbd, 0x61, 0xac, 0x75, 0xbb, + 0x27, 0x1a, 0x45, 0xa6, 0x4d, 0x56, 0x8b, 0xf1, 0x2e, 0x39, 0xb5, 0x29, 0x75, 0x81, 0xb4, 0xc9, + 0x9a, 0xc3, 0xc2, 0x2f, 0xd3, 0x29, 0x8d, 0x23, 0xe4, 0xe6, 0xe8, 0xe0, 0x72, 0x13, 0x19, 0x02, + 0xf1, 0x3e, 0x55, 0x1f, 0xd5, 0xb3, 0xb8, 0xba, 0x39, 0x46, 0xc4, 0xe4, 0x63, 0xfa, 0x44, 0x20, + 0xde, 0x26, 0x94, 0x45, 0x84, 0x4b, 0x16, 0x63, 0x32, 0x8e, 0xc7, 0x14, 0xbb, 0x99, 0x65, 0x87, + 0xc0, 0xcc, 0x99, 0xb7, 0x52, 0x32, 0xa2, 0x8d, 0xb4, 0x1c, 0x65, 0x84, 0xba, 0xc9, 0xd9, 0x0d, + 0x10, 0xc7, 0xad, 0x91, 0xf6, 0x99, 0x54, 0x28, 0x9b, 0xca, 0x25, 0x43, 0x8d, 0x94, 0xac, 0xc6, + 0xd5, 0x28, 0x37, 0xd2, 0x0b, 0xc7, 0x10, 0xfa, 0xa6, 0x72, 0xd9, 0x58, 0xc7, 0x09, 0x45, 0x70, + 0x39, 0x27, 0xb5, 0xab, 0x94, 0x56, 0xfb, 0xa7, 0xa0, 0xad, 0xdc, 0x39, 0x09, 0x28, 0x6f, 0x15, + 0xcb, 0x88, 0xb5, 0x69, 0x28, 0xf4, 0x96, 0xc1, 0x6d, 0xda, 0x94, 0x35, 0xb5, 0xd2, 0x2f, 0xab, + 0x2c, 0xda, 0x81, 0xf9, 0x84, 0x5b, 0xb7, 0xde, 0x52, 0x3f, 0x02, 0x99, 0x2b, 0xb8, 0x03, 0xf3, + 0xfc, 0x9d, 0xf9, 0x19, 0x13, 0xde, 0x85, 0xf9, 0xbc, 0x7c, 0xb1, 0xe8, 0x8e, 0xd9, 0x75, 0xdb, + 0x38, 0x3d, 0xd9, 0xa2, 0xeb, 0xb5, 0xb4, 0x0b, 0x77, 0x62, 0xdd, 0x4f, 0xcb, 0x56, 0x9e, 0xc1, + 0xa4, 0x9e, 0x2b, 0x16, 0xa9, 0xac, 0x23, 0x95, 0xb9, 0xb6, 0x72, 0x25, 0xa3, 0x96, 0xef, 0x8f, + 0x4f, 0x28, 0xa3, 0x97, 0x15, 0x6a, 0xec, 0x89, 0x64, 0x2e, 0xd6, 0x8a, 0x21, 0xad, 0x0d, 0xfa, + 0x2e, 0x4c, 0xc5, 0x6f, 0x05, 0x19, 0x09, 0x03, 0x58, 0x8e, 0xbd, 0x68, 0x2a, 0x7e, 0x35, 0x78, + 0x7a, 0xf4, 0x15, 0xc1, 0xed, 0x63, 0xf4, 0x2b, 0x29, 0x6f, 0x76, 0x6d, 0x0c, 0x27, 0x61, 0xfa, + 0xca, 0xdc, 0x9e, 0x76, 0x75, 0xda, 0xf4, 0xb8, 0x99, 0xc3, 0x37, 0xa9, 0xc7, 0x2d, 0x37, 0xc4, + 0x94, 0x94, 0x30, 0x33, 0xe8, 0x3c, 0x83, 0x1b, 0x34, 0xe4, 0xc1, 0x26, 0xf6, 0x3a, 0xae, 0xb7, + 0x67, 0x86, 0xca, 0xee, 0x7b, 0x32, 0x50, 0x42, 0x17, 0xae, 0xf7, 0x8d, 0x5f, 0x85, 0xee, 0x69, + 0x41, 0x1f, 0xfa, 0x47, 0xba, 0xca, 0x7b, 0x41, 0x62, 0x0a, 0x03, 0x25, 0x3f, 0x19, 0x39, 0x11, + 0xa9, 0xe4, 0x0b, 0x92, 0xdc, 0x38, 0x52, 0x9f, 0xd3, 0xe8, 0xd8, 0xfc, 0x9b, 0x45, 0xc3, 0x98, + 0x60, 0xcf, 0xf1, 0xda, 0xb8, 0xcf, 0xed, 0xc7, 0x75, 0xfd, 0xce, 0x2f, 0x85, 0x48, 0xd5, 0x86, + 0xab, 0x5c, 0xd9, 0xc9, 0x22, 0xde, 0x9f, 0x48, 0xd6, 0xbc, 0xd4, 0x97, 0x7e, 0xfe, 0x37, 0x57, + 0x0b, 0x3f, 0xff, 0xc5, 0xd5, 0xc2, 0x7f, 0xfc, 0xc5, 0xd5, 0xc2, 0x7f, 0xfd, 0xc5, 0xd5, 0xc2, + 0x0f, 0x16, 0x4e, 0x16, 0x0c, 0xb1, 0xdd, 0x75, 0xb1, 0x17, 0xdd, 0x63, 0xe4, 0xce, 0xd3, 0xff, + 0x1e, 0xfe, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x8c, 0xb6, 0x67, 0x48, 0xd6, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -15983,6 +15998,8 @@ type AuthServiceClient interface { DeleteAllUserGroups(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) // GetHeadlessAuthentication is a request to retrieve a headless authentication from the backend. GetHeadlessAuthentication(ctx context.Context, in *GetHeadlessAuthenticationRequest, opts ...grpc.CallOption) (*types.HeadlessAuthentication, error) + // WatchPendingHeadlessAuthentications watches the backend for pending headless authentication requests for the user. + WatchPendingHeadlessAuthentications(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (AuthService_WatchPendingHeadlessAuthenticationsClient, error) // UpdateHeadlessAuthenticationState is a request to update a headless authentication's state. UpdateHeadlessAuthenticationState(ctx context.Context, in *UpdateHeadlessAuthenticationStateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) // ExportUpgradeWindows is used to load derived maintenance window values for agents that @@ -18540,6 +18557,38 @@ func (c *authServiceClient) GetHeadlessAuthentication(ctx context.Context, in *G return out, nil } +func (c *authServiceClient) WatchPendingHeadlessAuthentications(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (AuthService_WatchPendingHeadlessAuthenticationsClient, error) { + stream, err := c.cc.NewStream(ctx, &_AuthService_serviceDesc.Streams[17], "/proto.AuthService/WatchPendingHeadlessAuthentications", opts...) + if err != nil { + return nil, err + } + x := &authServiceWatchPendingHeadlessAuthenticationsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type AuthService_WatchPendingHeadlessAuthenticationsClient interface { + Recv() (*Event, error) + grpc.ClientStream +} + +type authServiceWatchPendingHeadlessAuthenticationsClient struct { + grpc.ClientStream +} + +func (x *authServiceWatchPendingHeadlessAuthenticationsClient) Recv() (*Event, error) { + m := new(Event) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func (c *authServiceClient) UpdateHeadlessAuthenticationState(ctx context.Context, in *UpdateHeadlessAuthenticationStateRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, "/proto.AuthService/UpdateHeadlessAuthenticationState", in, out, opts...) @@ -19147,6 +19196,8 @@ type AuthServiceServer interface { DeleteAllUserGroups(context.Context, *emptypb.Empty) (*emptypb.Empty, error) // GetHeadlessAuthentication is a request to retrieve a headless authentication from the backend. GetHeadlessAuthentication(context.Context, *GetHeadlessAuthenticationRequest) (*types.HeadlessAuthentication, error) + // WatchPendingHeadlessAuthentications watches the backend for pending headless authentication requests for the user. + WatchPendingHeadlessAuthentications(*emptypb.Empty, AuthService_WatchPendingHeadlessAuthenticationsServer) error // UpdateHeadlessAuthenticationState is a request to update a headless authentication's state. UpdateHeadlessAuthenticationState(context.Context, *UpdateHeadlessAuthenticationStateRequest) (*emptypb.Empty, error) // ExportUpgradeWindows is used to load derived maintenance window values for agents that @@ -19879,6 +19930,9 @@ func (*UnimplementedAuthServiceServer) DeleteAllUserGroups(ctx context.Context, func (*UnimplementedAuthServiceServer) GetHeadlessAuthentication(ctx context.Context, req *GetHeadlessAuthenticationRequest) (*types.HeadlessAuthentication, error) { return nil, status.Errorf(codes.Unimplemented, "method GetHeadlessAuthentication not implemented") } +func (*UnimplementedAuthServiceServer) WatchPendingHeadlessAuthentications(req *emptypb.Empty, srv AuthService_WatchPendingHeadlessAuthenticationsServer) error { + return status.Errorf(codes.Unimplemented, "method WatchPendingHeadlessAuthentications not implemented") +} func (*UnimplementedAuthServiceServer) UpdateHeadlessAuthenticationState(ctx context.Context, req *UpdateHeadlessAuthenticationStateRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateHeadlessAuthenticationState not implemented") } @@ -24284,6 +24338,27 @@ func _AuthService_GetHeadlessAuthentication_Handler(srv interface{}, ctx context return interceptor(ctx, in, info, handler) } +func _AuthService_WatchPendingHeadlessAuthentications_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(emptypb.Empty) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(AuthServiceServer).WatchPendingHeadlessAuthentications(m, &authServiceWatchPendingHeadlessAuthenticationsServer{stream}) +} + +type AuthService_WatchPendingHeadlessAuthenticationsServer interface { + Send(*Event) error + grpc.ServerStream +} + +type authServiceWatchPendingHeadlessAuthenticationsServer struct { + grpc.ServerStream +} + +func (x *authServiceWatchPendingHeadlessAuthenticationsServer) Send(m *Event) error { + return x.ServerStream.SendMsg(m) +} + func _AuthService_UpdateHeadlessAuthenticationState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UpdateHeadlessAuthenticationStateRequest) if err := dec(in); err != nil { @@ -25357,6 +25432,11 @@ var _AuthService_serviceDesc = grpc.ServiceDesc{ Handler: _AuthService_StreamSessionEvents_Handler, ServerStreams: true, }, + { + StreamName: "WatchPendingHeadlessAuthentications", + Handler: _AuthService_WatchPendingHeadlessAuthentications_Handler, + ServerStreams: true, + }, }, Metadata: "teleport/legacy/client/proto/authservice.proto", } @@ -26319,6 +26399,29 @@ func (m *Event_WatchStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } +func (m *Event_HeadlessAuthentication) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Event_HeadlessAuthentication) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.HeadlessAuthentication != nil { + { + size, err := m.HeadlessAuthentication.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xe2 + } + return len(dAtA) - i, nil +} func (m *Watch) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -26778,12 +26881,12 @@ func (m *UserCertsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - n49, err49 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err49 != nil { - return 0, err49 + n50, err50 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err50 != nil { + return 0, err50 } - i -= n49 - i = encodeVarintAuthservice(dAtA, i, uint64(n49)) + i -= n50 + i = encodeVarintAuthservice(dAtA, i, uint64(n50)) i-- dAtA[i] = 0x1a if len(m.Username) > 0 { @@ -28424,12 +28527,12 @@ func (m *GenerateAppTokenRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) dAtA[i] = 0x2a } } - n61, err61 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err61 != nil { - return 0, err61 + n62, err62 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err62 != nil { + return 0, err62 } - i -= n61 - i = encodeVarintAuthservice(dAtA, i, uint64(n61)) + i -= n62 + i = encodeVarintAuthservice(dAtA, i, uint64(n62)) i-- dAtA[i] = 0x22 if len(m.URI) > 0 { @@ -31998,21 +32101,21 @@ func (m *GetEventsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x22 } } - n103, err103 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndDate):]) - if err103 != nil { - return 0, err103 - } - i -= n103 - i = encodeVarintAuthservice(dAtA, i, uint64(n103)) - i-- - dAtA[i] = 0x1a - n104, err104 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartDate):]) + n104, err104 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndDate):]) if err104 != nil { return 0, err104 } i -= n104 i = encodeVarintAuthservice(dAtA, i, uint64(n104)) i-- + dAtA[i] = 0x1a + n105, err105 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartDate):]) + if err105 != nil { + return 0, err105 + } + i -= n105 + i = encodeVarintAuthservice(dAtA, i, uint64(n105)) + i-- dAtA[i] = 0x12 if len(m.Namespace) > 0 { i -= len(m.Namespace) @@ -32065,21 +32168,21 @@ func (m *GetSessionEventsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x18 } - n105, err105 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndDate):]) - if err105 != nil { - return 0, err105 - } - i -= n105 - i = encodeVarintAuthservice(dAtA, i, uint64(n105)) - i-- - dAtA[i] = 0x12 - n106, err106 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartDate):]) + n106, err106 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndDate):]) if err106 != nil { return 0, err106 } i -= n106 i = encodeVarintAuthservice(dAtA, i, uint64(n106)) i-- + dAtA[i] = 0x12 + n107, err107 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartDate):]) + if err107 != nil { + return 0, err107 + } + i -= n107 + i = encodeVarintAuthservice(dAtA, i, uint64(n107)) + i-- dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -33410,12 +33513,12 @@ func (m *RecoveryCodes) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n113, err113 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err113 != nil { - return 0, err113 + n114, err114 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err114 != nil { + return 0, err114 } - i -= n113 - i = encodeVarintAuthservice(dAtA, i, uint64(n113)) + i -= n114 + i = encodeVarintAuthservice(dAtA, i, uint64(n114)) i-- dAtA[i] = 0x12 if len(m.Codes) > 0 { @@ -34469,12 +34572,12 @@ func (m *SessionTrackerUpdateExpiry) MarshalToSizedBuffer(dAtA []byte) (int, err copy(dAtA[i:], m.XXX_unrecognized) } if m.Expires != nil { - n131, err131 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err131 != nil { - return 0, err131 + n132, err132 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err132 != nil { + return 0, err132 } - i -= n131 - i = encodeVarintAuthservice(dAtA, i, uint64(n131)) + i -= n132 + i = encodeVarintAuthservice(dAtA, i, uint64(n132)) i-- dAtA[i] = 0xa } @@ -37218,6 +37321,18 @@ func (m *Event_WatchStatus) Size() (n int) { } return n } +func (m *Event_HeadlessAuthentication) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.HeadlessAuthentication != nil { + l = m.HeadlessAuthentication.Size() + n += 2 + l + sovAuthservice(uint64(l)) + } + return n +} func (m *Watch) Size() (n int) { if m == nil { return 0 @@ -43602,6 +43717,41 @@ func (m *Event) Unmarshal(dAtA []byte) error { } m.Resource = &Event_WatchStatus{v} iNdEx = postIndex + case 44: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HeadlessAuthentication", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &types.HeadlessAuthentication{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &Event_HeadlessAuthentication{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuthservice(dAtA[iNdEx:]) diff --git a/api/client/proto/types.go b/api/client/proto/types.go index de8a094dcadd0..931f64b8c2c99 100644 --- a/api/client/proto/types.go +++ b/api/client/proto/types.go @@ -53,9 +53,13 @@ func (req *ListResourcesRequest) CheckAndSetDefaults() error { if req.Namespace == "" { req.Namespace = apidefaults.Namespace } + // If the Limit parameter was not provided instead of returning an error fallback to the default limit. + if req.Limit == 0 { + req.Limit = apidefaults.DefaultChunkSize + } - if req.Limit <= 0 { - return trace.BadParameter("nonpositive parameter limit") + if req.Limit < 0 { + return trace.BadParameter("negative parameter limit") } return nil diff --git a/api/client/webclient/webclient.go b/api/client/webclient/webclient.go index fe4cbb14b1d3e..084bce25838c2 100644 --- a/api/client/webclient/webclient.go +++ b/api/client/webclient/webclient.go @@ -41,6 +41,7 @@ import ( "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/observability/tracing" tracehttp "github.com/gravitational/teleport/api/observability/tracing/http" + "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/api/utils/keys" ) @@ -409,6 +410,9 @@ type AuthenticationSettings struct { HasMessageOfTheDay bool `json:"has_motd"` // LoadAllCAs tells tsh to load CAs for all clusters when trying to ssh into a node. LoadAllCAs bool `json:"load_all_cas,omitempty"` + // DefaultSessionTTL is the TTL requested for user certs if + // a TTL is not otherwise specified. + DefaultSessionTTL types.Duration `json:"default_session_ttl"` } // LocalSettings holds settings for local authentication. diff --git a/api/client/webclient/webconfig.go b/api/client/webclient/webconfig.go index d3de07bac26f1..cdedc2abd2281 100644 --- a/api/client/webclient/webconfig.go +++ b/api/client/webclient/webconfig.go @@ -63,6 +63,10 @@ type WebConfig struct { IsDashboard bool `json:"isDashboard,omitempty"` // IsUsageBasedBilling determines if the cloud user subscription is usage-based (pay-as-you-go). IsUsageBasedBilling bool `json:"isUsageBasedBilling,omitempty"` + // AutomaticUpgrades describes whether agents should automatically upgrade. + AutomaticUpgrades bool `json:"automaticUpgrades"` + // AssistEnabled is true when Teleport Assist is enabled. + AssistEnabled bool `json:"assistEnabled"` } // UIConfig provides config options for the web UI served by the proxy service. @@ -103,4 +107,6 @@ type WebConfigAuthSettings struct { LocalConnectorName string `json:"localConnectorName,omitempty"` // PrivateKeyPolicy is the configured private key policy for the cluster. PrivateKeyPolicy keys.PrivateKeyPolicy `json:"privateKeyPolicy,omitempty"` + // MOTD is message of the day. MOTD is displayed to users before login. + MOTD string `json:"motd"` } diff --git a/api/gen/proto/go/accesslist/v1/accesslist.pb.go b/api/gen/proto/go/accesslist/v1/accesslist.pb.go new file mode 100644 index 0000000000000..8cc33053be757 --- /dev/null +++ b/api/gen/proto/go/accesslist/v1/accesslist.pb.go @@ -0,0 +1,769 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/accesslist/v1/accesslist.proto + +package accesslist + +import ( + v1 "github.com/gravitational/teleport/api/gen/proto/go/header/v1" + v11 "github.com/gravitational/teleport/api/gen/proto/go/trait/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// AccessList describes the basic building block of access grants, which are +// similar to access requests but for longer lived permissions that need to be +// regularly audited. +type AccessList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // header is the header for the resource. + Header *v1.ResourceHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + // spec is the specification for the access list. + Spec *AccessListSpec `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (x *AccessList) Reset() { + *x = AccessList{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessList) ProtoMessage() {} + +func (x *AccessList) ProtoReflect() protoreflect.Message { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessList.ProtoReflect.Descriptor instead. +func (*AccessList) Descriptor() ([]byte, []int) { + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{0} +} + +func (x *AccessList) GetHeader() *v1.ResourceHeader { + if x != nil { + return x.Header + } + return nil +} + +func (x *AccessList) GetSpec() *AccessListSpec { + if x != nil { + return x.Spec + } + return nil +} + +// AccessListSpec is the specification for an access list. +type AccessListSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // description is a plaintext description of the access list. + Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + // owners is a list of owners of the access list. + Owners []*AccessListOwner `protobuf:"bytes,2,rep,name=owners,proto3" json:"owners,omitempty"` + // audit describes the frequency that this access list must be audited. + Audit *AccessListAudit `protobuf:"bytes,3,opt,name=audit,proto3" json:"audit,omitempty"` + // membership_requires describes the requirements for a user to be a member of the access list. + // For a membership to an access list to be effective, the user must meet the requirements of + // Membership_requires and must be in the members list. + MembershipRequires *AccessListRequires `protobuf:"bytes,4,opt,name=membership_requires,json=membershipRequires,proto3" json:"membership_requires,omitempty"` + // ownership_requires describes the requirements for a user to be an owner of the access list. + // For ownership of an access list to be effective, the user must meet the requirements of + // ownership_requires and must be in the owners list. + OwnershipRequires *AccessListRequires `protobuf:"bytes,5,opt,name=ownership_requires,json=ownershipRequires,proto3" json:"ownership_requires,omitempty"` + // grants describes the access granted by membership to this access list. + Grants *AccessListGrants `protobuf:"bytes,6,opt,name=grants,proto3" json:"grants,omitempty"` + // members describes the current members of the access list. + Members []*AccessListMember `protobuf:"bytes,7,rep,name=members,proto3" json:"members,omitempty"` +} + +func (x *AccessListSpec) Reset() { + *x = AccessListSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessListSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessListSpec) ProtoMessage() {} + +func (x *AccessListSpec) ProtoReflect() protoreflect.Message { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessListSpec.ProtoReflect.Descriptor instead. +func (*AccessListSpec) Descriptor() ([]byte, []int) { + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{1} +} + +func (x *AccessListSpec) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *AccessListSpec) GetOwners() []*AccessListOwner { + if x != nil { + return x.Owners + } + return nil +} + +func (x *AccessListSpec) GetAudit() *AccessListAudit { + if x != nil { + return x.Audit + } + return nil +} + +func (x *AccessListSpec) GetMembershipRequires() *AccessListRequires { + if x != nil { + return x.MembershipRequires + } + return nil +} + +func (x *AccessListSpec) GetOwnershipRequires() *AccessListRequires { + if x != nil { + return x.OwnershipRequires + } + return nil +} + +func (x *AccessListSpec) GetGrants() *AccessListGrants { + if x != nil { + return x.Grants + } + return nil +} + +func (x *AccessListSpec) GetMembers() []*AccessListMember { + if x != nil { + return x.Members + } + return nil +} + +// AccessListOwner is an owner of an access list. +type AccessListOwner struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the username of the owner. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // description is the plaintext description of the owner and why they are an owner. + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *AccessListOwner) Reset() { + *x = AccessListOwner{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessListOwner) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessListOwner) ProtoMessage() {} + +func (x *AccessListOwner) ProtoReflect() protoreflect.Message { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessListOwner.ProtoReflect.Descriptor instead. +func (*AccessListOwner) Descriptor() ([]byte, []int) { + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{2} +} + +func (x *AccessListOwner) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *AccessListOwner) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +// AccessListAudit describes the audit configuration for an access list. +type AccessListAudit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // frequency is a duration that describes how often an access list must be audited. + Frequency *durationpb.Duration `protobuf:"bytes,1,opt,name=frequency,proto3" json:"frequency,omitempty"` +} + +func (x *AccessListAudit) Reset() { + *x = AccessListAudit{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessListAudit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessListAudit) ProtoMessage() {} + +func (x *AccessListAudit) ProtoReflect() protoreflect.Message { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessListAudit.ProtoReflect.Descriptor instead. +func (*AccessListAudit) Descriptor() ([]byte, []int) { + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{3} +} + +func (x *AccessListAudit) GetFrequency() *durationpb.Duration { + if x != nil { + return x.Frequency + } + return nil +} + +// AccessListRequires describes a requirement section for an access list. A user must +// meet the following criteria to obtain the specific access to the list. +type AccessListRequires struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // roles are the user roles that must be present for the user to obtain access. + Roles []string `protobuf:"bytes,1,rep,name=roles,proto3" json:"roles,omitempty"` + // traits are the traits that must be present for the user to obtain access. + Traits []*v11.Trait `protobuf:"bytes,2,rep,name=traits,proto3" json:"traits,omitempty"` +} + +func (x *AccessListRequires) Reset() { + *x = AccessListRequires{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessListRequires) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessListRequires) ProtoMessage() {} + +func (x *AccessListRequires) ProtoReflect() protoreflect.Message { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessListRequires.ProtoReflect.Descriptor instead. +func (*AccessListRequires) Descriptor() ([]byte, []int) { + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{4} +} + +func (x *AccessListRequires) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *AccessListRequires) GetTraits() []*v11.Trait { + if x != nil { + return x.Traits + } + return nil +} + +// AccessListGrants describes what access is granted by membership to the access list. +type AccessListGrants struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // roles are the roles that are granted to users who are members of the access list. + Roles []string `protobuf:"bytes,1,rep,name=roles,proto3" json:"roles,omitempty"` + // traits are the traits that are granted to users who are members of the access list. + Traits []*v11.Trait `protobuf:"bytes,2,rep,name=traits,proto3" json:"traits,omitempty"` +} + +func (x *AccessListGrants) Reset() { + *x = AccessListGrants{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessListGrants) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessListGrants) ProtoMessage() {} + +func (x *AccessListGrants) ProtoReflect() protoreflect.Message { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessListGrants.ProtoReflect.Descriptor instead. +func (*AccessListGrants) Descriptor() ([]byte, []int) { + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{5} +} + +func (x *AccessListGrants) GetRoles() []string { + if x != nil { + return x.Roles + } + return nil +} + +func (x *AccessListGrants) GetTraits() []*v11.Trait { + if x != nil { + return x.Traits + } + return nil +} + +// AccessListMember describes a member of an access list. +type AccessListMember struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the name of the member of the access list. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // joined is when the user joined the access list. + Joined *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=joined,proto3" json:"joined,omitempty"` + // expires is when the user's membership to the access list expires. + Expires *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=expires,proto3" json:"expires,omitempty"` + // reason is the reason this user was added to the access list. + Reason string `protobuf:"bytes,4,opt,name=reason,proto3" json:"reason,omitempty"` + // added_by is the user that added this user to the access list. + AddedBy string `protobuf:"bytes,5,opt,name=added_by,json=addedBy,proto3" json:"added_by,omitempty"` +} + +func (x *AccessListMember) Reset() { + *x = AccessListMember{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessListMember) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessListMember) ProtoMessage() {} + +func (x *AccessListMember) ProtoReflect() protoreflect.Message { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessListMember.ProtoReflect.Descriptor instead. +func (*AccessListMember) Descriptor() ([]byte, []int) { + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{6} +} + +func (x *AccessListMember) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *AccessListMember) GetJoined() *timestamppb.Timestamp { + if x != nil { + return x.Joined + } + return nil +} + +func (x *AccessListMember) GetExpires() *timestamppb.Timestamp { + if x != nil { + return x.Expires + } + return nil +} + +func (x *AccessListMember) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *AccessListMember) GetAddedBy() string { + if x != nil { + return x.AddedBy + } + return "" +} + +var File_teleport_accesslist_v1_accesslist_proto protoreflect.FileDescriptor + +var file_teleport_accesslist_v1_accesslist_proto_rawDesc = []byte{ + 0x0a, 0x27, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, + 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x16, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x27, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x72, 0x61, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x01, 0x0a, 0x0a, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, + 0x63, 0x22, 0xf0, 0x03, 0x0a, 0x0e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x06, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x52, + 0x06, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x3d, 0x0a, 0x05, 0x61, 0x75, 0x64, 0x69, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x52, + 0x05, 0x61, 0x75, 0x64, 0x69, 0x74, 0x12, 0x5b, 0x0a, 0x13, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, + 0x12, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x73, 0x12, 0x59, 0x0a, 0x12, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, + 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, 0x11, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x12, 0x40, + 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, + 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x12, 0x42, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x22, 0x47, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, + 0x73, 0x74, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x4a, 0x0a, + 0x0f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, + 0x12, 0x37, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, + 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x5c, 0x0a, 0x12, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x74, 0x52, + 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, + 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, + 0x73, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x74, 0x72, 0x61, + 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x74, 0x52, 0x06, 0x74, 0x72, 0x61, + 0x69, 0x74, 0x73, 0x22, 0xc3, 0x01, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x06, + 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, + 0x12, 0x34, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x19, + 0x0a, 0x08, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x64, 0x64, 0x65, 0x64, 0x42, 0x79, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_accesslist_v1_accesslist_proto_rawDescOnce sync.Once + file_teleport_accesslist_v1_accesslist_proto_rawDescData = file_teleport_accesslist_v1_accesslist_proto_rawDesc +) + +func file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP() []byte { + file_teleport_accesslist_v1_accesslist_proto_rawDescOnce.Do(func() { + file_teleport_accesslist_v1_accesslist_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_accesslist_v1_accesslist_proto_rawDescData) + }) + return file_teleport_accesslist_v1_accesslist_proto_rawDescData +} + +var file_teleport_accesslist_v1_accesslist_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_teleport_accesslist_v1_accesslist_proto_goTypes = []interface{}{ + (*AccessList)(nil), // 0: teleport.accesslist.v1.AccessList + (*AccessListSpec)(nil), // 1: teleport.accesslist.v1.AccessListSpec + (*AccessListOwner)(nil), // 2: teleport.accesslist.v1.AccessListOwner + (*AccessListAudit)(nil), // 3: teleport.accesslist.v1.AccessListAudit + (*AccessListRequires)(nil), // 4: teleport.accesslist.v1.AccessListRequires + (*AccessListGrants)(nil), // 5: teleport.accesslist.v1.AccessListGrants + (*AccessListMember)(nil), // 6: teleport.accesslist.v1.AccessListMember + (*v1.ResourceHeader)(nil), // 7: teleport.header.v1.ResourceHeader + (*durationpb.Duration)(nil), // 8: google.protobuf.Duration + (*v11.Trait)(nil), // 9: teleport.trait.v1.Trait + (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp +} +var file_teleport_accesslist_v1_accesslist_proto_depIdxs = []int32{ + 7, // 0: teleport.accesslist.v1.AccessList.header:type_name -> teleport.header.v1.ResourceHeader + 1, // 1: teleport.accesslist.v1.AccessList.spec:type_name -> teleport.accesslist.v1.AccessListSpec + 2, // 2: teleport.accesslist.v1.AccessListSpec.owners:type_name -> teleport.accesslist.v1.AccessListOwner + 3, // 3: teleport.accesslist.v1.AccessListSpec.audit:type_name -> teleport.accesslist.v1.AccessListAudit + 4, // 4: teleport.accesslist.v1.AccessListSpec.membership_requires:type_name -> teleport.accesslist.v1.AccessListRequires + 4, // 5: teleport.accesslist.v1.AccessListSpec.ownership_requires:type_name -> teleport.accesslist.v1.AccessListRequires + 5, // 6: teleport.accesslist.v1.AccessListSpec.grants:type_name -> teleport.accesslist.v1.AccessListGrants + 6, // 7: teleport.accesslist.v1.AccessListSpec.members:type_name -> teleport.accesslist.v1.AccessListMember + 8, // 8: teleport.accesslist.v1.AccessListAudit.frequency:type_name -> google.protobuf.Duration + 9, // 9: teleport.accesslist.v1.AccessListRequires.traits:type_name -> teleport.trait.v1.Trait + 9, // 10: teleport.accesslist.v1.AccessListGrants.traits:type_name -> teleport.trait.v1.Trait + 10, // 11: teleport.accesslist.v1.AccessListMember.joined:type_name -> google.protobuf.Timestamp + 10, // 12: teleport.accesslist.v1.AccessListMember.expires:type_name -> google.protobuf.Timestamp + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name +} + +func init() { file_teleport_accesslist_v1_accesslist_proto_init() } +func file_teleport_accesslist_v1_accesslist_proto_init() { + if File_teleport_accesslist_v1_accesslist_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_accesslist_v1_accesslist_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_accesslist_v1_accesslist_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessListSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_accesslist_v1_accesslist_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessListOwner); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_accesslist_v1_accesslist_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessListAudit); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_accesslist_v1_accesslist_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessListRequires); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_accesslist_v1_accesslist_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessListGrants); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_accesslist_v1_accesslist_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessListMember); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_accesslist_v1_accesslist_proto_rawDesc, + NumEnums: 0, + NumMessages: 7, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_accesslist_v1_accesslist_proto_goTypes, + DependencyIndexes: file_teleport_accesslist_v1_accesslist_proto_depIdxs, + MessageInfos: file_teleport_accesslist_v1_accesslist_proto_msgTypes, + }.Build() + File_teleport_accesslist_v1_accesslist_proto = out.File + file_teleport_accesslist_v1_accesslist_proto_rawDesc = nil + file_teleport_accesslist_v1_accesslist_proto_goTypes = nil + file_teleport_accesslist_v1_accesslist_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/assist/v1/assist.pb.go b/api/gen/proto/go/assist/v1/assist.pb.go index cbc94ac60bcd3..a4d8f30d25dfd 100644 --- a/api/gen/proto/go/assist/v1/assist.pb.go +++ b/api/gen/proto/go/assist/v1/assist.pb.go @@ -765,6 +765,199 @@ func (x *DeleteAssistantConversationRequest) GetUsername() string { return "" } +// GetAssistantEmbeddingsRequest is a request to get embeddings. +type GetAssistantEmbeddingsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // username is a username of the user who requested the embeddings. + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + // query is the query used for similarity search. + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + // limit is the number of embeddings to return (also known as k). + Limit uint32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` + // kind is the kind of embeddings to return (ex, node). + Kind string `protobuf:"bytes,4,opt,name=kind,proto3" json:"kind,omitempty"` +} + +func (x *GetAssistantEmbeddingsRequest) Reset() { + *x = GetAssistantEmbeddingsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_assist_v1_assist_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAssistantEmbeddingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAssistantEmbeddingsRequest) ProtoMessage() {} + +func (x *GetAssistantEmbeddingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_assist_v1_assist_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAssistantEmbeddingsRequest.ProtoReflect.Descriptor instead. +func (*GetAssistantEmbeddingsRequest) Descriptor() ([]byte, []int) { + return file_teleport_assist_v1_assist_proto_rawDescGZIP(), []int{13} +} + +func (x *GetAssistantEmbeddingsRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *GetAssistantEmbeddingsRequest) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +func (x *GetAssistantEmbeddingsRequest) GetLimit() uint32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *GetAssistantEmbeddingsRequest) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +// EmbeddingDocument is a document with an embedding. +type EmbeddedDocument struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // id is the id of the document. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // content is the content of the document. + Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` + // similarityScore is the similarity score of the document. + SimilarityScore float32 `protobuf:"fixed32,3,opt,name=similarity_score,json=similarityScore,proto3" json:"similarity_score,omitempty"` +} + +func (x *EmbeddedDocument) Reset() { + *x = EmbeddedDocument{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_assist_v1_assist_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EmbeddedDocument) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmbeddedDocument) ProtoMessage() {} + +func (x *EmbeddedDocument) ProtoReflect() protoreflect.Message { + mi := &file_teleport_assist_v1_assist_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmbeddedDocument.ProtoReflect.Descriptor instead. +func (*EmbeddedDocument) Descriptor() ([]byte, []int) { + return file_teleport_assist_v1_assist_proto_rawDescGZIP(), []int{14} +} + +func (x *EmbeddedDocument) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *EmbeddedDocument) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *EmbeddedDocument) GetSimilarityScore() float32 { + if x != nil { + return x.SimilarityScore + } + return 0 +} + +// GetAssistantEmbeddingsResponse is a response from the assistant service. +type GetAssistantEmbeddingsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // embeddings is the list of embeddings. + // The list is sorted by similarity score in descending order. + Embeddings []*EmbeddedDocument `protobuf:"bytes,1,rep,name=embeddings,proto3" json:"embeddings,omitempty"` +} + +func (x *GetAssistantEmbeddingsResponse) Reset() { + *x = GetAssistantEmbeddingsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_assist_v1_assist_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAssistantEmbeddingsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAssistantEmbeddingsResponse) ProtoMessage() {} + +func (x *GetAssistantEmbeddingsResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_assist_v1_assist_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAssistantEmbeddingsResponse.ProtoReflect.Descriptor instead. +func (*GetAssistantEmbeddingsResponse) Descriptor() ([]byte, []int) { + return file_teleport_assist_v1_assist_proto_rawDescGZIP(), []int{15} +} + +func (x *GetAssistantEmbeddingsResponse) GetEmbeddings() []*EmbeddedDocument { + if x != nil { + return x.Embeddings + } + return nil +} + var File_teleport_assist_v1_assist_proto protoreflect.FileDescriptor var file_teleport_assist_v1_assist_proto_rawDesc = []byte{ @@ -856,66 +1049,96 @@ var file_teleport_assist_v1_assist_proto_rawDesc = []byte{ 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x32, 0xdd, 0x06, 0x0a, 0x0d, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, - 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x73, + 0x61, 0x6d, 0x65, 0x22, 0x7b, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x22, 0x67, 0x0a, 0x10, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x44, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x29, + 0x0a, 0x10, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x63, 0x6f, + 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0f, 0x73, 0x69, 0x6d, 0x69, 0x6c, 0x61, + 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x22, 0x66, 0x0a, 0x1e, 0x47, 0x65, 0x74, + 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x65, + 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x44, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x73, 0x32, 0xdd, 0x06, 0x0a, 0x0d, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, - 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x6d, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, + 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, + 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, + 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x79, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6e, 0x73, 0x12, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, + 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, + 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x6d, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x79, + 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x16, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, + 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, + 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x75, + 0x0a, 0x1f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x3a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, + 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, + 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x6a, 0x0a, 0x0f, 0x49, 0x73, 0x41, 0x73, 0x73, 0x69, 0x73, + 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, + 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x41, 0x73, 0x73, 0x69, + 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x32, 0x99, 0x01, 0x0a, 0x16, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x6d, 0x62, 0x65, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7f, 0x0a, 0x16, + 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x16, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x75, 0x0a, 0x1f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, - 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x3a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, - 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x6a, 0x0a, 0x0f, 0x49, 0x73, 0x41, 0x73, 0x73, - 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x49, 0x73, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x41, 0x73, - 0x73, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, - 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x65, 0x74, 0x41, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x45, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x45, 0x5a, + 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x73, + 0x73, 0x69, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -930,7 +1153,7 @@ func file_teleport_assist_v1_assist_proto_rawDescGZIP() []byte { return file_teleport_assist_v1_assist_proto_rawDescData } -var file_teleport_assist_v1_assist_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_teleport_assist_v1_assist_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_teleport_assist_v1_assist_proto_goTypes = []interface{}{ (*GetAssistantMessagesRequest)(nil), // 0: teleport.assist.v1.GetAssistantMessagesRequest (*AssistantMessage)(nil), // 1: teleport.assist.v1.AssistantMessage @@ -945,35 +1168,41 @@ var file_teleport_assist_v1_assist_proto_goTypes = []interface{}{ (*IsAssistEnabledRequest)(nil), // 10: teleport.assist.v1.IsAssistEnabledRequest (*IsAssistEnabledResponse)(nil), // 11: teleport.assist.v1.IsAssistEnabledResponse (*DeleteAssistantConversationRequest)(nil), // 12: teleport.assist.v1.DeleteAssistantConversationRequest - (*timestamppb.Timestamp)(nil), // 13: google.protobuf.Timestamp - (*emptypb.Empty)(nil), // 14: google.protobuf.Empty + (*GetAssistantEmbeddingsRequest)(nil), // 13: teleport.assist.v1.GetAssistantEmbeddingsRequest + (*EmbeddedDocument)(nil), // 14: teleport.assist.v1.EmbeddedDocument + (*GetAssistantEmbeddingsResponse)(nil), // 15: teleport.assist.v1.GetAssistantEmbeddingsResponse + (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp + (*emptypb.Empty)(nil), // 17: google.protobuf.Empty } var file_teleport_assist_v1_assist_proto_depIdxs = []int32{ - 13, // 0: teleport.assist.v1.AssistantMessage.created_time:type_name -> google.protobuf.Timestamp + 16, // 0: teleport.assist.v1.AssistantMessage.created_time:type_name -> google.protobuf.Timestamp 1, // 1: teleport.assist.v1.CreateAssistantMessageRequest.message:type_name -> teleport.assist.v1.AssistantMessage 1, // 2: teleport.assist.v1.GetAssistantMessagesResponse.messages:type_name -> teleport.assist.v1.AssistantMessage - 13, // 3: teleport.assist.v1.ConversationInfo.created_time:type_name -> google.protobuf.Timestamp + 16, // 3: teleport.assist.v1.ConversationInfo.created_time:type_name -> google.protobuf.Timestamp 5, // 4: teleport.assist.v1.GetAssistantConversationsResponse.conversations:type_name -> teleport.assist.v1.ConversationInfo - 13, // 5: teleport.assist.v1.CreateAssistantConversationRequest.created_time:type_name -> google.protobuf.Timestamp - 7, // 6: teleport.assist.v1.AssistService.CreateAssistantConversation:input_type -> teleport.assist.v1.CreateAssistantConversationRequest - 4, // 7: teleport.assist.v1.AssistService.GetAssistantConversations:input_type -> teleport.assist.v1.GetAssistantConversationsRequest - 12, // 8: teleport.assist.v1.AssistService.DeleteAssistantConversation:input_type -> teleport.assist.v1.DeleteAssistantConversationRequest - 0, // 9: teleport.assist.v1.AssistService.GetAssistantMessages:input_type -> teleport.assist.v1.GetAssistantMessagesRequest - 2, // 10: teleport.assist.v1.AssistService.CreateAssistantMessage:input_type -> teleport.assist.v1.CreateAssistantMessageRequest - 9, // 11: teleport.assist.v1.AssistService.UpdateAssistantConversationInfo:input_type -> teleport.assist.v1.UpdateAssistantConversationInfoRequest - 10, // 12: teleport.assist.v1.AssistService.IsAssistEnabled:input_type -> teleport.assist.v1.IsAssistEnabledRequest - 8, // 13: teleport.assist.v1.AssistService.CreateAssistantConversation:output_type -> teleport.assist.v1.CreateAssistantConversationResponse - 6, // 14: teleport.assist.v1.AssistService.GetAssistantConversations:output_type -> teleport.assist.v1.GetAssistantConversationsResponse - 14, // 15: teleport.assist.v1.AssistService.DeleteAssistantConversation:output_type -> google.protobuf.Empty - 3, // 16: teleport.assist.v1.AssistService.GetAssistantMessages:output_type -> teleport.assist.v1.GetAssistantMessagesResponse - 14, // 17: teleport.assist.v1.AssistService.CreateAssistantMessage:output_type -> google.protobuf.Empty - 14, // 18: teleport.assist.v1.AssistService.UpdateAssistantConversationInfo:output_type -> google.protobuf.Empty - 11, // 19: teleport.assist.v1.AssistService.IsAssistEnabled:output_type -> teleport.assist.v1.IsAssistEnabledResponse - 13, // [13:20] is the sub-list for method output_type - 6, // [6:13] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 16, // 5: teleport.assist.v1.CreateAssistantConversationRequest.created_time:type_name -> google.protobuf.Timestamp + 14, // 6: teleport.assist.v1.GetAssistantEmbeddingsResponse.embeddings:type_name -> teleport.assist.v1.EmbeddedDocument + 7, // 7: teleport.assist.v1.AssistService.CreateAssistantConversation:input_type -> teleport.assist.v1.CreateAssistantConversationRequest + 4, // 8: teleport.assist.v1.AssistService.GetAssistantConversations:input_type -> teleport.assist.v1.GetAssistantConversationsRequest + 12, // 9: teleport.assist.v1.AssistService.DeleteAssistantConversation:input_type -> teleport.assist.v1.DeleteAssistantConversationRequest + 0, // 10: teleport.assist.v1.AssistService.GetAssistantMessages:input_type -> teleport.assist.v1.GetAssistantMessagesRequest + 2, // 11: teleport.assist.v1.AssistService.CreateAssistantMessage:input_type -> teleport.assist.v1.CreateAssistantMessageRequest + 9, // 12: teleport.assist.v1.AssistService.UpdateAssistantConversationInfo:input_type -> teleport.assist.v1.UpdateAssistantConversationInfoRequest + 10, // 13: teleport.assist.v1.AssistService.IsAssistEnabled:input_type -> teleport.assist.v1.IsAssistEnabledRequest + 13, // 14: teleport.assist.v1.AssistEmbeddingService.GetAssistantEmbeddings:input_type -> teleport.assist.v1.GetAssistantEmbeddingsRequest + 8, // 15: teleport.assist.v1.AssistService.CreateAssistantConversation:output_type -> teleport.assist.v1.CreateAssistantConversationResponse + 6, // 16: teleport.assist.v1.AssistService.GetAssistantConversations:output_type -> teleport.assist.v1.GetAssistantConversationsResponse + 17, // 17: teleport.assist.v1.AssistService.DeleteAssistantConversation:output_type -> google.protobuf.Empty + 3, // 18: teleport.assist.v1.AssistService.GetAssistantMessages:output_type -> teleport.assist.v1.GetAssistantMessagesResponse + 17, // 19: teleport.assist.v1.AssistService.CreateAssistantMessage:output_type -> google.protobuf.Empty + 17, // 20: teleport.assist.v1.AssistService.UpdateAssistantConversationInfo:output_type -> google.protobuf.Empty + 11, // 21: teleport.assist.v1.AssistService.IsAssistEnabled:output_type -> teleport.assist.v1.IsAssistEnabledResponse + 15, // 22: teleport.assist.v1.AssistEmbeddingService.GetAssistantEmbeddings:output_type -> teleport.assist.v1.GetAssistantEmbeddingsResponse + 15, // [15:23] is the sub-list for method output_type + 7, // [7:15] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_teleport_assist_v1_assist_proto_init() } @@ -1138,6 +1367,42 @@ func file_teleport_assist_v1_assist_proto_init() { return nil } } + file_teleport_assist_v1_assist_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAssistantEmbeddingsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_assist_v1_assist_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EmbeddedDocument); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_assist_v1_assist_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAssistantEmbeddingsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1145,9 +1410,9 @@ func file_teleport_assist_v1_assist_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_assist_v1_assist_proto_rawDesc, NumEnums: 0, - NumMessages: 13, + NumMessages: 16, NumExtensions: 0, - NumServices: 1, + NumServices: 2, }, GoTypes: file_teleport_assist_v1_assist_proto_goTypes, DependencyIndexes: file_teleport_assist_v1_assist_proto_depIdxs, diff --git a/api/gen/proto/go/assist/v1/assist_grpc.pb.go b/api/gen/proto/go/assist/v1/assist_grpc.pb.go index ccf7a2eef4df0..cb399e7316958 100644 --- a/api/gen/proto/go/assist/v1/assist_grpc.pb.go +++ b/api/gen/proto/go/assist/v1/assist_grpc.pb.go @@ -358,3 +358,96 @@ var AssistService_ServiceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "teleport/assist/v1/assist.proto", } + +const ( + AssistEmbeddingService_GetAssistantEmbeddings_FullMethodName = "/teleport.assist.v1.AssistEmbeddingService/GetAssistantEmbeddings" +) + +// AssistEmbeddingServiceClient is the client API for AssistEmbeddingService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AssistEmbeddingServiceClient interface { + // AssistantGetEmbeddings returns the embeddings for the given query. + GetAssistantEmbeddings(ctx context.Context, in *GetAssistantEmbeddingsRequest, opts ...grpc.CallOption) (*GetAssistantEmbeddingsResponse, error) +} + +type assistEmbeddingServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAssistEmbeddingServiceClient(cc grpc.ClientConnInterface) AssistEmbeddingServiceClient { + return &assistEmbeddingServiceClient{cc} +} + +func (c *assistEmbeddingServiceClient) GetAssistantEmbeddings(ctx context.Context, in *GetAssistantEmbeddingsRequest, opts ...grpc.CallOption) (*GetAssistantEmbeddingsResponse, error) { + out := new(GetAssistantEmbeddingsResponse) + err := c.cc.Invoke(ctx, AssistEmbeddingService_GetAssistantEmbeddings_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AssistEmbeddingServiceServer is the server API for AssistEmbeddingService service. +// All implementations must embed UnimplementedAssistEmbeddingServiceServer +// for forward compatibility +type AssistEmbeddingServiceServer interface { + // AssistantGetEmbeddings returns the embeddings for the given query. + GetAssistantEmbeddings(context.Context, *GetAssistantEmbeddingsRequest) (*GetAssistantEmbeddingsResponse, error) + mustEmbedUnimplementedAssistEmbeddingServiceServer() +} + +// UnimplementedAssistEmbeddingServiceServer must be embedded to have forward compatible implementations. +type UnimplementedAssistEmbeddingServiceServer struct { +} + +func (UnimplementedAssistEmbeddingServiceServer) GetAssistantEmbeddings(context.Context, *GetAssistantEmbeddingsRequest) (*GetAssistantEmbeddingsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAssistantEmbeddings not implemented") +} +func (UnimplementedAssistEmbeddingServiceServer) mustEmbedUnimplementedAssistEmbeddingServiceServer() { +} + +// UnsafeAssistEmbeddingServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AssistEmbeddingServiceServer will +// result in compilation errors. +type UnsafeAssistEmbeddingServiceServer interface { + mustEmbedUnimplementedAssistEmbeddingServiceServer() +} + +func RegisterAssistEmbeddingServiceServer(s grpc.ServiceRegistrar, srv AssistEmbeddingServiceServer) { + s.RegisterService(&AssistEmbeddingService_ServiceDesc, srv) +} + +func _AssistEmbeddingService_GetAssistantEmbeddings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAssistantEmbeddingsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AssistEmbeddingServiceServer).GetAssistantEmbeddings(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AssistEmbeddingService_GetAssistantEmbeddings_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AssistEmbeddingServiceServer).GetAssistantEmbeddings(ctx, req.(*GetAssistantEmbeddingsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AssistEmbeddingService_ServiceDesc is the grpc.ServiceDesc for AssistEmbeddingService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AssistEmbeddingService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "teleport.assist.v1.AssistEmbeddingService", + HandlerType: (*AssistEmbeddingServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAssistantEmbeddings", + Handler: _AssistEmbeddingService_GetAssistantEmbeddings_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "teleport/assist/v1/assist.proto", +} diff --git a/api/gen/proto/go/header/v1/metadata.pb.go b/api/gen/proto/go/header/v1/metadata.pb.go new file mode 100644 index 0000000000000..de5469c1fabf4 --- /dev/null +++ b/api/gen/proto/go/header/v1/metadata.pb.go @@ -0,0 +1,233 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/header/v1/metadata.proto + +package header + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Metadata is resource metadata. +type Metadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is an object name. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // namespace is object namespace. The field should be called "namespace" + // when it returns in Teleport 2.4. + Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` + // description is object description. + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // labels is a set of labels. + Labels map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // expires is a global expiry time header can be set on any resource in the + // system. + Expires *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=expires,proto3" json:"expires,omitempty"` + // ID is a record ID + Id int64 `protobuf:"varint,7,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *Metadata) Reset() { + *x = Metadata{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_header_v1_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Metadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Metadata) ProtoMessage() {} + +func (x *Metadata) ProtoReflect() protoreflect.Message { + mi := &file_teleport_header_v1_metadata_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. +func (*Metadata) Descriptor() ([]byte, []int) { + return file_teleport_header_v1_metadata_proto_rawDescGZIP(), []int{0} +} + +func (x *Metadata) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Metadata) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *Metadata) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Metadata) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Metadata) GetExpires() *timestamppb.Timestamp { + if x != nil { + return x.Expires + } + return nil +} + +func (x *Metadata) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +var File_teleport_header_v1_metadata_proto protoreflect.FileDescriptor + +var file_teleport_header_v1_metadata_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa1, 0x02, 0x0a, 0x08, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x06, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, + 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, + 0x64, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x45, 0x5a, 0x43, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x67, 0x6f, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_header_v1_metadata_proto_rawDescOnce sync.Once + file_teleport_header_v1_metadata_proto_rawDescData = file_teleport_header_v1_metadata_proto_rawDesc +) + +func file_teleport_header_v1_metadata_proto_rawDescGZIP() []byte { + file_teleport_header_v1_metadata_proto_rawDescOnce.Do(func() { + file_teleport_header_v1_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_header_v1_metadata_proto_rawDescData) + }) + return file_teleport_header_v1_metadata_proto_rawDescData +} + +var file_teleport_header_v1_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_teleport_header_v1_metadata_proto_goTypes = []interface{}{ + (*Metadata)(nil), // 0: teleport.header.v1.Metadata + nil, // 1: teleport.header.v1.Metadata.LabelsEntry + (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp +} +var file_teleport_header_v1_metadata_proto_depIdxs = []int32{ + 1, // 0: teleport.header.v1.Metadata.labels:type_name -> teleport.header.v1.Metadata.LabelsEntry + 2, // 1: teleport.header.v1.Metadata.expires:type_name -> google.protobuf.Timestamp + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_teleport_header_v1_metadata_proto_init() } +func file_teleport_header_v1_metadata_proto_init() { + if File_teleport_header_v1_metadata_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_header_v1_metadata_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Metadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_header_v1_metadata_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_header_v1_metadata_proto_goTypes, + DependencyIndexes: file_teleport_header_v1_metadata_proto_depIdxs, + MessageInfos: file_teleport_header_v1_metadata_proto_msgTypes, + }.Build() + File_teleport_header_v1_metadata_proto = out.File + file_teleport_header_v1_metadata_proto_rawDesc = nil + file_teleport_header_v1_metadata_proto_goTypes = nil + file_teleport_header_v1_metadata_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/header/v1/resourceheader.pb.go b/api/gen/proto/go/header/v1/resourceheader.pb.go new file mode 100644 index 0000000000000..21fabebb417ad --- /dev/null +++ b/api/gen/proto/go/header/v1/resourceheader.pb.go @@ -0,0 +1,203 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/header/v1/resourceheader.proto + +package header + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// ResourceHeader is a shared resource header. +type ResourceHeader struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // kind is a resource kind. + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + // sub_kind is an optional resource sub kind, used in some resources. + SubKind string `protobuf:"bytes,2,opt,name=sub_kind,json=subKind,proto3" json:"sub_kind,omitempty"` + // version is version. + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + // metadata is resource metadata. + Metadata *Metadata `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *ResourceHeader) Reset() { + *x = ResourceHeader{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_header_v1_resourceheader_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceHeader) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceHeader) ProtoMessage() {} + +func (x *ResourceHeader) ProtoReflect() protoreflect.Message { + mi := &file_teleport_header_v1_resourceheader_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceHeader.ProtoReflect.Descriptor instead. +func (*ResourceHeader) Descriptor() ([]byte, []int) { + return file_teleport_header_v1_resourceheader_proto_rawDescGZIP(), []int{0} +} + +func (x *ResourceHeader) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *ResourceHeader) GetSubKind() string { + if x != nil { + return x.SubKind + } + return "" +} + +func (x *ResourceHeader) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ResourceHeader) GetMetadata() *Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +var File_teleport_header_v1_resourceheader_proto protoreflect.FileDescriptor + +var file_teleport_header_v1_resourceheader_proto_rawDesc = []byte{ + 0x0a, 0x27, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x21, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x76, + 0x31, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x93, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, + 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, + 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_header_v1_resourceheader_proto_rawDescOnce sync.Once + file_teleport_header_v1_resourceheader_proto_rawDescData = file_teleport_header_v1_resourceheader_proto_rawDesc +) + +func file_teleport_header_v1_resourceheader_proto_rawDescGZIP() []byte { + file_teleport_header_v1_resourceheader_proto_rawDescOnce.Do(func() { + file_teleport_header_v1_resourceheader_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_header_v1_resourceheader_proto_rawDescData) + }) + return file_teleport_header_v1_resourceheader_proto_rawDescData +} + +var file_teleport_header_v1_resourceheader_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_header_v1_resourceheader_proto_goTypes = []interface{}{ + (*ResourceHeader)(nil), // 0: teleport.header.v1.ResourceHeader + (*Metadata)(nil), // 1: teleport.header.v1.Metadata +} +var file_teleport_header_v1_resourceheader_proto_depIdxs = []int32{ + 1, // 0: teleport.header.v1.ResourceHeader.metadata:type_name -> teleport.header.v1.Metadata + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_teleport_header_v1_resourceheader_proto_init() } +func file_teleport_header_v1_resourceheader_proto_init() { + if File_teleport_header_v1_resourceheader_proto != nil { + return + } + file_teleport_header_v1_metadata_proto_init() + if !protoimpl.UnsafeEnabled { + file_teleport_header_v1_resourceheader_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceHeader); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_header_v1_resourceheader_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_header_v1_resourceheader_proto_goTypes, + DependencyIndexes: file_teleport_header_v1_resourceheader_proto_depIdxs, + MessageInfos: file_teleport_header_v1_resourceheader_proto_msgTypes, + }.Build() + File_teleport_header_v1_resourceheader_proto = out.File + file_teleport_header_v1_resourceheader_proto_rawDesc = nil + file_teleport_header_v1_resourceheader_proto_goTypes = nil + file_teleport_header_v1_resourceheader_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/devicetrust/v1/device_collected_data.pb.go b/api/gen/proto/go/teleport/devicetrust/v1/device_collected_data.pb.go index fb5410b913327..44c405f0a12d7 100644 --- a/api/gen/proto/go/teleport/devicetrust/v1/device_collected_data.pb.go +++ b/api/gen/proto/go/teleport/devicetrust/v1/device_collected_data.pb.go @@ -87,6 +87,19 @@ type DeviceCollectedData struct { // The serial number of the "base board" as reported by BIOS DMI Type 2. // This field can be empty if no value has been configured. BaseBoardSerialNumber string `protobuf:"bytes,13,opt,name=base_board_serial_number,json=baseBoardSerialNumber,proto3" json:"base_board_serial_number,omitempty"` + // If during the collection of this device data, the device performed a TPM + // platform attestation (e.g during enrollment or authentication), then this + // field holds the record of this attestation. This allows the state of the + // device to be compared to historical state, and allows for the platform + // attestations to be revalidated at a later date. + // + // This field is not explicitly sent up by the client, and any DCD sent by a + // client including this field should be rejected. The server should inject + // this field once verifying that the submitted platform attestation during + // the enrollment or authentication. + // + // System managed. + TpmPlatformAttestation *TPMPlatformAttestation `protobuf:"bytes,14,opt,name=tpm_platform_attestation,json=tpmPlatformAttestation,proto3" json:"tpm_platform_attestation,omitempty"` } func (x *DeviceCollectedData) Reset() { @@ -212,6 +225,13 @@ func (x *DeviceCollectedData) GetBaseBoardSerialNumber() string { return "" } +func (x *DeviceCollectedData) GetTpmPlatformAttestation() *TPMPlatformAttestation { + if x != nil { + return x.TpmPlatformAttestation + } + return nil +} + var File_teleport_devicetrust_v1_device_collected_data_proto protoreflect.FileDescriptor var file_teleport_devicetrust_v1_device_collected_data_proto_rawDesc = []byte{ @@ -224,53 +244,62 @@ var file_teleport_devicetrust_v1_device_collected_data_proto_rawDesc = []byte{ 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x25, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfb, 0x04, 0x0a, 0x13, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x12, 0x3d, - 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, - 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, - 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x6f, 0x73, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x6f, 0x73, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x72, - 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x6d, 0x6f, 0x64, - 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x73, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x73, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x1f, - 0x0a, 0x0b, 0x6f, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x73, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x2e, 0x0a, 0x13, 0x6a, 0x61, 0x6d, 0x66, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6a, 0x61, - 0x6d, 0x66, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x3a, 0x0a, 0x19, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, - 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x17, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, - 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x74, 0x61, - 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x61, 0x67, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, - 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x18, 0x62, - 0x61, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, - 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x62, - 0x61, 0x73, 0x65, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, - 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, - 0x76, 0x31, 0x3b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, + 0x74, 0x70, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x05, 0x0a, 0x13, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, + 0x07, 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x06, 0x6f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x73, 0x5f, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x73, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x73, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x6a, 0x61, 0x6d, 0x66, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, + 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x6a, 0x61, 0x6d, 0x66, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x19, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x65, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x45, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2c, + 0x0a, 0x12, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x74, + 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x54, 0x61, 0x67, 0x12, 0x30, 0x0a, 0x14, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x37, + 0x0a, 0x18, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x73, 0x65, 0x72, + 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x15, 0x62, 0x61, 0x73, 0x65, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x69, 0x0a, 0x18, 0x74, 0x70, 0x6d, 0x5f, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x41, + 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x16, 0x74, 0x70, 0x6d, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, + 0x3b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -287,19 +316,21 @@ func file_teleport_devicetrust_v1_device_collected_data_proto_rawDescGZIP() []by var file_teleport_devicetrust_v1_device_collected_data_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_teleport_devicetrust_v1_device_collected_data_proto_goTypes = []interface{}{ - (*DeviceCollectedData)(nil), // 0: teleport.devicetrust.v1.DeviceCollectedData - (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp - (OSType)(0), // 2: teleport.devicetrust.v1.OSType + (*DeviceCollectedData)(nil), // 0: teleport.devicetrust.v1.DeviceCollectedData + (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp + (OSType)(0), // 2: teleport.devicetrust.v1.OSType + (*TPMPlatformAttestation)(nil), // 3: teleport.devicetrust.v1.TPMPlatformAttestation } var file_teleport_devicetrust_v1_device_collected_data_proto_depIdxs = []int32{ 1, // 0: teleport.devicetrust.v1.DeviceCollectedData.collect_time:type_name -> google.protobuf.Timestamp 1, // 1: teleport.devicetrust.v1.DeviceCollectedData.record_time:type_name -> google.protobuf.Timestamp 2, // 2: teleport.devicetrust.v1.DeviceCollectedData.os_type:type_name -> teleport.devicetrust.v1.OSType - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 3, // 3: teleport.devicetrust.v1.DeviceCollectedData.tpm_platform_attestation:type_name -> teleport.devicetrust.v1.TPMPlatformAttestation + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_teleport_devicetrust_v1_device_collected_data_proto_init() } @@ -308,6 +339,7 @@ func file_teleport_devicetrust_v1_device_collected_data_proto_init() { return } file_teleport_devicetrust_v1_os_type_proto_init() + file_teleport_devicetrust_v1_tpm_proto_init() if !protoimpl.UnsafeEnabled { file_teleport_devicetrust_v1_device_collected_data_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeviceCollectedData); i { diff --git a/api/gen/proto/go/teleport/devicetrust/v1/device_profile.pb.go b/api/gen/proto/go/teleport/devicetrust/v1/device_profile.pb.go index 36a2553e4a583..9f19843c48127 100644 --- a/api/gen/proto/go/teleport/devicetrust/v1/device_profile.pb.go +++ b/api/gen/proto/go/teleport/devicetrust/v1/device_profile.pb.go @@ -60,6 +60,8 @@ type DeviceProfile struct { // Jamf binary version, without the leading 'v'. // Example: "9.27" or "10.44.1-t1677509507". JamfBinaryVersion string `protobuf:"bytes,6,opt,name=jamf_binary_version,json=jamfBinaryVersion,proto3" json:"jamf_binary_version,omitempty"` + // External device identifier, for example the Jamf or Intune ID. + ExternalId string `protobuf:"bytes,7,opt,name=external_id,json=externalId,proto3" json:"external_id,omitempty"` } func (x *DeviceProfile) Reset() { @@ -136,6 +138,13 @@ func (x *DeviceProfile) GetJamfBinaryVersion() string { return "" } +func (x *DeviceProfile) GetExternalId() string { + if x != nil { + return x.ExternalId + } + return "" +} + var File_teleport_devicetrust_v1_device_profile_proto protoreflect.FileDescriptor var file_teleport_devicetrust_v1_device_profile_proto_rawDesc = []byte{ @@ -145,7 +154,7 @@ var file_teleport_devicetrust_v1_device_profile_proto_rawDesc = []byte{ 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x02, 0x0a, 0x0d, 0x44, 0x65, 0x76, + 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa5, 0x02, 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, @@ -161,14 +170,16 @@ var file_teleport_devicetrust_v1_device_profile_proto_rawDesc = []byte{ 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x73, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6a, 0x61, 0x6d, 0x66, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6a, 0x61, - 0x6d, 0x66, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, - 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, - 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x6d, 0x66, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, + 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/gen/proto/go/teleport/devicetrust/v1/devicetrust_service.pb.go b/api/gen/proto/go/teleport/devicetrust/v1/devicetrust_service.pb.go index 8e04676f83122..332a710aa7920 100644 --- a/api/gen/proto/go/teleport/devicetrust/v1/devicetrust_service.pb.go +++ b/api/gen/proto/go/teleport/devicetrust/v1/devicetrust_service.pb.go @@ -91,115 +91,6 @@ func (DeviceView) EnumDescriptor() ([]byte, []int) { return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{0} } -// Mode of sync for SyncInventory. -type SyncInventoryMode int32 - -const ( - SyncInventoryMode_SYNC_INVENTORY_MODE_UNSPECIFIED SyncInventoryMode = 0 - // Partial inventory sync; not all devices in the external inventory are sent - // to the stream. - // Partial sync precludes inventory cleanup. - SyncInventoryMode_SYNC_INVENTORY_MODE_PARTIAL SyncInventoryMode = 1 - // Full inventory sync; all devices in the external inventory must be sent to - // the stream. - // Full sync allows for handling of missing devices. - SyncInventoryMode_SYNC_INVENTORY_MODE_FULL SyncInventoryMode = 2 -) - -// Enum value maps for SyncInventoryMode. -var ( - SyncInventoryMode_name = map[int32]string{ - 0: "SYNC_INVENTORY_MODE_UNSPECIFIED", - 1: "SYNC_INVENTORY_MODE_PARTIAL", - 2: "SYNC_INVENTORY_MODE_FULL", - } - SyncInventoryMode_value = map[string]int32{ - "SYNC_INVENTORY_MODE_UNSPECIFIED": 0, - "SYNC_INVENTORY_MODE_PARTIAL": 1, - "SYNC_INVENTORY_MODE_FULL": 2, - } -) - -func (x SyncInventoryMode) Enum() *SyncInventoryMode { - p := new(SyncInventoryMode) - *p = x - return p -} - -func (x SyncInventoryMode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (SyncInventoryMode) Descriptor() protoreflect.EnumDescriptor { - return file_teleport_devicetrust_v1_devicetrust_service_proto_enumTypes[1].Descriptor() -} - -func (SyncInventoryMode) Type() protoreflect.EnumType { - return &file_teleport_devicetrust_v1_devicetrust_service_proto_enumTypes[1] -} - -func (x SyncInventoryMode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use SyncInventoryMode.Descriptor instead. -func (SyncInventoryMode) EnumDescriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{1} -} - -// Device action for SyncInventory. -// Typically triggered at the end of FULL syncs.. -type SyncInventoryDeviceAction int32 - -const ( - SyncInventoryDeviceAction_SYNC_INVENTORY_DEVICE_ACTION_UNSPECIFIED SyncInventoryDeviceAction = 0 - // Noop is a no-action. - SyncInventoryDeviceAction_SYNC_INVENTORY_DEVICE_ACTION_NOOP SyncInventoryDeviceAction = 1 - // Deletes the device if the action condition is met. - SyncInventoryDeviceAction_SYNC_INVENTORY_DEVICE_ACTION_DELETE SyncInventoryDeviceAction = 2 -) - -// Enum value maps for SyncInventoryDeviceAction. -var ( - SyncInventoryDeviceAction_name = map[int32]string{ - 0: "SYNC_INVENTORY_DEVICE_ACTION_UNSPECIFIED", - 1: "SYNC_INVENTORY_DEVICE_ACTION_NOOP", - 2: "SYNC_INVENTORY_DEVICE_ACTION_DELETE", - } - SyncInventoryDeviceAction_value = map[string]int32{ - "SYNC_INVENTORY_DEVICE_ACTION_UNSPECIFIED": 0, - "SYNC_INVENTORY_DEVICE_ACTION_NOOP": 1, - "SYNC_INVENTORY_DEVICE_ACTION_DELETE": 2, - } -) - -func (x SyncInventoryDeviceAction) Enum() *SyncInventoryDeviceAction { - p := new(SyncInventoryDeviceAction) - *p = x - return p -} - -func (x SyncInventoryDeviceAction) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (SyncInventoryDeviceAction) Descriptor() protoreflect.EnumDescriptor { - return file_teleport_devicetrust_v1_devicetrust_service_proto_enumTypes[2].Descriptor() -} - -func (SyncInventoryDeviceAction) Type() protoreflect.EnumType { - return &file_teleport_devicetrust_v1_devicetrust_service_proto_enumTypes[2] -} - -func (x SyncInventoryDeviceAction) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use SyncInventoryDeviceAction.Descriptor instead. -func (SyncInventoryDeviceAction) EnumDescriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{2} -} - // Request for CreateDevice. type CreateDeviceRequest struct { state protoimpl.MessageState @@ -1815,200 +1706,6 @@ func (x *TPMEnrollChallengeResponse) GetPlatformParameters() *TPMPlatformParamet return nil } -// Encapsulates the value of a PCR at a point at time. -// See https://pkg.go.dev/github.com/google/go-attestation/attest#PCR -type TPMPCR struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // the PCR index in the PCR bank - Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` - // the digest currently held in the PCR - Digest []byte `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"` - // the hash algorithm used to produce the digest in this PCR bank. This value - // is the underlying value of the Go crypto.Hash type. - DigestAlg uint64 `protobuf:"varint,3,opt,name=digest_alg,json=digestAlg,proto3" json:"digest_alg,omitempty"` -} - -func (x *TPMPCR) Reset() { - *x = TPMPCR{} - if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TPMPCR) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TPMPCR) ProtoMessage() {} - -func (x *TPMPCR) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TPMPCR.ProtoReflect.Descriptor instead. -func (*TPMPCR) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{25} -} - -func (x *TPMPCR) GetIndex() int32 { - if x != nil { - return x.Index - } - return 0 -} - -func (x *TPMPCR) GetDigest() []byte { - if x != nil { - return x.Digest - } - return nil -} - -func (x *TPMPCR) GetDigestAlg() uint64 { - if x != nil { - return x.DigestAlg - } - return 0 -} - -// Encapsulates the result of a quote operation against the TPM over a PCR -// using an attestation key. -// See https://pkg.go.dev/github.com/google/go-attestation/attest#Quote -type TPMQuote struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Quote []byte `protobuf:"bytes,1,opt,name=quote,proto3" json:"quote,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` -} - -func (x *TPMQuote) Reset() { - *x = TPMQuote{} - if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TPMQuote) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TPMQuote) ProtoMessage() {} - -func (x *TPMQuote) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TPMQuote.ProtoReflect.Descriptor instead. -func (*TPMQuote) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{26} -} - -func (x *TPMQuote) GetQuote() []byte { - if x != nil { - return x.Quote - } - return nil -} - -func (x *TPMQuote) GetSignature() []byte { - if x != nil { - return x.Signature - } - return nil -} - -// The quotes, PCRs and event log from a TPM that attest to the booted state -// of the machine. -// See https://pkg.go.dev/github.com/google/go-attestation/attest#PlatformParameters -// Excludes TPMVersion and Public since these are already known values. -type TPMPlatformParameters struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Quotes []*TPMQuote `protobuf:"bytes,1,rep,name=quotes,proto3" json:"quotes,omitempty"` - Pcrs []*TPMPCR `protobuf:"bytes,2,rep,name=pcrs,proto3" json:"pcrs,omitempty"` - EventLog []byte `protobuf:"bytes,3,opt,name=event_log,json=eventLog,proto3" json:"event_log,omitempty"` -} - -func (x *TPMPlatformParameters) Reset() { - *x = TPMPlatformParameters{} - if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TPMPlatformParameters) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TPMPlatformParameters) ProtoMessage() {} - -func (x *TPMPlatformParameters) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TPMPlatformParameters.ProtoReflect.Descriptor instead. -func (*TPMPlatformParameters) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{27} -} - -func (x *TPMPlatformParameters) GetQuotes() []*TPMQuote { - if x != nil { - return x.Quotes - } - return nil -} - -func (x *TPMPlatformParameters) GetPcrs() []*TPMPCR { - if x != nil { - return x.Pcrs - } - return nil -} - -func (x *TPMPlatformParameters) GetEventLog() []byte { - if x != nil { - return x.EventLog - } - return nil -} - // Request for AuthenticateDevice. // // Authentication ceremony flow: @@ -2032,7 +1729,7 @@ type AuthenticateDeviceRequest struct { func (x *AuthenticateDeviceRequest) Reset() { *x = AuthenticateDeviceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2045,7 +1742,7 @@ func (x *AuthenticateDeviceRequest) String() string { func (*AuthenticateDeviceRequest) ProtoMessage() {} func (x *AuthenticateDeviceRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2058,7 +1755,7 @@ func (x *AuthenticateDeviceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AuthenticateDeviceRequest.ProtoReflect.Descriptor instead. func (*AuthenticateDeviceRequest) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{28} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{25} } func (m *AuthenticateDeviceRequest) GetPayload() isAuthenticateDeviceRequest_Payload { @@ -2128,7 +1825,7 @@ type AuthenticateDeviceResponse struct { func (x *AuthenticateDeviceResponse) Reset() { *x = AuthenticateDeviceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2141,7 +1838,7 @@ func (x *AuthenticateDeviceResponse) String() string { func (*AuthenticateDeviceResponse) ProtoMessage() {} func (x *AuthenticateDeviceResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2154,7 +1851,7 @@ func (x *AuthenticateDeviceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AuthenticateDeviceResponse.ProtoReflect.Descriptor instead. func (*AuthenticateDeviceResponse) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{29} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{26} } func (m *AuthenticateDeviceResponse) GetPayload() isAuthenticateDeviceResponse_Payload { @@ -2233,7 +1930,7 @@ type AuthenticateDeviceInit struct { func (x *AuthenticateDeviceInit) Reset() { *x = AuthenticateDeviceInit{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2246,7 +1943,7 @@ func (x *AuthenticateDeviceInit) String() string { func (*AuthenticateDeviceInit) ProtoMessage() {} func (x *AuthenticateDeviceInit) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2259,7 +1956,7 @@ func (x *AuthenticateDeviceInit) ProtoReflect() protoreflect.Message { // Deprecated: Use AuthenticateDeviceInit.ProtoReflect.Descriptor instead. func (*AuthenticateDeviceInit) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{30} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{27} } func (x *AuthenticateDeviceInit) GetUserCertificates() *UserCertificates { @@ -2298,7 +1995,7 @@ type TPMAuthenticateDeviceChallenge struct { func (x *TPMAuthenticateDeviceChallenge) Reset() { *x = TPMAuthenticateDeviceChallenge{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2311,7 +2008,7 @@ func (x *TPMAuthenticateDeviceChallenge) String() string { func (*TPMAuthenticateDeviceChallenge) ProtoMessage() {} func (x *TPMAuthenticateDeviceChallenge) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2324,7 +2021,7 @@ func (x *TPMAuthenticateDeviceChallenge) ProtoReflect() protoreflect.Message { // Deprecated: Use TPMAuthenticateDeviceChallenge.ProtoReflect.Descriptor instead. func (*TPMAuthenticateDeviceChallenge) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{31} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{28} } func (x *TPMAuthenticateDeviceChallenge) GetAttestationNonce() []byte { @@ -2349,7 +2046,7 @@ type TPMAuthenticateDeviceChallengeResponse struct { func (x *TPMAuthenticateDeviceChallengeResponse) Reset() { *x = TPMAuthenticateDeviceChallengeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2362,7 +2059,7 @@ func (x *TPMAuthenticateDeviceChallengeResponse) String() string { func (*TPMAuthenticateDeviceChallengeResponse) ProtoMessage() {} func (x *TPMAuthenticateDeviceChallengeResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2375,7 +2072,7 @@ func (x *TPMAuthenticateDeviceChallengeResponse) ProtoReflect() protoreflect.Mes // Deprecated: Use TPMAuthenticateDeviceChallengeResponse.ProtoReflect.Descriptor instead. func (*TPMAuthenticateDeviceChallengeResponse) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{32} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{29} } func (x *TPMAuthenticateDeviceChallengeResponse) GetPlatformParameters() *TPMPlatformParameters { @@ -2398,7 +2095,7 @@ type AuthenticateDeviceChallenge struct { func (x *AuthenticateDeviceChallenge) Reset() { *x = AuthenticateDeviceChallenge{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2411,7 +2108,7 @@ func (x *AuthenticateDeviceChallenge) String() string { func (*AuthenticateDeviceChallenge) ProtoMessage() {} func (x *AuthenticateDeviceChallenge) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2424,7 +2121,7 @@ func (x *AuthenticateDeviceChallenge) ProtoReflect() protoreflect.Message { // Deprecated: Use AuthenticateDeviceChallenge.ProtoReflect.Descriptor instead. func (*AuthenticateDeviceChallenge) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{33} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{30} } func (x *AuthenticateDeviceChallenge) GetChallenge() []byte { @@ -2448,7 +2145,7 @@ type AuthenticateDeviceChallengeResponse struct { func (x *AuthenticateDeviceChallengeResponse) Reset() { *x = AuthenticateDeviceChallengeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2461,7 +2158,7 @@ func (x *AuthenticateDeviceChallengeResponse) String() string { func (*AuthenticateDeviceChallengeResponse) ProtoMessage() {} func (x *AuthenticateDeviceChallengeResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2474,7 +2171,7 @@ func (x *AuthenticateDeviceChallengeResponse) ProtoReflect() protoreflect.Messag // Deprecated: Use AuthenticateDeviceChallengeResponse.ProtoReflect.Descriptor instead. func (*AuthenticateDeviceChallengeResponse) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{34} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{31} } func (x *AuthenticateDeviceChallengeResponse) GetSignature() []byte { @@ -2496,8 +2193,10 @@ func (x *AuthenticateDeviceChallengeResponse) GetSignature() []byte { // (end loop) // -> SyncInventoryEnd // (loop until server closes the stream, zero or more times) -// <- SyncInventoryResult (deleted/missing devices) -// (end) +// <- SyncInventoryMissingDevices +// -> SyncInventoryDevices (removals only) +// <- SyncInventoryResult +// (end loop) type SyncInventoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2515,7 +2214,7 @@ type SyncInventoryRequest struct { func (x *SyncInventoryRequest) Reset() { *x = SyncInventoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2528,7 +2227,7 @@ func (x *SyncInventoryRequest) String() string { func (*SyncInventoryRequest) ProtoMessage() {} func (x *SyncInventoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2541,7 +2240,7 @@ func (x *SyncInventoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryRequest.ProtoReflect.Descriptor instead. func (*SyncInventoryRequest) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{35} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{32} } func (m *SyncInventoryRequest) GetPayload() isSyncInventoryRequest_Payload { @@ -2617,13 +2316,14 @@ type SyncInventoryResponse struct { // // *SyncInventoryResponse_Ack // *SyncInventoryResponse_Result + // *SyncInventoryResponse_MissingDevices Payload isSyncInventoryResponse_Payload `protobuf_oneof:"payload"` } func (x *SyncInventoryResponse) Reset() { *x = SyncInventoryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2636,7 +2336,7 @@ func (x *SyncInventoryResponse) String() string { func (*SyncInventoryResponse) ProtoMessage() {} func (x *SyncInventoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2649,7 +2349,7 @@ func (x *SyncInventoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryResponse.ProtoReflect.Descriptor instead. func (*SyncInventoryResponse) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{36} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{33} } func (m *SyncInventoryResponse) GetPayload() isSyncInventoryResponse_Payload { @@ -2673,6 +2373,13 @@ func (x *SyncInventoryResponse) GetResult() *SyncInventoryResult { return nil } +func (x *SyncInventoryResponse) GetMissingDevices() *SyncInventoryMissingDevices { + if x, ok := x.GetPayload().(*SyncInventoryResponse_MissingDevices); ok { + return x.MissingDevices + } + return nil +} + type isSyncInventoryResponse_Payload interface { isSyncInventoryResponse_Payload() } @@ -2685,10 +2392,16 @@ type SyncInventoryResponse_Result struct { Result *SyncInventoryResult `protobuf:"bytes,2,opt,name=result,proto3,oneof"` } +type SyncInventoryResponse_MissingDevices struct { + MissingDevices *SyncInventoryMissingDevices `protobuf:"bytes,3,opt,name=missing_devices,json=missingDevices,proto3,oneof"` +} + func (*SyncInventoryResponse_Ack) isSyncInventoryResponse_Payload() {} func (*SyncInventoryResponse_Result) isSyncInventoryResponse_Payload() {} +func (*SyncInventoryResponse_MissingDevices) isSyncInventoryResponse_Payload() {} + // SyncInventoryStart starts the inventory sync. type SyncInventoryStart struct { state protoimpl.MessageState @@ -2699,20 +2412,18 @@ type SyncInventoryStart struct { // Used for all devices. The `source` field in individual devices is ignored // by this RPC. Source *DeviceSource `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` - // Mode of syncing. - // Required. - Mode SyncInventoryMode `protobuf:"varint,2,opt,name=mode,proto3,enum=teleport.devicetrust.v1.SyncInventoryMode" json:"mode,omitempty"` - // Action for devices missing from the external inventory, but present in - // Teleport. - // Only executed if mode is FULL and external_sync_successful is set to true - // in the SyncInventoryEnd message. - OnMissingAction SyncInventoryDeviceAction `protobuf:"varint,3,opt,name=on_missing_action,json=onMissingAction,proto3,enum=teleport.devicetrust.v1.SyncInventoryDeviceAction" json:"on_missing_action,omitempty"` + // If true, the server keeps track of the devices upserted during the sync. + // After receiving the [SyncInventoryEnd] message, the server informs the + // client of all devices that are present in storage but not observed in the + // upserts. + // See [SyncInventoryRequest] and [SyncInventoryMissingDevices] for details. + TrackMissingDevices bool `protobuf:"varint,4,opt,name=track_missing_devices,json=trackMissingDevices,proto3" json:"track_missing_devices,omitempty"` } func (x *SyncInventoryStart) Reset() { *x = SyncInventoryStart{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2725,7 +2436,7 @@ func (x *SyncInventoryStart) String() string { func (*SyncInventoryStart) ProtoMessage() {} func (x *SyncInventoryStart) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2738,7 +2449,7 @@ func (x *SyncInventoryStart) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryStart.ProtoReflect.Descriptor instead. func (*SyncInventoryStart) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{37} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{34} } func (x *SyncInventoryStart) GetSource() *DeviceSource { @@ -2748,18 +2459,11 @@ func (x *SyncInventoryStart) GetSource() *DeviceSource { return nil } -func (x *SyncInventoryStart) GetMode() SyncInventoryMode { +func (x *SyncInventoryStart) GetTrackMissingDevices() bool { if x != nil { - return x.Mode + return x.TrackMissingDevices } - return SyncInventoryMode_SYNC_INVENTORY_MODE_UNSPECIFIED -} - -func (x *SyncInventoryStart) GetOnMissingAction() SyncInventoryDeviceAction { - if x != nil { - return x.OnMissingAction - } - return SyncInventoryDeviceAction_SYNC_INVENTORY_DEVICE_ACTION_UNSPECIFIED + return false } // SyncInventoryEnd ends the inventory sync, signaling that no more @@ -2768,17 +2472,12 @@ type SyncInventoryEnd struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - // True if the external sync was fully successful (for example, all reads from - // an MDM API were successful). - // If false the sync's on_missing_action is skipped. - ExternalSyncSuccessful bool `protobuf:"varint,1,opt,name=external_sync_successful,json=externalSyncSuccessful,proto3" json:"external_sync_successful,omitempty"` } func (x *SyncInventoryEnd) Reset() { *x = SyncInventoryEnd{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2791,7 +2490,7 @@ func (x *SyncInventoryEnd) String() string { func (*SyncInventoryEnd) ProtoMessage() {} func (x *SyncInventoryEnd) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2804,14 +2503,7 @@ func (x *SyncInventoryEnd) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryEnd.ProtoReflect.Descriptor instead. func (*SyncInventoryEnd) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{38} -} - -func (x *SyncInventoryEnd) GetExternalSyncSuccessful() bool { - if x != nil { - return x.ExternalSyncSuccessful - } - return false + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{35} } // SyncInventoryDevices transports devices to add/update/remove. @@ -2828,7 +2520,7 @@ type SyncInventoryDevices struct { func (x *SyncInventoryDevices) Reset() { *x = SyncInventoryDevices{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[39] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2841,7 +2533,7 @@ func (x *SyncInventoryDevices) String() string { func (*SyncInventoryDevices) ProtoMessage() {} func (x *SyncInventoryDevices) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[39] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2854,7 +2546,7 @@ func (x *SyncInventoryDevices) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryDevices.ProtoReflect.Descriptor instead. func (*SyncInventoryDevices) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{39} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{36} } func (x *SyncInventoryDevices) GetDevices() []*Device { @@ -2875,7 +2567,7 @@ type SyncInventoryAck struct { func (x *SyncInventoryAck) Reset() { *x = SyncInventoryAck{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[40] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2888,7 +2580,7 @@ func (x *SyncInventoryAck) String() string { func (*SyncInventoryAck) ProtoMessage() {} func (x *SyncInventoryAck) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[40] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2901,7 +2593,7 @@ func (x *SyncInventoryAck) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryAck.ProtoReflect.Descriptor instead. func (*SyncInventoryAck) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{40} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{37} } // SyncInventoryResult is the response for SyncInventoryDevices or @@ -2919,7 +2611,7 @@ type SyncInventoryResult struct { func (x *SyncInventoryResult) Reset() { *x = SyncInventoryResult{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[41] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2932,7 +2624,7 @@ func (x *SyncInventoryResult) String() string { func (*SyncInventoryResult) ProtoMessage() {} func (x *SyncInventoryResult) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[41] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2945,7 +2637,7 @@ func (x *SyncInventoryResult) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryResult.ProtoReflect.Descriptor instead. func (*SyncInventoryResult) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{41} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{38} } func (x *SyncInventoryResult) GetDevices() []*DeviceOrStatus { @@ -2955,6 +2647,64 @@ func (x *SyncInventoryResult) GetDevices() []*DeviceOrStatus { return nil } +// SyncInventoryMissingDevices informs the sync client of all stored devices +// that were not observed in upserts during the sync. +// +// Requires `track_missing_devices` to be set in the [SyncInventoryStart] +// message. +// +// The client must follow up with a [SyncInventoryDevices] message, including +// any devices to be deleted. +type SyncInventoryMissingDevices struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Devices missing from the client-side sync. + // Guaranteed to have the following fields: id, os_type, asset_tag and + // profile.external_id. + Devices []*Device `protobuf:"bytes,1,rep,name=devices,proto3" json:"devices,omitempty"` +} + +func (x *SyncInventoryMissingDevices) Reset() { + *x = SyncInventoryMissingDevices{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SyncInventoryMissingDevices) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncInventoryMissingDevices) ProtoMessage() {} + +func (x *SyncInventoryMissingDevices) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncInventoryMissingDevices.ProtoReflect.Descriptor instead. +func (*SyncInventoryMissingDevices) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{39} +} + +func (x *SyncInventoryMissingDevices) GetDevices() []*Device { + if x != nil { + return x.Devices + } + return nil +} + var File_teleport_devicetrust_v1_devicetrust_service_proto protoreflect.FileDescriptor var file_teleport_devicetrust_v1_devicetrust_service_proto_rawDesc = []byte{ @@ -2980,492 +2730,462 @@ var file_teleport_devicetrust_v1_devicetrust_service_proto_rawDesc = []byte{ 0x74, 0x6f, 0x1a, 0x2b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0xac, 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x73, 0x5f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, - 0x8b, 0x01, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x70, 0x6d, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xac, 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x65, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, + 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x22, 0x8b, 0x01, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, + 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, + 0x22, 0x7c, 0x0a, 0x13, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, - 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x7c, 0x0a, - 0x13, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x0a, - 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x41, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x32, 0x0a, 0x13, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, - 0x30, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x74, - 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x64, 0x4f, 0x72, 0x54, 0x61, - 0x67, 0x22, 0x50, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x49, 0x64, 0x22, 0x89, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, - 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, - 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, - 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x73, 0x5f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x32, + 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x49, 0x64, 0x22, 0x30, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x6f, + 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x64, 0x4f, + 0x72, 0x54, 0x61, 0x67, 0x22, 0x50, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, 0x89, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x0a, 0x04, 0x76, 0x69, + 0x65, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x69, 0x65, 0x77, 0x52, 0x04, 0x76, + 0x69, 0x65, 0x77, 0x22, 0x78, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x83, 0x01, + 0x0a, 0x18, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, + 0x61, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x22, 0x5e, 0x0a, 0x19, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x4f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x22, 0x66, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, + 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x1e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0xc1, 0x02, 0x0a, 0x13, 0x45, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x69, + 0x6e, 0x69, 0x74, 0x12, 0x71, 0x0a, 0x18, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x63, 0x68, 0x61, + 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x69, 0x65, 0x77, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, - 0x22, 0x78, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, + 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, + 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x16, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, + 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x14, 0x74, + 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x99, + 0x02, 0x0a, 0x14, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, - 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x42, - 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x58, 0x0a, 0x0f, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, + 0x65, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x61, 0x63, + 0x6f, 0x73, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x52, 0x0a, 0x0d, 0x74, + 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, + 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, + 0x00, 0x52, 0x0c, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x42, + 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x9c, 0x02, 0x0a, 0x10, 0x45, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x05, 0x6d, 0x61, 0x63, + 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x73, 0x5f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0x5e, 0x0a, 0x19, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, - 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x22, 0x66, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, - 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x1e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x05, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x12, 0x3b, 0x0a, 0x03, + 0x74, 0x70, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x03, 0x74, 0x70, 0x6d, 0x22, 0x4e, 0x0a, 0x13, 0x45, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x12, 0x4d, 0x61, 0x63, + 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, + 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x44, 0x65, 0x72, 0x22, 0x34, 0x0a, 0x14, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, + 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, + 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x22, 0x3c, 0x0a, 0x1c, 0x4d, + 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xb6, 0x01, 0x0a, 0x10, 0x54, 0x50, + 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x19, + 0x0a, 0x07, 0x65, 0x6b, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, + 0x00, 0x52, 0x06, 0x65, 0x6b, 0x43, 0x65, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x06, 0x65, 0x6b, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6b, 0x4b, + 0x65, 0x79, 0x12, 0x68, 0x0a, 0x16, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, + 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x15, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x42, 0x04, 0x0a, 0x02, + 0x65, 0x6b, 0x22, 0xad, 0x01, 0x0a, 0x18, 0x54, 0x50, 0x4d, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x62, 0x0a, 0x14, 0x65, 0x6e, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x13, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, + 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2b, 0x0a, + 0x11, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x59, 0x0a, 0x16, 0x54, 0x50, + 0x4d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x99, 0x01, 0x0a, 0x1a, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x5f, 0x0a, 0x13, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0xc1, 0x02, 0x0a, 0x13, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x3f, 0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x12, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x22, 0xd5, 0x02, 0x0a, 0x19, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x45, 0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x69, 0x6e, 0x69, 0x74, - 0x12, 0x71, 0x0a, 0x18, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x48, 0x00, + 0x52, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x12, 0x6d, 0x0a, 0x12, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, - 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, 0x6d, 0x61, 0x63, - 0x6f, 0x73, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x16, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, - 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, - 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x14, 0x74, 0x70, 0x6d, 0x43, + 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x99, 0x02, 0x0a, 0x14, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x48, 0x00, 0x52, 0x11, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, + 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x58, - 0x0a, 0x0f, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, - 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x43, - 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x52, 0x0a, 0x0d, 0x74, 0x70, 0x6d, 0x5f, + 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x14, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, + 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, + 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xb7, 0x02, 0x0a, 0x1a, 0x41, 0x75, + 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x48, 0x00, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x58, + 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x5e, 0x0a, 0x0d, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x70, 0x6d, 0x43, + 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x22, 0xe4, 0x01, 0x0a, 0x16, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x56, + 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x73, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0x4d, 0x0a, 0x1e, 0x54, 0x50, + 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11, + 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x89, 0x01, 0x0a, 0x26, 0x54, 0x50, + 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x13, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x52, 0x12, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x3b, 0x0a, 0x1b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, + 0x65, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, + 0x67, 0x65, 0x22, 0x43, 0x0a, 0x23, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xdf, 0x02, 0x0a, 0x14, 0x53, 0x79, 0x6e, 0x63, + 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x43, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, - 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x42, 0x09, 0x0a, 0x07, - 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x9c, 0x02, 0x0a, 0x10, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x3d, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, + 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x64, 0x48, 0x00, 0x52, + 0x03, 0x65, 0x6e, 0x64, 0x12, 0x5b, 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, + 0x74, 0x6f, 0x5f, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, 0x00, + 0x52, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x54, 0x6f, 0x55, 0x70, 0x73, 0x65, 0x72, + 0x74, 0x12, 0x5b, 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x5f, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, - 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x05, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x52, 0x05, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x12, 0x3b, 0x0a, 0x03, 0x74, 0x70, 0x6d, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, - 0x64, 0x52, 0x03, 0x74, 0x70, 0x6d, 0x22, 0x4e, 0x0a, 0x13, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, - 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, + 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x09, + 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x8a, 0x02, 0x0a, 0x15, 0x53, 0x79, + 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x03, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, + 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x03, 0x61, + 0x63, 0x6b, 0x12, 0x46, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, + 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x5f, 0x0a, 0x0f, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, + 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x70, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xac, 0x01, 0x0a, 0x12, 0x53, 0x79, 0x6e, 0x63, 0x49, + 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x3d, 0x0a, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x12, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, - 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x24, 0x0a, 0x0e, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x65, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x44, - 0x65, 0x72, 0x22, 0x34, 0x0a, 0x14, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x68, - 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, - 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x22, 0x3c, 0x0a, 0x1c, 0x4d, 0x61, 0x63, 0x4f, - 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xb6, 0x01, 0x0a, 0x10, 0x54, 0x50, 0x4d, 0x45, 0x6e, - 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x19, 0x0a, 0x07, 0x65, - 0x6b, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x06, - 0x65, 0x6b, 0x43, 0x65, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x06, 0x65, 0x6b, 0x5f, 0x6b, 0x65, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6b, 0x4b, 0x65, 0x79, 0x12, - 0x68, 0x0a, 0x16, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x41, 0x74, 0x74, - 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x73, 0x52, 0x15, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x42, 0x04, 0x0a, 0x02, 0x65, 0x6b, 0x22, - 0xad, 0x01, 0x0a, 0x18, 0x54, 0x50, 0x4d, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, - 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, - 0xa5, 0x01, 0x0a, 0x12, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, - 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x62, 0x0a, 0x14, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x65, 0x64, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, - 0x50, 0x4d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x13, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, - 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x74, - 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x59, 0x0a, 0x16, 0x54, 0x50, 0x4d, 0x45, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, - 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x22, 0x99, 0x01, 0x0a, 0x1a, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5f, 0x0a, - 0x13, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x12, 0x70, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x55, - 0x0a, 0x06, 0x54, 0x50, 0x4d, 0x50, 0x43, 0x52, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x16, - 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, - 0x5f, 0x61, 0x6c, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x64, 0x69, 0x67, 0x65, - 0x73, 0x74, 0x41, 0x6c, 0x67, 0x22, 0x3e, 0x0a, 0x08, 0x54, 0x50, 0x4d, 0x51, 0x75, 0x6f, 0x74, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x05, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x15, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, - 0x39, 0x0a, 0x06, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x21, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x51, 0x75, 0x6f, - 0x74, 0x65, 0x52, 0x06, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x04, 0x70, 0x63, - 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x43, 0x52, 0x52, 0x04, 0x70, 0x63, 0x72, 0x73, 0x12, - 0x1b, 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x22, 0xd5, 0x02, 0x0a, - 0x19, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x04, 0x69, 0x6e, - 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x0a, 0x15, + 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x74, 0x72, 0x61, + 0x63, 0x6b, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x52, 0x04, 0x6d, 0x6f, + 0x64, 0x65, 0x52, 0x11, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x32, 0x0a, 0x10, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, + 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, + 0x18, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x22, 0x51, 0x0a, 0x14, 0x53, 0x79, 0x6e, + 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x12, 0x0a, 0x10, + 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x63, 0x6b, + 0x22, 0x58, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x69, 0x6e, 0x69, - 0x74, 0x12, 0x6d, 0x0a, 0x12, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, - 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x11, 0x63, - 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x77, 0x0a, 0x16, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, - 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x3f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x48, 0x00, 0x52, 0x14, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xb7, 0x02, 0x0a, 0x1a, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x09, - 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x58, 0x0a, 0x11, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x48, - 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x73, 0x12, 0x5e, 0x0a, 0x0d, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, - 0x65, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x65, 0x6c, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x58, 0x0a, 0x1b, 0x53, 0x79, + 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, - 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, - 0x6e, 0x67, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xe4, - 0x01, 0x0a, 0x16, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x56, 0x0a, 0x11, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2a, 0x59, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x69, + 0x65, 0x77, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x56, 0x49, 0x45, + 0x57, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x14, 0x0a, 0x10, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4c, + 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, + 0x56, 0x49, 0x45, 0x57, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x02, 0x32, + 0x99, 0x0a, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x52, - 0x10, 0x75, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0x4d, 0x0a, 0x1e, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, - 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x74, 0x74, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, - 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x89, 0x01, 0x0a, 0x26, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, - 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x5f, 0x0a, 0x13, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x12, 0x70, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x22, 0x3b, 0x0a, 0x1b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x22, 0x43, 0x0a, - 0x23, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x22, 0xdf, 0x02, 0x0a, 0x14, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, - 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, - 0x72, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x12, 0x3d, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, - 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, - 0x5b, 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x75, 0x70, - 0x73, 0x65, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, - 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x54, 0x6f, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x5b, 0x0a, 0x11, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x54, 0x6f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xa9, 0x01, 0x0a, 0x15, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, - 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, - 0x0a, 0x03, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, - 0x6f, 0x72, 0x79, 0x41, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x03, 0x61, 0x63, 0x6b, 0x12, 0x46, 0x0a, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, - 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x06, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, - 0x22, 0xf3, 0x01, 0x0a, 0x12, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, - 0x72, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x6f, 0x64, 0x65, - 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x5e, 0x0a, 0x11, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, - 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x6f, 0x6e, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x4c, 0x0a, 0x10, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, - 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x65, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x65, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x66, 0x75, 0x6c, 0x22, 0x51, 0x0a, 0x14, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, - 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x07, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x79, 0x6e, 0x63, 0x49, - 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x63, 0x6b, 0x22, 0x58, 0x0a, 0x13, 0x53, - 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, + 0x70, 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2a, 0x59, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, - 0x69, 0x65, 0x77, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x56, 0x49, - 0x45, 0x57, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x14, 0x0a, 0x10, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, - 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, - 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x02, - 0x2a, 0x77, 0x0a, 0x11, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, - 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x49, 0x4e, - 0x56, 0x45, 0x4e, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1f, 0x0a, 0x1b, 0x53, 0x59, - 0x4e, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x45, 0x4e, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, - 0x45, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x53, - 0x59, 0x4e, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x45, 0x4e, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x4d, 0x4f, - 0x44, 0x45, 0x5f, 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x02, 0x2a, 0x99, 0x01, 0x0a, 0x19, 0x53, 0x79, - 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x28, 0x53, 0x59, 0x4e, 0x43, 0x5f, - 0x49, 0x4e, 0x56, 0x45, 0x4e, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, - 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x49, 0x4e, - 0x56, 0x45, 0x4e, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x41, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x27, 0x0a, 0x23, - 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x45, 0x4e, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, - 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, - 0x45, 0x54, 0x45, 0x10, 0x02, 0x32, 0x99, 0x0a, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x68, 0x0a, 0x0b, 0x46, 0x69, 0x6e, + 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x55, 0x70, - 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x68, 0x0a, 0x0b, + 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x0c, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x68, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2b, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x11, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x68, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x11, - 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, - 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x6f, 0x0a, 0x0c, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, - 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x72, 0x0a, - 0x0d, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2d, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x6f, 0x0a, 0x0c, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, + 0x01, 0x30, 0x01, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, - 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, - 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, - 0x01, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x72, 0x0a, 0x0d, 0x53, 0x79, 0x6e, 0x63, 0x49, + 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x5a, 0x5a, 0x58, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, + 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3480,139 +3200,134 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP() []byte return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescData } -var file_teleport_devicetrust_v1_devicetrust_service_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes = make([]protoimpl.MessageInfo, 42) +var file_teleport_devicetrust_v1_devicetrust_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes = make([]protoimpl.MessageInfo, 40) var file_teleport_devicetrust_v1_devicetrust_service_proto_goTypes = []interface{}{ (DeviceView)(0), // 0: teleport.devicetrust.v1.DeviceView - (SyncInventoryMode)(0), // 1: teleport.devicetrust.v1.SyncInventoryMode - (SyncInventoryDeviceAction)(0), // 2: teleport.devicetrust.v1.SyncInventoryDeviceAction - (*CreateDeviceRequest)(nil), // 3: teleport.devicetrust.v1.CreateDeviceRequest - (*UpdateDeviceRequest)(nil), // 4: teleport.devicetrust.v1.UpdateDeviceRequest - (*UpsertDeviceRequest)(nil), // 5: teleport.devicetrust.v1.UpsertDeviceRequest - (*DeleteDeviceRequest)(nil), // 6: teleport.devicetrust.v1.DeleteDeviceRequest - (*FindDevicesRequest)(nil), // 7: teleport.devicetrust.v1.FindDevicesRequest - (*FindDevicesResponse)(nil), // 8: teleport.devicetrust.v1.FindDevicesResponse - (*GetDeviceRequest)(nil), // 9: teleport.devicetrust.v1.GetDeviceRequest - (*ListDevicesRequest)(nil), // 10: teleport.devicetrust.v1.ListDevicesRequest - (*ListDevicesResponse)(nil), // 11: teleport.devicetrust.v1.ListDevicesResponse - (*BulkCreateDevicesRequest)(nil), // 12: teleport.devicetrust.v1.BulkCreateDevicesRequest - (*BulkCreateDevicesResponse)(nil), // 13: teleport.devicetrust.v1.BulkCreateDevicesResponse - (*DeviceOrStatus)(nil), // 14: teleport.devicetrust.v1.DeviceOrStatus - (*CreateDeviceEnrollTokenRequest)(nil), // 15: teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest - (*EnrollDeviceRequest)(nil), // 16: teleport.devicetrust.v1.EnrollDeviceRequest - (*EnrollDeviceResponse)(nil), // 17: teleport.devicetrust.v1.EnrollDeviceResponse - (*EnrollDeviceInit)(nil), // 18: teleport.devicetrust.v1.EnrollDeviceInit - (*EnrollDeviceSuccess)(nil), // 19: teleport.devicetrust.v1.EnrollDeviceSuccess - (*MacOSEnrollPayload)(nil), // 20: teleport.devicetrust.v1.MacOSEnrollPayload - (*MacOSEnrollChallenge)(nil), // 21: teleport.devicetrust.v1.MacOSEnrollChallenge - (*MacOSEnrollChallengeResponse)(nil), // 22: teleport.devicetrust.v1.MacOSEnrollChallengeResponse - (*TPMEnrollPayload)(nil), // 23: teleport.devicetrust.v1.TPMEnrollPayload - (*TPMAttestationParameters)(nil), // 24: teleport.devicetrust.v1.TPMAttestationParameters - (*TPMEnrollChallenge)(nil), // 25: teleport.devicetrust.v1.TPMEnrollChallenge - (*TPMEncryptedCredential)(nil), // 26: teleport.devicetrust.v1.TPMEncryptedCredential - (*TPMEnrollChallengeResponse)(nil), // 27: teleport.devicetrust.v1.TPMEnrollChallengeResponse - (*TPMPCR)(nil), // 28: teleport.devicetrust.v1.TPMPCR - (*TPMQuote)(nil), // 29: teleport.devicetrust.v1.TPMQuote - (*TPMPlatformParameters)(nil), // 30: teleport.devicetrust.v1.TPMPlatformParameters - (*AuthenticateDeviceRequest)(nil), // 31: teleport.devicetrust.v1.AuthenticateDeviceRequest - (*AuthenticateDeviceResponse)(nil), // 32: teleport.devicetrust.v1.AuthenticateDeviceResponse - (*AuthenticateDeviceInit)(nil), // 33: teleport.devicetrust.v1.AuthenticateDeviceInit - (*TPMAuthenticateDeviceChallenge)(nil), // 34: teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge - (*TPMAuthenticateDeviceChallengeResponse)(nil), // 35: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse - (*AuthenticateDeviceChallenge)(nil), // 36: teleport.devicetrust.v1.AuthenticateDeviceChallenge - (*AuthenticateDeviceChallengeResponse)(nil), // 37: teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse - (*SyncInventoryRequest)(nil), // 38: teleport.devicetrust.v1.SyncInventoryRequest - (*SyncInventoryResponse)(nil), // 39: teleport.devicetrust.v1.SyncInventoryResponse - (*SyncInventoryStart)(nil), // 40: teleport.devicetrust.v1.SyncInventoryStart - (*SyncInventoryEnd)(nil), // 41: teleport.devicetrust.v1.SyncInventoryEnd - (*SyncInventoryDevices)(nil), // 42: teleport.devicetrust.v1.SyncInventoryDevices - (*SyncInventoryAck)(nil), // 43: teleport.devicetrust.v1.SyncInventoryAck - (*SyncInventoryResult)(nil), // 44: teleport.devicetrust.v1.SyncInventoryResult - (*Device)(nil), // 45: teleport.devicetrust.v1.Device - (*fieldmaskpb.FieldMask)(nil), // 46: google.protobuf.FieldMask - (*status.Status)(nil), // 47: google.rpc.Status - (*DeviceCollectedData)(nil), // 48: teleport.devicetrust.v1.DeviceCollectedData - (*UserCertificates)(nil), // 49: teleport.devicetrust.v1.UserCertificates - (*DeviceSource)(nil), // 50: teleport.devicetrust.v1.DeviceSource - (*emptypb.Empty)(nil), // 51: google.protobuf.Empty - (*DeviceEnrollToken)(nil), // 52: teleport.devicetrust.v1.DeviceEnrollToken + (*CreateDeviceRequest)(nil), // 1: teleport.devicetrust.v1.CreateDeviceRequest + (*UpdateDeviceRequest)(nil), // 2: teleport.devicetrust.v1.UpdateDeviceRequest + (*UpsertDeviceRequest)(nil), // 3: teleport.devicetrust.v1.UpsertDeviceRequest + (*DeleteDeviceRequest)(nil), // 4: teleport.devicetrust.v1.DeleteDeviceRequest + (*FindDevicesRequest)(nil), // 5: teleport.devicetrust.v1.FindDevicesRequest + (*FindDevicesResponse)(nil), // 6: teleport.devicetrust.v1.FindDevicesResponse + (*GetDeviceRequest)(nil), // 7: teleport.devicetrust.v1.GetDeviceRequest + (*ListDevicesRequest)(nil), // 8: teleport.devicetrust.v1.ListDevicesRequest + (*ListDevicesResponse)(nil), // 9: teleport.devicetrust.v1.ListDevicesResponse + (*BulkCreateDevicesRequest)(nil), // 10: teleport.devicetrust.v1.BulkCreateDevicesRequest + (*BulkCreateDevicesResponse)(nil), // 11: teleport.devicetrust.v1.BulkCreateDevicesResponse + (*DeviceOrStatus)(nil), // 12: teleport.devicetrust.v1.DeviceOrStatus + (*CreateDeviceEnrollTokenRequest)(nil), // 13: teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest + (*EnrollDeviceRequest)(nil), // 14: teleport.devicetrust.v1.EnrollDeviceRequest + (*EnrollDeviceResponse)(nil), // 15: teleport.devicetrust.v1.EnrollDeviceResponse + (*EnrollDeviceInit)(nil), // 16: teleport.devicetrust.v1.EnrollDeviceInit + (*EnrollDeviceSuccess)(nil), // 17: teleport.devicetrust.v1.EnrollDeviceSuccess + (*MacOSEnrollPayload)(nil), // 18: teleport.devicetrust.v1.MacOSEnrollPayload + (*MacOSEnrollChallenge)(nil), // 19: teleport.devicetrust.v1.MacOSEnrollChallenge + (*MacOSEnrollChallengeResponse)(nil), // 20: teleport.devicetrust.v1.MacOSEnrollChallengeResponse + (*TPMEnrollPayload)(nil), // 21: teleport.devicetrust.v1.TPMEnrollPayload + (*TPMAttestationParameters)(nil), // 22: teleport.devicetrust.v1.TPMAttestationParameters + (*TPMEnrollChallenge)(nil), // 23: teleport.devicetrust.v1.TPMEnrollChallenge + (*TPMEncryptedCredential)(nil), // 24: teleport.devicetrust.v1.TPMEncryptedCredential + (*TPMEnrollChallengeResponse)(nil), // 25: teleport.devicetrust.v1.TPMEnrollChallengeResponse + (*AuthenticateDeviceRequest)(nil), // 26: teleport.devicetrust.v1.AuthenticateDeviceRequest + (*AuthenticateDeviceResponse)(nil), // 27: teleport.devicetrust.v1.AuthenticateDeviceResponse + (*AuthenticateDeviceInit)(nil), // 28: teleport.devicetrust.v1.AuthenticateDeviceInit + (*TPMAuthenticateDeviceChallenge)(nil), // 29: teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge + (*TPMAuthenticateDeviceChallengeResponse)(nil), // 30: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse + (*AuthenticateDeviceChallenge)(nil), // 31: teleport.devicetrust.v1.AuthenticateDeviceChallenge + (*AuthenticateDeviceChallengeResponse)(nil), // 32: teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse + (*SyncInventoryRequest)(nil), // 33: teleport.devicetrust.v1.SyncInventoryRequest + (*SyncInventoryResponse)(nil), // 34: teleport.devicetrust.v1.SyncInventoryResponse + (*SyncInventoryStart)(nil), // 35: teleport.devicetrust.v1.SyncInventoryStart + (*SyncInventoryEnd)(nil), // 36: teleport.devicetrust.v1.SyncInventoryEnd + (*SyncInventoryDevices)(nil), // 37: teleport.devicetrust.v1.SyncInventoryDevices + (*SyncInventoryAck)(nil), // 38: teleport.devicetrust.v1.SyncInventoryAck + (*SyncInventoryResult)(nil), // 39: teleport.devicetrust.v1.SyncInventoryResult + (*SyncInventoryMissingDevices)(nil), // 40: teleport.devicetrust.v1.SyncInventoryMissingDevices + (*Device)(nil), // 41: teleport.devicetrust.v1.Device + (*fieldmaskpb.FieldMask)(nil), // 42: google.protobuf.FieldMask + (*status.Status)(nil), // 43: google.rpc.Status + (*DeviceCollectedData)(nil), // 44: teleport.devicetrust.v1.DeviceCollectedData + (*TPMPlatformParameters)(nil), // 45: teleport.devicetrust.v1.TPMPlatformParameters + (*UserCertificates)(nil), // 46: teleport.devicetrust.v1.UserCertificates + (*DeviceSource)(nil), // 47: teleport.devicetrust.v1.DeviceSource + (*emptypb.Empty)(nil), // 48: google.protobuf.Empty + (*DeviceEnrollToken)(nil), // 49: teleport.devicetrust.v1.DeviceEnrollToken } var file_teleport_devicetrust_v1_devicetrust_service_proto_depIdxs = []int32{ - 45, // 0: teleport.devicetrust.v1.CreateDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device - 45, // 1: teleport.devicetrust.v1.UpdateDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device - 46, // 2: teleport.devicetrust.v1.UpdateDeviceRequest.update_mask:type_name -> google.protobuf.FieldMask - 45, // 3: teleport.devicetrust.v1.UpsertDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device - 45, // 4: teleport.devicetrust.v1.FindDevicesResponse.devices:type_name -> teleport.devicetrust.v1.Device + 41, // 0: teleport.devicetrust.v1.CreateDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device + 41, // 1: teleport.devicetrust.v1.UpdateDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device + 42, // 2: teleport.devicetrust.v1.UpdateDeviceRequest.update_mask:type_name -> google.protobuf.FieldMask + 41, // 3: teleport.devicetrust.v1.UpsertDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device + 41, // 4: teleport.devicetrust.v1.FindDevicesResponse.devices:type_name -> teleport.devicetrust.v1.Device 0, // 5: teleport.devicetrust.v1.ListDevicesRequest.view:type_name -> teleport.devicetrust.v1.DeviceView - 45, // 6: teleport.devicetrust.v1.ListDevicesResponse.devices:type_name -> teleport.devicetrust.v1.Device - 45, // 7: teleport.devicetrust.v1.BulkCreateDevicesRequest.devices:type_name -> teleport.devicetrust.v1.Device - 14, // 8: teleport.devicetrust.v1.BulkCreateDevicesResponse.devices:type_name -> teleport.devicetrust.v1.DeviceOrStatus - 47, // 9: teleport.devicetrust.v1.DeviceOrStatus.status:type_name -> google.rpc.Status - 48, // 10: teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData - 18, // 11: teleport.devicetrust.v1.EnrollDeviceRequest.init:type_name -> teleport.devicetrust.v1.EnrollDeviceInit - 22, // 12: teleport.devicetrust.v1.EnrollDeviceRequest.macos_challenge_response:type_name -> teleport.devicetrust.v1.MacOSEnrollChallengeResponse - 27, // 13: teleport.devicetrust.v1.EnrollDeviceRequest.tpm_challenge_response:type_name -> teleport.devicetrust.v1.TPMEnrollChallengeResponse - 19, // 14: teleport.devicetrust.v1.EnrollDeviceResponse.success:type_name -> teleport.devicetrust.v1.EnrollDeviceSuccess - 21, // 15: teleport.devicetrust.v1.EnrollDeviceResponse.macos_challenge:type_name -> teleport.devicetrust.v1.MacOSEnrollChallenge - 25, // 16: teleport.devicetrust.v1.EnrollDeviceResponse.tpm_challenge:type_name -> teleport.devicetrust.v1.TPMEnrollChallenge - 48, // 17: teleport.devicetrust.v1.EnrollDeviceInit.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData - 20, // 18: teleport.devicetrust.v1.EnrollDeviceInit.macos:type_name -> teleport.devicetrust.v1.MacOSEnrollPayload - 23, // 19: teleport.devicetrust.v1.EnrollDeviceInit.tpm:type_name -> teleport.devicetrust.v1.TPMEnrollPayload - 45, // 20: teleport.devicetrust.v1.EnrollDeviceSuccess.device:type_name -> teleport.devicetrust.v1.Device - 24, // 21: teleport.devicetrust.v1.TPMEnrollPayload.attestation_parameters:type_name -> teleport.devicetrust.v1.TPMAttestationParameters - 26, // 22: teleport.devicetrust.v1.TPMEnrollChallenge.encrypted_credential:type_name -> teleport.devicetrust.v1.TPMEncryptedCredential - 30, // 23: teleport.devicetrust.v1.TPMEnrollChallengeResponse.platform_parameters:type_name -> teleport.devicetrust.v1.TPMPlatformParameters - 29, // 24: teleport.devicetrust.v1.TPMPlatformParameters.quotes:type_name -> teleport.devicetrust.v1.TPMQuote - 28, // 25: teleport.devicetrust.v1.TPMPlatformParameters.pcrs:type_name -> teleport.devicetrust.v1.TPMPCR - 33, // 26: teleport.devicetrust.v1.AuthenticateDeviceRequest.init:type_name -> teleport.devicetrust.v1.AuthenticateDeviceInit - 37, // 27: teleport.devicetrust.v1.AuthenticateDeviceRequest.challenge_response:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse - 35, // 28: teleport.devicetrust.v1.AuthenticateDeviceRequest.tpm_challenge_response:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse - 36, // 29: teleport.devicetrust.v1.AuthenticateDeviceResponse.challenge:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallenge - 49, // 30: teleport.devicetrust.v1.AuthenticateDeviceResponse.user_certificates:type_name -> teleport.devicetrust.v1.UserCertificates - 34, // 31: teleport.devicetrust.v1.AuthenticateDeviceResponse.tpm_challenge:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge - 49, // 32: teleport.devicetrust.v1.AuthenticateDeviceInit.user_certificates:type_name -> teleport.devicetrust.v1.UserCertificates - 48, // 33: teleport.devicetrust.v1.AuthenticateDeviceInit.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData - 30, // 34: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse.platform_parameters:type_name -> teleport.devicetrust.v1.TPMPlatformParameters - 40, // 35: teleport.devicetrust.v1.SyncInventoryRequest.start:type_name -> teleport.devicetrust.v1.SyncInventoryStart - 41, // 36: teleport.devicetrust.v1.SyncInventoryRequest.end:type_name -> teleport.devicetrust.v1.SyncInventoryEnd - 42, // 37: teleport.devicetrust.v1.SyncInventoryRequest.devices_to_upsert:type_name -> teleport.devicetrust.v1.SyncInventoryDevices - 42, // 38: teleport.devicetrust.v1.SyncInventoryRequest.devices_to_remove:type_name -> teleport.devicetrust.v1.SyncInventoryDevices - 43, // 39: teleport.devicetrust.v1.SyncInventoryResponse.ack:type_name -> teleport.devicetrust.v1.SyncInventoryAck - 44, // 40: teleport.devicetrust.v1.SyncInventoryResponse.result:type_name -> teleport.devicetrust.v1.SyncInventoryResult - 50, // 41: teleport.devicetrust.v1.SyncInventoryStart.source:type_name -> teleport.devicetrust.v1.DeviceSource - 1, // 42: teleport.devicetrust.v1.SyncInventoryStart.mode:type_name -> teleport.devicetrust.v1.SyncInventoryMode - 2, // 43: teleport.devicetrust.v1.SyncInventoryStart.on_missing_action:type_name -> teleport.devicetrust.v1.SyncInventoryDeviceAction - 45, // 44: teleport.devicetrust.v1.SyncInventoryDevices.devices:type_name -> teleport.devicetrust.v1.Device - 14, // 45: teleport.devicetrust.v1.SyncInventoryResult.devices:type_name -> teleport.devicetrust.v1.DeviceOrStatus - 3, // 46: teleport.devicetrust.v1.DeviceTrustService.CreateDevice:input_type -> teleport.devicetrust.v1.CreateDeviceRequest - 4, // 47: teleport.devicetrust.v1.DeviceTrustService.UpdateDevice:input_type -> teleport.devicetrust.v1.UpdateDeviceRequest - 5, // 48: teleport.devicetrust.v1.DeviceTrustService.UpsertDevice:input_type -> teleport.devicetrust.v1.UpsertDeviceRequest - 6, // 49: teleport.devicetrust.v1.DeviceTrustService.DeleteDevice:input_type -> teleport.devicetrust.v1.DeleteDeviceRequest - 7, // 50: teleport.devicetrust.v1.DeviceTrustService.FindDevices:input_type -> teleport.devicetrust.v1.FindDevicesRequest - 9, // 51: teleport.devicetrust.v1.DeviceTrustService.GetDevice:input_type -> teleport.devicetrust.v1.GetDeviceRequest - 10, // 52: teleport.devicetrust.v1.DeviceTrustService.ListDevices:input_type -> teleport.devicetrust.v1.ListDevicesRequest - 12, // 53: teleport.devicetrust.v1.DeviceTrustService.BulkCreateDevices:input_type -> teleport.devicetrust.v1.BulkCreateDevicesRequest - 15, // 54: teleport.devicetrust.v1.DeviceTrustService.CreateDeviceEnrollToken:input_type -> teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest - 16, // 55: teleport.devicetrust.v1.DeviceTrustService.EnrollDevice:input_type -> teleport.devicetrust.v1.EnrollDeviceRequest - 31, // 56: teleport.devicetrust.v1.DeviceTrustService.AuthenticateDevice:input_type -> teleport.devicetrust.v1.AuthenticateDeviceRequest - 38, // 57: teleport.devicetrust.v1.DeviceTrustService.SyncInventory:input_type -> teleport.devicetrust.v1.SyncInventoryRequest - 45, // 58: teleport.devicetrust.v1.DeviceTrustService.CreateDevice:output_type -> teleport.devicetrust.v1.Device - 45, // 59: teleport.devicetrust.v1.DeviceTrustService.UpdateDevice:output_type -> teleport.devicetrust.v1.Device - 45, // 60: teleport.devicetrust.v1.DeviceTrustService.UpsertDevice:output_type -> teleport.devicetrust.v1.Device - 51, // 61: teleport.devicetrust.v1.DeviceTrustService.DeleteDevice:output_type -> google.protobuf.Empty - 8, // 62: teleport.devicetrust.v1.DeviceTrustService.FindDevices:output_type -> teleport.devicetrust.v1.FindDevicesResponse - 45, // 63: teleport.devicetrust.v1.DeviceTrustService.GetDevice:output_type -> teleport.devicetrust.v1.Device - 11, // 64: teleport.devicetrust.v1.DeviceTrustService.ListDevices:output_type -> teleport.devicetrust.v1.ListDevicesResponse - 13, // 65: teleport.devicetrust.v1.DeviceTrustService.BulkCreateDevices:output_type -> teleport.devicetrust.v1.BulkCreateDevicesResponse - 52, // 66: teleport.devicetrust.v1.DeviceTrustService.CreateDeviceEnrollToken:output_type -> teleport.devicetrust.v1.DeviceEnrollToken - 17, // 67: teleport.devicetrust.v1.DeviceTrustService.EnrollDevice:output_type -> teleport.devicetrust.v1.EnrollDeviceResponse - 32, // 68: teleport.devicetrust.v1.DeviceTrustService.AuthenticateDevice:output_type -> teleport.devicetrust.v1.AuthenticateDeviceResponse - 39, // 69: teleport.devicetrust.v1.DeviceTrustService.SyncInventory:output_type -> teleport.devicetrust.v1.SyncInventoryResponse - 58, // [58:70] is the sub-list for method output_type - 46, // [46:58] is the sub-list for method input_type - 46, // [46:46] is the sub-list for extension type_name - 46, // [46:46] is the sub-list for extension extendee - 0, // [0:46] is the sub-list for field type_name + 41, // 6: teleport.devicetrust.v1.ListDevicesResponse.devices:type_name -> teleport.devicetrust.v1.Device + 41, // 7: teleport.devicetrust.v1.BulkCreateDevicesRequest.devices:type_name -> teleport.devicetrust.v1.Device + 12, // 8: teleport.devicetrust.v1.BulkCreateDevicesResponse.devices:type_name -> teleport.devicetrust.v1.DeviceOrStatus + 43, // 9: teleport.devicetrust.v1.DeviceOrStatus.status:type_name -> google.rpc.Status + 44, // 10: teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData + 16, // 11: teleport.devicetrust.v1.EnrollDeviceRequest.init:type_name -> teleport.devicetrust.v1.EnrollDeviceInit + 20, // 12: teleport.devicetrust.v1.EnrollDeviceRequest.macos_challenge_response:type_name -> teleport.devicetrust.v1.MacOSEnrollChallengeResponse + 25, // 13: teleport.devicetrust.v1.EnrollDeviceRequest.tpm_challenge_response:type_name -> teleport.devicetrust.v1.TPMEnrollChallengeResponse + 17, // 14: teleport.devicetrust.v1.EnrollDeviceResponse.success:type_name -> teleport.devicetrust.v1.EnrollDeviceSuccess + 19, // 15: teleport.devicetrust.v1.EnrollDeviceResponse.macos_challenge:type_name -> teleport.devicetrust.v1.MacOSEnrollChallenge + 23, // 16: teleport.devicetrust.v1.EnrollDeviceResponse.tpm_challenge:type_name -> teleport.devicetrust.v1.TPMEnrollChallenge + 44, // 17: teleport.devicetrust.v1.EnrollDeviceInit.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData + 18, // 18: teleport.devicetrust.v1.EnrollDeviceInit.macos:type_name -> teleport.devicetrust.v1.MacOSEnrollPayload + 21, // 19: teleport.devicetrust.v1.EnrollDeviceInit.tpm:type_name -> teleport.devicetrust.v1.TPMEnrollPayload + 41, // 20: teleport.devicetrust.v1.EnrollDeviceSuccess.device:type_name -> teleport.devicetrust.v1.Device + 22, // 21: teleport.devicetrust.v1.TPMEnrollPayload.attestation_parameters:type_name -> teleport.devicetrust.v1.TPMAttestationParameters + 24, // 22: teleport.devicetrust.v1.TPMEnrollChallenge.encrypted_credential:type_name -> teleport.devicetrust.v1.TPMEncryptedCredential + 45, // 23: teleport.devicetrust.v1.TPMEnrollChallengeResponse.platform_parameters:type_name -> teleport.devicetrust.v1.TPMPlatformParameters + 28, // 24: teleport.devicetrust.v1.AuthenticateDeviceRequest.init:type_name -> teleport.devicetrust.v1.AuthenticateDeviceInit + 32, // 25: teleport.devicetrust.v1.AuthenticateDeviceRequest.challenge_response:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse + 30, // 26: teleport.devicetrust.v1.AuthenticateDeviceRequest.tpm_challenge_response:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse + 31, // 27: teleport.devicetrust.v1.AuthenticateDeviceResponse.challenge:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallenge + 46, // 28: teleport.devicetrust.v1.AuthenticateDeviceResponse.user_certificates:type_name -> teleport.devicetrust.v1.UserCertificates + 29, // 29: teleport.devicetrust.v1.AuthenticateDeviceResponse.tpm_challenge:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge + 46, // 30: teleport.devicetrust.v1.AuthenticateDeviceInit.user_certificates:type_name -> teleport.devicetrust.v1.UserCertificates + 44, // 31: teleport.devicetrust.v1.AuthenticateDeviceInit.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData + 45, // 32: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse.platform_parameters:type_name -> teleport.devicetrust.v1.TPMPlatformParameters + 35, // 33: teleport.devicetrust.v1.SyncInventoryRequest.start:type_name -> teleport.devicetrust.v1.SyncInventoryStart + 36, // 34: teleport.devicetrust.v1.SyncInventoryRequest.end:type_name -> teleport.devicetrust.v1.SyncInventoryEnd + 37, // 35: teleport.devicetrust.v1.SyncInventoryRequest.devices_to_upsert:type_name -> teleport.devicetrust.v1.SyncInventoryDevices + 37, // 36: teleport.devicetrust.v1.SyncInventoryRequest.devices_to_remove:type_name -> teleport.devicetrust.v1.SyncInventoryDevices + 38, // 37: teleport.devicetrust.v1.SyncInventoryResponse.ack:type_name -> teleport.devicetrust.v1.SyncInventoryAck + 39, // 38: teleport.devicetrust.v1.SyncInventoryResponse.result:type_name -> teleport.devicetrust.v1.SyncInventoryResult + 40, // 39: teleport.devicetrust.v1.SyncInventoryResponse.missing_devices:type_name -> teleport.devicetrust.v1.SyncInventoryMissingDevices + 47, // 40: teleport.devicetrust.v1.SyncInventoryStart.source:type_name -> teleport.devicetrust.v1.DeviceSource + 41, // 41: teleport.devicetrust.v1.SyncInventoryDevices.devices:type_name -> teleport.devicetrust.v1.Device + 12, // 42: teleport.devicetrust.v1.SyncInventoryResult.devices:type_name -> teleport.devicetrust.v1.DeviceOrStatus + 41, // 43: teleport.devicetrust.v1.SyncInventoryMissingDevices.devices:type_name -> teleport.devicetrust.v1.Device + 1, // 44: teleport.devicetrust.v1.DeviceTrustService.CreateDevice:input_type -> teleport.devicetrust.v1.CreateDeviceRequest + 2, // 45: teleport.devicetrust.v1.DeviceTrustService.UpdateDevice:input_type -> teleport.devicetrust.v1.UpdateDeviceRequest + 3, // 46: teleport.devicetrust.v1.DeviceTrustService.UpsertDevice:input_type -> teleport.devicetrust.v1.UpsertDeviceRequest + 4, // 47: teleport.devicetrust.v1.DeviceTrustService.DeleteDevice:input_type -> teleport.devicetrust.v1.DeleteDeviceRequest + 5, // 48: teleport.devicetrust.v1.DeviceTrustService.FindDevices:input_type -> teleport.devicetrust.v1.FindDevicesRequest + 7, // 49: teleport.devicetrust.v1.DeviceTrustService.GetDevice:input_type -> teleport.devicetrust.v1.GetDeviceRequest + 8, // 50: teleport.devicetrust.v1.DeviceTrustService.ListDevices:input_type -> teleport.devicetrust.v1.ListDevicesRequest + 10, // 51: teleport.devicetrust.v1.DeviceTrustService.BulkCreateDevices:input_type -> teleport.devicetrust.v1.BulkCreateDevicesRequest + 13, // 52: teleport.devicetrust.v1.DeviceTrustService.CreateDeviceEnrollToken:input_type -> teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest + 14, // 53: teleport.devicetrust.v1.DeviceTrustService.EnrollDevice:input_type -> teleport.devicetrust.v1.EnrollDeviceRequest + 26, // 54: teleport.devicetrust.v1.DeviceTrustService.AuthenticateDevice:input_type -> teleport.devicetrust.v1.AuthenticateDeviceRequest + 33, // 55: teleport.devicetrust.v1.DeviceTrustService.SyncInventory:input_type -> teleport.devicetrust.v1.SyncInventoryRequest + 41, // 56: teleport.devicetrust.v1.DeviceTrustService.CreateDevice:output_type -> teleport.devicetrust.v1.Device + 41, // 57: teleport.devicetrust.v1.DeviceTrustService.UpdateDevice:output_type -> teleport.devicetrust.v1.Device + 41, // 58: teleport.devicetrust.v1.DeviceTrustService.UpsertDevice:output_type -> teleport.devicetrust.v1.Device + 48, // 59: teleport.devicetrust.v1.DeviceTrustService.DeleteDevice:output_type -> google.protobuf.Empty + 6, // 60: teleport.devicetrust.v1.DeviceTrustService.FindDevices:output_type -> teleport.devicetrust.v1.FindDevicesResponse + 41, // 61: teleport.devicetrust.v1.DeviceTrustService.GetDevice:output_type -> teleport.devicetrust.v1.Device + 9, // 62: teleport.devicetrust.v1.DeviceTrustService.ListDevices:output_type -> teleport.devicetrust.v1.ListDevicesResponse + 11, // 63: teleport.devicetrust.v1.DeviceTrustService.BulkCreateDevices:output_type -> teleport.devicetrust.v1.BulkCreateDevicesResponse + 49, // 64: teleport.devicetrust.v1.DeviceTrustService.CreateDeviceEnrollToken:output_type -> teleport.devicetrust.v1.DeviceEnrollToken + 15, // 65: teleport.devicetrust.v1.DeviceTrustService.EnrollDevice:output_type -> teleport.devicetrust.v1.EnrollDeviceResponse + 27, // 66: teleport.devicetrust.v1.DeviceTrustService.AuthenticateDevice:output_type -> teleport.devicetrust.v1.AuthenticateDeviceResponse + 34, // 67: teleport.devicetrust.v1.DeviceTrustService.SyncInventory:output_type -> teleport.devicetrust.v1.SyncInventoryResponse + 56, // [56:68] is the sub-list for method output_type + 44, // [44:56] is the sub-list for method input_type + 44, // [44:44] is the sub-list for extension type_name + 44, // [44:44] is the sub-list for extension extendee + 0, // [0:44] is the sub-list for field type_name } func init() { file_teleport_devicetrust_v1_devicetrust_service_proto_init() } @@ -3624,6 +3339,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { file_teleport_devicetrust_v1_device_collected_data_proto_init() file_teleport_devicetrust_v1_device_enroll_token_proto_init() file_teleport_devicetrust_v1_device_source_proto_init() + file_teleport_devicetrust_v1_tpm_proto_init() file_teleport_devicetrust_v1_user_certificates_proto_init() if !protoimpl.UnsafeEnabled { file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { @@ -3927,7 +3643,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TPMPCR); i { + switch v := v.(*AuthenticateDeviceRequest); i { case 0: return &v.state case 1: @@ -3939,7 +3655,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TPMQuote); i { + switch v := v.(*AuthenticateDeviceResponse); i { case 0: return &v.state case 1: @@ -3951,7 +3667,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TPMPlatformParameters); i { + switch v := v.(*AuthenticateDeviceInit); i { case 0: return &v.state case 1: @@ -3963,7 +3679,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthenticateDeviceRequest); i { + switch v := v.(*TPMAuthenticateDeviceChallenge); i { case 0: return &v.state case 1: @@ -3975,7 +3691,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthenticateDeviceResponse); i { + switch v := v.(*TPMAuthenticateDeviceChallengeResponse); i { case 0: return &v.state case 1: @@ -3987,7 +3703,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthenticateDeviceInit); i { + switch v := v.(*AuthenticateDeviceChallenge); i { case 0: return &v.state case 1: @@ -3999,7 +3715,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TPMAuthenticateDeviceChallenge); i { + switch v := v.(*AuthenticateDeviceChallengeResponse); i { case 0: return &v.state case 1: @@ -4011,7 +3727,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TPMAuthenticateDeviceChallengeResponse); i { + switch v := v.(*SyncInventoryRequest); i { case 0: return &v.state case 1: @@ -4023,7 +3739,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthenticateDeviceChallenge); i { + switch v := v.(*SyncInventoryResponse); i { case 0: return &v.state case 1: @@ -4035,7 +3751,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthenticateDeviceChallengeResponse); i { + switch v := v.(*SyncInventoryStart); i { case 0: return &v.state case 1: @@ -4047,7 +3763,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncInventoryRequest); i { + switch v := v.(*SyncInventoryEnd); i { case 0: return &v.state case 1: @@ -4059,7 +3775,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncInventoryResponse); i { + switch v := v.(*SyncInventoryDevices); i { case 0: return &v.state case 1: @@ -4071,7 +3787,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncInventoryStart); i { + switch v := v.(*SyncInventoryAck); i { case 0: return &v.state case 1: @@ -4083,7 +3799,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncInventoryEnd); i { + switch v := v.(*SyncInventoryResult); i { case 0: return &v.state case 1: @@ -4095,31 +3811,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncInventoryDevices); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncInventoryAck); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncInventoryResult); i { + switch v := v.(*SyncInventoryMissingDevices); i { case 0: return &v.state case 1: @@ -4145,33 +3837,34 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { (*TPMEnrollPayload_EkCert)(nil), (*TPMEnrollPayload_EkKey)(nil), } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28].OneofWrappers = []interface{}{ + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[25].OneofWrappers = []interface{}{ (*AuthenticateDeviceRequest_Init)(nil), (*AuthenticateDeviceRequest_ChallengeResponse)(nil), (*AuthenticateDeviceRequest_TpmChallengeResponse)(nil), } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29].OneofWrappers = []interface{}{ + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[26].OneofWrappers = []interface{}{ (*AuthenticateDeviceResponse_Challenge)(nil), (*AuthenticateDeviceResponse_UserCertificates)(nil), (*AuthenticateDeviceResponse_TpmChallenge)(nil), } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35].OneofWrappers = []interface{}{ + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32].OneofWrappers = []interface{}{ (*SyncInventoryRequest_Start)(nil), (*SyncInventoryRequest_End)(nil), (*SyncInventoryRequest_DevicesToUpsert)(nil), (*SyncInventoryRequest_DevicesToRemove)(nil), } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36].OneofWrappers = []interface{}{ + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33].OneofWrappers = []interface{}{ (*SyncInventoryResponse_Ack)(nil), (*SyncInventoryResponse_Result)(nil), + (*SyncInventoryResponse_MissingDevices)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_devicetrust_v1_devicetrust_service_proto_rawDesc, - NumEnums: 3, - NumMessages: 42, + NumEnums: 1, + NumMessages: 40, NumExtensions: 0, NumServices: 1, }, diff --git a/api/gen/proto/go/teleport/devicetrust/v1/tpm.pb.go b/api/gen/proto/go/teleport/devicetrust/v1/tpm.pb.go new file mode 100644 index 0000000000000..d82a24ec325fd --- /dev/null +++ b/api/gen/proto/go/teleport/devicetrust/v1/tpm.pb.go @@ -0,0 +1,438 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/devicetrust/v1/tpm.proto + +package devicetrustv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Encapsulates the value of a PCR at a point at time. +// See https://pkg.go.dev/github.com/google/go-attestation/attest#PCR +type TPMPCR struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the PCR index in the PCR bank + Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + // the digest currently held in the PCR + Digest []byte `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"` + // the hash algorithm used to produce the digest in this PCR bank. This value + // is the underlying value of the Go crypto.Hash type. + DigestAlg uint64 `protobuf:"varint,3,opt,name=digest_alg,json=digestAlg,proto3" json:"digest_alg,omitempty"` +} + +func (x *TPMPCR) Reset() { + *x = TPMPCR{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_tpm_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TPMPCR) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TPMPCR) ProtoMessage() {} + +func (x *TPMPCR) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_tpm_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TPMPCR.ProtoReflect.Descriptor instead. +func (*TPMPCR) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_tpm_proto_rawDescGZIP(), []int{0} +} + +func (x *TPMPCR) GetIndex() int32 { + if x != nil { + return x.Index + } + return 0 +} + +func (x *TPMPCR) GetDigest() []byte { + if x != nil { + return x.Digest + } + return nil +} + +func (x *TPMPCR) GetDigestAlg() uint64 { + if x != nil { + return x.DigestAlg + } + return 0 +} + +// Encapsulates the result of a quote operation against the TPM over a PCR +// using an attestation key. +// See https://pkg.go.dev/github.com/google/go-attestation/attest#Quote +type TPMQuote struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Quote []byte `protobuf:"bytes,1,opt,name=quote,proto3" json:"quote,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *TPMQuote) Reset() { + *x = TPMQuote{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_tpm_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TPMQuote) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TPMQuote) ProtoMessage() {} + +func (x *TPMQuote) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_tpm_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TPMQuote.ProtoReflect.Descriptor instead. +func (*TPMQuote) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_tpm_proto_rawDescGZIP(), []int{1} +} + +func (x *TPMQuote) GetQuote() []byte { + if x != nil { + return x.Quote + } + return nil +} + +func (x *TPMQuote) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +// The quotes, PCRs and event log from a TPM that attest to the booted state +// of the machine. +// See https://pkg.go.dev/github.com/google/go-attestation/attest#PlatformParameters +// Excludes TPMVersion and Public since these are already known values. +type TPMPlatformParameters struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Quotes []*TPMQuote `protobuf:"bytes,1,rep,name=quotes,proto3" json:"quotes,omitempty"` + Pcrs []*TPMPCR `protobuf:"bytes,2,rep,name=pcrs,proto3" json:"pcrs,omitempty"` + EventLog []byte `protobuf:"bytes,3,opt,name=event_log,json=eventLog,proto3" json:"event_log,omitempty"` +} + +func (x *TPMPlatformParameters) Reset() { + *x = TPMPlatformParameters{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_tpm_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TPMPlatformParameters) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TPMPlatformParameters) ProtoMessage() {} + +func (x *TPMPlatformParameters) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_tpm_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TPMPlatformParameters.ProtoReflect.Descriptor instead. +func (*TPMPlatformParameters) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_tpm_proto_rawDescGZIP(), []int{2} +} + +func (x *TPMPlatformParameters) GetQuotes() []*TPMQuote { + if x != nil { + return x.Quotes + } + return nil +} + +func (x *TPMPlatformParameters) GetPcrs() []*TPMPCR { + if x != nil { + return x.Pcrs + } + return nil +} + +func (x *TPMPlatformParameters) GetEventLog() []byte { + if x != nil { + return x.EventLog + } + return nil +} + +// Holds the record of a TPM platform attestation, including the platform +// parameters sent by the device and the nonce the server generated. This allows +// a historical platform attestation to be revalidated and allows us to compare +// the incoming state of a device (e.g during authentication) against the +// historical state in order to detect potentially malicious actions. +type TPMPlatformAttestation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nonce []byte `protobuf:"bytes,1,opt,name=nonce,proto3" json:"nonce,omitempty"` + PlatformParameters *TPMPlatformParameters `protobuf:"bytes,2,opt,name=platform_parameters,json=platformParameters,proto3" json:"platform_parameters,omitempty"` +} + +func (x *TPMPlatformAttestation) Reset() { + *x = TPMPlatformAttestation{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_tpm_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TPMPlatformAttestation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TPMPlatformAttestation) ProtoMessage() {} + +func (x *TPMPlatformAttestation) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_tpm_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TPMPlatformAttestation.ProtoReflect.Descriptor instead. +func (*TPMPlatformAttestation) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_tpm_proto_rawDescGZIP(), []int{3} +} + +func (x *TPMPlatformAttestation) GetNonce() []byte { + if x != nil { + return x.Nonce + } + return nil +} + +func (x *TPMPlatformAttestation) GetPlatformParameters() *TPMPlatformParameters { + if x != nil { + return x.PlatformParameters + } + return nil +} + +var File_teleport_devicetrust_v1_tpm_proto protoreflect.FileDescriptor + +var file_teleport_devicetrust_v1_tpm_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x70, 0x6d, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x22, 0x55, 0x0a, 0x06, + 0x54, 0x50, 0x4d, 0x50, 0x43, 0x52, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x16, 0x0a, 0x06, + 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x5f, 0x61, + 0x6c, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x41, 0x6c, 0x67, 0x22, 0x3e, 0x0a, 0x08, 0x54, 0x50, 0x4d, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x71, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x15, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x39, 0x0a, + 0x06, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x51, 0x75, 0x6f, 0x74, 0x65, + 0x52, 0x06, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x04, 0x70, 0x63, 0x72, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x43, 0x52, 0x52, 0x04, 0x70, 0x63, 0x72, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x67, 0x22, 0x8f, 0x01, 0x0a, 0x16, 0x54, + 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x13, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x12, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x42, 0x5a, 0x5a, 0x58, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_devicetrust_v1_tpm_proto_rawDescOnce sync.Once + file_teleport_devicetrust_v1_tpm_proto_rawDescData = file_teleport_devicetrust_v1_tpm_proto_rawDesc +) + +func file_teleport_devicetrust_v1_tpm_proto_rawDescGZIP() []byte { + file_teleport_devicetrust_v1_tpm_proto_rawDescOnce.Do(func() { + file_teleport_devicetrust_v1_tpm_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_devicetrust_v1_tpm_proto_rawDescData) + }) + return file_teleport_devicetrust_v1_tpm_proto_rawDescData +} + +var file_teleport_devicetrust_v1_tpm_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_teleport_devicetrust_v1_tpm_proto_goTypes = []interface{}{ + (*TPMPCR)(nil), // 0: teleport.devicetrust.v1.TPMPCR + (*TPMQuote)(nil), // 1: teleport.devicetrust.v1.TPMQuote + (*TPMPlatformParameters)(nil), // 2: teleport.devicetrust.v1.TPMPlatformParameters + (*TPMPlatformAttestation)(nil), // 3: teleport.devicetrust.v1.TPMPlatformAttestation +} +var file_teleport_devicetrust_v1_tpm_proto_depIdxs = []int32{ + 1, // 0: teleport.devicetrust.v1.TPMPlatformParameters.quotes:type_name -> teleport.devicetrust.v1.TPMQuote + 0, // 1: teleport.devicetrust.v1.TPMPlatformParameters.pcrs:type_name -> teleport.devicetrust.v1.TPMPCR + 2, // 2: teleport.devicetrust.v1.TPMPlatformAttestation.platform_parameters:type_name -> teleport.devicetrust.v1.TPMPlatformParameters + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_teleport_devicetrust_v1_tpm_proto_init() } +func file_teleport_devicetrust_v1_tpm_proto_init() { + if File_teleport_devicetrust_v1_tpm_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_devicetrust_v1_tpm_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TPMPCR); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_devicetrust_v1_tpm_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TPMQuote); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_devicetrust_v1_tpm_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TPMPlatformParameters); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_devicetrust_v1_tpm_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TPMPlatformAttestation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_devicetrust_v1_tpm_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_devicetrust_v1_tpm_proto_goTypes, + DependencyIndexes: file_teleport_devicetrust_v1_tpm_proto_depIdxs, + MessageInfos: file_teleport_devicetrust_v1_tpm_proto_msgTypes, + }.Build() + File_teleport_devicetrust_v1_tpm_proto = out.File + file_teleport_devicetrust_v1_tpm_proto_rawDesc = nil + file_teleport_devicetrust_v1_tpm_proto_goTypes = nil + file_teleport_devicetrust_v1_tpm_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/embedding/v1/embedding.pb.go b/api/gen/proto/go/teleport/embedding/v1/embedding.pb.go new file mode 100644 index 0000000000000..58f343c52306c --- /dev/null +++ b/api/gen/proto/go/teleport/embedding/v1/embedding.pb.go @@ -0,0 +1,202 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/embedding/v1/embedding.proto + +package embeddingv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Embedding contains a Teleport resource embedding. Embeddings are small semantic +// representations of larger and more complex data. Embeddings can be compared, +// the smaller the distance between two vectors, the closer the concepts are. +// Teleport Assist embeds resources to perform semantic search. +type Embedding struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // EmbeddedKind is the kind of the embedded resource. + EmbeddedKind string `protobuf:"bytes,1,opt,name=embedded_kind,json=embeddedKind,proto3" json:"embedded_kind,omitempty"` + // EmbeddedId is the ID of the embedded resource. + EmbeddedId string `protobuf:"bytes,2,opt,name=embedded_id,json=embeddedId,proto3" json:"embedded_id,omitempty"` + // EmbeddedHash is the hash of the embedded resource after serialization. + // This helps checking if the resource has changed and needs a new embedding. + EmbeddedHash []byte `protobuf:"bytes,3,opt,name=embedded_hash,json=embeddedHash,proto3" json:"embedded_hash,omitempty"` + // Vector is the embedding itself, as provided by the model. + Vector []float64 `protobuf:"fixed64,4,rep,packed,name=vector,proto3" json:"vector,omitempty"` +} + +func (x *Embedding) Reset() { + *x = Embedding{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_embedding_v1_embedding_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Embedding) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Embedding) ProtoMessage() {} + +func (x *Embedding) ProtoReflect() protoreflect.Message { + mi := &file_teleport_embedding_v1_embedding_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Embedding.ProtoReflect.Descriptor instead. +func (*Embedding) Descriptor() ([]byte, []int) { + return file_teleport_embedding_v1_embedding_proto_rawDescGZIP(), []int{0} +} + +func (x *Embedding) GetEmbeddedKind() string { + if x != nil { + return x.EmbeddedKind + } + return "" +} + +func (x *Embedding) GetEmbeddedId() string { + if x != nil { + return x.EmbeddedId + } + return "" +} + +func (x *Embedding) GetEmbeddedHash() []byte { + if x != nil { + return x.EmbeddedHash + } + return nil +} + +func (x *Embedding) GetVector() []float64 { + if x != nil { + return x.Vector + } + return nil +} + +var File_teleport_embedding_v1_embedding_proto protoreflect.FileDescriptor + +var file_teleport_embedding_v1_embedding_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x65, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x22, 0x8e, + 0x01, 0x0a, 0x09, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x0d, + 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x4b, 0x69, 0x6e, + 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, + 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x01, 0x52, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x42, + 0x56, 0x5a, 0x54, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, + 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x65, + 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6d, 0x62, 0x65, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_embedding_v1_embedding_proto_rawDescOnce sync.Once + file_teleport_embedding_v1_embedding_proto_rawDescData = file_teleport_embedding_v1_embedding_proto_rawDesc +) + +func file_teleport_embedding_v1_embedding_proto_rawDescGZIP() []byte { + file_teleport_embedding_v1_embedding_proto_rawDescOnce.Do(func() { + file_teleport_embedding_v1_embedding_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_embedding_v1_embedding_proto_rawDescData) + }) + return file_teleport_embedding_v1_embedding_proto_rawDescData +} + +var file_teleport_embedding_v1_embedding_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_embedding_v1_embedding_proto_goTypes = []interface{}{ + (*Embedding)(nil), // 0: teleport.embedding.v1.Embedding +} +var file_teleport_embedding_v1_embedding_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_teleport_embedding_v1_embedding_proto_init() } +func file_teleport_embedding_v1_embedding_proto_init() { + if File_teleport_embedding_v1_embedding_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_embedding_v1_embedding_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Embedding); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_embedding_v1_embedding_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_embedding_v1_embedding_proto_goTypes, + DependencyIndexes: file_teleport_embedding_v1_embedding_proto_depIdxs, + MessageInfos: file_teleport_embedding_v1_embedding_proto_msgTypes, + }.Build() + File_teleport_embedding_v1_embedding_proto = out.File + file_teleport_embedding_v1_embedding_proto_rawDesc = nil + file_teleport_embedding_v1_embedding_proto_goTypes = nil + file_teleport_embedding_v1_embedding_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/trait/v1/trait.pb.go b/api/gen/proto/go/trait/v1/trait.pb.go new file mode 100644 index 0000000000000..431ba814986ba --- /dev/null +++ b/api/gen/proto/go/trait/v1/trait.pb.go @@ -0,0 +1,173 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/trait/v1/trait.proto + +package trait + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Trait is a trait that can be use in various resources. +type Trait struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // key is the name of the trait. + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // values is the list of trait values. + Values []string `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"` +} + +func (x *Trait) Reset() { + *x = Trait{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_trait_v1_trait_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Trait) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Trait) ProtoMessage() {} + +func (x *Trait) ProtoReflect() protoreflect.Message { + mi := &file_teleport_trait_v1_trait_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Trait.ProtoReflect.Descriptor instead. +func (*Trait) Descriptor() ([]byte, []int) { + return file_teleport_trait_v1_trait_proto_rawDescGZIP(), []int{0} +} + +func (x *Trait) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *Trait) GetValues() []string { + if x != nil { + return x.Values + } + return nil +} + +var File_teleport_trait_v1_trait_proto protoreflect.FileDescriptor + +var file_teleport_trait_v1_trait_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x74, 0x72, 0x61, 0x69, 0x74, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x11, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x22, 0x31, 0x0a, 0x05, 0x54, 0x72, 0x61, 0x69, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, + 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x43, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, + 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x72, 0x61, 0x69, + 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x72, 0x61, 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_teleport_trait_v1_trait_proto_rawDescOnce sync.Once + file_teleport_trait_v1_trait_proto_rawDescData = file_teleport_trait_v1_trait_proto_rawDesc +) + +func file_teleport_trait_v1_trait_proto_rawDescGZIP() []byte { + file_teleport_trait_v1_trait_proto_rawDescOnce.Do(func() { + file_teleport_trait_v1_trait_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_trait_v1_trait_proto_rawDescData) + }) + return file_teleport_trait_v1_trait_proto_rawDescData +} + +var file_teleport_trait_v1_trait_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_trait_v1_trait_proto_goTypes = []interface{}{ + (*Trait)(nil), // 0: teleport.trait.v1.Trait +} +var file_teleport_trait_v1_trait_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_teleport_trait_v1_trait_proto_init() } +func file_teleport_trait_v1_trait_proto_init() { + if File_teleport_trait_v1_trait_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_trait_v1_trait_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Trait); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_trait_v1_trait_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_trait_v1_trait_proto_goTypes, + DependencyIndexes: file_teleport_trait_v1_trait_proto_depIdxs, + MessageInfos: file_teleport_trait_v1_trait_proto_msgTypes, + }.Build() + File_teleport_trait_v1_trait_proto = out.File + file_teleport_trait_v1_trait_proto_rawDesc = nil + file_teleport_trait_v1_trait_proto_goTypes = nil + file_teleport_trait_v1_trait_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/usageevents/v1/usageevents.pb.go b/api/gen/proto/go/usageevents/v1/usageevents.pb.go index 7a584d16fcc9c..b7eea04b302f9 100644 --- a/api/gen/proto/go/usageevents/v1/usageevents.pb.go +++ b/api/gen/proto/go/usageevents/v1/usageevents.pb.go @@ -63,6 +63,7 @@ const ( DiscoverResource_DISCOVER_RESOURCE_DOC_DATABASE_RDS_PROXY DiscoverResource = 34 DiscoverResource_DISCOVER_RESOURCE_DOC_DATABASE_HIGH_AVAILABILITY DiscoverResource = 35 DiscoverResource_DISCOVER_RESOURCE_DOC_DATABASE_DYNAMIC_REGISTRATION DiscoverResource = 36 + DiscoverResource_DISCOVER_RESOURCE_SAML_APPLICATION DiscoverResource = 37 ) var DiscoverResource_name = map[int32]string{ @@ -103,6 +104,7 @@ var DiscoverResource_name = map[int32]string{ 34: "DISCOVER_RESOURCE_DOC_DATABASE_RDS_PROXY", 35: "DISCOVER_RESOURCE_DOC_DATABASE_HIGH_AVAILABILITY", 36: "DISCOVER_RESOURCE_DOC_DATABASE_DYNAMIC_REGISTRATION", + 37: "DISCOVER_RESOURCE_SAML_APPLICATION", } var DiscoverResource_value = map[string]int32{ @@ -143,6 +145,7 @@ var DiscoverResource_value = map[string]int32{ "DISCOVER_RESOURCE_DOC_DATABASE_RDS_PROXY": 34, "DISCOVER_RESOURCE_DOC_DATABASE_HIGH_AVAILABILITY": 35, "DISCOVER_RESOURCE_DOC_DATABASE_DYNAMIC_REGISTRATION": 36, + "DISCOVER_RESOURCE_SAML_APPLICATION": 37, } func (x DiscoverResource) String() string { @@ -209,6 +212,7 @@ const ( CTA_CTA_PREMIUM_SUPPORT CTA = 4 CTA_CTA_TRUSTED_DEVICES CTA = 5 CTA_CTA_UPGRADE_BANNER CTA = 6 + CTA_CTA_BILLING_SUMMARY CTA = 7 ) var CTA_name = map[int32]string{ @@ -219,6 +223,7 @@ var CTA_name = map[int32]string{ 4: "CTA_PREMIUM_SUPPORT", 5: "CTA_TRUSTED_DEVICES", 6: "CTA_UPGRADE_BANNER", + 7: "CTA_BILLING_SUMMARY", } var CTA_value = map[string]int32{ @@ -229,6 +234,7 @@ var CTA_value = map[string]int32{ "CTA_PREMIUM_SUPPORT": 4, "CTA_TRUSTED_DEVICES": 5, "CTA_UPGRADE_BANNER": 6, + "CTA_BILLING_SUMMARY": 7, } func (x CTA) String() string { @@ -296,6 +302,74 @@ func (IntegrationEnrollKind) EnumDescriptor() ([]byte, []int) { return fileDescriptor_94cf2ca1c69fd564, []int{3} } +// DeployMethod describes the method used to deploy a service. +type UIDiscoverDeployServiceEvent_DeployMethod int32 + +const ( + // DEPLOY_METHOD_UNSPECIFIED means there was an existing service + // so deploying step got skipped. + UIDiscoverDeployServiceEvent_DEPLOY_METHOD_UNSPECIFIED UIDiscoverDeployServiceEvent_DeployMethod = 0 + // DEPLOY_METHOD_AUTO means Teleport deployed a service for the user. + UIDiscoverDeployServiceEvent_DEPLOY_METHOD_AUTO UIDiscoverDeployServiceEvent_DeployMethod = 1 + // DEPLOY_METHOD_MANUAL means a user deployed a service by themselves. + UIDiscoverDeployServiceEvent_DEPLOY_METHOD_MANUAL UIDiscoverDeployServiceEvent_DeployMethod = 2 +) + +var UIDiscoverDeployServiceEvent_DeployMethod_name = map[int32]string{ + 0: "DEPLOY_METHOD_UNSPECIFIED", + 1: "DEPLOY_METHOD_AUTO", + 2: "DEPLOY_METHOD_MANUAL", +} + +var UIDiscoverDeployServiceEvent_DeployMethod_value = map[string]int32{ + "DEPLOY_METHOD_UNSPECIFIED": 0, + "DEPLOY_METHOD_AUTO": 1, + "DEPLOY_METHOD_MANUAL": 2, +} + +func (x UIDiscoverDeployServiceEvent_DeployMethod) String() string { + return proto.EnumName(UIDiscoverDeployServiceEvent_DeployMethod_name, int32(x)) +} + +func (UIDiscoverDeployServiceEvent_DeployMethod) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_94cf2ca1c69fd564, []int{18, 0} +} + +// DeployType describes the type of deployment. +type UIDiscoverDeployServiceEvent_DeployType int32 + +const ( + // DEPLOY_METHOD_UNSPECIFIED means there was an existing service + // so deploying step got skipped. + UIDiscoverDeployServiceEvent_DEPLOY_TYPE_UNSPECIFIED UIDiscoverDeployServiceEvent_DeployType = 0 + // DEPLOY_TYPE_INSTALL_SCRIPT means service was deployed using an + // install script. + UIDiscoverDeployServiceEvent_DEPLOY_TYPE_INSTALL_SCRIPT UIDiscoverDeployServiceEvent_DeployType = 1 + // DEPLOY_TYPE_AMAZON_ECS means service was deployed using amazon's + // elastic container service. + UIDiscoverDeployServiceEvent_DEPLOY_TYPE_AMAZON_ECS UIDiscoverDeployServiceEvent_DeployType = 2 +) + +var UIDiscoverDeployServiceEvent_DeployType_name = map[int32]string{ + 0: "DEPLOY_TYPE_UNSPECIFIED", + 1: "DEPLOY_TYPE_INSTALL_SCRIPT", + 2: "DEPLOY_TYPE_AMAZON_ECS", +} + +var UIDiscoverDeployServiceEvent_DeployType_value = map[string]int32{ + "DEPLOY_TYPE_UNSPECIFIED": 0, + "DEPLOY_TYPE_INSTALL_SCRIPT": 1, + "DEPLOY_TYPE_AMAZON_ECS": 2, +} + +func (x UIDiscoverDeployServiceEvent_DeployType) String() string { + return proto.EnumName(UIDiscoverDeployServiceEvent_DeployType_name, int32(x)) +} + +func (UIDiscoverDeployServiceEvent_DeployType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_94cf2ca1c69fd564, []int{18, 1} +} + // UIBannerClickEvent is a usage event sent by the UI when the upgrade // banner is clicked. type UIBannerClickEvent struct { @@ -532,6 +606,56 @@ func (m *UIOnboardSetCredentialSubmitEvent) GetUsername() string { return "" } +// UIOnboardQuestionnaireSubmitEvent is a UI event sent during registration when +// the user submits their onboarding questionnaire. +type UIOnboardQuestionnaireSubmitEvent struct { + // The event username. Not extracted from identity as this is pre-registration. + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UIOnboardQuestionnaireSubmitEvent) Reset() { *m = UIOnboardQuestionnaireSubmitEvent{} } +func (m *UIOnboardQuestionnaireSubmitEvent) String() string { return proto.CompactTextString(m) } +func (*UIOnboardQuestionnaireSubmitEvent) ProtoMessage() {} +func (*UIOnboardQuestionnaireSubmitEvent) Descriptor() ([]byte, []int) { + return fileDescriptor_94cf2ca1c69fd564, []int{5} +} +func (m *UIOnboardQuestionnaireSubmitEvent) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UIOnboardQuestionnaireSubmitEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UIOnboardQuestionnaireSubmitEvent.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UIOnboardQuestionnaireSubmitEvent) XXX_Merge(src proto.Message) { + xxx_messageInfo_UIOnboardQuestionnaireSubmitEvent.Merge(m, src) +} +func (m *UIOnboardQuestionnaireSubmitEvent) XXX_Size() int { + return m.Size() +} +func (m *UIOnboardQuestionnaireSubmitEvent) XXX_DiscardUnknown() { + xxx_messageInfo_UIOnboardQuestionnaireSubmitEvent.DiscardUnknown(m) +} + +var xxx_messageInfo_UIOnboardQuestionnaireSubmitEvent proto.InternalMessageInfo + +func (m *UIOnboardQuestionnaireSubmitEvent) GetUsername() string { + if m != nil { + return m.Username + } + return "" +} + // UIOnboardRegisterChallengeSubmitEvent is a UI event sent during registration // when the MFA challenge is completed. type UIOnboardRegisterChallengeSubmitEvent struct { @@ -550,7 +674,7 @@ func (m *UIOnboardRegisterChallengeSubmitEvent) Reset() { *m = UIOnboard func (m *UIOnboardRegisterChallengeSubmitEvent) String() string { return proto.CompactTextString(m) } func (*UIOnboardRegisterChallengeSubmitEvent) ProtoMessage() {} func (*UIOnboardRegisterChallengeSubmitEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{5} + return fileDescriptor_94cf2ca1c69fd564, []int{6} } func (m *UIOnboardRegisterChallengeSubmitEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -614,7 +738,7 @@ func (m *UIRecoveryCodesContinueClickEvent) Reset() { *m = UIRecoveryCod func (m *UIRecoveryCodesContinueClickEvent) String() string { return proto.CompactTextString(m) } func (*UIRecoveryCodesContinueClickEvent) ProtoMessage() {} func (*UIRecoveryCodesContinueClickEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{6} + return fileDescriptor_94cf2ca1c69fd564, []int{7} } func (m *UIRecoveryCodesContinueClickEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -664,7 +788,7 @@ func (m *UIRecoveryCodesCopyClickEvent) Reset() { *m = UIRecoveryCodesCo func (m *UIRecoveryCodesCopyClickEvent) String() string { return proto.CompactTextString(m) } func (*UIRecoveryCodesCopyClickEvent) ProtoMessage() {} func (*UIRecoveryCodesCopyClickEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{7} + return fileDescriptor_94cf2ca1c69fd564, []int{8} } func (m *UIRecoveryCodesCopyClickEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -714,7 +838,7 @@ func (m *UIRecoveryCodesPrintClickEvent) Reset() { *m = UIRecoveryCodesP func (m *UIRecoveryCodesPrintClickEvent) String() string { return proto.CompactTextString(m) } func (*UIRecoveryCodesPrintClickEvent) ProtoMessage() {} func (*UIRecoveryCodesPrintClickEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{8} + return fileDescriptor_94cf2ca1c69fd564, []int{9} } func (m *UIRecoveryCodesPrintClickEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -764,7 +888,7 @@ func (m *DiscoverMetadata) Reset() { *m = DiscoverMetadata{} } func (m *DiscoverMetadata) String() string { return proto.CompactTextString(m) } func (*DiscoverMetadata) ProtoMessage() {} func (*DiscoverMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{9} + return fileDescriptor_94cf2ca1c69fd564, []int{10} } func (m *DiscoverMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -813,7 +937,7 @@ func (m *DiscoverResourceMetadata) Reset() { *m = DiscoverResourceMetada func (m *DiscoverResourceMetadata) String() string { return proto.CompactTextString(m) } func (*DiscoverResourceMetadata) ProtoMessage() {} func (*DiscoverResourceMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{10} + return fileDescriptor_94cf2ca1c69fd564, []int{11} } func (m *DiscoverResourceMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -866,7 +990,7 @@ func (m *DiscoverStepStatus) Reset() { *m = DiscoverStepStatus{} } func (m *DiscoverStepStatus) String() string { return proto.CompactTextString(m) } func (*DiscoverStepStatus) ProtoMessage() {} func (*DiscoverStepStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{11} + return fileDescriptor_94cf2ca1c69fd564, []int{12} } func (m *DiscoverStepStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -922,7 +1046,7 @@ func (m *UIDiscoverStartedEvent) Reset() { *m = UIDiscoverStartedEvent{} func (m *UIDiscoverStartedEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverStartedEvent) ProtoMessage() {} func (*UIDiscoverStartedEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{12} + return fileDescriptor_94cf2ca1c69fd564, []int{13} } func (m *UIDiscoverStartedEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -980,7 +1104,7 @@ func (m *UIDiscoverResourceSelectionEvent) Reset() { *m = UIDiscoverReso func (m *UIDiscoverResourceSelectionEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverResourceSelectionEvent) ProtoMessage() {} func (*UIDiscoverResourceSelectionEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{13} + return fileDescriptor_94cf2ca1c69fd564, []int{14} } func (m *UIDiscoverResourceSelectionEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1048,7 +1172,7 @@ func (m *UIDiscoverIntegrationAWSOIDCConnectEvent) Reset() { func (m *UIDiscoverIntegrationAWSOIDCConnectEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverIntegrationAWSOIDCConnectEvent) ProtoMessage() {} func (*UIDiscoverIntegrationAWSOIDCConnectEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{14} + return fileDescriptor_94cf2ca1c69fd564, []int{15} } func (m *UIDiscoverIntegrationAWSOIDCConnectEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1114,7 +1238,7 @@ func (m *UIDiscoverDatabaseRDSEnrollEvent) Reset() { *m = UIDiscoverData func (m *UIDiscoverDatabaseRDSEnrollEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverDatabaseRDSEnrollEvent) ProtoMessage() {} func (*UIDiscoverDatabaseRDSEnrollEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{15} + return fileDescriptor_94cf2ca1c69fd564, []int{16} } func (m *UIDiscoverDatabaseRDSEnrollEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1183,7 +1307,7 @@ func (m *UICallToActionClickEvent) Reset() { *m = UICallToActionClickEve func (m *UICallToActionClickEvent) String() string { return proto.CompactTextString(m) } func (*UICallToActionClickEvent) ProtoMessage() {} func (*UICallToActionClickEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{16} + return fileDescriptor_94cf2ca1c69fd564, []int{17} } func (m *UICallToActionClickEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1227,19 +1351,21 @@ func (m *UICallToActionClickEvent) GetCta() CTA { // For Database Access this step is the installation of the teleport 'install-db' script. // It can be skipped if the cluster already has a Database Service capable of proxying the database. type UIDiscoverDeployServiceEvent struct { - Metadata *DiscoverMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` - Resource *DiscoverResourceMetadata `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"` - Status *DiscoverStepStatus `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Metadata *DiscoverMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + Resource *DiscoverResourceMetadata `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"` + Status *DiscoverStepStatus `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` + DeployMethod UIDiscoverDeployServiceEvent_DeployMethod `protobuf:"varint,4,opt,name=deploy_method,json=deployMethod,proto3,enum=teleport.usageevents.v1.UIDiscoverDeployServiceEvent_DeployMethod" json:"deploy_method,omitempty"` + DeployType UIDiscoverDeployServiceEvent_DeployType `protobuf:"varint,5,opt,name=deploy_type,json=deployType,proto3,enum=teleport.usageevents.v1.UIDiscoverDeployServiceEvent_DeployType" json:"deploy_type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *UIDiscoverDeployServiceEvent) Reset() { *m = UIDiscoverDeployServiceEvent{} } func (m *UIDiscoverDeployServiceEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverDeployServiceEvent) ProtoMessage() {} func (*UIDiscoverDeployServiceEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{17} + return fileDescriptor_94cf2ca1c69fd564, []int{18} } func (m *UIDiscoverDeployServiceEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1289,6 +1415,20 @@ func (m *UIDiscoverDeployServiceEvent) GetStatus() *DiscoverStepStatus { return nil } +func (m *UIDiscoverDeployServiceEvent) GetDeployMethod() UIDiscoverDeployServiceEvent_DeployMethod { + if m != nil { + return m.DeployMethod + } + return UIDiscoverDeployServiceEvent_DEPLOY_METHOD_UNSPECIFIED +} + +func (m *UIDiscoverDeployServiceEvent) GetDeployType() UIDiscoverDeployServiceEvent_DeployType { + if m != nil { + return m.DeployType + } + return UIDiscoverDeployServiceEvent_DEPLOY_TYPE_UNSPECIFIED +} + // UIDiscoverDatabaseRegisterEvent is emitted when a user is finished with the step that registers a database resource. type UIDiscoverDatabaseRegisterEvent struct { Metadata *DiscoverMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` @@ -1303,7 +1443,7 @@ func (m *UIDiscoverDatabaseRegisterEvent) Reset() { *m = UIDiscoverDatab func (m *UIDiscoverDatabaseRegisterEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverDatabaseRegisterEvent) ProtoMessage() {} func (*UIDiscoverDatabaseRegisterEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{18} + return fileDescriptor_94cf2ca1c69fd564, []int{19} } func (m *UIDiscoverDatabaseRegisterEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1367,7 +1507,7 @@ func (m *UIDiscoverDatabaseConfigureMTLSEvent) Reset() { *m = UIDiscover func (m *UIDiscoverDatabaseConfigureMTLSEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverDatabaseConfigureMTLSEvent) ProtoMessage() {} func (*UIDiscoverDatabaseConfigureMTLSEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{19} + return fileDescriptor_94cf2ca1c69fd564, []int{20} } func (m *UIDiscoverDatabaseConfigureMTLSEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1435,7 +1575,7 @@ func (m *UIDiscoverDesktopActiveDirectoryToolsInstallEvent) String() string { } func (*UIDiscoverDesktopActiveDirectoryToolsInstallEvent) ProtoMessage() {} func (*UIDiscoverDesktopActiveDirectoryToolsInstallEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{20} + return fileDescriptor_94cf2ca1c69fd564, []int{21} } func (m *UIDiscoverDesktopActiveDirectoryToolsInstallEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1503,7 +1643,7 @@ func (m *UIDiscoverDesktopActiveDirectoryConfigureEvent) String() string { } func (*UIDiscoverDesktopActiveDirectoryConfigureEvent) ProtoMessage() {} func (*UIDiscoverDesktopActiveDirectoryConfigureEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{21} + return fileDescriptor_94cf2ca1c69fd564, []int{22} } func (m *UIDiscoverDesktopActiveDirectoryConfigureEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1571,7 +1711,7 @@ func (m *UIDiscoverAutoDiscoveredResourcesEvent) Reset() { func (m *UIDiscoverAutoDiscoveredResourcesEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverAutoDiscoveredResourcesEvent) ProtoMessage() {} func (*UIDiscoverAutoDiscoveredResourcesEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{22} + return fileDescriptor_94cf2ca1c69fd564, []int{23} } func (m *UIDiscoverAutoDiscoveredResourcesEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1646,7 +1786,7 @@ func (m *UIDiscoverDatabaseConfigureIAMPolicyEvent) String() string { } func (*UIDiscoverDatabaseConfigureIAMPolicyEvent) ProtoMessage() {} func (*UIDiscoverDatabaseConfigureIAMPolicyEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{23} + return fileDescriptor_94cf2ca1c69fd564, []int{24} } func (m *UIDiscoverDatabaseConfigureIAMPolicyEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1710,7 +1850,7 @@ func (m *UIDiscoverPrincipalsConfigureEvent) Reset() { *m = UIDiscoverPr func (m *UIDiscoverPrincipalsConfigureEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverPrincipalsConfigureEvent) ProtoMessage() {} func (*UIDiscoverPrincipalsConfigureEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{24} + return fileDescriptor_94cf2ca1c69fd564, []int{25} } func (m *UIDiscoverPrincipalsConfigureEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1775,7 +1915,7 @@ func (m *UIDiscoverTestConnectionEvent) Reset() { *m = UIDiscoverTestCon func (m *UIDiscoverTestConnectionEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverTestConnectionEvent) ProtoMessage() {} func (*UIDiscoverTestConnectionEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{25} + return fileDescriptor_94cf2ca1c69fd564, []int{26} } func (m *UIDiscoverTestConnectionEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1839,7 +1979,7 @@ func (m *UIDiscoverCompletedEvent) Reset() { *m = UIDiscoverCompletedEve func (m *UIDiscoverCompletedEvent) String() string { return proto.CompactTextString(m) } func (*UIDiscoverCompletedEvent) ProtoMessage() {} func (*UIDiscoverCompletedEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{26} + return fileDescriptor_94cf2ca1c69fd564, []int{27} } func (m *UIDiscoverCompletedEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1900,7 +2040,7 @@ func (m *UICreateNewRoleClickEvent) Reset() { *m = UICreateNewRoleClickE func (m *UICreateNewRoleClickEvent) String() string { return proto.CompactTextString(m) } func (*UICreateNewRoleClickEvent) ProtoMessage() {} func (*UICreateNewRoleClickEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{27} + return fileDescriptor_94cf2ca1c69fd564, []int{28} } func (m *UICreateNewRoleClickEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1940,7 +2080,7 @@ func (m *UICreateNewRoleSaveClickEvent) Reset() { *m = UICreateNewRoleSa func (m *UICreateNewRoleSaveClickEvent) String() string { return proto.CompactTextString(m) } func (*UICreateNewRoleSaveClickEvent) ProtoMessage() {} func (*UICreateNewRoleSaveClickEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{28} + return fileDescriptor_94cf2ca1c69fd564, []int{29} } func (m *UICreateNewRoleSaveClickEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1980,7 +2120,7 @@ func (m *UICreateNewRoleCancelClickEvent) Reset() { *m = UICreateNewRole func (m *UICreateNewRoleCancelClickEvent) String() string { return proto.CompactTextString(m) } func (*UICreateNewRoleCancelClickEvent) ProtoMessage() {} func (*UICreateNewRoleCancelClickEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{29} + return fileDescriptor_94cf2ca1c69fd564, []int{30} } func (m *UICreateNewRoleCancelClickEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2024,7 +2164,7 @@ func (m *UICreateNewRoleViewDocumentationClickEvent) String() string { } func (*UICreateNewRoleViewDocumentationClickEvent) ProtoMessage() {} func (*UICreateNewRoleViewDocumentationClickEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{30} + return fileDescriptor_94cf2ca1c69fd564, []int{31} } func (m *UICreateNewRoleViewDocumentationClickEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2072,7 +2212,7 @@ func (m *AssistCompletionEvent) Reset() { *m = AssistCompletionEvent{} } func (m *AssistCompletionEvent) String() string { return proto.CompactTextString(m) } func (*AssistCompletionEvent) ProtoMessage() {} func (*AssistCompletionEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{31} + return fileDescriptor_94cf2ca1c69fd564, []int{32} } func (m *AssistCompletionEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2148,7 +2288,7 @@ func (m *IntegrationEnrollMetadata) Reset() { *m = IntegrationEnrollMeta func (m *IntegrationEnrollMetadata) String() string { return proto.CompactTextString(m) } func (*IntegrationEnrollMetadata) ProtoMessage() {} func (*IntegrationEnrollMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{32} + return fileDescriptor_94cf2ca1c69fd564, []int{33} } func (m *IntegrationEnrollMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2211,7 +2351,7 @@ func (m *UIIntegrationEnrollStartEvent) Reset() { *m = UIIntegrationEnro func (m *UIIntegrationEnrollStartEvent) String() string { return proto.CompactTextString(m) } func (*UIIntegrationEnrollStartEvent) ProtoMessage() {} func (*UIIntegrationEnrollStartEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{33} + return fileDescriptor_94cf2ca1c69fd564, []int{34} } func (m *UIIntegrationEnrollStartEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2260,7 +2400,7 @@ func (m *UIIntegrationEnrollCompleteEvent) Reset() { *m = UIIntegrationE func (m *UIIntegrationEnrollCompleteEvent) String() string { return proto.CompactTextString(m) } func (*UIIntegrationEnrollCompleteEvent) ProtoMessage() {} func (*UIIntegrationEnrollCompleteEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{34} + return fileDescriptor_94cf2ca1c69fd564, []int{35} } func (m *UIIntegrationEnrollCompleteEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2332,6 +2472,7 @@ type UsageEventOneOf struct { // *UsageEventOneOf_AssistCompletion // *UsageEventOneOf_UiIntegrationEnrollStartEvent // *UsageEventOneOf_UiIntegrationEnrollCompleteEvent + // *UsageEventOneOf_UiOnboardQuestionnaireSubmit Event isUsageEventOneOf_Event `protobuf_oneof:"event"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -2342,7 +2483,7 @@ func (m *UsageEventOneOf) Reset() { *m = UsageEventOneOf{} } func (m *UsageEventOneOf) String() string { return proto.CompactTextString(m) } func (*UsageEventOneOf) ProtoMessage() {} func (*UsageEventOneOf) Descriptor() ([]byte, []int) { - return fileDescriptor_94cf2ca1c69fd564, []int{35} + return fileDescriptor_94cf2ca1c69fd564, []int{36} } func (m *UsageEventOneOf) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2470,6 +2611,9 @@ type UsageEventOneOf_UiIntegrationEnrollStartEvent struct { type UsageEventOneOf_UiIntegrationEnrollCompleteEvent struct { UiIntegrationEnrollCompleteEvent *UIIntegrationEnrollCompleteEvent `protobuf:"bytes,32,opt,name=ui_integration_enroll_complete_event,json=uiIntegrationEnrollCompleteEvent,proto3,oneof" json:"ui_integration_enroll_complete_event,omitempty"` } +type UsageEventOneOf_UiOnboardQuestionnaireSubmit struct { + UiOnboardQuestionnaireSubmit *UIOnboardQuestionnaireSubmitEvent `protobuf:"bytes,33,opt,name=ui_onboard_questionnaire_submit,json=uiOnboardQuestionnaireSubmit,proto3,oneof" json:"ui_onboard_questionnaire_submit,omitempty"` +} func (*UsageEventOneOf_UiBannerClick) isUsageEventOneOf_Event() {} func (*UsageEventOneOf_UiOnboardCompleteGoToDashboardClick) isUsageEventOneOf_Event() {} @@ -2502,6 +2646,7 @@ func (*UsageEventOneOf_UiCallToActionClickEvent) isUsageEventOneOf_Event() func (*UsageEventOneOf_AssistCompletion) isUsageEventOneOf_Event() {} func (*UsageEventOneOf_UiIntegrationEnrollStartEvent) isUsageEventOneOf_Event() {} func (*UsageEventOneOf_UiIntegrationEnrollCompleteEvent) isUsageEventOneOf_Event() {} +func (*UsageEventOneOf_UiOnboardQuestionnaireSubmit) isUsageEventOneOf_Event() {} func (m *UsageEventOneOf) GetEvent() isUsageEventOneOf_Event { if m != nil { @@ -2727,6 +2872,13 @@ func (m *UsageEventOneOf) GetUiIntegrationEnrollCompleteEvent() *UIIntegrationEn return nil } +func (m *UsageEventOneOf) GetUiOnboardQuestionnaireSubmit() *UIOnboardQuestionnaireSubmitEvent { + if x, ok := m.GetEvent().(*UsageEventOneOf_UiOnboardQuestionnaireSubmit); ok { + return x.UiOnboardQuestionnaireSubmit + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*UsageEventOneOf) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -2761,6 +2913,7 @@ func (*UsageEventOneOf) XXX_OneofWrappers() []interface{} { (*UsageEventOneOf_AssistCompletion)(nil), (*UsageEventOneOf_UiIntegrationEnrollStartEvent)(nil), (*UsageEventOneOf_UiIntegrationEnrollCompleteEvent)(nil), + (*UsageEventOneOf_UiOnboardQuestionnaireSubmit)(nil), } } @@ -2769,11 +2922,14 @@ func init() { proto.RegisterEnum("teleport.usageevents.v1.DiscoverStatus", DiscoverStatus_name, DiscoverStatus_value) proto.RegisterEnum("teleport.usageevents.v1.CTA", CTA_name, CTA_value) proto.RegisterEnum("teleport.usageevents.v1.IntegrationEnrollKind", IntegrationEnrollKind_name, IntegrationEnrollKind_value) + proto.RegisterEnum("teleport.usageevents.v1.UIDiscoverDeployServiceEvent_DeployMethod", UIDiscoverDeployServiceEvent_DeployMethod_name, UIDiscoverDeployServiceEvent_DeployMethod_value) + proto.RegisterEnum("teleport.usageevents.v1.UIDiscoverDeployServiceEvent_DeployType", UIDiscoverDeployServiceEvent_DeployType_name, UIDiscoverDeployServiceEvent_DeployType_value) proto.RegisterType((*UIBannerClickEvent)(nil), "teleport.usageevents.v1.UIBannerClickEvent") proto.RegisterType((*UIOnboardCompleteGoToDashboardClickEvent)(nil), "teleport.usageevents.v1.UIOnboardCompleteGoToDashboardClickEvent") proto.RegisterType((*UIOnboardAddFirstResourceClickEvent)(nil), "teleport.usageevents.v1.UIOnboardAddFirstResourceClickEvent") proto.RegisterType((*UIOnboardAddFirstResourceLaterClickEvent)(nil), "teleport.usageevents.v1.UIOnboardAddFirstResourceLaterClickEvent") proto.RegisterType((*UIOnboardSetCredentialSubmitEvent)(nil), "teleport.usageevents.v1.UIOnboardSetCredentialSubmitEvent") + proto.RegisterType((*UIOnboardQuestionnaireSubmitEvent)(nil), "teleport.usageevents.v1.UIOnboardQuestionnaireSubmitEvent") proto.RegisterType((*UIOnboardRegisterChallengeSubmitEvent)(nil), "teleport.usageevents.v1.UIOnboardRegisterChallengeSubmitEvent") proto.RegisterType((*UIRecoveryCodesContinueClickEvent)(nil), "teleport.usageevents.v1.UIRecoveryCodesContinueClickEvent") proto.RegisterType((*UIRecoveryCodesCopyClickEvent)(nil), "teleport.usageevents.v1.UIRecoveryCodesCopyClickEvent") @@ -2812,188 +2968,201 @@ func init() { } var fileDescriptor_94cf2ca1c69fd564 = []byte{ - // 2887 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5b, 0xdb, 0x6f, 0xdc, 0xc6, - 0xd5, 0x5f, 0xee, 0xfa, 0x22, 0x8f, 0x6d, 0x99, 0x1e, 0xdf, 0x56, 0xd6, 0x7d, 0xe5, 0xab, 0x9c, - 0x4f, 0x8a, 0x9d, 0x7c, 0x89, 0xbf, 0xcf, 0x69, 0x03, 0x8a, 0xa4, 0x44, 0x5a, 0xbb, 0xcb, 0xcd, - 0x0c, 0xd7, 0xae, 0x02, 0x04, 0x03, 0x7a, 0x77, 0xac, 0x10, 0xa6, 0xc8, 0x05, 0xc9, 0x95, 0x2a, - 0x14, 0x45, 0xd0, 0xa2, 0x2d, 0x0a, 0x24, 0x28, 0xda, 0xb7, 0x02, 0x05, 0x02, 0x14, 0x6d, 0x81, - 0x3e, 0x14, 0x7d, 0x2b, 0xf2, 0xdc, 0xb7, 0x3e, 0x16, 0xfd, 0x0b, 0x8a, 0xbc, 0xf7, 0xb1, 0x0f, - 0x2d, 0x5a, 0xb4, 0xe0, 0xf0, 0xb2, 0xdc, 0x1b, 0xc9, 0x04, 0xed, 0x8b, 0xf2, 0x26, 0x72, 0x7e, - 0x67, 0xe6, 0x37, 0xe7, 0x9c, 0xb9, 0x9c, 0x1f, 0xb5, 0xe0, 0xbe, 0x4f, 0x2d, 0xda, 0x73, 0x5c, - 0x7f, 0xb3, 0xef, 0x19, 0xfb, 0x94, 0x1e, 0x52, 0xdb, 0xf7, 0x36, 0x0f, 0x1f, 0xa6, 0x1f, 0x37, - 0x7a, 0xae, 0xe3, 0x3b, 0xf0, 0x46, 0x0c, 0xdd, 0x48, 0xb7, 0x1d, 0x3e, 0xac, 0xad, 0x03, 0xd8, - 0x56, 0xb7, 0x0c, 0xdb, 0xa6, 0xae, 0x68, 0x99, 0x9d, 0x57, 0x72, 0xd0, 0x02, 0xaf, 0x82, 0xd3, - 0x86, 0x45, 0x5d, 0xbf, 0xca, 0xad, 0x70, 0xf7, 0xce, 0xa1, 0xf0, 0xa1, 0xb6, 0x0d, 0xee, 0xb5, - 0x55, 0xcd, 0x7e, 0xe1, 0x18, 0x6e, 0x57, 0x74, 0x0e, 0x7a, 0x16, 0xf5, 0xe9, 0x8e, 0xa3, 0x3b, - 0x92, 0xe1, 0x7d, 0x18, 0xbe, 0x1c, 0xf4, 0x70, 0x13, 0xcc, 0xf4, 0x3d, 0xea, 0xda, 0xc6, 0x01, - 0x8d, 0x3a, 0x49, 0x9e, 0x6b, 0xb7, 0xc1, 0x5a, 0xd2, 0x8f, 0xd0, 0xed, 0x6e, 0x9b, 0xae, 0xe7, - 0x23, 0xea, 0x39, 0x7d, 0xb7, 0x43, 0x07, 0x5d, 0xd4, 0xd6, 0x53, 0xc3, 0x8d, 0xc2, 0xea, 0x86, - 0x9f, 0x26, 0x5c, 0x7b, 0x17, 0xac, 0x26, 0x58, 0x4c, 0x7d, 0xd1, 0xa5, 0x5d, 0x6a, 0xfb, 0xa6, - 0x61, 0xe1, 0xfe, 0x8b, 0x03, 0xd3, 0xcf, 0xe7, 0xf4, 0x6d, 0x70, 0x3b, 0xe9, 0x00, 0xd1, 0x7d, - 0xd3, 0x0b, 0xfa, 0xff, 0xd0, 0xb0, 0x2c, 0x6a, 0xef, 0xd3, 0x82, 0x9d, 0xc0, 0x39, 0x30, 0x73, - 0xf0, 0xd2, 0x20, 0xfe, 0x71, 0x8f, 0x56, 0xcb, 0xac, 0xed, 0xec, 0xc1, 0x4b, 0x43, 0x3f, 0xee, - 0x51, 0xb8, 0x08, 0x80, 0xe5, 0xec, 0x9b, 0x36, 0x79, 0x69, 0x39, 0x47, 0xd5, 0x0a, 0x6b, 0x3c, - 0xc7, 0xde, 0x6c, 0x5b, 0xce, 0x51, 0xc8, 0x1f, 0xd1, 0x8e, 0x73, 0x48, 0xdd, 0x63, 0xd1, 0xe9, - 0x52, 0x4f, 0x74, 0x6c, 0xdf, 0xb4, 0xfb, 0xb4, 0xa0, 0x4f, 0x9f, 0x80, 0xc5, 0xb1, 0x0e, 0x7a, - 0xc7, 0x05, 0x8d, 0xdf, 0x01, 0x4b, 0x23, 0xc6, 0x2d, 0xd7, 0xb4, 0xfd, 0x82, 0xd6, 0x35, 0xc0, - 0x4b, 0xa6, 0xc7, 0x8c, 0x1b, 0xd4, 0x37, 0xba, 0x86, 0x6f, 0xc0, 0x59, 0x50, 0x36, 0xbb, 0x11, - 0xb2, 0x6c, 0x76, 0x6b, 0x06, 0xa8, 0xc6, 0x98, 0x38, 0x84, 0x09, 0x56, 0x06, 0x33, 0x6e, 0xf4, - 0x8e, 0x59, 0xcc, 0x3e, 0xba, 0xbf, 0x31, 0x25, 0x5d, 0x37, 0x46, 0x3b, 0x41, 0x89, 0x69, 0xed, - 0x15, 0x80, 0x71, 0x2b, 0xf6, 0x69, 0x0f, 0xfb, 0x86, 0xdf, 0xf7, 0xe0, 0xbb, 0xe0, 0x8c, 0xc7, - 0xfe, 0x8a, 0xba, 0xbe, 0x9b, 0xdb, 0x75, 0x68, 0x88, 0x22, 0xb3, 0x60, 0x29, 0x50, 0xd7, 0x75, - 0xdc, 0x28, 0xa0, 0xe1, 0x43, 0xed, 0x97, 0x1c, 0xb8, 0xde, 0x56, 0x53, 0x26, 0xae, 0x4f, 0xbb, - 0xa1, 0xab, 0x64, 0x30, 0x73, 0x10, 0x4d, 0x8d, 0x8d, 0x79, 0xbe, 0xc0, 0x74, 0x62, 0x5f, 0xa0, - 0xc4, 0x14, 0x8a, 0x09, 0xf1, 0x32, 0xeb, 0xe4, 0x41, 0x01, 0xe2, 0xf1, 0xac, 0x63, 0xf2, 0xb5, - 0x7f, 0x72, 0x60, 0x65, 0x40, 0x33, 0x76, 0x1a, 0xa6, 0x16, 0xed, 0xf8, 0xa6, 0x63, 0xff, 0x47, - 0x09, 0x37, 0x52, 0x61, 0x0c, 0x29, 0x3f, 0x2c, 0x1c, 0xc6, 0x41, 0x77, 0x71, 0x17, 0xa9, 0xf9, - 0x57, 0xbe, 0xfc, 0xfc, 0xbf, 0x5f, 0x0e, 0xf6, 0x90, 0x18, 0xa0, 0xda, 0x3e, 0xdd, 0x77, 0x8d, - 0x60, 0xe6, 0xc2, 0x73, 0xac, 0xa9, 0x92, 0x28, 0x3a, 0xb6, 0x4d, 0x3b, 0xfe, 0x89, 0xf7, 0xc3, - 0x67, 0xe5, 0x74, 0x1e, 0x48, 0x86, 0x6f, 0xbc, 0x30, 0x3c, 0x8a, 0x24, 0x2c, 0xdb, 0xae, 0x63, - 0x59, 0x27, 0x7d, 0xfe, 0xf0, 0x31, 0xa8, 0x7a, 0x2c, 0xe9, 0x69, 0x97, 0xc4, 0x3d, 0x7b, 0xa4, - 0xe3, 0xf4, 0x6d, 0xbf, 0x7a, 0x6a, 0x85, 0xbb, 0x57, 0x41, 0xd7, 0xe3, 0xf6, 0x98, 0x8a, 0x27, - 0x06, 0xad, 0xb5, 0xa7, 0xa0, 0xda, 0x56, 0x45, 0xc3, 0xb2, 0x74, 0x47, 0x60, 0x6b, 0x26, 0xb5, - 0x29, 0x6e, 0x80, 0x4a, 0x27, 0xf2, 0xd5, 0xec, 0xa3, 0x85, 0xa9, 0xbc, 0x44, 0x5d, 0x40, 0x01, - 0xb0, 0xf6, 0x37, 0x0e, 0x2c, 0xa4, 0xa2, 0x40, 0x7b, 0x96, 0x73, 0x8c, 0xa9, 0x7b, 0x68, 0x76, - 0xe8, 0x89, 0xcf, 0xc0, 0x7f, 0x70, 0x60, 0x79, 0x42, 0x06, 0x46, 0x27, 0xed, 0x89, 0x9f, 0xfe, - 0x77, 0xca, 0xe0, 0xd6, 0xf8, 0xf4, 0x45, 0xc7, 0x7e, 0x69, 0xee, 0xf7, 0x5d, 0xda, 0xd0, 0xeb, - 0xf8, 0xc4, 0xfb, 0xe0, 0x47, 0x65, 0xf0, 0x30, 0x9d, 0xfe, 0xde, 0x2b, 0xdf, 0xe9, 0x05, 0x8b, - 0xea, 0x90, 0x4a, 0xa6, 0x4b, 0x3b, 0xbe, 0xe3, 0x1e, 0xeb, 0x8e, 0x63, 0x79, 0xaa, 0xed, 0xf9, - 0xc6, 0xc9, 0xdf, 0x95, 0x6a, 0x1f, 0x97, 0xc1, 0x46, 0x9e, 0x43, 0x92, 0x14, 0x39, 0xf1, 0xde, - 0xf8, 0x4d, 0x19, 0xdc, 0x19, 0x78, 0x43, 0xe8, 0xfb, 0x4e, 0xfc, 0x77, 0x6a, 0x53, 0x3e, 0xf1, - 0x27, 0xd5, 0x5d, 0x70, 0x69, 0xf2, 0x01, 0x35, 0xeb, 0x0e, 0x1f, 0x4c, 0x3f, 0x28, 0x83, 0xfb, - 0x19, 0x3b, 0x8a, 0x2a, 0x34, 0x5a, 0x8e, 0x65, 0x76, 0x8e, 0x4f, 0x7c, 0xde, 0xfc, 0x8b, 0x03, - 0xb5, 0x81, 0x23, 0x82, 0xc2, 0xa5, 0x63, 0xf6, 0x0c, 0xcb, 0xfb, 0xea, 0xac, 0x9c, 0xbf, 0x73, - 0x41, 0xf1, 0x17, 0x03, 0x74, 0xea, 0xf9, 0xd1, 0xbd, 0xf6, 0xab, 0x70, 0xc5, 0xff, 0x2b, 0x17, - 0xdc, 0xd0, 0x62, 0x40, 0x2c, 0x4b, 0x74, 0x4f, 0xfc, 0xbc, 0xe7, 0xc1, 0x5c, 0x5b, 0x15, 0x5d, - 0x6a, 0xf8, 0xb4, 0x49, 0x8f, 0x90, 0x63, 0xa5, 0xa5, 0x93, 0xe5, 0x20, 0x21, 0x86, 0x1a, 0xb1, - 0x71, 0x98, 0x06, 0xac, 0x06, 0xb7, 0xb1, 0x61, 0x6b, 0xc3, 0xee, 0x50, 0x2b, 0x05, 0x79, 0x0d, - 0xac, 0x8f, 0x40, 0x9e, 0x99, 0xf4, 0x48, 0x72, 0x3a, 0xfd, 0x03, 0x6a, 0xfb, 0xc6, 0xf0, 0x5d, - 0xb8, 0xf6, 0x3b, 0x0e, 0x5c, 0x13, 0x3c, 0xcf, 0x0c, 0x72, 0x8f, 0x85, 0x20, 0xc9, 0xbd, 0xbb, - 0xe0, 0x52, 0xc7, 0xb1, 0x0f, 0xa9, 0xeb, 0x31, 0x1b, 0x92, 0xe8, 0x02, 0xb3, 0xe9, 0xd7, 0x6a, - 0x17, 0xae, 0x82, 0x0b, 0xbe, 0xe3, 0x1b, 0x16, 0xf1, 0x9d, 0x57, 0xd4, 0x0e, 0xeb, 0xde, 0x0a, - 0x3a, 0xcf, 0xde, 0xe9, 0xec, 0x15, 0x5c, 0x03, 0x17, 0x7b, 0xae, 0x73, 0xd0, 0xf3, 0x63, 0x4c, - 0x85, 0x61, 0x2e, 0x84, 0x2f, 0x23, 0xd0, 0x03, 0x70, 0xb9, 0x93, 0x70, 0x88, 0x81, 0xe1, 0x26, - 0xca, 0x0f, 0x1a, 0x42, 0x70, 0xed, 0x13, 0x0e, 0xcc, 0xa5, 0xea, 0xc2, 0xb0, 0x1e, 0x9a, 0x26, - 0x63, 0xc0, 0x2d, 0x70, 0xea, 0x95, 0x69, 0x77, 0x19, 0xb5, 0xd9, 0x47, 0x1b, 0x53, 0xe3, 0x36, - 0xd6, 0xe3, 0xae, 0x69, 0x77, 0x11, 0xb3, 0x85, 0xf3, 0xe0, 0x5c, 0xdf, 0xa3, 0x2e, 0x61, 0x5a, - 0x4a, 0x65, 0xa0, 0xa5, 0x34, 0x8d, 0x03, 0x5a, 0x73, 0x82, 0xc0, 0x8d, 0x59, 0x33, 0x7d, 0x21, - 0xf4, 0x66, 0x73, 0x2c, 0xa3, 0x1f, 0x15, 0x67, 0x31, 0x9e, 0xda, 0x35, 0x37, 0x28, 0x0c, 0xc7, - 0x80, 0xf1, 0x32, 0xfa, 0xef, 0x8c, 0xf9, 0x69, 0x0d, 0x5c, 0x6a, 0x07, 0x66, 0xac, 0x7b, 0xcd, - 0xa6, 0xda, 0x4b, 0xd8, 0x06, 0x97, 0xfa, 0x26, 0x79, 0xc1, 0x84, 0x48, 0xd2, 0x09, 0xf2, 0x2a, - 0x1a, 0x6a, 0xfa, 0xe2, 0x18, 0xd7, 0x2d, 0x95, 0x12, 0xba, 0xd8, 0x37, 0x53, 0x6f, 0xe1, 0xcf, - 0x38, 0x70, 0xbf, 0x6f, 0x12, 0x27, 0x14, 0xf6, 0x48, 0x14, 0x7e, 0x4a, 0xf6, 0x1d, 0xe2, 0x3b, - 0xa4, 0x1b, 0x0b, 0x97, 0xd1, 0x88, 0xe1, 0x72, 0x14, 0x32, 0x46, 0x2c, 0xa6, 0x7e, 0x2a, 0x25, - 0xb4, 0xd6, 0x37, 0x73, 0xb1, 0xf0, 0x63, 0x0e, 0xac, 0xa5, 0xd8, 0x19, 0xdd, 0x2e, 0x79, 0x69, - 0xba, 0x9e, 0x9f, 0xd4, 0xa8, 0x11, 0xaf, 0x53, 0x8c, 0xd7, 0x3b, 0xf9, 0xbc, 0xa6, 0xab, 0xa9, - 0x4a, 0x09, 0x2d, 0x25, 0x94, 0x26, 0xc2, 0x46, 0x7d, 0x35, 0x81, 0x8d, 0x65, 0xf8, 0x49, 0x74, - 0x4e, 0x17, 0xf5, 0x55, 0x8e, 0x74, 0x3b, 0xe4, 0xab, 0xe9, 0x58, 0xf8, 0x3d, 0x0e, 0xac, 0xa4, - 0xd8, 0x79, 0xd4, 0x27, 0x9d, 0x44, 0xe5, 0x25, 0x1e, 0x53, 0x68, 0xab, 0x67, 0x18, 0xa9, 0xff, - 0xcf, 0x27, 0x35, 0x4d, 0x23, 0x56, 0x4a, 0x68, 0x21, 0x61, 0x33, 0x01, 0x04, 0x7f, 0xcc, 0x81, - 0x5b, 0x29, 0x1a, 0x6e, 0x54, 0xc0, 0x92, 0x4e, 0xac, 0x15, 0xc7, 0x54, 0xce, 0x32, 0x2a, 0x5f, - 0xcf, 0xa7, 0x92, 0xa5, 0x36, 0x2b, 0x25, 0xb4, 0x92, 0xd0, 0x99, 0x02, 0x8c, 0x3d, 0xe3, 0x46, - 0xfa, 0x2d, 0xe9, 0x38, 0x5d, 0x76, 0x77, 0x0c, 0xf5, 0xe3, 0x28, 0x5c, 0x33, 0xb9, 0x9e, 0xc9, - 0x51, 0x9f, 0x43, 0xcf, 0x4c, 0x07, 0xc1, 0x6f, 0x82, 0x85, 0x49, 0x2c, 0x7a, 0xc7, 0x11, 0x83, - 0x73, 0x8c, 0xc1, 0x5b, 0xc5, 0x19, 0xa4, 0xe5, 0x6b, 0xa5, 0x84, 0xaa, 0x63, 0xa3, 0x47, 0x00, - 0xf8, 0x2d, 0xb0, 0x38, 0x3e, 0x72, 0xcf, 0x35, 0x6d, 0x3f, 0x1a, 0x1a, 0xb0, 0xa1, 0xdf, 0x2e, - 0x3a, 0xf4, 0x88, 0xf8, 0xad, 0x94, 0xd0, 0xdc, 0xc8, 0xd8, 0x03, 0x04, 0xb4, 0xc0, 0x5c, 0xdf, - 0x24, 0xdd, 0xe8, 0xa0, 0x26, 0x5e, 0x28, 0x05, 0x13, 0xd6, 0x79, 0xf5, 0x3c, 0x1b, 0x78, 0x33, - 0x63, 0xe0, 0x49, 0x12, 0xb2, 0x52, 0x42, 0xd7, 0xfb, 0xe6, 0x44, 0x71, 0xf9, 0xe3, 0x30, 0xfd, - 0x92, 0xe1, 0x92, 0xa5, 0xe9, 0xc5, 0x9a, 0x6e, 0x34, 0xf2, 0x05, 0x36, 0xf2, 0xff, 0x15, 0x18, - 0x79, 0xb2, 0x2a, 0x1c, 0x66, 0x5e, 0x8e, 0x72, 0xfc, 0x11, 0x4b, 0xbc, 0x84, 0x4c, 0x97, 0x29, - 0x5a, 0xc4, 0x0b, 0x25, 0xad, 0x88, 0xc8, 0x45, 0x46, 0xe4, 0x7f, 0x0b, 0x10, 0x19, 0x17, 0xc4, - 0xc2, 0x9c, 0xcb, 0x10, 0xcc, 0x7e, 0x18, 0x6e, 0xa0, 0x03, 0x06, 0x51, 0x19, 0x34, 0x58, 0x97, - 0x21, 0x89, 0x59, 0x46, 0xe2, 0x71, 0x11, 0x12, 0x93, 0x94, 0x29, 0xa5, 0x84, 0x96, 0x53, 0x3c, - 0x26, 0x8a, 0x57, 0x3f, 0x0d, 0x77, 0xcf, 0x71, 0x2a, 0x9d, 0xb8, 0x0e, 0x21, 0x07, 0xbe, 0xe5, - 0x45, 0x84, 0x2e, 0x31, 0x42, 0x5f, 0xfb, 0x02, 0x84, 0xc6, 0xb5, 0x22, 0xa5, 0x84, 0x6e, 0x8d, - 0xb3, 0x1a, 0xe0, 0x7c, 0x2b, 0x2a, 0x97, 0x7f, 0xcf, 0x81, 0xc7, 0xc3, 0x71, 0x62, 0x4a, 0x03, - 0x31, 0x98, 0xd4, 0x40, 0xba, 0xb1, 0xd6, 0x40, 0x7c, 0xc7, 0xb1, 0x3c, 0x62, 0x86, 0xf2, 0x4b, - 0xc4, 0x94, 0x67, 0x4c, 0x9f, 0x16, 0x8a, 0x5f, 0x21, 0x45, 0x47, 0x29, 0xa1, 0x87, 0xe9, 0xa0, - 0x16, 0x93, 0x81, 0x3e, 0xe3, 0xc0, 0x9b, 0x85, 0xe6, 0x30, 0x70, 0x77, 0xc8, 0xff, 0x32, 0xe3, - 0xbf, 0xf3, 0xa5, 0xf9, 0x0f, 0x97, 0x91, 0x4a, 0x09, 0x6d, 0xe4, 0x91, 0x1f, 0x29, 0x3c, 0x3f, - 0xe5, 0xc0, 0x83, 0x34, 0x73, 0xa3, 0x1f, 0xdc, 0x3c, 0x12, 0x69, 0x23, 0xa5, 0x47, 0x87, 0x84, - 0x21, 0x23, 0xfc, 0x6e, 0x01, 0xc2, 0x59, 0x1a, 0x89, 0x52, 0x42, 0x77, 0x06, 0x44, 0x33, 0xd5, - 0x94, 0x5f, 0x73, 0x60, 0x33, 0x27, 0x73, 0x4d, 0xe3, 0x80, 0xf4, 0x98, 0x9c, 0x10, 0x91, 0xbc, - 0xc2, 0x48, 0x6e, 0x7d, 0x99, 0xfc, 0x1d, 0x56, 0x26, 0x94, 0x12, 0xba, 0x9f, 0x91, 0xc4, 0xaa, - 0x71, 0x90, 0x96, 0x31, 0x7e, 0xc2, 0x81, 0x3b, 0x69, 0xaa, 0xbd, 0xa4, 0xda, 0x1f, 0x8b, 0xfb, - 0x55, 0xc6, 0xf0, 0x49, 0x01, 0x86, 0xd3, 0x24, 0x03, 0xa5, 0x84, 0x6a, 0x03, 0x6a, 0x53, 0x85, - 0x85, 0xef, 0x72, 0x60, 0x35, 0xcd, 0xc9, 0xa7, 0x9e, 0x1f, 0xb0, 0xb1, 0x87, 0xf6, 0xe3, 0x6b, - 0xb9, 0xa7, 0x5f, 0x46, 0xfd, 0xae, 0x94, 0xd0, 0xe2, 0x80, 0xc9, 0xa4, 0x02, 0xdf, 0x05, 0xf3, - 0x69, 0x0e, 0xf1, 0x3d, 0x37, 0x3e, 0x87, 0xae, 0xe7, 0x14, 0xad, 0xd3, 0x0a, 0xe8, 0xf0, 0xd8, - 0x9d, 0x52, 0x5c, 0x5b, 0xa0, 0xda, 0x37, 0x83, 0x4b, 0x98, 0xe1, 0x53, 0x62, 0xd3, 0x23, 0xe2, - 0x3a, 0x56, 0x7c, 0xdd, 0xb8, 0x91, 0x53, 0x26, 0x4c, 0x2d, 0x5d, 0x95, 0x12, 0xba, 0xda, 0x37, - 0xc7, 0x1b, 0xe1, 0x31, 0x3b, 0xe4, 0x47, 0x47, 0xf3, 0x8c, 0xc3, 0x78, 0xc8, 0x6a, 0xae, 0x87, - 0x33, 0x0a, 0xe2, 0x70, 0xa2, 0x93, 0x01, 0xf0, 0x23, 0xb0, 0x3c, 0x69, 0xa2, 0xac, 0x60, 0x8e, - 0x06, 0x9f, 0xcb, 0x3d, 0x60, 0x32, 0x8b, 0x6d, 0xa5, 0x84, 0x6e, 0x8e, 0xce, 0x7a, 0x00, 0x81, - 0x3f, 0x0f, 0xb7, 0x90, 0x51, 0x06, 0x87, 0x26, 0x3d, 0x22, 0xdd, 0x74, 0x41, 0x1e, 0xb1, 0xb9, - 0xc9, 0xd8, 0x88, 0x45, 0xd9, 0x64, 0xd4, 0xf5, 0x4a, 0x09, 0xdd, 0x1e, 0x21, 0x36, 0x19, 0x0d, - 0x7f, 0xc5, 0x81, 0x8d, 0x74, 0x0a, 0x9a, 0x83, 0x42, 0x90, 0x18, 0x47, 0x1e, 0x71, 0xcc, 0x6e, - 0x27, 0x5e, 0x16, 0x51, 0x56, 0xce, 0xe7, 0x96, 0x10, 0xc5, 0xbe, 0xdc, 0x2a, 0x25, 0x74, 0x6f, - 0x90, 0xa5, 0x69, 0xec, 0x91, 0xa7, 0x99, 0xdd, 0xce, 0xd0, 0x57, 0xde, 0x4f, 0x38, 0x70, 0x7b, - 0xf2, 0x95, 0xa1, 0xeb, 0x11, 0xca, 0x4a, 0xd6, 0x88, 0xde, 0x42, 0xe1, 0x2b, 0xd4, 0xe4, 0x0f, - 0xaa, 0xc3, 0x57, 0xa8, 0x04, 0xd3, 0xf5, 0xd2, 0x1f, 0x5d, 0xfd, 0x30, 0xad, 0x83, 0xf3, 0xd6, - 0x77, 0xd8, 0x69, 0x16, 0x47, 0x31, 0x62, 0xb1, 0x98, 0xbb, 0x74, 0x27, 0x7f, 0x9d, 0x8c, 0x32, - 0x7a, 0xf2, 0x97, 0xcb, 0x0f, 0xc0, 0x65, 0x83, 0x89, 0x35, 0x64, 0x20, 0x88, 0x54, 0x97, 0xd8, - 0x48, 0xd3, 0x45, 0x8d, 0x89, 0xf2, 0x8e, 0x52, 0x42, 0xbc, 0x31, 0xd2, 0x10, 0x6f, 0x89, 0xe9, - 0x14, 0x88, 0x3c, 0xcb, 0xae, 0xc7, 0xd1, 0xcc, 0x96, 0x73, 0x17, 0x6c, 0x86, 0x10, 0x12, 0x6e, - 0x89, 0x59, 0x4a, 0x49, 0x74, 0x55, 0x9e, 0x40, 0x22, 0x51, 0x01, 0x42, 0x1e, 0x2b, 0xb9, 0x71, - 0xce, 0xd6, 0x47, 0xc2, 0x38, 0x67, 0x63, 0xb6, 0xce, 0x82, 0xd3, 0xac, 0xc7, 0xa7, 0xa7, 0x66, - 0xca, 0x7c, 0x25, 0xb8, 0xd6, 0x26, 0x35, 0xe4, 0x3e, 0xf5, 0x93, 0xb2, 0x81, 0x45, 0x7e, 0xfd, - 0x2f, 0x17, 0x07, 0xff, 0x52, 0x13, 0x1f, 0xd6, 0x70, 0x15, 0x2c, 0x4a, 0x2a, 0x16, 0xb5, 0x67, - 0x32, 0x22, 0x48, 0xc6, 0x5a, 0x1b, 0x89, 0x32, 0x69, 0x37, 0x71, 0x4b, 0x16, 0xd5, 0x6d, 0x55, - 0x96, 0xf8, 0x12, 0x5c, 0x00, 0xd5, 0x71, 0x08, 0x96, 0xd1, 0x33, 0x19, 0xf1, 0x1c, 0x5c, 0x01, - 0x0b, 0xe3, 0xad, 0xbb, 0xed, 0x2d, 0x19, 0x35, 0x65, 0x5d, 0xc6, 0x7c, 0x19, 0xbe, 0x01, 0x36, - 0xc7, 0x11, 0x92, 0xa0, 0x0b, 0x5b, 0x02, 0x96, 0x49, 0x4b, 0xc3, 0xfa, 0x0e, 0x92, 0x31, 0xc1, - 0x72, 0x7d, 0x9b, 0x28, 0x1a, 0xd6, 0x65, 0x89, 0xaf, 0xc0, 0xd7, 0xc1, 0x6b, 0x19, 0x46, 0x8d, - 0x3d, 0xfc, 0x5e, 0x7d, 0xc8, 0xe2, 0x14, 0x7c, 0x04, 0x36, 0xb2, 0x2c, 0xb4, 0xe6, 0x8e, 0x26, - 0x6d, 0x0d, 0xd9, 0x9c, 0x86, 0x0f, 0xc0, 0xdd, 0x22, 0xd4, 0x90, 0x84, 0xf9, 0x33, 0xf0, 0x1e, - 0xb8, 0x95, 0x4b, 0x29, 0x40, 0x9e, 0x85, 0x77, 0x40, 0x6d, 0x1c, 0x29, 0xb4, 0x5a, 0x75, 0x55, - 0x14, 0x74, 0x55, 0x6b, 0x12, 0x45, 0xd7, 0x5b, 0xfc, 0x0c, 0xbc, 0x0d, 0x56, 0xb3, 0x71, 0xba, - 0xd8, 0xe2, 0xcf, 0x4d, 0x86, 0x3d, 0x57, 0x9b, 0x92, 0xf6, 0x1c, 0x13, 0x49, 0xc6, 0xbb, 0xba, - 0xd6, 0xe2, 0x01, 0x7c, 0x0d, 0xdc, 0xcb, 0xe0, 0x87, 0xdf, 0xab, 0x87, 0x31, 0x63, 0x1c, 0xcf, - 0xe7, 0x38, 0x78, 0x30, 0x75, 0x59, 0xc2, 0x8a, 0xba, 0xad, 0xf3, 0x17, 0xe0, 0x9b, 0xe0, 0xf5, - 0x42, 0xfd, 0xa7, 0x5d, 0x7c, 0x31, 0x67, 0x1c, 0x24, 0x4b, 0xea, 0x70, 0xe8, 0x67, 0x8b, 0x06, - 0x65, 0x47, 0x6c, 0xf1, 0x97, 0x0a, 0x05, 0x25, 0x40, 0xf2, 0x85, 0xdd, 0x13, 0xa0, 0x2f, 0xc3, - 0x27, 0xe0, 0xed, 0x2f, 0xe2, 0x9e, 0x68, 0x3d, 0xd4, 0x65, 0x8c, 0x79, 0x08, 0xff, 0x07, 0xdc, - 0x2f, 0x62, 0x2c, 0xbc, 0xdf, 0x46, 0x32, 0x7f, 0x05, 0xde, 0x05, 0x6b, 0x19, 0x70, 0x69, 0xaf, - 0x29, 0x34, 0x34, 0x69, 0x8b, 0xbf, 0x9a, 0x93, 0xe2, 0xa2, 0x80, 0xb1, 0xd0, 0x94, 0x90, 0x40, - 0x76, 0xe5, 0x3d, 0xdc, 0x12, 0x44, 0x19, 0xf3, 0xd7, 0x72, 0xa2, 0x36, 0xb0, 0x49, 0xc7, 0xe0, - 0x3a, 0x7c, 0x0c, 0xde, 0xcc, 0xb0, 0x92, 0xeb, 0x02, 0xd6, 0x55, 0x11, 0xcb, 0x02, 0x12, 0x95, - 0x21, 0xcb, 0x1b, 0x85, 0xe2, 0x1d, 0xd9, 0x0b, 0xa2, 0x22, 0xf3, 0xd5, 0x1c, 0x6f, 0x85, 0x16, - 0x0d, 0xb9, 0xa1, 0xa1, 0x3d, 0x69, 0x8b, 0x9f, 0x2b, 0x34, 0x00, 0xf3, 0x2c, 0x09, 0x07, 0xb8, - 0x99, 0x33, 0x99, 0xd0, 0x42, 0xac, 0xb7, 0xb1, 0x3e, 0x92, 0xbc, 0xf3, 0x70, 0x1d, 0xdc, 0xc9, - 0xcd, 0xae, 0x30, 0x8a, 0x0b, 0x70, 0x03, 0xac, 0x17, 0xca, 0xaf, 0x10, 0xbf, 0x98, 0x13, 0xcc, - 0x01, 0xbe, 0xa1, 0x8a, 0x48, 0xc3, 0xda, 0xb6, 0xce, 0x2f, 0xc1, 0xb7, 0xc0, 0xa3, 0xac, 0x60, - 0x6a, 0xe2, 0x2e, 0xd2, 0x04, 0x51, 0x19, 0xd9, 0xe7, 0x96, 0x73, 0x72, 0x3f, 0xde, 0x1b, 0x05, - 0xbd, 0x2e, 0x60, 0x7e, 0x25, 0x67, 0x4d, 0xe1, 0xa6, 0xf6, 0x7c, 0xbb, 0x2e, 0xec, 0xca, 0xfc, - 0xea, 0x94, 0x7e, 0x35, 0x31, 0xe5, 0x5d, 0x09, 0x93, 0x16, 0xd2, 0xbe, 0xb1, 0xc7, 0xd7, 0xa6, - 0xa4, 0x62, 0x1a, 0xad, 0xa8, 0x3b, 0x0a, 0x11, 0x9e, 0x09, 0x6a, 0x5d, 0xd8, 0x52, 0xeb, 0xaa, - 0xbe, 0xc7, 0xaf, 0xc1, 0xb7, 0xc1, 0x1b, 0x39, 0x56, 0x6c, 0x85, 0xa8, 0x22, 0x41, 0xf2, 0x8e, - 0x8a, 0x75, 0xc4, 0xb6, 0x4e, 0xfe, 0xd6, 0xfa, 0x2f, 0x38, 0x30, 0x3b, 0xfc, 0xef, 0x97, 0x70, - 0x19, 0xcc, 0x27, 0x7d, 0x61, 0x5d, 0xd0, 0xdb, 0x78, 0xe4, 0xac, 0x9b, 0x07, 0x37, 0x46, 0x01, - 0xb8, 0x2d, 0x8a, 0xc1, 0xb2, 0xe6, 0x26, 0x36, 0xee, 0xaa, 0xad, 0x96, 0x2c, 0xf1, 0x65, 0x38, - 0x07, 0xae, 0x8d, 0x36, 0xca, 0x08, 0x69, 0x88, 0xaf, 0x4c, 0xb2, 0x13, 0xb6, 0x34, 0xc4, 0x8e, - 0xad, 0xf5, 0xdf, 0x72, 0xa0, 0x22, 0xea, 0x02, 0xbc, 0x02, 0x2e, 0x89, 0xba, 0x30, 0x42, 0xe7, - 0x3a, 0x80, 0xc1, 0x4b, 0xa1, 0xad, 0x2b, 0x44, 0xd4, 0x9a, 0x4d, 0x59, 0xd4, 0xb5, 0xe0, 0xd0, - 0xbd, 0x01, 0xae, 0xb0, 0xf7, 0xa2, 0xae, 0x3e, 0x0b, 0xce, 0x62, 0x8c, 0x55, 0xad, 0x19, 0x9c, - 0xb5, 0x49, 0x43, 0x40, 0x99, 0x20, 0xf9, 0xbd, 0xb6, 0x8c, 0x75, 0xcc, 0x57, 0xe2, 0x86, 0x16, - 0x92, 0x1b, 0x6a, 0xbb, 0x41, 0x70, 0xbb, 0xd5, 0xd2, 0x90, 0xce, 0x9f, 0x8a, 0x1b, 0x74, 0x14, - 0xe4, 0xbf, 0x44, 0x24, 0xf9, 0x99, 0x1a, 0x6c, 0x1c, 0xa7, 0xe3, 0xb1, 0xdb, 0xad, 0x1d, 0x24, - 0x48, 0x32, 0xd9, 0x12, 0x9a, 0x4d, 0x19, 0xf1, 0x67, 0xd6, 0xff, 0x54, 0x01, 0xd7, 0x26, 0x7e, - 0x89, 0x0a, 0xf6, 0x31, 0xb5, 0xa9, 0xcb, 0x3b, 0x61, 0x04, 0x88, 0xdc, 0x44, 0x5a, 0xbd, 0x4e, - 0x76, 0xd5, 0xa6, 0x34, 0x32, 0xad, 0x55, 0xb0, 0x38, 0x0d, 0x88, 0xeb, 0x82, 0xb8, 0xcb, 0x73, - 0xf0, 0x16, 0x58, 0x99, 0x06, 0x11, 0x9e, 0x63, 0x12, 0x5c, 0xd6, 0xf9, 0x72, 0x70, 0x32, 0x4e, - 0x43, 0xb5, 0x84, 0x1d, 0x19, 0x49, 0x6d, 0x7d, 0x8f, 0xaf, 0x64, 0x8d, 0x27, 0x37, 0x04, 0xb5, - 0xce, 0x9f, 0x0a, 0xae, 0x31, 0xd3, 0x20, 0x4f, 0x55, 0x24, 0xf0, 0xa7, 0xe1, 0x1a, 0x58, 0x9e, - 0x86, 0x60, 0xd1, 0x45, 0x12, 0x7f, 0x26, 0x38, 0xf9, 0xa7, 0x81, 0x1a, 0x82, 0xae, 0xcb, 0xa8, - 0xa1, 0x61, 0x9d, 0x3f, 0x9b, 0x35, 0xbd, 0x06, 0x26, 0xba, 0x2c, 0x34, 0x30, 0x3f, 0x93, 0x85, - 0xd2, 0x5a, 0x78, 0x47, 0x6e, 0xaa, 0x32, 0x7f, 0x2e, 0x8b, 0xba, 0xb6, 0xab, 0x0b, 0x3c, 0xc8, - 0x9c, 0x9c, 0xd0, 0xd8, 0xe6, 0xcf, 0x6f, 0x7d, 0xf0, 0x87, 0xcf, 0x97, 0xb8, 0x3f, 0x7e, 0xbe, - 0xc4, 0xfd, 0xf9, 0xf3, 0x25, 0xee, 0x7d, 0x6d, 0xdf, 0xf4, 0x3f, 0xec, 0xbf, 0xd8, 0xe8, 0x38, - 0x07, 0x9b, 0xfb, 0xae, 0x71, 0x68, 0x86, 0x25, 0x99, 0x61, 0x6d, 0x26, 0xbf, 0x0d, 0x30, 0x7a, - 0xe6, 0xe6, 0x3e, 0xb5, 0x37, 0xd9, 0x0f, 0x01, 0x36, 0xf7, 0x9d, 0x91, 0x1f, 0x0b, 0x3c, 0x49, - 0x3d, 0x1e, 0x3e, 0x7c, 0x71, 0x86, 0xc1, 0xde, 0xf8, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa4, - 0x95, 0xb6, 0x98, 0x5c, 0x30, 0x00, 0x00, + // 3092 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5b, 0xdb, 0x6f, 0xdc, 0x58, + 0x19, 0x1f, 0x4f, 0x9a, 0x36, 0x3d, 0x6d, 0x53, 0xf7, 0xf4, 0x36, 0x69, 0xee, 0x93, 0x5e, 0xd3, + 0x25, 0xd9, 0x76, 0x97, 0xdd, 0x42, 0x17, 0x16, 0x8f, 0xed, 0xc4, 0x6e, 0x66, 0xc6, 0xd3, 0x73, + 0x3c, 0x2d, 0x59, 0x69, 0x75, 0xe4, 0xce, 0x9c, 0xa6, 0x56, 0x1d, 0x7b, 0xb0, 0x3d, 0x09, 0x11, + 0x42, 0x2b, 0xae, 0x42, 0xda, 0x05, 0xc1, 0x03, 0x12, 0x12, 0x12, 0x12, 0x62, 0x91, 0x78, 0xe0, + 0x15, 0xed, 0x33, 0x4f, 0xf0, 0x88, 0xf8, 0x0b, 0xd0, 0xfe, 0x0f, 0xbc, 0x20, 0x10, 0xc8, 0xc7, + 0x97, 0xf1, 0x5c, 0xed, 0x2d, 0xf0, 0x92, 0x7d, 0xcb, 0xf8, 0xfc, 0xbe, 0xf3, 0xfd, 0xce, 0xf9, + 0xbe, 0x73, 0xf9, 0x7e, 0x76, 0xc0, 0x1d, 0x9f, 0x5a, 0xb4, 0xe3, 0xb8, 0xfe, 0x66, 0xd7, 0x33, + 0xf6, 0x28, 0x3d, 0xa0, 0xb6, 0xef, 0x6d, 0x1e, 0xdc, 0x4b, 0xff, 0xdc, 0xe8, 0xb8, 0x8e, 0xef, + 0xc0, 0xab, 0x31, 0x74, 0x23, 0xdd, 0x76, 0x70, 0xaf, 0xbc, 0x0e, 0x60, 0x53, 0xad, 0x18, 0xb6, + 0x4d, 0x5d, 0xd1, 0x32, 0x5b, 0x2f, 0xe5, 0xa0, 0x05, 0x5e, 0x02, 0xd3, 0x86, 0x45, 0x5d, 0xbf, + 0xc4, 0xad, 0x70, 0xb7, 0x4f, 0xa3, 0xf0, 0x47, 0x79, 0x0b, 0xdc, 0x6e, 0xaa, 0x9a, 0xfd, 0xcc, + 0x31, 0xdc, 0xb6, 0xe8, 0xec, 0x77, 0x2c, 0xea, 0xd3, 0x6d, 0x47, 0x77, 0x24, 0xc3, 0x7b, 0x11, + 0x3e, 0xec, 0xf5, 0x70, 0x0d, 0xcc, 0x74, 0x3d, 0xea, 0xda, 0xc6, 0x3e, 0x8d, 0x3a, 0x49, 0x7e, + 0x97, 0x6f, 0x80, 0xb5, 0xa4, 0x1f, 0xa1, 0xdd, 0xde, 0x32, 0x5d, 0xcf, 0x47, 0xd4, 0x73, 0xba, + 0x6e, 0x8b, 0xf6, 0xba, 0x28, 0xaf, 0xa7, 0xdc, 0x0d, 0xc2, 0xaa, 0x86, 0x9f, 0x26, 0x5c, 0x7e, + 0x17, 0xac, 0x26, 0x58, 0x4c, 0x7d, 0xd1, 0xa5, 0x6d, 0x6a, 0xfb, 0xa6, 0x61, 0xe1, 0xee, 0xb3, + 0x7d, 0xd3, 0xcf, 0xe6, 0x94, 0xee, 0xe0, 0x71, 0x97, 0x7a, 0xbe, 0xe9, 0xd8, 0xb6, 0x61, 0xba, + 0x34, 0x6f, 0x07, 0xdf, 0x06, 0x37, 0x92, 0x0e, 0x10, 0xdd, 0x33, 0xbd, 0x80, 0xe0, 0x0b, 0xc3, + 0xb2, 0xa8, 0xbd, 0x97, 0xb7, 0x13, 0x38, 0x07, 0x66, 0xf6, 0x9f, 0x1b, 0xc4, 0x3f, 0xea, 0xd0, + 0x52, 0x91, 0xb5, 0x9d, 0xda, 0x7f, 0x6e, 0xe8, 0x47, 0x1d, 0x0a, 0x17, 0x01, 0xb0, 0x9c, 0x3d, + 0xd3, 0x26, 0xcf, 0x2d, 0xe7, 0xb0, 0x34, 0xc5, 0x1a, 0x4f, 0xb3, 0x27, 0x5b, 0x96, 0x73, 0x18, + 0xf2, 0x47, 0xb4, 0xe5, 0x1c, 0x50, 0xf7, 0x48, 0x74, 0xda, 0xd4, 0x13, 0x1d, 0xdb, 0x37, 0xed, + 0x2e, 0xcd, 0x19, 0x94, 0x87, 0x60, 0x71, 0xa8, 0x83, 0xce, 0x51, 0x4e, 0xe3, 0x77, 0xc0, 0xd2, + 0x80, 0x71, 0xc3, 0x35, 0x6d, 0x3f, 0xa7, 0x75, 0x19, 0xf0, 0x92, 0xe9, 0x31, 0xe3, 0x1a, 0xf5, + 0x8d, 0xb6, 0xe1, 0x1b, 0x70, 0x16, 0x14, 0xcd, 0x76, 0x84, 0x2c, 0x9a, 0xed, 0xb2, 0x01, 0x4a, + 0x31, 0x26, 0xce, 0x81, 0x04, 0x2b, 0x83, 0x19, 0x37, 0x7a, 0xc6, 0x2c, 0x66, 0xef, 0xdf, 0xd9, + 0x18, 0x93, 0xef, 0x1b, 0x83, 0x9d, 0xa0, 0xc4, 0xb4, 0xfc, 0x12, 0xc0, 0xb8, 0x15, 0xfb, 0xb4, + 0x83, 0x7d, 0xc3, 0xef, 0x7a, 0xf0, 0x5d, 0x70, 0xd2, 0x63, 0x7f, 0x45, 0x5d, 0xdf, 0xca, 0xec, + 0x3a, 0x34, 0x44, 0x91, 0x59, 0xb0, 0x96, 0xa8, 0xeb, 0x3a, 0x6e, 0x14, 0xd0, 0xf0, 0x47, 0xf9, + 0x63, 0x0e, 0x5c, 0x69, 0xaa, 0x29, 0x13, 0xd7, 0xa7, 0xed, 0x70, 0xaa, 0x64, 0x30, 0xb3, 0x1f, + 0x0d, 0x8d, 0xf9, 0x3c, 0x93, 0x63, 0x38, 0xf1, 0x5c, 0xa0, 0xc4, 0x14, 0x8a, 0x09, 0xf1, 0x22, + 0xeb, 0xe4, 0x6e, 0x0e, 0xe2, 0xf1, 0xa8, 0x63, 0xf2, 0xe5, 0x7f, 0x71, 0x60, 0xa5, 0x47, 0x33, + 0x9e, 0x34, 0x4c, 0x2d, 0xda, 0x0a, 0x56, 0xc8, 0xff, 0x94, 0x70, 0x2d, 0x15, 0xc6, 0x90, 0xf2, + 0xbd, 0xdc, 0x61, 0xec, 0x75, 0x17, 0x77, 0x91, 0x1a, 0xff, 0xd4, 0xab, 0x8f, 0xff, 0x07, 0xc5, + 0x60, 0x13, 0x8a, 0x01, 0xaa, 0xed, 0xd3, 0x3d, 0xd7, 0x08, 0x46, 0x2e, 0x3c, 0xc5, 0x9a, 0x2a, + 0x89, 0xa2, 0x63, 0xdb, 0xb4, 0xe5, 0x1f, 0xfb, 0x79, 0xf8, 0xa4, 0x98, 0xce, 0x03, 0xc9, 0xf0, + 0x8d, 0x67, 0x86, 0x47, 0x91, 0x84, 0x65, 0xdb, 0x75, 0x2c, 0xeb, 0xb8, 0x8f, 0x1f, 0x3e, 0x00, + 0x25, 0x8f, 0x25, 0x3d, 0x6d, 0x93, 0xb8, 0x67, 0x8f, 0xb4, 0x9c, 0xae, 0xed, 0x97, 0x4e, 0xac, + 0x70, 0xb7, 0xa7, 0xd0, 0x95, 0xb8, 0x3d, 0xa6, 0xe2, 0x89, 0x41, 0x6b, 0xf9, 0x11, 0x28, 0x35, + 0x55, 0xd1, 0xb0, 0x2c, 0xdd, 0x11, 0xd8, 0x9a, 0x49, 0x6d, 0x8a, 0x1b, 0x60, 0xaa, 0x15, 0xcd, + 0xd5, 0xec, 0xfd, 0x85, 0xb1, 0xbc, 0x44, 0x5d, 0x40, 0x01, 0xb0, 0xfc, 0xe3, 0x69, 0xb0, 0x90, + 0x8a, 0x02, 0xed, 0x58, 0xce, 0x11, 0xa6, 0xee, 0x81, 0xd9, 0xa2, 0xc7, 0x3e, 0x02, 0x7b, 0xe0, + 0x5c, 0x9b, 0x0d, 0x98, 0xec, 0x53, 0xff, 0x85, 0xd3, 0x66, 0xd3, 0x3e, 0x7b, 0xbf, 0x32, 0xb6, + 0xaf, 0x49, 0x13, 0xb5, 0x11, 0x3e, 0xaa, 0xb1, 0x9e, 0xd0, 0xd9, 0x76, 0xea, 0x17, 0x34, 0xc0, + 0x99, 0xc8, 0x11, 0x3b, 0x86, 0xa7, 0x99, 0x9b, 0xaf, 0xfd, 0x37, 0x6e, 0x82, 0xf3, 0x1b, 0x81, + 0x76, 0xf2, 0x77, 0x99, 0x80, 0xb3, 0x69, 0x02, 0x70, 0x11, 0xcc, 0x49, 0x72, 0xa3, 0xaa, 0xed, + 0x92, 0x9a, 0xac, 0x2b, 0x9a, 0x44, 0x9a, 0x75, 0xdc, 0x90, 0x45, 0x75, 0x4b, 0x95, 0x25, 0xbe, + 0x00, 0xaf, 0x00, 0xd8, 0xdf, 0x2c, 0x34, 0x75, 0x8d, 0xe7, 0x60, 0x09, 0x5c, 0xea, 0x7f, 0x5e, + 0x13, 0xea, 0x4d, 0xa1, 0xca, 0x17, 0xcb, 0x14, 0x80, 0x9e, 0x6b, 0x38, 0x0f, 0xae, 0x46, 0x38, + 0x7d, 0xb7, 0x21, 0x0f, 0x74, 0xbe, 0x04, 0xae, 0xa5, 0x1b, 0xd5, 0x3a, 0xd6, 0x85, 0x6a, 0x95, + 0x60, 0x11, 0xa9, 0x0d, 0x9d, 0xe7, 0xe0, 0x35, 0x70, 0x25, 0xdd, 0x2e, 0xd4, 0x84, 0xf7, 0xb4, + 0x3a, 0x91, 0x45, 0xcc, 0x17, 0xcb, 0xff, 0xe4, 0xc0, 0xf2, 0x88, 0x5d, 0x21, 0xba, 0xfd, 0x1c, + 0xfb, 0x4d, 0xf1, 0x3b, 0x45, 0x70, 0x7d, 0x78, 0xf8, 0xa2, 0x63, 0x3f, 0x37, 0xf7, 0xba, 0x2e, + 0xad, 0xe9, 0x55, 0x7c, 0xec, 0xe7, 0xe0, 0x27, 0x45, 0x70, 0x2f, 0xbd, 0x04, 0xbc, 0x97, 0xbe, + 0xd3, 0x09, 0x36, 0xba, 0x03, 0x2a, 0x99, 0x2e, 0x6d, 0xf9, 0x8e, 0x7b, 0xa4, 0x3b, 0x8e, 0xe5, + 0xa9, 0xb6, 0xe7, 0x1b, 0xc7, 0xff, 0xa4, 0x28, 0x7f, 0x58, 0x04, 0x1b, 0x59, 0x13, 0x92, 0xa4, + 0xc8, 0xb1, 0x9f, 0x8d, 0xdf, 0x17, 0xc1, 0xcd, 0xde, 0x6c, 0x08, 0x5d, 0xdf, 0x89, 0xff, 0x4e, + 0x1d, 0x94, 0xc7, 0xfe, 0xec, 0xba, 0x05, 0xce, 0x8f, 0xbe, 0x34, 0xcc, 0xba, 0xfd, 0x97, 0x85, + 0x1f, 0x16, 0xc1, 0x9d, 0x09, 0x3b, 0x8a, 0x2a, 0xd4, 0x1a, 0x8e, 0x65, 0xb6, 0x8e, 0x8e, 0x7d, + 0xde, 0xfc, 0x9b, 0x03, 0xe5, 0xde, 0x44, 0x04, 0xc5, 0x64, 0xcb, 0xec, 0x18, 0x96, 0xf7, 0xf9, + 0x59, 0x39, 0xff, 0xe0, 0x82, 0x82, 0x3c, 0x06, 0xe8, 0xd4, 0xf3, 0xa3, 0x5a, 0xe3, 0xf3, 0x50, + 0x76, 0xfd, 0x9d, 0x0b, 0x6e, 0xcd, 0x31, 0x20, 0xd6, 0x9a, 0xda, 0xc7, 0x7e, 0xdc, 0xf3, 0x60, + 0xae, 0xa9, 0x8a, 0x2e, 0x35, 0x7c, 0x5a, 0xa7, 0x87, 0xc8, 0xb1, 0xd2, 0x7a, 0xd8, 0x72, 0x90, + 0x10, 0x7d, 0x8d, 0xd8, 0x38, 0x48, 0x03, 0x56, 0x83, 0xdb, 0x58, 0xbf, 0xb5, 0x61, 0xb7, 0xa8, + 0x95, 0x82, 0xbc, 0x06, 0xd6, 0x07, 0x20, 0x4f, 0x4c, 0x7a, 0x28, 0x39, 0xad, 0xee, 0x3e, 0xb5, + 0x7d, 0xa3, 0xbf, 0x3e, 0x29, 0xff, 0x81, 0x03, 0x97, 0x05, 0xcf, 0x33, 0x83, 0xdc, 0x63, 0x21, + 0x48, 0x72, 0xef, 0x16, 0x38, 0xdf, 0x72, 0xec, 0x03, 0xea, 0x7a, 0xcc, 0x86, 0x24, 0x5a, 0xcd, + 0x6c, 0xfa, 0xb1, 0xda, 0x86, 0xab, 0xe0, 0xac, 0xef, 0xf8, 0x86, 0x45, 0x7c, 0xe7, 0x25, 0xb5, + 0x43, 0x2d, 0x62, 0x0a, 0x9d, 0x61, 0xcf, 0x74, 0xf6, 0x08, 0xae, 0x81, 0x73, 0x1d, 0xd7, 0xd9, + 0xef, 0xf8, 0x31, 0x66, 0x8a, 0x61, 0xce, 0x86, 0x0f, 0x23, 0xd0, 0x5d, 0x70, 0xa1, 0x95, 0x70, + 0x88, 0x81, 0xe1, 0x26, 0xca, 0xf7, 0x1a, 0x42, 0x70, 0xf9, 0x23, 0x0e, 0xcc, 0xa5, 0x6a, 0xf5, + 0xb0, 0x46, 0x1d, 0x27, 0x2d, 0xc1, 0x0a, 0x38, 0xf1, 0xd2, 0xb4, 0xdb, 0x8c, 0xda, 0xec, 0xfd, + 0x8d, 0xb1, 0x71, 0x1b, 0xea, 0x71, 0xc7, 0xb4, 0xdb, 0x88, 0xd9, 0xc2, 0x79, 0x70, 0xba, 0xeb, + 0x51, 0x97, 0x30, 0x7d, 0x6b, 0xaa, 0xa7, 0x6f, 0xd5, 0x8d, 0x7d, 0x5a, 0x76, 0x82, 0xc0, 0x0d, + 0x59, 0x33, 0xcd, 0x27, 0x9c, 0xcd, 0xfa, 0x50, 0x46, 0xdf, 0xcf, 0xcf, 0x62, 0x38, 0xb5, 0xcb, + 0x6e, 0x50, 0xac, 0x0f, 0x01, 0xe3, 0x65, 0xf4, 0xff, 0xf1, 0xf9, 0xf1, 0x1a, 0x38, 0xdf, 0x0c, + 0xcc, 0x58, 0xf7, 0x9a, 0x4d, 0xb5, 0xe7, 0xb0, 0x09, 0xce, 0x77, 0x4d, 0xf2, 0x8c, 0xa9, 0xcb, + 0xa4, 0x15, 0xe4, 0x55, 0xe4, 0xea, 0xee, 0x84, 0x72, 0x6a, 0x50, 0x8c, 0x56, 0x0a, 0xe8, 0x5c, + 0xd7, 0x4c, 0x3d, 0x85, 0xbf, 0xe4, 0xc0, 0x9d, 0xae, 0x49, 0x9c, 0x50, 0x6c, 0x25, 0x51, 0xf8, + 0x29, 0xd9, 0x73, 0x88, 0xef, 0x90, 0x76, 0xac, 0x46, 0x47, 0x1e, 0xc3, 0xe5, 0x28, 0x4c, 0xf0, + 0x98, 0x4f, 0xd2, 0x56, 0x0a, 0x68, 0xad, 0x6b, 0x66, 0x62, 0xe1, 0x87, 0x1c, 0x58, 0x4b, 0xb1, + 0x33, 0xda, 0x6d, 0xf2, 0xdc, 0x74, 0x3d, 0x3f, 0xd1, 0x0d, 0x22, 0x5e, 0x27, 0x18, 0xaf, 0x77, + 0xb2, 0x79, 0x8d, 0x97, 0xc8, 0x95, 0x02, 0x5a, 0x4a, 0x28, 0x8d, 0x84, 0x0d, 0xce, 0xd5, 0x08, + 0x36, 0x96, 0xe1, 0x27, 0xd1, 0x99, 0xce, 0x3b, 0x57, 0x19, 0x7a, 0x7c, 0xdf, 0x5c, 0x8d, 0xc7, + 0xc2, 0xef, 0x73, 0x60, 0x25, 0xc5, 0xce, 0xa3, 0x3e, 0x69, 0x25, 0xd2, 0x3d, 0xf1, 0x98, 0x6a, + 0x5e, 0x3a, 0xc9, 0x48, 0x7d, 0x39, 0x9b, 0xd4, 0x38, 0xe1, 0x5f, 0x29, 0xa0, 0x85, 0x84, 0xcd, + 0x08, 0x10, 0xfc, 0x29, 0x07, 0xae, 0xa7, 0x68, 0xb8, 0x51, 0x01, 0x4b, 0x5a, 0xb1, 0x7e, 0x1f, + 0x53, 0x39, 0xc5, 0xa8, 0x7c, 0x35, 0x9b, 0xca, 0xa4, 0x37, 0x00, 0x4a, 0x01, 0xad, 0x24, 0x74, + 0xc6, 0x00, 0xe3, 0x99, 0x71, 0x23, 0x4d, 0x9d, 0xb4, 0x9c, 0x36, 0xbb, 0x3b, 0x86, 0x9a, 0x7e, + 0x14, 0xae, 0x99, 0xcc, 0x99, 0xc9, 0x78, 0x23, 0x10, 0xce, 0xcc, 0x78, 0x10, 0xfc, 0x26, 0x58, + 0x18, 0xc5, 0xa2, 0x73, 0x14, 0x31, 0x38, 0xcd, 0x18, 0xbc, 0x95, 0x9f, 0x41, 0xfa, 0x95, 0x82, + 0x52, 0x40, 0xa5, 0x21, 0xef, 0x11, 0x00, 0x7e, 0x0b, 0x2c, 0x0e, 0x7b, 0xee, 0xb8, 0xa6, 0xed, + 0x47, 0xae, 0x01, 0x73, 0xfd, 0x76, 0x5e, 0xd7, 0x03, 0x2f, 0x24, 0x94, 0x02, 0x9a, 0x1b, 0xf0, + 0xdd, 0x43, 0x40, 0x0b, 0xcc, 0x75, 0x4d, 0xd2, 0x8e, 0x0e, 0x6a, 0xe2, 0x85, 0xf2, 0x3c, 0x61, + 0x9d, 0x97, 0xce, 0x30, 0xc7, 0x9b, 0x39, 0x14, 0xa1, 0xb4, 0xac, 0xaf, 0x14, 0xd0, 0x95, 0xae, + 0x39, 0x52, 0xf0, 0xff, 0x30, 0x4c, 0xbf, 0xc4, 0x5d, 0xb2, 0x34, 0xbd, 0x58, 0x67, 0x8f, 0x3c, + 0x9f, 0x65, 0x9e, 0xbf, 0x94, 0xc3, 0xf3, 0x68, 0xa5, 0x3e, 0xcc, 0xbc, 0x0c, 0x35, 0xff, 0x03, + 0x96, 0x78, 0x09, 0x99, 0x48, 0x0b, 0xf3, 0x42, 0x59, 0x2b, 0x22, 0x72, 0x8e, 0x11, 0xf9, 0xe2, + 0x2b, 0x89, 0x62, 0x61, 0xce, 0x4d, 0x10, 0x31, 0x7f, 0x14, 0x6e, 0xa0, 0x3d, 0x06, 0x51, 0x19, + 0xd4, 0x5b, 0x97, 0x21, 0x89, 0x59, 0x46, 0xe2, 0x41, 0x1e, 0x12, 0xa3, 0x94, 0x29, 0xa5, 0x80, + 0x96, 0x53, 0x3c, 0x46, 0x8a, 0x57, 0xbf, 0x08, 0x77, 0xcf, 0x61, 0x2a, 0xad, 0xb8, 0x0e, 0x21, + 0xfb, 0xbe, 0xe5, 0x45, 0x84, 0xce, 0x33, 0x42, 0x5f, 0xf9, 0x0c, 0x84, 0x86, 0xb5, 0x22, 0xa5, + 0x80, 0xae, 0x0f, 0xb3, 0xea, 0xe1, 0x7c, 0x2b, 0x2a, 0x97, 0xff, 0xc8, 0x81, 0x07, 0xfd, 0x71, + 0x62, 0x4a, 0x03, 0x31, 0x98, 0xd4, 0x40, 0xda, 0xb1, 0xd6, 0x40, 0x7c, 0xc7, 0xb1, 0x3c, 0x62, + 0x86, 0xf2, 0x4b, 0xc4, 0x94, 0x67, 0x4c, 0x1f, 0xe5, 0x8a, 0x5f, 0x2e, 0x45, 0x47, 0x29, 0xa0, + 0x7b, 0xe9, 0xa0, 0xe6, 0x93, 0x81, 0x3e, 0xe1, 0xc0, 0x9b, 0xb9, 0xc6, 0xd0, 0x9b, 0xee, 0x90, + 0xff, 0x05, 0xc6, 0x7f, 0xfb, 0x95, 0xf9, 0xf7, 0x97, 0x91, 0x4a, 0x01, 0x6d, 0x64, 0x91, 0x1f, + 0x28, 0x3c, 0x7f, 0xc5, 0x81, 0xbb, 0x69, 0xe6, 0x46, 0x37, 0xb8, 0x79, 0x24, 0xd2, 0x46, 0xea, + 0x1d, 0x41, 0x48, 0x18, 0x32, 0xc2, 0xef, 0xe6, 0x20, 0x3c, 0x49, 0x23, 0x51, 0x0a, 0xe8, 0x66, + 0x8f, 0xe8, 0x44, 0x35, 0xe5, 0x77, 0x1c, 0xd8, 0xcc, 0xc8, 0x5c, 0xd3, 0xd8, 0x27, 0x1d, 0x26, + 0x27, 0x44, 0x24, 0x2f, 0x32, 0x92, 0x95, 0x57, 0xc9, 0xdf, 0x7e, 0x65, 0x42, 0x29, 0xa0, 0x3b, + 0x13, 0x92, 0x58, 0x35, 0xf6, 0xd3, 0x32, 0xc6, 0xcf, 0x38, 0x70, 0x33, 0x4d, 0xb5, 0x93, 0x54, + 0xfb, 0x43, 0x71, 0xbf, 0xc4, 0x18, 0x3e, 0xcc, 0xc1, 0x70, 0x9c, 0x64, 0xa0, 0x14, 0x50, 0xb9, + 0x47, 0x6d, 0xac, 0xb0, 0xf0, 0x5d, 0x0e, 0xac, 0xa6, 0x39, 0xf9, 0xd4, 0xf3, 0x03, 0x36, 0x76, + 0xdf, 0x7e, 0x7c, 0x39, 0xf3, 0xf4, 0x9b, 0x50, 0xbf, 0x2b, 0x05, 0xb4, 0xd8, 0x63, 0x32, 0xaa, + 0xc0, 0x77, 0xc1, 0x7c, 0x9a, 0x43, 0x7c, 0xcf, 0x8d, 0xcf, 0xa1, 0x2b, 0x19, 0x45, 0xeb, 0xb8, + 0x02, 0x3a, 0x3c, 0x76, 0xc7, 0x14, 0xd7, 0x16, 0x28, 0x75, 0xcd, 0xe0, 0x12, 0x66, 0xf8, 0x94, + 0xd8, 0xf4, 0x90, 0xb8, 0x8e, 0x15, 0x5f, 0x37, 0xae, 0x66, 0x94, 0x09, 0x63, 0x4b, 0x57, 0xa5, + 0x80, 0x2e, 0x75, 0xcd, 0xe1, 0x46, 0x78, 0xc4, 0x0e, 0xf9, 0x41, 0x6f, 0x9e, 0x71, 0x10, 0xbb, + 0x2c, 0x65, 0xce, 0xf0, 0x84, 0x82, 0x38, 0x1c, 0xe8, 0x68, 0x00, 0xfc, 0x00, 0x2c, 0x8f, 0x1a, + 0x28, 0x2b, 0x98, 0x23, 0xe7, 0x73, 0x99, 0x07, 0xcc, 0xc4, 0x62, 0x5b, 0x29, 0xa0, 0x6b, 0x83, + 0xa3, 0xee, 0x41, 0xe0, 0xaf, 0xc3, 0x2d, 0x64, 0x90, 0xc1, 0x81, 0x49, 0x0f, 0x49, 0x3b, 0x5d, + 0x90, 0x47, 0x6c, 0xae, 0x31, 0x36, 0x62, 0x5e, 0x36, 0x13, 0xea, 0x7a, 0xa5, 0x80, 0x6e, 0x0c, + 0x10, 0x1b, 0x8d, 0x86, 0xbf, 0xe5, 0xc0, 0x46, 0x3a, 0x05, 0xcd, 0x5e, 0x21, 0x48, 0x8c, 0x43, + 0x8f, 0x38, 0x66, 0xbb, 0x15, 0x2f, 0x8b, 0x28, 0x2b, 0xe7, 0x33, 0x4b, 0x88, 0x7c, 0x6f, 0xd3, + 0x95, 0x02, 0xba, 0xdd, 0xcb, 0xd2, 0x34, 0xf6, 0xd0, 0xd3, 0xcc, 0x76, 0xab, 0xef, 0xcd, 0xfb, + 0x47, 0x1c, 0xb8, 0x31, 0xfa, 0xca, 0xd0, 0xf6, 0x08, 0x65, 0x25, 0x6b, 0x44, 0x6f, 0x21, 0xf7, + 0x15, 0x6a, 0xf4, 0x4b, 0xee, 0xfe, 0x2b, 0x54, 0x82, 0x69, 0x7b, 0xe9, 0x17, 0xe1, 0x7e, 0x98, + 0xd6, 0xc1, 0x79, 0xeb, 0x3b, 0xec, 0x34, 0x8b, 0xa3, 0x18, 0xb1, 0x58, 0xcc, 0x5c, 0xba, 0xa3, + 0xdf, 0x18, 0x47, 0x19, 0x3d, 0xfa, 0x6d, 0xf2, 0xfb, 0xe0, 0x82, 0xc1, 0xc4, 0x1a, 0xd2, 0x13, + 0x44, 0x4a, 0x4b, 0xcc, 0xd3, 0x78, 0x51, 0x63, 0xa4, 0xbc, 0xa3, 0x14, 0x10, 0x6f, 0x0c, 0x34, + 0xc4, 0x5b, 0x62, 0x3a, 0x05, 0xa2, 0x99, 0x65, 0xd7, 0xe3, 0x68, 0x64, 0xcb, 0x99, 0x0b, 0x76, + 0x82, 0x10, 0x12, 0x6e, 0x89, 0x93, 0x94, 0x92, 0xe8, 0xaa, 0x3c, 0x82, 0x44, 0xa2, 0x02, 0x84, + 0x3c, 0x56, 0x32, 0xe3, 0x3c, 0x59, 0x1f, 0x09, 0xe3, 0x9c, 0xa1, 0xa1, 0x7c, 0x8f, 0x63, 0x9b, + 0x48, 0x5c, 0x37, 0x7e, 0x23, 0xfd, 0xdd, 0x58, 0x5c, 0x32, 0xae, 0xe6, 0xad, 0x5e, 0xc7, 0x7d, + 0x75, 0xd6, 0x57, 0xbd, 0x8e, 0x00, 0x55, 0x4e, 0x81, 0x69, 0xd6, 0xdd, 0xa3, 0x13, 0x33, 0x45, + 0x7e, 0x2a, 0x00, 0x27, 0x8c, 0xf6, 0xa8, 0x9f, 0x14, 0x2f, 0x2c, 0xff, 0xd6, 0x7f, 0x3e, 0xdb, + 0xfb, 0xd8, 0x2a, 0xbe, 0x32, 0xc0, 0x55, 0xb0, 0x28, 0xa9, 0x58, 0xd4, 0x9e, 0xc8, 0x88, 0x20, + 0x19, 0x6b, 0x4d, 0x24, 0x0e, 0xbe, 0x26, 0x5e, 0x00, 0xa5, 0x61, 0x08, 0x96, 0xd1, 0x13, 0x19, + 0xf1, 0x1c, 0x5c, 0x01, 0x0b, 0xc3, 0xad, 0x3b, 0xcd, 0x8a, 0x8c, 0xea, 0xb2, 0x2e, 0x63, 0xbe, + 0x08, 0xdf, 0x00, 0x9b, 0xc3, 0x08, 0x49, 0xd0, 0x85, 0x8a, 0x80, 0x65, 0xd2, 0xd0, 0xb0, 0xbe, + 0x8d, 0x64, 0x4c, 0xb0, 0x5c, 0xdd, 0x22, 0x8a, 0x86, 0x75, 0x59, 0xe2, 0xa7, 0xe0, 0xeb, 0xe0, + 0xb5, 0x09, 0x46, 0xb5, 0x5d, 0xfc, 0xb8, 0xda, 0x67, 0x71, 0x02, 0xde, 0x07, 0x1b, 0x93, 0x2c, + 0xb4, 0xfa, 0xb6, 0x26, 0x55, 0xfa, 0x6c, 0xa6, 0xe1, 0x5d, 0x70, 0x2b, 0x0f, 0x35, 0x24, 0x61, + 0xfe, 0x24, 0xbc, 0x0d, 0xae, 0x67, 0x52, 0x0a, 0x90, 0xa7, 0xe0, 0x4d, 0x50, 0x1e, 0x46, 0x0a, + 0x8d, 0x46, 0x55, 0x15, 0x05, 0x5d, 0xd5, 0xea, 0x44, 0xd1, 0xf5, 0x06, 0x3f, 0x03, 0x6f, 0x80, + 0xd5, 0xc9, 0x38, 0x5d, 0x6c, 0xf0, 0xa7, 0x47, 0xc3, 0x9e, 0xaa, 0x75, 0x49, 0x7b, 0x8a, 0x89, + 0x24, 0xe3, 0x1d, 0x5d, 0x6b, 0xf0, 0x00, 0xbe, 0x06, 0x6e, 0x4f, 0xe0, 0x87, 0x1f, 0x57, 0xc3, + 0x98, 0x31, 0x8e, 0x67, 0x32, 0x26, 0xb8, 0x37, 0x74, 0x59, 0xc2, 0x8a, 0xba, 0xa5, 0xf3, 0x67, + 0xe1, 0x9b, 0xe0, 0xf5, 0x5c, 0xfd, 0xa7, 0xa7, 0xf8, 0x5c, 0x86, 0x1f, 0x24, 0x4b, 0x6a, 0x7f, + 0xe8, 0x67, 0xf3, 0x06, 0x65, 0x5b, 0x6c, 0xf0, 0xe7, 0x73, 0x05, 0x25, 0x40, 0xf2, 0xb9, 0xa7, + 0x27, 0x40, 0x5f, 0x80, 0x0f, 0xc1, 0xdb, 0x9f, 0x65, 0x7a, 0xa2, 0xf5, 0x50, 0x95, 0x31, 0xe6, + 0x21, 0xfc, 0x02, 0xb8, 0x93, 0xc7, 0x58, 0x78, 0xaf, 0x89, 0x64, 0xfe, 0x22, 0xbc, 0x05, 0xd6, + 0x26, 0xc0, 0xa5, 0xdd, 0xba, 0x50, 0xd3, 0xa4, 0x0a, 0x7f, 0x29, 0x23, 0xc5, 0x45, 0x01, 0x63, + 0xa1, 0x2e, 0x21, 0x81, 0xec, 0xc8, 0xbb, 0xb8, 0x21, 0x88, 0x32, 0xe6, 0x2f, 0x67, 0x44, 0xad, + 0x67, 0x93, 0x8e, 0xc1, 0x15, 0xf8, 0x00, 0xbc, 0x39, 0xc1, 0x4a, 0xae, 0x0a, 0x58, 0x57, 0x45, + 0x2c, 0x0b, 0x48, 0x54, 0xfa, 0x2c, 0xaf, 0xe6, 0x8a, 0x77, 0x64, 0x2f, 0x88, 0x8a, 0xcc, 0x97, + 0x32, 0x66, 0x2b, 0xb4, 0xa8, 0xc9, 0x35, 0x0d, 0xed, 0x4a, 0x15, 0x7e, 0x2e, 0x97, 0x03, 0x36, + 0xb3, 0x24, 0x74, 0x70, 0x2d, 0x63, 0x30, 0xa1, 0x85, 0x58, 0x6d, 0x62, 0x7d, 0x20, 0x79, 0xe7, + 0xe1, 0x3a, 0xb8, 0x99, 0x99, 0x5d, 0x61, 0x14, 0x17, 0xe0, 0x06, 0x58, 0xcf, 0x95, 0x5f, 0x21, + 0x7e, 0x31, 0x23, 0x98, 0x3d, 0x7c, 0x4d, 0x15, 0x91, 0x86, 0xb5, 0x2d, 0x9d, 0x5f, 0x82, 0x6f, + 0x81, 0xfb, 0x93, 0x82, 0xa9, 0x89, 0x3b, 0x48, 0x13, 0x44, 0x65, 0x60, 0x9f, 0x5b, 0xce, 0xc8, + 0xfd, 0x78, 0x6f, 0x14, 0xf4, 0xaa, 0x80, 0xf9, 0x95, 0x8c, 0x35, 0x85, 0xeb, 0xda, 0xd3, 0xad, + 0xaa, 0xb0, 0x23, 0xf3, 0xab, 0x63, 0xfa, 0xd5, 0xc4, 0xd4, 0xec, 0x4a, 0x98, 0x34, 0x90, 0xf6, + 0xf5, 0x5d, 0xbe, 0x3c, 0x26, 0x15, 0xd3, 0x68, 0x45, 0xdd, 0x56, 0x88, 0xf0, 0x44, 0x50, 0xab, + 0x42, 0x45, 0xad, 0xaa, 0xfa, 0x2e, 0xbf, 0x06, 0xdf, 0x06, 0x6f, 0x64, 0x58, 0xb1, 0x15, 0xa2, + 0x8a, 0x04, 0xc9, 0xdb, 0x2a, 0xd6, 0x11, 0xdb, 0x3a, 0xf9, 0xeb, 0xa3, 0x77, 0x61, 0x2c, 0xd4, + 0xaa, 0xe9, 0x2d, 0x96, 0xbf, 0xb1, 0xfe, 0x1b, 0x0e, 0xcc, 0xf6, 0x7f, 0xc0, 0x0b, 0x97, 0xc1, + 0x7c, 0x62, 0x8a, 0x75, 0x41, 0x6f, 0xe2, 0x81, 0x33, 0x71, 0x1e, 0x5c, 0x1d, 0x04, 0xe0, 0xa6, + 0x28, 0x06, 0xcb, 0x9f, 0x1b, 0xd9, 0xb8, 0xa3, 0x36, 0x1a, 0xb2, 0xc4, 0x17, 0xe1, 0x1c, 0xb8, + 0x3c, 0xd8, 0x28, 0x23, 0xa4, 0x21, 0x7e, 0x6a, 0x94, 0x9d, 0x50, 0xd1, 0x10, 0x3b, 0xde, 0xd6, + 0xff, 0xc4, 0x81, 0x29, 0x51, 0x17, 0xe0, 0x45, 0x70, 0x5e, 0xd4, 0x85, 0xe1, 0xcf, 0xc4, 0x82, + 0x87, 0x42, 0x53, 0x57, 0x88, 0xa8, 0xd5, 0xeb, 0xb2, 0xa8, 0x6b, 0xc1, 0xe1, 0x7c, 0x15, 0x5c, + 0x64, 0xcf, 0x45, 0x5d, 0x7d, 0x12, 0x9c, 0xd9, 0x18, 0xab, 0x5a, 0x3d, 0x38, 0x93, 0x93, 0x86, + 0x80, 0x32, 0x41, 0xf2, 0xe3, 0xa6, 0x8c, 0x75, 0xcc, 0x4f, 0xc5, 0x0d, 0x0d, 0x24, 0xd7, 0xd4, + 0x66, 0x8d, 0xe0, 0x66, 0xa3, 0xa1, 0x21, 0x9d, 0x3f, 0x11, 0x37, 0xe8, 0x28, 0x58, 0x27, 0x12, + 0x91, 0xe4, 0x27, 0x6a, 0xb0, 0xc1, 0x4c, 0xc7, 0xbe, 0x9b, 0x8d, 0x6d, 0x24, 0x48, 0x32, 0xa9, + 0x08, 0xf5, 0xba, 0x8c, 0xf8, 0x93, 0xb1, 0x41, 0x45, 0xad, 0x56, 0xd5, 0xfa, 0x36, 0xc1, 0xcd, + 0x5a, 0x4d, 0x40, 0xbb, 0xfc, 0xa9, 0xf5, 0xbf, 0x4e, 0x81, 0xcb, 0x23, 0x5f, 0xa8, 0x05, 0x1b, + 0xa1, 0x5a, 0xd7, 0xe5, 0xed, 0x30, 0x84, 0x44, 0xae, 0x23, 0xad, 0x5a, 0x25, 0x3b, 0x6a, 0x7d, + 0xf0, 0xb3, 0xb8, 0x55, 0xb0, 0x38, 0x0e, 0x88, 0xab, 0x82, 0xb8, 0xc3, 0x73, 0xf0, 0x3a, 0x58, + 0x19, 0x07, 0x11, 0x9e, 0x62, 0x12, 0xd4, 0x1c, 0x7c, 0x31, 0x38, 0x5a, 0xc7, 0xa1, 0x1a, 0xc2, + 0xb6, 0x8c, 0xa4, 0xa6, 0xbe, 0xcb, 0x4f, 0x4d, 0xf2, 0x27, 0xd7, 0x04, 0xb5, 0xca, 0x9f, 0x08, + 0xee, 0x41, 0xe3, 0x20, 0x8f, 0x54, 0x24, 0xf0, 0xd3, 0x70, 0x0d, 0x2c, 0x8f, 0x43, 0xb0, 0xb0, + 0x23, 0x89, 0x3f, 0x19, 0x24, 0xed, 0x38, 0x50, 0x4d, 0xd0, 0x75, 0x19, 0xd5, 0x34, 0xac, 0xf3, + 0xa7, 0x26, 0x0d, 0xaf, 0x86, 0x89, 0x2e, 0x0b, 0x35, 0xcc, 0xcf, 0x4c, 0x42, 0x69, 0x0d, 0xbc, + 0x2d, 0xd7, 0x55, 0x99, 0x3f, 0x3d, 0x89, 0xba, 0xb6, 0xa3, 0x0b, 0x3c, 0x98, 0x38, 0x38, 0xa1, + 0xb6, 0xc5, 0x9f, 0xa9, 0xbc, 0xff, 0xe7, 0x4f, 0x97, 0xb8, 0xbf, 0x7c, 0xba, 0xc4, 0xfd, 0xed, + 0xd3, 0x25, 0xee, 0x3d, 0x6d, 0xcf, 0xf4, 0x5f, 0x74, 0x9f, 0x6d, 0xb4, 0x9c, 0xfd, 0xcd, 0x3d, + 0xd7, 0x38, 0x30, 0xc3, 0xca, 0xd2, 0xb0, 0x36, 0x93, 0xff, 0x5b, 0x31, 0x3a, 0xe6, 0xe6, 0x1e, + 0xb5, 0x37, 0xd9, 0x3f, 0xa9, 0x6c, 0xee, 0x39, 0x03, 0xff, 0xc8, 0xf2, 0x30, 0xf5, 0xf3, 0xe0, + 0xde, 0xb3, 0x93, 0x0c, 0xf6, 0xc6, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x12, 0x7b, 0xfa, 0xa1, + 0xf8, 0x32, 0x00, 0x00, } func (m *UIBannerClickEvent) Marshal() (dAtA []byte, err error) { @@ -3152,6 +3321,40 @@ func (m *UIOnboardSetCredentialSubmitEvent) MarshalToSizedBuffer(dAtA []byte) (i return len(dAtA) - i, nil } +func (m *UIOnboardQuestionnaireSubmitEvent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UIOnboardQuestionnaireSubmitEvent) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UIOnboardQuestionnaireSubmitEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Username) > 0 { + i -= len(m.Username) + copy(dAtA[i:], m.Username) + i = encodeVarintUsageevents(dAtA, i, uint64(len(m.Username))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *UIOnboardRegisterChallengeSubmitEvent) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3708,6 +3911,16 @@ func (m *UIDiscoverDeployServiceEvent) MarshalToSizedBuffer(dAtA []byte) (int, e i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DeployType != 0 { + i = encodeVarintUsageevents(dAtA, i, uint64(m.DeployType)) + i-- + dAtA[i] = 0x28 + } + if m.DeployMethod != 0 { + i = encodeVarintUsageevents(dAtA, i, uint64(m.DeployMethod)) + i-- + dAtA[i] = 0x20 + } if m.Status != nil { { size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) @@ -5321,6 +5534,29 @@ func (m *UsageEventOneOf_UiIntegrationEnrollCompleteEvent) MarshalToSizedBuffer( } return len(dAtA) - i, nil } +func (m *UsageEventOneOf_UiOnboardQuestionnaireSubmit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UsageEventOneOf_UiOnboardQuestionnaireSubmit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.UiOnboardQuestionnaireSubmit != nil { + { + size, err := m.UiOnboardQuestionnaireSubmit.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintUsageevents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x8a + } + return len(dAtA) - i, nil +} func encodeVarintUsageevents(dAtA []byte, offset int, v uint64) int { offset -= sovUsageevents(v) base := offset @@ -5404,6 +5640,22 @@ func (m *UIOnboardSetCredentialSubmitEvent) Size() (n int) { return n } +func (m *UIOnboardQuestionnaireSubmitEvent) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Username) + if l > 0 { + n += 1 + l + sovUsageevents(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *UIOnboardRegisterChallengeSubmitEvent) Size() (n int) { if m == nil { return 0 @@ -5654,6 +5906,12 @@ func (m *UIDiscoverDeployServiceEvent) Size() (n int) { l = m.Status.Size() n += 1 + l + sovUsageevents(uint64(l)) } + if m.DeployMethod != 0 { + n += 1 + sovUsageevents(uint64(m.DeployMethod)) + } + if m.DeployType != 0 { + n += 1 + sovUsageevents(uint64(m.DeployType)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6394,6 +6652,18 @@ func (m *UsageEventOneOf_UiIntegrationEnrollCompleteEvent) Size() (n int) { } return n } +func (m *UsageEventOneOf_UiOnboardQuestionnaireSubmit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UiOnboardQuestionnaireSubmit != nil { + l = m.UiOnboardQuestionnaireSubmit.Size() + n += 2 + l + sovUsageevents(uint64(l)) + } + return n +} func sovUsageevents(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 @@ -6752,6 +7022,89 @@ func (m *UIOnboardSetCredentialSubmitEvent) Unmarshal(dAtA []byte) error { } return nil } +func (m *UIOnboardQuestionnaireSubmitEvent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUsageevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UIOnboardQuestionnaireSubmitEvent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UIOnboardQuestionnaireSubmitEvent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUsageevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthUsageevents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthUsageevents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Username = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipUsageevents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthUsageevents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *UIOnboardRegisterChallengeSubmitEvent) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -8229,6 +8582,44 @@ func (m *UIDiscoverDeployServiceEvent) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DeployMethod", wireType) + } + m.DeployMethod = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUsageevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DeployMethod |= UIDiscoverDeployServiceEvent_DeployMethod(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DeployType", wireType) + } + m.DeployType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUsageevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DeployType |= UIDiscoverDeployServiceEvent_DeployType(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipUsageevents(dAtA[iNdEx:]) @@ -11467,6 +11858,41 @@ func (m *UsageEventOneOf) Unmarshal(dAtA []byte) error { } m.Event = &UsageEventOneOf_UiIntegrationEnrollCompleteEvent{v} iNdEx = postIndex + case 33: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UiOnboardQuestionnaireSubmit", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUsageevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthUsageevents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthUsageevents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &UIOnboardQuestionnaireSubmitEvent{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Event = &UsageEventOneOf_UiOnboardQuestionnaireSubmit{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipUsageevents(dAtA[iNdEx:]) diff --git a/api/gen/proto/go/userpreferences/v1/assist.pb.go b/api/gen/proto/go/userpreferences/v1/assist.pb.go new file mode 100644 index 0000000000000..31871fd3d91c0 --- /dev/null +++ b/api/gen/proto/go/userpreferences/v1/assist.pb.go @@ -0,0 +1,258 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/userpreferences/v1/assist.proto + +package userpreferencesv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// AssistViewMode is the way the assistant is displayed. +type AssistViewMode int32 + +const ( + AssistViewMode_ASSIST_VIEW_MODE_UNSPECIFIED AssistViewMode = 0 + // DOCKED is the assistant is docked to the right hand side of the screen. + AssistViewMode_ASSIST_VIEW_MODE_DOCKED AssistViewMode = 1 + // POPUP is the assistant is displayed as a popup. + AssistViewMode_ASSIST_VIEW_MODE_POPUP AssistViewMode = 2 + // POPUP_EXPANDED is the assistant is displayed as a popup and expanded. + AssistViewMode_ASSIST_VIEW_MODE_POPUP_EXPANDED AssistViewMode = 3 + // POPUP_EXPANDED_SIDEBAR_VISIBLE is the assistant is displayed as a popup and expanded with the sidebar visible. + AssistViewMode_ASSIST_VIEW_MODE_POPUP_EXPANDED_SIDEBAR_VISIBLE AssistViewMode = 4 +) + +// Enum value maps for AssistViewMode. +var ( + AssistViewMode_name = map[int32]string{ + 0: "ASSIST_VIEW_MODE_UNSPECIFIED", + 1: "ASSIST_VIEW_MODE_DOCKED", + 2: "ASSIST_VIEW_MODE_POPUP", + 3: "ASSIST_VIEW_MODE_POPUP_EXPANDED", + 4: "ASSIST_VIEW_MODE_POPUP_EXPANDED_SIDEBAR_VISIBLE", + } + AssistViewMode_value = map[string]int32{ + "ASSIST_VIEW_MODE_UNSPECIFIED": 0, + "ASSIST_VIEW_MODE_DOCKED": 1, + "ASSIST_VIEW_MODE_POPUP": 2, + "ASSIST_VIEW_MODE_POPUP_EXPANDED": 3, + "ASSIST_VIEW_MODE_POPUP_EXPANDED_SIDEBAR_VISIBLE": 4, + } +) + +func (x AssistViewMode) Enum() *AssistViewMode { + p := new(AssistViewMode) + *p = x + return p +} + +func (x AssistViewMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AssistViewMode) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_userpreferences_v1_assist_proto_enumTypes[0].Descriptor() +} + +func (AssistViewMode) Type() protoreflect.EnumType { + return &file_teleport_userpreferences_v1_assist_proto_enumTypes[0] +} + +func (x AssistViewMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AssistViewMode.Descriptor instead. +func (AssistViewMode) EnumDescriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_assist_proto_rawDescGZIP(), []int{0} +} + +// AssistUserPreferences is the user preferences for Assist. +type AssistUserPreferences struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // preferredLogins is an array of the logins a user would prefer to use when running a command, ordered by preference. + PreferredLogins []string `protobuf:"bytes,1,rep,name=preferred_logins,json=preferredLogins,proto3" json:"preferred_logins,omitempty"` + // viewMode is the way the assistant is displayed. + ViewMode AssistViewMode `protobuf:"varint,2,opt,name=view_mode,json=viewMode,proto3,enum=teleport.userpreferences.v1.AssistViewMode" json:"view_mode,omitempty"` +} + +func (x *AssistUserPreferences) Reset() { + *x = AssistUserPreferences{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_userpreferences_v1_assist_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AssistUserPreferences) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssistUserPreferences) ProtoMessage() {} + +func (x *AssistUserPreferences) ProtoReflect() protoreflect.Message { + mi := &file_teleport_userpreferences_v1_assist_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssistUserPreferences.ProtoReflect.Descriptor instead. +func (*AssistUserPreferences) Descriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_assist_proto_rawDescGZIP(), []int{0} +} + +func (x *AssistUserPreferences) GetPreferredLogins() []string { + if x != nil { + return x.PreferredLogins + } + return nil +} + +func (x *AssistUserPreferences) GetViewMode() AssistViewMode { + if x != nil { + return x.ViewMode + } + return AssistViewMode_ASSIST_VIEW_MODE_UNSPECIFIED +} + +var File_teleport_userpreferences_v1_assist_proto protoreflect.FileDescriptor + +var file_teleport_userpreferences_v1_assist_proto_rawDesc = []byte{ + 0x0a, 0x28, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x73, + 0x73, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x22, 0x8c, 0x01, 0x0a, 0x15, 0x41, 0x73, 0x73, 0x69, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x6c, + 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x12, 0x48, 0x0a, 0x09, + 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, + 0x73, 0x69, 0x73, 0x74, 0x56, 0x69, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x76, 0x69, + 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x2a, 0xc5, 0x01, 0x0a, 0x0e, 0x41, 0x73, 0x73, 0x69, 0x73, + 0x74, 0x56, 0x69, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x53, 0x53, + 0x49, 0x53, 0x54, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x41, + 0x53, 0x53, 0x49, 0x53, 0x54, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, + 0x44, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x53, 0x53, 0x49, + 0x53, 0x54, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x4f, 0x50, + 0x55, 0x50, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x53, 0x53, 0x49, 0x53, 0x54, 0x5f, 0x56, + 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x4f, 0x50, 0x55, 0x50, 0x5f, 0x45, + 0x58, 0x50, 0x41, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x03, 0x12, 0x33, 0x0a, 0x2f, 0x41, 0x53, 0x53, + 0x49, 0x53, 0x54, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x4f, + 0x50, 0x55, 0x50, 0x5f, 0x45, 0x58, 0x50, 0x41, 0x4e, 0x44, 0x45, 0x44, 0x5f, 0x53, 0x49, 0x44, + 0x45, 0x42, 0x41, 0x52, 0x5f, 0x56, 0x49, 0x53, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x42, 0x59, + 0x5a, 0x57, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, + 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_teleport_userpreferences_v1_assist_proto_rawDescOnce sync.Once + file_teleport_userpreferences_v1_assist_proto_rawDescData = file_teleport_userpreferences_v1_assist_proto_rawDesc +) + +func file_teleport_userpreferences_v1_assist_proto_rawDescGZIP() []byte { + file_teleport_userpreferences_v1_assist_proto_rawDescOnce.Do(func() { + file_teleport_userpreferences_v1_assist_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_userpreferences_v1_assist_proto_rawDescData) + }) + return file_teleport_userpreferences_v1_assist_proto_rawDescData +} + +var file_teleport_userpreferences_v1_assist_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_userpreferences_v1_assist_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_userpreferences_v1_assist_proto_goTypes = []interface{}{ + (AssistViewMode)(0), // 0: teleport.userpreferences.v1.AssistViewMode + (*AssistUserPreferences)(nil), // 1: teleport.userpreferences.v1.AssistUserPreferences +} +var file_teleport_userpreferences_v1_assist_proto_depIdxs = []int32{ + 0, // 0: teleport.userpreferences.v1.AssistUserPreferences.view_mode:type_name -> teleport.userpreferences.v1.AssistViewMode + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_teleport_userpreferences_v1_assist_proto_init() } +func file_teleport_userpreferences_v1_assist_proto_init() { + if File_teleport_userpreferences_v1_assist_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_userpreferences_v1_assist_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AssistUserPreferences); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_userpreferences_v1_assist_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_userpreferences_v1_assist_proto_goTypes, + DependencyIndexes: file_teleport_userpreferences_v1_assist_proto_depIdxs, + EnumInfos: file_teleport_userpreferences_v1_assist_proto_enumTypes, + MessageInfos: file_teleport_userpreferences_v1_assist_proto_msgTypes, + }.Build() + File_teleport_userpreferences_v1_assist_proto = out.File + file_teleport_userpreferences_v1_assist_proto_rawDesc = nil + file_teleport_userpreferences_v1_assist_proto_goTypes = nil + file_teleport_userpreferences_v1_assist_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/userpreferences/v1/onboard.pb.go b/api/gen/proto/go/userpreferences/v1/onboard.pb.go new file mode 100644 index 0000000000000..1c81c44e4539e --- /dev/null +++ b/api/gen/proto/go/userpreferences/v1/onboard.pb.go @@ -0,0 +1,244 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/userpreferences/v1/onboard.proto + +package userpreferencesv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Resources are the Resource options in the onboarding questionnaire +type Resource int32 + +const ( + Resource_RESOURCE_UNSPECIFIED Resource = 0 + Resource_RESOURCE_WINDOWS_DESKTOPS Resource = 1 + Resource_RESOURCE_SERVER_SSH Resource = 2 + Resource_RESOURCE_DATABASES Resource = 3 + Resource_RESOURCE_KUBERNETES Resource = 4 + Resource_RESOURCE_WEB_APPLICATIONS Resource = 5 +) + +// Enum value maps for Resource. +var ( + Resource_name = map[int32]string{ + 0: "RESOURCE_UNSPECIFIED", + 1: "RESOURCE_WINDOWS_DESKTOPS", + 2: "RESOURCE_SERVER_SSH", + 3: "RESOURCE_DATABASES", + 4: "RESOURCE_KUBERNETES", + 5: "RESOURCE_WEB_APPLICATIONS", + } + Resource_value = map[string]int32{ + "RESOURCE_UNSPECIFIED": 0, + "RESOURCE_WINDOWS_DESKTOPS": 1, + "RESOURCE_SERVER_SSH": 2, + "RESOURCE_DATABASES": 3, + "RESOURCE_KUBERNETES": 4, + "RESOURCE_WEB_APPLICATIONS": 5, + } +) + +func (x Resource) Enum() *Resource { + p := new(Resource) + *p = x + return p +} + +func (x Resource) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Resource) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_userpreferences_v1_onboard_proto_enumTypes[0].Descriptor() +} + +func (Resource) Type() protoreflect.EnumType { + return &file_teleport_userpreferences_v1_onboard_proto_enumTypes[0] +} + +func (x Resource) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Resource.Descriptor instead. +func (Resource) EnumDescriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_onboard_proto_rawDescGZIP(), []int{0} +} + +// OnboardUserPreferences is the user preferences selected during onboarding. +type OnboardUserPreferences struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // preferredResources is an array of the resources a user selected during their onboarding questionnaire. + PreferredResources []Resource `protobuf:"varint,1,rep,packed,name=preferred_resources,json=preferredResources,proto3,enum=teleport.userpreferences.v1.Resource" json:"preferred_resources,omitempty"` +} + +func (x *OnboardUserPreferences) Reset() { + *x = OnboardUserPreferences{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_userpreferences_v1_onboard_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OnboardUserPreferences) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OnboardUserPreferences) ProtoMessage() {} + +func (x *OnboardUserPreferences) ProtoReflect() protoreflect.Message { + mi := &file_teleport_userpreferences_v1_onboard_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OnboardUserPreferences.ProtoReflect.Descriptor instead. +func (*OnboardUserPreferences) Descriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_onboard_proto_rawDescGZIP(), []int{0} +} + +func (x *OnboardUserPreferences) GetPreferredResources() []Resource { + if x != nil { + return x.PreferredResources + } + return nil +} + +var File_teleport_userpreferences_v1_onboard_proto protoreflect.FileDescriptor + +var file_teleport_userpreferences_v1_onboard_proto_rawDesc = []byte{ + 0x0a, 0x29, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x6e, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x22, 0x70, 0x0a, 0x16, 0x4f, 0x6e, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x12, 0x56, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x12, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, + 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2a, 0xac, 0x01, 0x0a, 0x08, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x57, 0x49, + 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x45, 0x53, 0x4b, 0x54, 0x4f, 0x50, 0x53, 0x10, 0x01, + 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x5f, 0x53, 0x53, 0x48, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x53, 0x10, + 0x03, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4b, 0x55, + 0x42, 0x45, 0x52, 0x4e, 0x45, 0x54, 0x45, 0x53, 0x10, 0x04, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, + 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x57, 0x45, 0x42, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, + 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x05, 0x42, 0x59, 0x5a, 0x57, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, + 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, + 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_userpreferences_v1_onboard_proto_rawDescOnce sync.Once + file_teleport_userpreferences_v1_onboard_proto_rawDescData = file_teleport_userpreferences_v1_onboard_proto_rawDesc +) + +func file_teleport_userpreferences_v1_onboard_proto_rawDescGZIP() []byte { + file_teleport_userpreferences_v1_onboard_proto_rawDescOnce.Do(func() { + file_teleport_userpreferences_v1_onboard_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_userpreferences_v1_onboard_proto_rawDescData) + }) + return file_teleport_userpreferences_v1_onboard_proto_rawDescData +} + +var file_teleport_userpreferences_v1_onboard_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_userpreferences_v1_onboard_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_userpreferences_v1_onboard_proto_goTypes = []interface{}{ + (Resource)(0), // 0: teleport.userpreferences.v1.Resource + (*OnboardUserPreferences)(nil), // 1: teleport.userpreferences.v1.OnboardUserPreferences +} +var file_teleport_userpreferences_v1_onboard_proto_depIdxs = []int32{ + 0, // 0: teleport.userpreferences.v1.OnboardUserPreferences.preferred_resources:type_name -> teleport.userpreferences.v1.Resource + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_teleport_userpreferences_v1_onboard_proto_init() } +func file_teleport_userpreferences_v1_onboard_proto_init() { + if File_teleport_userpreferences_v1_onboard_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_userpreferences_v1_onboard_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OnboardUserPreferences); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_userpreferences_v1_onboard_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_userpreferences_v1_onboard_proto_goTypes, + DependencyIndexes: file_teleport_userpreferences_v1_onboard_proto_depIdxs, + EnumInfos: file_teleport_userpreferences_v1_onboard_proto_enumTypes, + MessageInfos: file_teleport_userpreferences_v1_onboard_proto_msgTypes, + }.Build() + File_teleport_userpreferences_v1_onboard_proto = out.File + file_teleport_userpreferences_v1_onboard_proto_rawDesc = nil + file_teleport_userpreferences_v1_onboard_proto_goTypes = nil + file_teleport_userpreferences_v1_onboard_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/userpreferences/v1/theme.pb.go b/api/gen/proto/go/userpreferences/v1/theme.pb.go new file mode 100644 index 0000000000000..5706d90412c59 --- /dev/null +++ b/api/gen/proto/go/userpreferences/v1/theme.pb.go @@ -0,0 +1,156 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/userpreferences/v1/theme.proto + +package userpreferencesv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Theme is a frontend theme. +type Theme int32 + +const ( + Theme_THEME_UNSPECIFIED Theme = 0 + // THEME_LIGHT is the light theme. + Theme_THEME_LIGHT Theme = 1 + // THEME_DARK is the dark theme. + Theme_THEME_DARK Theme = 2 +) + +// Enum value maps for Theme. +var ( + Theme_name = map[int32]string{ + 0: "THEME_UNSPECIFIED", + 1: "THEME_LIGHT", + 2: "THEME_DARK", + } + Theme_value = map[string]int32{ + "THEME_UNSPECIFIED": 0, + "THEME_LIGHT": 1, + "THEME_DARK": 2, + } +) + +func (x Theme) Enum() *Theme { + p := new(Theme) + *p = x + return p +} + +func (x Theme) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Theme) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_userpreferences_v1_theme_proto_enumTypes[0].Descriptor() +} + +func (Theme) Type() protoreflect.EnumType { + return &file_teleport_userpreferences_v1_theme_proto_enumTypes[0] +} + +func (x Theme) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Theme.Descriptor instead. +func (Theme) EnumDescriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_theme_proto_rawDescGZIP(), []int{0} +} + +var File_teleport_userpreferences_v1_theme_proto protoreflect.FileDescriptor + +var file_teleport_userpreferences_v1_theme_proto_rawDesc = []byte{ + 0x0a, 0x27, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x68, + 0x65, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2a, 0x3f, 0x0a, 0x05, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x12, + 0x15, 0x0a, 0x11, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, + 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x48, 0x45, 0x4d, 0x45, + 0x5f, 0x44, 0x41, 0x52, 0x4b, 0x10, 0x02, 0x42, 0x59, 0x5a, 0x57, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x75, 0x73, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, + 0x3b, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_userpreferences_v1_theme_proto_rawDescOnce sync.Once + file_teleport_userpreferences_v1_theme_proto_rawDescData = file_teleport_userpreferences_v1_theme_proto_rawDesc +) + +func file_teleport_userpreferences_v1_theme_proto_rawDescGZIP() []byte { + file_teleport_userpreferences_v1_theme_proto_rawDescOnce.Do(func() { + file_teleport_userpreferences_v1_theme_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_userpreferences_v1_theme_proto_rawDescData) + }) + return file_teleport_userpreferences_v1_theme_proto_rawDescData +} + +var file_teleport_userpreferences_v1_theme_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_userpreferences_v1_theme_proto_goTypes = []interface{}{ + (Theme)(0), // 0: teleport.userpreferences.v1.Theme +} +var file_teleport_userpreferences_v1_theme_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_teleport_userpreferences_v1_theme_proto_init() } +func file_teleport_userpreferences_v1_theme_proto_init() { + if File_teleport_userpreferences_v1_theme_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_userpreferences_v1_theme_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_userpreferences_v1_theme_proto_goTypes, + DependencyIndexes: file_teleport_userpreferences_v1_theme_proto_depIdxs, + EnumInfos: file_teleport_userpreferences_v1_theme_proto_enumTypes, + }.Build() + File_teleport_userpreferences_v1_theme_proto = out.File + file_teleport_userpreferences_v1_theme_proto_rawDesc = nil + file_teleport_userpreferences_v1_theme_proto_goTypes = nil + file_teleport_userpreferences_v1_theme_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/userpreferences/v1/userpreferences.pb.go b/api/gen/proto/go/userpreferences/v1/userpreferences.pb.go new file mode 100644 index 0000000000000..864f8130dc01f --- /dev/null +++ b/api/gen/proto/go/userpreferences/v1/userpreferences.pb.go @@ -0,0 +1,454 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: teleport/userpreferences/v1/userpreferences.proto + +package userpreferencesv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// UserPreferences is a collection of different user changeable preferences for the frontend. +type UserPreferences struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // assist is the preferences for the Teleport Assist. + Assist *AssistUserPreferences `protobuf:"bytes,1,opt,name=assist,proto3" json:"assist,omitempty"` + // theme is the theme of the frontend. + Theme Theme `protobuf:"varint,2,opt,name=theme,proto3,enum=teleport.userpreferences.v1.Theme" json:"theme,omitempty"` + // onboard is the preferences from the onboarding questionnaire. + Onboard *OnboardUserPreferences `protobuf:"bytes,3,opt,name=onboard,proto3" json:"onboard,omitempty"` +} + +func (x *UserPreferences) Reset() { + *x = UserPreferences{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserPreferences) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserPreferences) ProtoMessage() {} + +func (x *UserPreferences) ProtoReflect() protoreflect.Message { + mi := &file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserPreferences.ProtoReflect.Descriptor instead. +func (*UserPreferences) Descriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_userpreferences_proto_rawDescGZIP(), []int{0} +} + +func (x *UserPreferences) GetAssist() *AssistUserPreferences { + if x != nil { + return x.Assist + } + return nil +} + +func (x *UserPreferences) GetTheme() Theme { + if x != nil { + return x.Theme + } + return Theme_THEME_UNSPECIFIED +} + +func (x *UserPreferences) GetOnboard() *OnboardUserPreferences { + if x != nil { + return x.Onboard + } + return nil +} + +// GetUserPreferencesRequest is a request to get the user preferences. +type GetUserPreferencesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // username is the username of the owner of the user preferences to get. + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` +} + +func (x *GetUserPreferencesRequest) Reset() { + *x = GetUserPreferencesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserPreferencesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserPreferencesRequest) ProtoMessage() {} + +func (x *GetUserPreferencesRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserPreferencesRequest.ProtoReflect.Descriptor instead. +func (*GetUserPreferencesRequest) Descriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_userpreferences_proto_rawDescGZIP(), []int{1} +} + +func (x *GetUserPreferencesRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +// GetUserPreferencesResponse is a response to get the user preferences. +type GetUserPreferencesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // preferences is the user preferences. + Preferences *UserPreferences `protobuf:"bytes,1,opt,name=preferences,proto3" json:"preferences,omitempty"` +} + +func (x *GetUserPreferencesResponse) Reset() { + *x = GetUserPreferencesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserPreferencesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserPreferencesResponse) ProtoMessage() {} + +func (x *GetUserPreferencesResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserPreferencesResponse.ProtoReflect.Descriptor instead. +func (*GetUserPreferencesResponse) Descriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_userpreferences_proto_rawDescGZIP(), []int{2} +} + +func (x *GetUserPreferencesResponse) GetPreferences() *UserPreferences { + if x != nil { + return x.Preferences + } + return nil +} + +// UpsertUserPreferencesRequest is a request to create or update the user preferences. +type UpsertUserPreferencesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // preferences is the new user preferences to set. + Preferences *UserPreferences `protobuf:"bytes,1,opt,name=preferences,proto3" json:"preferences,omitempty"` + // username is the username of the owner of the user preferences to update. + Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` +} + +func (x *UpsertUserPreferencesRequest) Reset() { + *x = UpsertUserPreferencesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpsertUserPreferencesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpsertUserPreferencesRequest) ProtoMessage() {} + +func (x *UpsertUserPreferencesRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpsertUserPreferencesRequest.ProtoReflect.Descriptor instead. +func (*UpsertUserPreferencesRequest) Descriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_userpreferences_proto_rawDescGZIP(), []int{3} +} + +func (x *UpsertUserPreferencesRequest) GetPreferences() *UserPreferences { + if x != nil { + return x.Preferences + } + return nil +} + +func (x *UpsertUserPreferencesRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +var File_teleport_userpreferences_v1_userpreferences_proto protoreflect.FileDescriptor + +var file_teleport_userpreferences_v1_userpreferences_proto_rawDesc = []byte{ + 0x0a, 0x31, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, + 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x28, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x73, 0x73, 0x69, 0x73, + 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x27, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x73, 0x65, + 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, + 0x74, 0x68, 0x65, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x01, 0x0a, 0x0f, + 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, + 0x4a, 0x0a, 0x06, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, + 0x73, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x52, 0x06, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x05, 0x74, + 0x68, 0x65, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x52, 0x05, + 0x74, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x07, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x55, 0x73, 0x65, 0x72, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x07, 0x6f, 0x6e, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x22, 0x37, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x6c, 0x0a, + 0x1a, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0b, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x0b, + 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x1c, + 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4e, 0x0a, 0x0b, + 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, + 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, + 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x32, 0x8c, 0x02, 0x0a, 0x16, 0x55, 0x73, 0x65, + 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x85, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x36, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x15, 0x55, + 0x70, 0x73, 0x65, 0x72, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x12, 0x39, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x59, 0x5a, 0x57, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x75, 0x73, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, + 0x3b, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_userpreferences_v1_userpreferences_proto_rawDescOnce sync.Once + file_teleport_userpreferences_v1_userpreferences_proto_rawDescData = file_teleport_userpreferences_v1_userpreferences_proto_rawDesc +) + +func file_teleport_userpreferences_v1_userpreferences_proto_rawDescGZIP() []byte { + file_teleport_userpreferences_v1_userpreferences_proto_rawDescOnce.Do(func() { + file_teleport_userpreferences_v1_userpreferences_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_userpreferences_v1_userpreferences_proto_rawDescData) + }) + return file_teleport_userpreferences_v1_userpreferences_proto_rawDescData +} + +var file_teleport_userpreferences_v1_userpreferences_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_teleport_userpreferences_v1_userpreferences_proto_goTypes = []interface{}{ + (*UserPreferences)(nil), // 0: teleport.userpreferences.v1.UserPreferences + (*GetUserPreferencesRequest)(nil), // 1: teleport.userpreferences.v1.GetUserPreferencesRequest + (*GetUserPreferencesResponse)(nil), // 2: teleport.userpreferences.v1.GetUserPreferencesResponse + (*UpsertUserPreferencesRequest)(nil), // 3: teleport.userpreferences.v1.UpsertUserPreferencesRequest + (*AssistUserPreferences)(nil), // 4: teleport.userpreferences.v1.AssistUserPreferences + (Theme)(0), // 5: teleport.userpreferences.v1.Theme + (*OnboardUserPreferences)(nil), // 6: teleport.userpreferences.v1.OnboardUserPreferences + (*emptypb.Empty)(nil), // 7: google.protobuf.Empty +} +var file_teleport_userpreferences_v1_userpreferences_proto_depIdxs = []int32{ + 4, // 0: teleport.userpreferences.v1.UserPreferences.assist:type_name -> teleport.userpreferences.v1.AssistUserPreferences + 5, // 1: teleport.userpreferences.v1.UserPreferences.theme:type_name -> teleport.userpreferences.v1.Theme + 6, // 2: teleport.userpreferences.v1.UserPreferences.onboard:type_name -> teleport.userpreferences.v1.OnboardUserPreferences + 0, // 3: teleport.userpreferences.v1.GetUserPreferencesResponse.preferences:type_name -> teleport.userpreferences.v1.UserPreferences + 0, // 4: teleport.userpreferences.v1.UpsertUserPreferencesRequest.preferences:type_name -> teleport.userpreferences.v1.UserPreferences + 1, // 5: teleport.userpreferences.v1.UserPreferencesService.GetUserPreferences:input_type -> teleport.userpreferences.v1.GetUserPreferencesRequest + 3, // 6: teleport.userpreferences.v1.UserPreferencesService.UpsertUserPreferences:input_type -> teleport.userpreferences.v1.UpsertUserPreferencesRequest + 2, // 7: teleport.userpreferences.v1.UserPreferencesService.GetUserPreferences:output_type -> teleport.userpreferences.v1.GetUserPreferencesResponse + 7, // 8: teleport.userpreferences.v1.UserPreferencesService.UpsertUserPreferences:output_type -> google.protobuf.Empty + 7, // [7:9] is the sub-list for method output_type + 5, // [5:7] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_teleport_userpreferences_v1_userpreferences_proto_init() } +func file_teleport_userpreferences_v1_userpreferences_proto_init() { + if File_teleport_userpreferences_v1_userpreferences_proto != nil { + return + } + file_teleport_userpreferences_v1_assist_proto_init() + file_teleport_userpreferences_v1_onboard_proto_init() + file_teleport_userpreferences_v1_theme_proto_init() + if !protoimpl.UnsafeEnabled { + file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserPreferences); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserPreferencesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserPreferencesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_userpreferences_v1_userpreferences_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpsertUserPreferencesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_userpreferences_v1_userpreferences_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_teleport_userpreferences_v1_userpreferences_proto_goTypes, + DependencyIndexes: file_teleport_userpreferences_v1_userpreferences_proto_depIdxs, + MessageInfos: file_teleport_userpreferences_v1_userpreferences_proto_msgTypes, + }.Build() + File_teleport_userpreferences_v1_userpreferences_proto = out.File + file_teleport_userpreferences_v1_userpreferences_proto_rawDesc = nil + file_teleport_userpreferences_v1_userpreferences_proto_goTypes = nil + file_teleport_userpreferences_v1_userpreferences_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/userpreferences/v1/userpreferences_grpc.pb.go b/api/gen/proto/go/userpreferences/v1/userpreferences_grpc.pb.go new file mode 100644 index 0000000000000..47fd6c6475447 --- /dev/null +++ b/api/gen/proto/go/userpreferences/v1/userpreferences_grpc.pb.go @@ -0,0 +1,166 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: teleport/userpreferences/v1/userpreferences.proto + +package userpreferencesv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + UserPreferencesService_GetUserPreferences_FullMethodName = "/teleport.userpreferences.v1.UserPreferencesService/GetUserPreferences" + UserPreferencesService_UpsertUserPreferences_FullMethodName = "/teleport.userpreferences.v1.UserPreferencesService/UpsertUserPreferences" +) + +// UserPreferencesServiceClient is the client API for UserPreferencesService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type UserPreferencesServiceClient interface { + // GetUserPreferences returns the user preferences for a given user. + GetUserPreferences(ctx context.Context, in *GetUserPreferencesRequest, opts ...grpc.CallOption) (*GetUserPreferencesResponse, error) + // UpsertUserPreferences creates or updates user preferences for a given username. + UpsertUserPreferences(ctx context.Context, in *UpsertUserPreferencesRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type userPreferencesServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserPreferencesServiceClient(cc grpc.ClientConnInterface) UserPreferencesServiceClient { + return &userPreferencesServiceClient{cc} +} + +func (c *userPreferencesServiceClient) GetUserPreferences(ctx context.Context, in *GetUserPreferencesRequest, opts ...grpc.CallOption) (*GetUserPreferencesResponse, error) { + out := new(GetUserPreferencesResponse) + err := c.cc.Invoke(ctx, UserPreferencesService_GetUserPreferences_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userPreferencesServiceClient) UpsertUserPreferences(ctx context.Context, in *UpsertUserPreferencesRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, UserPreferencesService_UpsertUserPreferences_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserPreferencesServiceServer is the server API for UserPreferencesService service. +// All implementations must embed UnimplementedUserPreferencesServiceServer +// for forward compatibility +type UserPreferencesServiceServer interface { + // GetUserPreferences returns the user preferences for a given user. + GetUserPreferences(context.Context, *GetUserPreferencesRequest) (*GetUserPreferencesResponse, error) + // UpsertUserPreferences creates or updates user preferences for a given username. + UpsertUserPreferences(context.Context, *UpsertUserPreferencesRequest) (*emptypb.Empty, error) + mustEmbedUnimplementedUserPreferencesServiceServer() +} + +// UnimplementedUserPreferencesServiceServer must be embedded to have forward compatible implementations. +type UnimplementedUserPreferencesServiceServer struct { +} + +func (UnimplementedUserPreferencesServiceServer) GetUserPreferences(context.Context, *GetUserPreferencesRequest) (*GetUserPreferencesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUserPreferences not implemented") +} +func (UnimplementedUserPreferencesServiceServer) UpsertUserPreferences(context.Context, *UpsertUserPreferencesRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpsertUserPreferences not implemented") +} +func (UnimplementedUserPreferencesServiceServer) mustEmbedUnimplementedUserPreferencesServiceServer() { +} + +// UnsafeUserPreferencesServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserPreferencesServiceServer will +// result in compilation errors. +type UnsafeUserPreferencesServiceServer interface { + mustEmbedUnimplementedUserPreferencesServiceServer() +} + +func RegisterUserPreferencesServiceServer(s grpc.ServiceRegistrar, srv UserPreferencesServiceServer) { + s.RegisterService(&UserPreferencesService_ServiceDesc, srv) +} + +func _UserPreferencesService_GetUserPreferences_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserPreferencesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserPreferencesServiceServer).GetUserPreferences(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserPreferencesService_GetUserPreferences_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserPreferencesServiceServer).GetUserPreferences(ctx, req.(*GetUserPreferencesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserPreferencesService_UpsertUserPreferences_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpsertUserPreferencesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserPreferencesServiceServer).UpsertUserPreferences(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserPreferencesService_UpsertUserPreferences_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserPreferencesServiceServer).UpsertUserPreferences(ctx, req.(*UpsertUserPreferencesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// UserPreferencesService_ServiceDesc is the grpc.ServiceDesc for UserPreferencesService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserPreferencesService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "teleport.userpreferences.v1.UserPreferencesService", + HandlerType: (*UserPreferencesServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetUserPreferences", + Handler: _UserPreferencesService_GetUserPreferences_Handler, + }, + { + MethodName: "UpsertUserPreferences", + Handler: _UserPreferencesService_UpsertUserPreferences_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "teleport/userpreferences/v1/userpreferences.proto", +} diff --git a/api/go.mod b/api/go.mod index da7ecda56a4f6..d1bbd1a01baf3 100644 --- a/api/go.mod +++ b/api/go.mod @@ -3,6 +3,7 @@ module github.com/gravitational/teleport/api go 1.19 require ( + cloud.google.com/go/compute/metadata v0.2.3 github.com/coreos/go-semver v0.3.1 github.com/go-piv/piv-go v1.11.0 github.com/gogo/protobuf v1.3.2 @@ -20,17 +21,18 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 go.opentelemetry.io/otel/sdk v1.16.0 go.opentelemetry.io/otel/trace v1.16.0 - go.opentelemetry.io/proto/otlp v0.19.0 - golang.org/x/crypto v0.9.0 + go.opentelemetry.io/proto/otlp v0.20.0 + golang.org/x/crypto v0.10.0 golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 - golang.org/x/net v0.10.0 - google.golang.org/genproto v0.0.0-20230327152035-dc694ad2151e - google.golang.org/grpc v1.55.0 + golang.org/x/net v0.11.0 + google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc + google.golang.org/grpc v1.56.1 google.golang.org/protobuf v1.30.0 gopkg.in/yaml.v2 v2.4.0 ) require ( + cloud.google.com/go/compute v1.19.1 // indirect github.com/beevik/etree v1.1.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -38,14 +40,15 @@ require ( github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russellhaering/goxmldsig v1.3.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect go.opentelemetry.io/otel/metric v1.16.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/api/go.sum b/api/go.sum index f89f8cf481599..7b13e084864f9 100644 --- a/api/go.sum +++ b/api/go.sum @@ -1,61 +1,25 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ= +cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -66,15 +30,12 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -85,24 +46,11 @@ github.com/go-piv/piv-go v1.11.0/go.mod h1:NZ2zmjVkfFaL/CF8cVQ/pXdXtuj110zEKGdJM github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -112,57 +60,34 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gravitational/trace v1.2.1 h1:Iaf43aqbKV5H8bdiRs1qByjEHgAfADJ0lt0JwRyu+q8= github.com/gravitational/trace v1.2.1/go.mod h1:n0ijrq6psJY0sOI/NzLp+xdd8xl79jjwzVOFHDY6+kQ= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -174,7 +99,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= @@ -185,24 +109,15 @@ github.com/russellhaering/goxmldsig v1.3.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWy github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM= @@ -222,47 +137,21 @@ go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.20.0 h1:BLOA1cZBAGSbRiNuGCCKiFrCdYB7deeHDeD1SueyOfA= +go.opentelemetry.io/proto/otlp v0.20.0/go.mod h1:3QgjzPALBIv9pcknj2EXGPXjYPFdUh/RQfF8Lz3+Vnw= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 h1:yZNXmy+j/JpX19vZkVktWqAo7Gny4PBWYYK3zskGpx4= golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -271,223 +160,80 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230327152035-dc694ad2151e h1:rRGPYd0STm9H4Ci+iGrSLG35mkAKY41/nzCcG7PQADw= -google.golang.org/genproto v0.0.0-20230327152035-dc694ad2151e/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e h1:Ao9GzfUMPH3zjVfzXG5rlWlk+Q8MXWKwWpwVQE1MXfw= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= +google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -496,11 +242,9 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -517,12 +261,4 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/lib/fuzz/fuzz.go b/api/import_compute.go similarity index 55% rename from lib/fuzz/fuzz.go rename to api/import_compute.go index d83eaf2d9c3fc..b3978b19bbe42 100644 --- a/lib/fuzz/fuzz.go +++ b/api/import_compute.go @@ -1,4 +1,4 @@ -// Copyright 2021 Gravitational, Inc +// Copyright 2023 Gravitational, Inc // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,28 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build gofuzz -// +build gofuzz - -package fuzz +package api import ( - "github.com/gravitational/teleport/lib/utils" - "github.com/gravitational/teleport/lib/utils/parse" + _ "cloud.google.com/go/compute/metadata" // fix tidy issues with otel ) - -func FuzzParseProxyJump(data []byte) int { - _, err := utils.ParseProxyJump(string(data)) - if err != nil { - return 0 - } - return 1 -} - -func FuzzNewExpression(data []byte) int { - _, err := parse.NewExpression(string(data)) - if err != nil { - return 0 - } - return 1 -} diff --git a/api/observability/tracing/tracing.go b/api/observability/tracing/tracing.go index 6e6f848404135..6e33cb073c046 100644 --- a/api/observability/tracing/tracing.go +++ b/api/observability/tracing/tracing.go @@ -47,3 +47,9 @@ func WithPropagationContext(ctx context.Context, pc PropagationContext, opts ... func DefaultProvider() oteltrace.TracerProvider { return otel.GetTracerProvider() } + +// NewTracer creates a new [oteltrace.Tracer] from the global default +// [oteltrace.TracerProvider] with the provided name. +func NewTracer(name string) oteltrace.Tracer { + return DefaultProvider().Tracer(name) +} diff --git a/api/profile/profile.go b/api/profile/profile.go index a0564ef30dd10..abc8f45d16f6c 100644 --- a/api/profile/profile.go +++ b/api/profile/profile.go @@ -142,6 +142,12 @@ func (p *Profile) TLSConfig() (*tls.Config, error) { }, nil } +// RequireKubeLocalProxy returns true if this profile indicates a local proxy +// is required for kube access. +func (p *Profile) RequireKubeLocalProxy() bool { + return p.KubeProxyAddr == p.WebProxyAddr && p.TLSRoutingConnUpgradeRequired +} + func certPoolFromProfile(p *Profile) (*x509.CertPool, error) { // Check if CAS dir exist if not try to load certs from legacy certs.pem file. if _, err := os.Stat(p.TLSClusterCASDir()); err != nil { diff --git a/api/profile/profile_test.go b/api/profile/profile_test.go index 663e6fd9eafd4..5ef6181de2320 100644 --- a/api/profile/profile_test.go +++ b/api/profile/profile_test.go @@ -115,3 +115,58 @@ func TestProfilePath(t *testing.T) { require.Equal(t, "/foo/bar", profile.FullProfilePath("/foo/bar")) require.Equal(t, filepath.Join(dir, ".tsh"), profile.FullProfilePath("")) } + +func TestRequireKubeLocalProxy(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + inputProfile *profile.Profile + checkResult require.BoolAssertionFunc + }{ + { + name: "kube not enabled", + inputProfile: &profile.Profile{ + WebProxyAddr: "example.com:443", + TLSRoutingEnabled: true, + TLSRoutingConnUpgradeRequired: true, + }, + checkResult: require.False, + }, + { + name: "ALPN connection upgrade not required", + inputProfile: &profile.Profile{ + WebProxyAddr: "example.com:443", + KubeProxyAddr: "example.com:443", + TLSRoutingEnabled: true, + }, + checkResult: require.False, + }, + { + name: "kube uses separate listener", + inputProfile: &profile.Profile{ + WebProxyAddr: "example.com:443", + KubeProxyAddr: "example.com:3026", + TLSRoutingEnabled: false, + TLSRoutingConnUpgradeRequired: true, + }, + checkResult: require.False, + }, + { + name: "local proxy required", + inputProfile: &profile.Profile{ + WebProxyAddr: "example.com:443", + KubeProxyAddr: "example.com:443", + TLSRoutingEnabled: true, + TLSRoutingConnUpgradeRequired: true, + }, + checkResult: require.True, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.checkResult(t, test.inputProfile.RequireKubeLocalProxy()) + }) + } +} diff --git a/api/proto/teleport/accesslist/v1/accesslist.proto b/api/proto/teleport/accesslist/v1/accesslist.proto new file mode 100644 index 0000000000000..7745b35b30dc2 --- /dev/null +++ b/api/proto/teleport/accesslist/v1/accesslist.proto @@ -0,0 +1,115 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.accesslist.v1; + +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "teleport/header/v1/resourceheader.proto"; +import "teleport/trait/v1/trait.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/accesslist/v1;accesslist"; + +// AccessList describes the basic building block of access grants, which are +// similar to access requests but for longer lived permissions that need to be +// regularly audited. +message AccessList { + // header is the header for the resource. + teleport.header.v1.ResourceHeader header = 1; + + // spec is the specification for the access list. + AccessListSpec spec = 2; +} + +// AccessListSpec is the specification for an access list. +message AccessListSpec { + // description is a plaintext description of the access list. + string description = 1; + + // owners is a list of owners of the access list. + repeated AccessListOwner owners = 2; + + // audit describes the frequency that this access list must be audited. + AccessListAudit audit = 3; + + // membership_requires describes the requirements for a user to be a member of the access list. + // For a membership to an access list to be effective, the user must meet the requirements of + // Membership_requires and must be in the members list. + AccessListRequires membership_requires = 4; + + // ownership_requires describes the requirements for a user to be an owner of the access list. + // For ownership of an access list to be effective, the user must meet the requirements of + // ownership_requires and must be in the owners list. + AccessListRequires ownership_requires = 5; + + // grants describes the access granted by membership to this access list. + AccessListGrants grants = 6; + + // members describes the current members of the access list. + repeated AccessListMember members = 7; +} + +// AccessListOwner is an owner of an access list. +message AccessListOwner { + // name is the username of the owner. + string name = 1; + + // description is the plaintext description of the owner and why they are an owner. + string description = 2; +} + +// AccessListAudit describes the audit configuration for an access list. +message AccessListAudit { + // frequency is a duration that describes how often an access list must be audited. + google.protobuf.Duration frequency = 1; +} + +// AccessListRequires describes a requirement section for an access list. A user must +// meet the following criteria to obtain the specific access to the list. +message AccessListRequires { + // roles are the user roles that must be present for the user to obtain access. + repeated string roles = 1; + + // traits are the traits that must be present for the user to obtain access. + repeated teleport.trait.v1.Trait traits = 2; +} + +// AccessListGrants describes what access is granted by membership to the access list. +message AccessListGrants { + // roles are the roles that are granted to users who are members of the access list. + repeated string roles = 1; + + // traits are the traits that are granted to users who are members of the access list. + repeated teleport.trait.v1.Trait traits = 2; +} + +// AccessListMember describes a member of an access list. +message AccessListMember { + // name is the name of the member of the access list. + string name = 1; + + // joined is when the user joined the access list. + google.protobuf.Timestamp joined = 2; + + // expires is when the user's membership to the access list expires. + google.protobuf.Timestamp expires = 3; + + // reason is the reason this user was added to the access list. + string reason = 4; + + // added_by is the user that added this user to the access list. + string added_by = 5; +} diff --git a/api/proto/teleport/assist/v1/assist.proto b/api/proto/teleport/assist/v1/assist.proto index d3065ff35214c..6157198d791c0 100644 --- a/api/proto/teleport/assist/v1/assist.proto +++ b/api/proto/teleport/assist/v1/assist.proto @@ -121,6 +121,35 @@ message DeleteAssistantConversationRequest { string username = 2; } +// GetAssistantEmbeddingsRequest is a request to get embeddings. +message GetAssistantEmbeddingsRequest { + // username is a username of the user who requested the embeddings. + string username = 1; + // query is the query used for similarity search. + string query = 2; + // limit is the number of embeddings to return (also known as k). + uint32 limit = 3; + // kind is the kind of embeddings to return (ex, node). + string kind = 4; +} + +// EmbeddingDocument is a document with an embedding. +message EmbeddedDocument { + // id is the id of the document. + string id = 1; + // content is the content of the document. + string content = 2; + // similarityScore is the similarity score of the document. + float similarity_score = 3; +} + +// GetAssistantEmbeddingsResponse is a response from the assistant service. +message GetAssistantEmbeddingsResponse { + // embeddings is the list of embeddings. + // The list is sorted by similarity score in descending order. + repeated EmbeddedDocument embeddings = 1; +} + // AssistService is a service that provides an ability to communicate with the Teleport Assist. service AssistService { // CreateNewConversation creates a new conversation and returns the UUID of it. @@ -144,3 +173,9 @@ service AssistService { // IsAssistEnabled returns true if the assist is enabled or not on the auth level. rpc IsAssistEnabled(IsAssistEnabledRequest) returns (IsAssistEnabledResponse); } + +// AssistEmbeddingService is a service that provides an ability to communicate with the Assist Embedding service. +service AssistEmbeddingService { + // AssistantGetEmbeddings returns the embeddings for the given query. + rpc GetAssistantEmbeddings(GetAssistantEmbeddingsRequest) returns (GetAssistantEmbeddingsResponse); +} diff --git a/api/proto/teleport/devicetrust/v1/device_collected_data.proto b/api/proto/teleport/devicetrust/v1/device_collected_data.proto index 5a07a4f1eeebf..92a69e1d0d236 100644 --- a/api/proto/teleport/devicetrust/v1/device_collected_data.proto +++ b/api/proto/teleport/devicetrust/v1/device_collected_data.proto @@ -18,6 +18,7 @@ package teleport.devicetrust.v1; import "google/protobuf/timestamp.proto"; import "teleport/devicetrust/v1/os_type.proto"; +import "teleport/devicetrust/v1/tpm.proto"; option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1;devicetrustv1"; @@ -81,4 +82,18 @@ message DeviceCollectedData { // The serial number of the "base board" as reported by BIOS DMI Type 2. // This field can be empty if no value has been configured. string base_board_serial_number = 13; + + // If during the collection of this device data, the device performed a TPM + // platform attestation (e.g during enrollment or authentication), then this + // field holds the record of this attestation. This allows the state of the + // device to be compared to historical state, and allows for the platform + // attestations to be revalidated at a later date. + // + // This field is not explicitly sent up by the client, and any DCD sent by a + // client including this field should be rejected. The server should inject + // this field once verifying that the submitted platform attestation during + // the enrollment or authentication. + // + // System managed. + TPMPlatformAttestation tpm_platform_attestation = 14; } diff --git a/api/proto/teleport/devicetrust/v1/device_profile.proto b/api/proto/teleport/devicetrust/v1/device_profile.proto index 0c474dc525418..f1fde92053ae4 100644 --- a/api/proto/teleport/devicetrust/v1/device_profile.proto +++ b/api/proto/teleport/devicetrust/v1/device_profile.proto @@ -46,4 +46,7 @@ message DeviceProfile { // Jamf binary version, without the leading 'v'. // Example: "9.27" or "10.44.1-t1677509507". string jamf_binary_version = 6; + + // External device identifier, for example the Jamf or Intune ID. + string external_id = 7; } diff --git a/api/proto/teleport/devicetrust/v1/devicetrust_service.proto b/api/proto/teleport/devicetrust/v1/devicetrust_service.proto index e7dd695d1bb59..c081b395c0092 100644 --- a/api/proto/teleport/devicetrust/v1/devicetrust_service.proto +++ b/api/proto/teleport/devicetrust/v1/devicetrust_service.proto @@ -23,6 +23,7 @@ import "teleport/devicetrust/v1/device.proto"; import "teleport/devicetrust/v1/device_collected_data.proto"; import "teleport/devicetrust/v1/device_enroll_token.proto"; import "teleport/devicetrust/v1/device_source.proto"; +import "teleport/devicetrust/v1/tpm.proto"; import "teleport/devicetrust/v1/user_certificates.proto"; option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1;devicetrustv1"; @@ -438,36 +439,6 @@ message TPMEnrollChallengeResponse { TPMPlatformParameters platform_parameters = 2; } -// Encapsulates the value of a PCR at a point at time. -// See https://pkg.go.dev/github.com/google/go-attestation/attest#PCR -message TPMPCR { - // the PCR index in the PCR bank - int32 index = 1; - // the digest currently held in the PCR - bytes digest = 2; - // the hash algorithm used to produce the digest in this PCR bank. This value - // is the underlying value of the Go crypto.Hash type. - uint64 digest_alg = 3; -} - -// Encapsulates the result of a quote operation against the TPM over a PCR -// using an attestation key. -// See https://pkg.go.dev/github.com/google/go-attestation/attest#Quote -message TPMQuote { - bytes quote = 1; - bytes signature = 2; -} - -// The quotes, PCRs and event log from a TPM that attest to the booted state -// of the machine. -// See https://pkg.go.dev/github.com/google/go-attestation/attest#PlatformParameters -// Excludes TPMVersion and Public since these are already known values. -message TPMPlatformParameters { - repeated TPMQuote quotes = 1; - repeated TPMPCR pcrs = 2; - bytes event_log = 3; -} - // Request for AuthenticateDevice. // // Authentication ceremony flow: @@ -554,8 +525,10 @@ message AuthenticateDeviceChallengeResponse { // (end loop) // -> SyncInventoryEnd // (loop until server closes the stream, zero or more times) -// <- SyncInventoryResult (deleted/missing devices) -// (end) +// <- SyncInventoryMissingDevices +// -> SyncInventoryDevices (removals only) +// <- SyncInventoryResult +// (end loop) message SyncInventoryRequest { oneof payload { SyncInventoryStart start = 1; @@ -570,6 +543,7 @@ message SyncInventoryResponse { oneof payload { SyncInventoryAck ack = 1; SyncInventoryResult result = 2; + SyncInventoryMissingDevices missing_devices = 3; } } @@ -580,51 +554,25 @@ message SyncInventoryStart { // by this RPC. DeviceSource source = 1; - // Mode of syncing. - // Required. - SyncInventoryMode mode = 2; - - // Action for devices missing from the external inventory, but present in - // Teleport. - // Only executed if mode is FULL and external_sync_successful is set to true - // in the SyncInventoryEnd message. - SyncInventoryDeviceAction on_missing_action = 3; -} + reserved 2; // SyncInventoryMode mode + reserved "mode"; -// Mode of sync for SyncInventory. -enum SyncInventoryMode { - SYNC_INVENTORY_MODE_UNSPECIFIED = 0; + reserved 3; // SyncInventoryDeviceAction on_missing_action + reserved "on_missing_action"; - // Partial inventory sync; not all devices in the external inventory are sent - // to the stream. - // Partial sync precludes inventory cleanup. - SYNC_INVENTORY_MODE_PARTIAL = 1; - - // Full inventory sync; all devices in the external inventory must be sent to - // the stream. - // Full sync allows for handling of missing devices. - SYNC_INVENTORY_MODE_FULL = 2; -} - -// Device action for SyncInventory. -// Typically triggered at the end of FULL syncs.. -enum SyncInventoryDeviceAction { - SYNC_INVENTORY_DEVICE_ACTION_UNSPECIFIED = 0; - - // Noop is a no-action. - SYNC_INVENTORY_DEVICE_ACTION_NOOP = 1; - - // Deletes the device if the action condition is met. - SYNC_INVENTORY_DEVICE_ACTION_DELETE = 2; + // If true, the server keeps track of the devices upserted during the sync. + // After receiving the [SyncInventoryEnd] message, the server informs the + // client of all devices that are present in storage but not observed in the + // upserts. + // See [SyncInventoryRequest] and [SyncInventoryMissingDevices] for details. + bool track_missing_devices = 4; } // SyncInventoryEnd ends the inventory sync, signaling that no more // SyncInventoryDevices messages will be sent by the client. message SyncInventoryEnd { - // True if the external sync was fully successful (for example, all reads from - // an MDM API were successful). - // If false the sync's on_missing_action is skipped. - bool external_sync_successful = 1; + reserved 1; // bool external_sync_successful + reserved "external_sync_successful"; } // SyncInventoryDevices transports devices to add/update/remove. @@ -645,3 +593,18 @@ message SyncInventoryResult { // Devices modified, in the same order as the input when applicable. repeated DeviceOrStatus devices = 1; } + +// SyncInventoryMissingDevices informs the sync client of all stored devices +// that were not observed in upserts during the sync. +// +// Requires `track_missing_devices` to be set in the [SyncInventoryStart] +// message. +// +// The client must follow up with a [SyncInventoryDevices] message, including +// any devices to be deleted. +message SyncInventoryMissingDevices { + // Devices missing from the client-side sync. + // Guaranteed to have the following fields: id, os_type, asset_tag and + // profile.external_id. + repeated Device devices = 1; +} diff --git a/api/proto/teleport/devicetrust/v1/tpm.proto b/api/proto/teleport/devicetrust/v1/tpm.proto new file mode 100644 index 0000000000000..77b88b14e838c --- /dev/null +++ b/api/proto/teleport/devicetrust/v1/tpm.proto @@ -0,0 +1,59 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.devicetrust.v1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1;devicetrustv1"; + +// Encapsulates the value of a PCR at a point at time. +// See https://pkg.go.dev/github.com/google/go-attestation/attest#PCR +message TPMPCR { + // the PCR index in the PCR bank + int32 index = 1; + // the digest currently held in the PCR + bytes digest = 2; + // the hash algorithm used to produce the digest in this PCR bank. This value + // is the underlying value of the Go crypto.Hash type. + uint64 digest_alg = 3; +} + +// Encapsulates the result of a quote operation against the TPM over a PCR +// using an attestation key. +// See https://pkg.go.dev/github.com/google/go-attestation/attest#Quote +message TPMQuote { + bytes quote = 1; + bytes signature = 2; +} + +// The quotes, PCRs and event log from a TPM that attest to the booted state +// of the machine. +// See https://pkg.go.dev/github.com/google/go-attestation/attest#PlatformParameters +// Excludes TPMVersion and Public since these are already known values. +message TPMPlatformParameters { + repeated TPMQuote quotes = 1; + repeated TPMPCR pcrs = 2; + bytes event_log = 3; +} + +// Holds the record of a TPM platform attestation, including the platform +// parameters sent by the device and the nonce the server generated. This allows +// a historical platform attestation to be revalidated and allows us to compare +// the incoming state of a device (e.g during authentication) against the +// historical state in order to detect potentially malicious actions. +message TPMPlatformAttestation { + bytes nonce = 1; + TPMPlatformParameters platform_parameters = 2; +} diff --git a/api/proto/teleport/embedding/v1/embedding.proto b/api/proto/teleport/embedding/v1/embedding.proto new file mode 100644 index 0000000000000..cef7732aab551 --- /dev/null +++ b/api/proto/teleport/embedding/v1/embedding.proto @@ -0,0 +1,38 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.embedding.v1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/embedding/v1;embeddingv1"; + +// Embedding contains a Teleport resource embedding. Embeddings are small semantic +// representations of larger and more complex data. Embeddings can be compared, +// the smaller the distance between two vectors, the closer the concepts are. +// Teleport Assist embeds resources to perform semantic search. +message Embedding { + // EmbeddedKind is the kind of the embedded resource. + string embedded_kind = 1; + + // EmbeddedId is the ID of the embedded resource. + string embedded_id = 2; + + // EmbeddedHash is the hash of the embedded resource after serialization. + // This helps checking if the resource has changed and needs a new embedding. + bytes embedded_hash = 3; + + // Vector is the embedding itself, as provided by the model. + repeated double vector = 4; +} diff --git a/api/proto/teleport/header/v1/metadata.proto b/api/proto/teleport/header/v1/metadata.proto new file mode 100644 index 0000000000000..f430c942401f2 --- /dev/null +++ b/api/proto/teleport/header/v1/metadata.proto @@ -0,0 +1,39 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.header.v1; + +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/header/v1;header"; + +// Metadata is resource metadata. +message Metadata { + // name is an object name. + string name = 1; + // namespace is object namespace. The field should be called "namespace" + // when it returns in Teleport 2.4. + string namespace = 2; + // description is object description. + string description = 3; + // labels is a set of labels. + map labels = 5; + // expires is a global expiry time header can be set on any resource in the + // system. + google.protobuf.Timestamp expires = 6; + // ID is a record ID + int64 id = 7; +} diff --git a/api/proto/teleport/header/v1/resourceheader.proto b/api/proto/teleport/header/v1/resourceheader.proto new file mode 100644 index 0000000000000..7c2de3551cc8c --- /dev/null +++ b/api/proto/teleport/header/v1/resourceheader.proto @@ -0,0 +1,33 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.header.v1; + +import "teleport/header/v1/metadata.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/header/v1;header"; + +// ResourceHeader is a shared resource header. +message ResourceHeader { + // kind is a resource kind. + string kind = 1; + // sub_kind is an optional resource sub kind, used in some resources. + string sub_kind = 2; + // version is version. + string version = 3; + // metadata is resource metadata. + Metadata metadata = 4; +} diff --git a/api/proto/teleport/legacy/client/proto/authservice.proto b/api/proto/teleport/legacy/client/proto/authservice.proto index d77f235c85d46..21be60ef47bc0 100644 --- a/api/proto/teleport/legacy/client/proto/authservice.proto +++ b/api/proto/teleport/legacy/client/proto/authservice.proto @@ -135,6 +135,8 @@ message Event { types.IntegrationV1 Integration = 42 [(gogoproto.jsontag) = "integration,omitempty"]; // WatchStatus is an WatchStatus resource. types.WatchStatusV1 WatchStatus = 43 [(gogoproto.jsontag) = "watch_status,omitempty"]; + // HeadlessAuthentication is a HeadlessAuthentication resource. + types.HeadlessAuthentication HeadlessAuthentication = 44 [(gogoproto.jsontag) = "headless_authentication,omitempty"]; } } @@ -3001,6 +3003,9 @@ service AuthService { // GetHeadlessAuthentication is a request to retrieve a headless authentication from the backend. rpc GetHeadlessAuthentication(GetHeadlessAuthenticationRequest) returns (types.HeadlessAuthentication); + // WatchPendingHeadlessAuthentications watches the backend for pending headless authentication requests for the user. + rpc WatchPendingHeadlessAuthentications(google.protobuf.Empty) returns (stream Event); + // UpdateHeadlessAuthenticationState is a request to update a headless authentication's state. rpc UpdateHeadlessAuthenticationState(UpdateHeadlessAuthenticationStateRequest) returns (google.protobuf.Empty); diff --git a/api/proto/teleport/legacy/types/device.proto b/api/proto/teleport/legacy/types/device.proto index 4da16d6f7659e..7f863c4af9bda 100644 --- a/api/proto/teleport/legacy/types/device.proto +++ b/api/proto/teleport/legacy/types/device.proto @@ -67,10 +67,10 @@ message DeviceSpec { // teleport.devicetrust.v1.DeviceCredential. message DeviceCredential { string id = 1 [(gogoproto.jsontag) = "id"]; - bytes public_key_der = 2 [(gogoproto.jsontag) = "public_key_der"]; - string device_attestation_type = 3 [(gogoproto.jsontag) = "device_attestation_type"]; - string tpm_ekcert_serial = 4 [(gogoproto.jsontag) = "tpm_ekcert_serial"]; - bytes tpm_ak_public = 5 [(gogoproto.jsontag) = "tpm_ak_public"]; + bytes public_key_der = 2 [(gogoproto.jsontag) = "public_key_der,omitempty"]; + string device_attestation_type = 3 [(gogoproto.jsontag) = "device_attestation_type,omitempty"]; + string tpm_ekcert_serial = 4 [(gogoproto.jsontag) = "tpm_ekcert_serial,omitempty"]; + bytes tpm_ak_public = 5 [(gogoproto.jsontag) = "tpm_ak_public,omitempty"]; } // DeviceCollectedData is the resource representation of @@ -95,10 +95,39 @@ message DeviceCollectedData { string reported_asset_tag = 11 [(gogoproto.jsontag) = "reported_asset_tag,omitempty"]; string system_serial_number = 12 [(gogoproto.jsontag) = "system_serial_number,omitempty"]; string base_board_serial_number = 13 [(gogoproto.jsontag) = "base_board_serial_number,omitempty"]; + TPMPlatformAttestation tpm_platform_attestation = 14 [(gogoproto.jsontag) = "tpm_platform_attestation,omitempty"]; +} + +// TPMPCR is the resource representation of teleport.devicetrust.v1.TPMPCR. +message TPMPCR { + int32 index = 1 [(gogoproto.jsontag) = "index"]; + bytes digest = 2 [(gogoproto.jsontag) = "digest"]; + uint64 digest_alg = 3 [(gogoproto.jsontag) = "digest_alg"]; +} + +// TPMQuote is the resource representation of teleport.devicetrust.v1.TPMQuote. +message TPMQuote { + bytes quote = 1 [(gogoproto.jsontag) = "quote"]; + bytes signature = 2 [(gogoproto.jsontag) = "signature"]; +} + +// TPMPlatformParameters is the resource representation of +// teleport.devicetrust.v1.TPMPlatformParameters. +message TPMPlatformParameters { + repeated TPMQuote quotes = 1 [(gogoproto.jsontag) = "quotes"]; + repeated TPMPCR pcrs = 2 [(gogoproto.jsontag) = "pcrs"]; + bytes event_log = 3 [(gogoproto.jsontag) = "event_log"]; +} + +// TPMPlatformAttestation is the resource representation of +// teleport.devicetrust.v1.TPMPlatformAttestation. +message TPMPlatformAttestation { + bytes nonce = 1 [(gogoproto.jsontag) = "nonce,omitempty"]; + TPMPlatformParameters platform_parameters = 2 [(gogoproto.jsontag) = "platform_parameters,omitempty"]; } // DeviceSource is the resource representation of -// teleport.devicetrust.v1.DeviceSource. +// teleport.devicetrust.v1.DeviceSource.. message DeviceSource { string name = 1 [(gogoproto.jsontag) = "name"]; string origin = 2 [(gogoproto.jsontag) = "origin"]; @@ -116,4 +145,5 @@ message DeviceProfile { string os_build = 4 [(gogoproto.jsontag) = "os_build,omitempty"]; repeated string os_usernames = 5 [(gogoproto.jsontag) = "os_usernames,omitempty"]; string jamf_binary_version = 6 [(gogoproto.jsontag) = "jamf_binary_version,omitempty"]; + string external_id = 7 [(gogoproto.jsontag) = "external_id,omitempty"]; } diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 4fc1ea60f98fc..5c3b5ad3beb90 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -348,6 +348,11 @@ message DatabaseSpecV3 { ]; // AdminUser is the database admin user for automatic user provisioning. DatabaseAdminUser AdminUser = 11 [(gogoproto.jsontag) = "admin_user,omitempty"]; + // MongoAtlas contains Atlas metadata about the database. + MongoAtlas MongoAtlas = 12 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "mongo_atlas,omitempty" + ]; } // DatabaseAdminUser contains information about privileged database user used @@ -426,6 +431,11 @@ message AWS { // AssumeRoleARN is an optional AWS role ARN to assume when accessing a database. // Set this field and ExternalID to enable access across AWS accounts. string AssumeRoleARN = 11 [(gogoproto.jsontag) = "assume_role_arn,omitempty"]; + // OpenSearch contains AWS OpenSearch specific metadata. + OpenSearch OpenSearch = 12 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "opensearch,omitempty" + ]; } // SecretStore contains secret store configurations. @@ -500,6 +510,16 @@ message RedshiftServerless { string WorkgroupID = 3 [(gogoproto.jsontag) = "workgroup_id,omitempty"]; } +// OpenSearch contains AWS OpenSearch specific metadata. +message OpenSearch { + // DomainName is the name of the domain. + string DomainName = 1 [(gogoproto.jsontag) = "domain_name,omitempty"]; + // DomainID is the ID of the domain. + string DomainID = 2 [(gogoproto.jsontag) = "domain_id,omitempty"]; + // EndpointType is the type of the endpoint. + string EndpointType = 3 [(gogoproto.jsontag) = "endpoint_type,omitempty"]; +} + // GCPCloudSQL contains parameters specific to GCP Cloud SQL databases. message GCPCloudSQL { // ProjectID is the GCP project ID the Cloud SQL instance resides in. @@ -575,6 +595,12 @@ message MySQLOptions { string ServerVersion = 1 [(gogoproto.jsontag) = "server_version,omitempty"]; } +// MongoAtlas contains Atlas metadata about the database. +message MongoAtlas { + // Name is the Atlas database instance name. + string Name = 1 [(gogoproto.jsontag) = "name,omitempty"]; +} + // InstanceV1 represents the state of a running teleport instance independent // of the specific services that instance exposes. message InstanceV1 { @@ -843,6 +869,8 @@ message AppSpecV3 { AppAWS AWS = 6 [(gogoproto.jsontag) = "aws,omitempty"]; // Cloud identifies the cloud instance the app represents. string Cloud = 7 [(gogoproto.jsontag) = "cloud,omitempty"]; + // UserGroups are a list of user group IDs that this app is associated with. + repeated string UserGroups = 8; } // App is a specific application that a server proxies. @@ -1709,6 +1737,13 @@ message AuthPreferenceSpecV2 { (gogoproto.jsontag) = "allow_headless,omitempty", (gogoproto.customtype) = "BoolOption" ]; + + // DefaultSessionTTL is the TTL to use for user certs when + // an explicit TTL is not requested. + int64 DefaultSessionTTL = 16 [ + (gogoproto.jsontag) = "default_session_ttl,omitempty", + (gogoproto.casttype) = "Duration" + ]; } // U2F defines settings for U2F device. @@ -2290,6 +2325,19 @@ message RoleSpecV6 { ]; } +// CreateHostUserMode determines whether host user creation should be +// disabled or if host users should be cleaned up or kept after +// sessions end. +enum CreateHostUserMode { + HOST_USER_MODE_UNSPECIFIED = 0; + // HOST_USER_MODE_OFF disables host user creation. + HOST_USER_MODE_OFF = 1; + // HOST_USER_MODE_DROP enables host user creation and deletes users at session end. + HOST_USER_MODE_DROP = 2; + // HOST_USER_MODE_KEEP enables host user creation and leaves users behind at session end. + HOST_USER_MODE_KEEP = 3; +} + // RoleOptions is a set of role options message RoleOptions { // ForwardAgent is SSH agent forwarding. @@ -2403,7 +2451,7 @@ message RoleOptions { // CreateHostUser allows users to be automatically created on a host BoolValue CreateHostUser = 20 [ (gogoproto.nullable) = true, - (gogoproto.jsontag) = "create_host_user", + (gogoproto.jsontag) = "create_host_user,omitempty", (gogoproto.customtype) = "BoolOption" ]; @@ -2447,6 +2495,10 @@ message RoleOptions { (gogoproto.jsontag) = "create_db_user", (gogoproto.customtype) = "BoolOption" ]; + + // CreateHostUserMode allows users to be automatically created on a + // host when not set to off + CreateHostUserMode CreateHostUserMode = 28 [(gogoproto.jsontag) = "create_host_user_mode,omitempty"]; } message RecordSession { @@ -4976,6 +5028,18 @@ message DatabaseResourceMatcher { (gogoproto.jsontag) = "labels", (gogoproto.customtype) = "Labels" ]; + ResourceMatcherAWS AWS = 2 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "aws" + ]; +} + +// ResourceMatcherAWS contains AWS specific settings for resource matcher. +message ResourceMatcherAWS { + // AssumeRoleARN is an optional AWS role ARN to assume when accessing a database. + string AssumeRoleARN = 1 [(gogoproto.jsontag) = "assume_role_arn,omitempty"]; + // ExternalID is an optional AWS external ID used to enable assuming an AWS role across accounts. + string ExternalID = 2 [(gogoproto.jsontag) = "external_id,omitempty"]; } // AlertSeverity represents how problematic/urgent an alert is, and is used to assist @@ -5144,6 +5208,8 @@ message PluginSpecV1 { PluginOktaSettings okta = 4; // Settings for device trust jamf plugin PluginJamfSettings jamf = 5; + // Settings for the PagerDuty plugin + PluginPagerDutySettings pager_duty = 6; } } @@ -5169,6 +5235,19 @@ message PluginOpsgenieAccessSettings { string api_endpoint = 5; } +message PluginPagerDutySettings { + option (gogoproto.equal) = true; + + // UserEmail is the email address of the PagerDuty user that will be + // listed as the reporter source of incidents, comments, etc + // within PagerDuty. Should usually be the same user the API key + // represents. + string user_email = 1; + + // APIEndpoint is the address of PagerDuty API. + string api_endpoint = 2; +} + // Defines settings for the OpenAI plugin. Currently there are no settings. message PluginOpenAISettings { option (gogoproto.equal) = true; @@ -5454,6 +5533,18 @@ message UserGroupV1 { (gogoproto.jsontag) = "", (gogoproto.embed) = true ]; + + // Spec is the user group resource spec. + UserGroupSpecV1 Spec = 2 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "spec" + ]; +} + +// UserGroupSpecV1 is the specification of a user group. +message UserGroupSpecV1 { + // Applications are a list of application IDs belonging to this user group. + repeated string Applications = 1; } // OktaImportRuleSpecV1 is a Okta import rule specification. @@ -5755,8 +5846,8 @@ message JamfSpecV1 { (gogoproto.jsontag) = "sync_delay,omitempty", (gogoproto.casttype) = "Duration" ]; - // Jamf API endpoint. - // Example: "https://yourtenant.jamfcloud.com". + // Jamf Pro API endpoint. + // Example: "https://yourtenant.jamfcloud.com/api". // Required. string api_endpoint = 4 [(gogoproto.jsontag) = "api_endpoint,omitempty"]; // Jamf API username. @@ -5785,8 +5876,7 @@ message JamfInventoryEntry { // PARTIAL syncs are scheduled in the time window between FULL syncs, so // sync_period_partial must always be smaller than sync_period_full, otherwise // it would never trigger. - // Set to negative to disable PARTIAL syncs. - // Defaults to 6h. + // Set to zero or negative to disable PARTIAL syncs. int64 sync_period_partial = 2 [ (gogoproto.jsontag) = "sync_period_partial,omitempty", (gogoproto.casttype) = "Duration" @@ -5794,8 +5884,7 @@ message JamfInventoryEntry { // Sync period for FULL syncs. // Ideally sync_period_full is a multiple of sync_period_partial, so schedules // line up perfectly. - // Set to negative to disable FULL syncs. - // Defaults to 24h. + // Set to zero or negative to disable FULL syncs. int64 sync_period_full = 3 [ (gogoproto.jsontag) = "sync_period_full,omitempty", (gogoproto.casttype) = "Duration" @@ -5837,3 +5926,100 @@ message MessageWithHeader { (gogoproto.embed) = true ]; } + +// AWSMatcher matches AWS EC2 instances and AWS Databases +message AWSMatcher { + // Types are AWS database types to match, "ec2", "rds", "redshift", "elasticache", + // or "memorydb". + repeated string Types = 1 [(gogoproto.jsontag) = "types,omitempty"]; + // Regions are AWS regions to query for databases. + repeated string Regions = 2 [(gogoproto.jsontag) = "regions,omitempty"]; + // AssumeRoleARN is the AWS role to assume for database discovery. + AssumeRole AssumeRole = 3 [(gogoproto.jsontag) = "assume_role,omitempty"]; + // Tags are AWS resource Tags to match. + wrappers.LabelValues Tags = 4 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "tags,omitempty", + (gogoproto.customtype) = "Labels" + ]; + // Params sets the join method when installing on discovered EC2 nodes + InstallerParams Params = 5 [(gogoproto.jsontag) = "install,omitempty"]; + // SSM provides options to use when sending a document command to + // an EC2 node + AWSSSM SSM = 6 [(gogoproto.jsontag) = "ssm,omitempty"]; +} + +// AssumeRole provides a role ARN and ExternalID to assume an AWS role +// when interacting with AWS resources. +message AssumeRole { + // RoleARN is the fully specified AWS IAM role ARN. + string RoleARN = 1 [(gogoproto.jsontag) = "role_arn"]; + // ExternalID is the external ID used to assume a role in another account. + string ExternalID = 2 [(gogoproto.jsontag) = "external_id"]; +} + +// InstallParams sets join method to use on discovered nodes +message InstallerParams { + // JoinMethod is the method to use when joining the cluster + string JoinMethod = 1 [ + (gogoproto.jsontag) = "join_method", + (gogoproto.casttype) = "JoinMethod" + ]; + // JoinToken is the token to use when joining the cluster + string JoinToken = 2 [(gogoproto.jsontag) = "join_token"]; + // ScriptName is the name of the teleport installer script + // resource for the cloud instance to execute + string ScriptName = 3 [(gogoproto.jsontag) = "script_name,omitempty"]; + // InstallTeleport disables agentless discovery + bool InstallTeleport = 4 [(gogoproto.jsontag) = "install_teleport,omitempty"]; + // SSHDConfig provides the path to write sshd configuration changes + string SSHDConfig = 5 [(gogoproto.jsontag) = "sshd_config,omitempty"]; + // PublicProxyAddr is the address of the proxy the discovered node should use + // to connect to the cluster. Used only in Azure. + string PublicProxyAddr = 6 [(gogoproto.jsontag) = "proxy_addr,omitempty"]; +} + +// AWSSSM provides options to use when executing SSM documents +message AWSSSM { + // DocumentName is the name of the document to use when executing an + // SSM command + string DocumentName = 1 [(gogoproto.jsontag) = "document_name,omitempty"]; +} + +// AzureMatcher matches Azure resources. +// It defines which resource types, filters and some configuration params. +message AzureMatcher { + // Subscriptions are Azure subscriptions to query for resources. + repeated string Subscriptions = 1 [(gogoproto.jsontag) = "subscriptions,omitempty"]; + // ResourceGroups are Azure resource groups to query for resources. + repeated string ResourceGroups = 2 [(gogoproto.jsontag) = "resource_groups,omitempty"]; + // Types are Azure types to match: "mysql", "postgres", "aks", "vm" + repeated string Types = 3 [(gogoproto.jsontag) = "types,omitempty"]; + // Regions are Azure locations to match for databases. + repeated string Regions = 4 [(gogoproto.jsontag) = "regions,omitempty"]; + // ResourceTags are Azure tags on resources to match. + wrappers.LabelValues ResourceTags = 5 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "tags,omitempty", + (gogoproto.customtype) = "Labels" + ]; + // Params sets the join method when installing on + // discovered Azure nodes. + InstallerParams Params = 6 [(gogoproto.jsontag) = "install_params,omitempty"]; +} + +// GCPMatcher matches GCP resources. +message GCPMatcher { + // Types are GKE resource types to match: "gke". + repeated string Types = 1 [(gogoproto.jsontag) = "types,omitempty"]; + // Locations are GKE locations to search resources for. + repeated string Locations = 2 [(gogoproto.jsontag) = "locations,omitempty"]; + // Tags are GCP labels to match. + wrappers.LabelValues Tags = 3 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "tags,omitempty", + (gogoproto.customtype) = "Labels" + ]; + // ProjectIDs are the GCP project ID where the resources are deployed. + repeated string ProjectIDs = 4 [(gogoproto.jsontag) = "project_ids,omitempty"]; +} diff --git a/api/proto/teleport/trait/v1/trait.proto b/api/proto/teleport/trait/v1/trait.proto new file mode 100644 index 0000000000000..0d6889d698b34 --- /dev/null +++ b/api/proto/teleport/trait/v1/trait.proto @@ -0,0 +1,27 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.trait.v1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/trait/v1;trait"; + +// Trait is a trait that can be use in various resources. +message Trait { + // key is the name of the trait. + string key = 1; + // values is the list of trait values. + repeated string values = 2; +} diff --git a/api/proto/teleport/usageevents/v1/usageevents.proto b/api/proto/teleport/usageevents/v1/usageevents.proto index b31542a4f7bf7..48a4d9bb86ccc 100644 --- a/api/proto/teleport/usageevents/v1/usageevents.proto +++ b/api/proto/teleport/usageevents/v1/usageevents.proto @@ -47,6 +47,13 @@ message UIOnboardSetCredentialSubmitEvent { string username = 1; } +// UIOnboardQuestionnaireSubmitEvent is a UI event sent during registration when +// the user submits their onboarding questionnaire. +message UIOnboardQuestionnaireSubmitEvent { + // The event username. Not extracted from identity as this is pre-registration. + string username = 1; +} + // UIOnboardRegisterChallengeSubmitEvent is a UI event sent during registration // when the MFA challenge is completed. message UIOnboardRegisterChallengeSubmitEvent { @@ -128,6 +135,8 @@ enum DiscoverResource { DISCOVER_RESOURCE_DOC_DATABASE_RDS_PROXY = 34; DISCOVER_RESOURCE_DOC_DATABASE_HIGH_AVAILABILITY = 35; DISCOVER_RESOURCE_DOC_DATABASE_DYNAMIC_REGISTRATION = 36; + + DISCOVER_RESOURCE_SAML_APPLICATION = 37; } // DiscoverResourceMetadata contains common metadata identifying resource type being added. @@ -211,6 +220,7 @@ enum CTA { CTA_PREMIUM_SUPPORT = 4; CTA_TRUSTED_DEVICES = 5; CTA_UPGRADE_BANNER = 6; + CTA_BILLING_SUMMARY = 7; } // UIDiscoverDeployServiceEvent is emitted after the user installs a Teleport Agent. @@ -224,6 +234,34 @@ message UIDiscoverDeployServiceEvent { DiscoverMetadata metadata = 1; DiscoverResourceMetadata resource = 2; DiscoverStepStatus status = 3; + + // DeployMethod describes the method used to deploy a service. + enum DeployMethod { + // DEPLOY_METHOD_UNSPECIFIED means there was an existing service + // so deploying step got skipped. + DEPLOY_METHOD_UNSPECIFIED = 0; + // DEPLOY_METHOD_AUTO means Teleport deployed a service for the user. + DEPLOY_METHOD_AUTO = 1; + // DEPLOY_METHOD_MANUAL means a user deployed a service by themselves. + DEPLOY_METHOD_MANUAL = 2; + } + + DeployMethod deploy_method = 4; + + // DeployType describes the type of deployment. + enum DeployType { + // DEPLOY_METHOD_UNSPECIFIED means there was an existing service + // so deploying step got skipped. + DEPLOY_TYPE_UNSPECIFIED = 0; + // DEPLOY_TYPE_INSTALL_SCRIPT means service was deployed using an + // install script. + DEPLOY_TYPE_INSTALL_SCRIPT = 1; + // DEPLOY_TYPE_AMAZON_ECS means service was deployed using amazon's + // elastic container service. + DEPLOY_TYPE_AMAZON_ECS = 2; + } + + DeployType deploy_type = 5; } // UIDiscoverDatabaseRegisterEvent is emitted when a user is finished with the step that registers a database resource. @@ -392,6 +430,7 @@ message UsageEventOneOf { AssistCompletionEvent assist_completion = 30; UIIntegrationEnrollStartEvent ui_integration_enroll_start_event = 31; UIIntegrationEnrollCompleteEvent ui_integration_enroll_complete_event = 32; + UIOnboardQuestionnaireSubmitEvent ui_onboard_questionnaire_submit = 33; } reserved 2; //UIOnboardGetStartedClickEvent reserved "ui_onboard_get_started_click"; diff --git a/api/proto/teleport/userpreferences/v1/assist.proto b/api/proto/teleport/userpreferences/v1/assist.proto new file mode 100644 index 0000000000000..2897dfad5ad96 --- /dev/null +++ b/api/proto/teleport/userpreferences/v1/assist.proto @@ -0,0 +1,40 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.userpreferences.v1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/userpreferences/v1;userpreferencesv1"; + +// AssistViewMode is the way the assistant is displayed. +enum AssistViewMode { + ASSIST_VIEW_MODE_UNSPECIFIED = 0; + // DOCKED is the assistant is docked to the right hand side of the screen. + ASSIST_VIEW_MODE_DOCKED = 1; + // POPUP is the assistant is displayed as a popup. + ASSIST_VIEW_MODE_POPUP = 2; + // POPUP_EXPANDED is the assistant is displayed as a popup and expanded. + ASSIST_VIEW_MODE_POPUP_EXPANDED = 3; + // POPUP_EXPANDED_SIDEBAR_VISIBLE is the assistant is displayed as a popup and expanded with the sidebar visible. + ASSIST_VIEW_MODE_POPUP_EXPANDED_SIDEBAR_VISIBLE = 4; +} + +// AssistUserPreferences is the user preferences for Assist. +message AssistUserPreferences { + // preferredLogins is an array of the logins a user would prefer to use when running a command, ordered by preference. + repeated string preferred_logins = 1; + // viewMode is the way the assistant is displayed. + AssistViewMode view_mode = 2; +} diff --git a/api/proto/teleport/userpreferences/v1/onboard.proto b/api/proto/teleport/userpreferences/v1/onboard.proto new file mode 100644 index 0000000000000..9df0ec0d04780 --- /dev/null +++ b/api/proto/teleport/userpreferences/v1/onboard.proto @@ -0,0 +1,35 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.userpreferences.v1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/userpreferences/v1;userpreferencesv1"; + +// Resources are the Resource options in the onboarding questionnaire +enum Resource { + RESOURCE_UNSPECIFIED = 0; + RESOURCE_WINDOWS_DESKTOPS = 1; + RESOURCE_SERVER_SSH = 2; + RESOURCE_DATABASES = 3; + RESOURCE_KUBERNETES = 4; + RESOURCE_WEB_APPLICATIONS = 5; +} + +// OnboardUserPreferences is the user preferences selected during onboarding. +message OnboardUserPreferences { + // preferredResources is an array of the resources a user selected during their onboarding questionnaire. + repeated Resource preferred_resources = 1; +} diff --git a/api/proto/teleport/userpreferences/v1/theme.proto b/api/proto/teleport/userpreferences/v1/theme.proto new file mode 100644 index 0000000000000..236c71a54b7a4 --- /dev/null +++ b/api/proto/teleport/userpreferences/v1/theme.proto @@ -0,0 +1,28 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.userpreferences.v1; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/userpreferences/v1;userpreferencesv1"; + +// Theme is a frontend theme. +enum Theme { + THEME_UNSPECIFIED = 0; + // THEME_LIGHT is the light theme. + THEME_LIGHT = 1; + // THEME_DARK is the dark theme. + THEME_DARK = 2; +} diff --git a/api/proto/teleport/userpreferences/v1/userpreferences.proto b/api/proto/teleport/userpreferences/v1/userpreferences.proto new file mode 100644 index 0000000000000..1d142c9632ee1 --- /dev/null +++ b/api/proto/teleport/userpreferences/v1/userpreferences.proto @@ -0,0 +1,62 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.userpreferences.v1; + +import "google/protobuf/empty.proto"; +import "teleport/userpreferences/v1/assist.proto"; +import "teleport/userpreferences/v1/onboard.proto"; +import "teleport/userpreferences/v1/theme.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/userpreferences/v1;userpreferencesv1"; + +// UserPreferences is a collection of different user changeable preferences for the frontend. +message UserPreferences { + // assist is the preferences for the Teleport Assist. + v1.AssistUserPreferences assist = 1; + // theme is the theme of the frontend. + Theme theme = 2; + // onboard is the preferences from the onboarding questionnaire. + v1.OnboardUserPreferences onboard = 3; +} + +// GetUserPreferencesRequest is a request to get the user preferences. +message GetUserPreferencesRequest { + // username is the username of the owner of the user preferences to get. + string username = 1; +} + +// GetUserPreferencesResponse is a response to get the user preferences. +message GetUserPreferencesResponse { + // preferences is the user preferences. + UserPreferences preferences = 1; +} + +// UpsertUserPreferencesRequest is a request to create or update the user preferences. +message UpsertUserPreferencesRequest { + // preferences is the new user preferences to set. + UserPreferences preferences = 1; + // username is the username of the owner of the user preferences to update. + string username = 2; +} + +// UserPreferencesService is a service that stores user settings. +service UserPreferencesService { + // GetUserPreferences returns the user preferences for a given user. + rpc GetUserPreferences(GetUserPreferencesRequest) returns (GetUserPreferencesResponse); + // UpsertUserPreferences creates or updates user preferences for a given username. + rpc UpsertUserPreferences(UpsertUserPreferencesRequest) returns (google.protobuf.Empty); +} diff --git a/api/testhelpers/proxy.go b/api/testhelpers/proxy.go new file mode 100644 index 0000000000000..4c85a10daf718 --- /dev/null +++ b/api/testhelpers/proxy.go @@ -0,0 +1,100 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package testhelpers + +import ( + "io" + "net" + "net/http" + "sync" + "time" + + "github.com/gravitational/trace" +) + +// ProxyHandler is a http.Handler that implements a simple HTTP proxy server. +type ProxyHandler struct { + sync.Mutex + count int +} + +// ServeHTTP only accepts the CONNECT verb and will tunnel your connection to +// the specified host. Also tracks the number of connections that it proxies for +// debugging purposes. +func (p *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Validate http connect parameters. + if r.Method != http.MethodConnect { + trace.WriteError(w, trace.BadParameter("%v not supported", r.Method)) + return + } + if r.Host == "" { + trace.WriteError(w, trace.BadParameter("host not set")) + return + } + + // Dial to the target host, this is done before hijacking the connection to + // ensure the target host is accessible. + dialer := net.Dialer{} + dconn, err := dialer.DialContext(r.Context(), "tcp", r.Host) + if err != nil { + trace.WriteError(w, err) + return + } + defer dconn.Close() + + // Once the client receives 200 OK, the rest of the data will no longer be + // http, but whatever protocol is being tunneled. + w.WriteHeader(http.StatusOK) + + // Hijack request so we can get underlying connection. + hj, ok := w.(http.Hijacker) + if !ok { + trace.WriteError(w, trace.AccessDenied("unable to hijack connection")) + return + } + sconn, _, err := hj.Hijack() + if err != nil { + trace.WriteError(w, err) + return + } + defer sconn.Close() + + // Success, we're proxying data now. + p.Lock() + p.count++ + p.Unlock() + + // Copy from src to dst and dst to src. + errc := make(chan error, 2) + replicate := func(dst io.Writer, src io.Reader) { + _, err := io.Copy(dst, src) + errc <- err + } + go replicate(sconn, dconn) + go replicate(dconn, sconn) + + // Wait until done, error, or 10 second. + select { + case <-time.After(10 * time.Second): + case <-errc: + } +} + +// Count returns the number of requests that have been proxied. +func (p *ProxyHandler) Count() int { + p.Lock() + defer p.Unlock() + return p.count +} diff --git a/api/types/app.go b/api/types/app.go index ad4f663c9b097..e2b7c4d77b882 100644 --- a/api/types/app.go +++ b/api/types/app.go @@ -72,6 +72,10 @@ type Application interface { GetAWSAccountID() string // GetAWSExternalID returns the AWS External ID configured for this app. GetAWSExternalID() string + // GetUserGroups will get the list of user group IDs associated with the application. + GetUserGroups() []string + // SetUserGroups will set the list of user group IDs associated with the application. + SetUserGroups([]string) // Copy returns a copy of this app resource. Copy() *AppV3 } @@ -289,6 +293,16 @@ func (a *AppV3) GetAWSExternalID() string { return a.Spec.AWS.ExternalID } +// GetUserGroups will get the list of user group IDss associated with the application. +func (a *AppV3) GetUserGroups() []string { + return a.Spec.UserGroups +} + +// SetUserGroups will set the list of user group IDs associated with the application. +func (a *AppV3) SetUserGroups(userGroups []string) { + a.Spec.UserGroups = userGroups +} + // String returns the app string representation. func (a *AppV3) String() string { return fmt.Sprintf("App(Name=%v, PublicAddr=%v, Labels=%v)", diff --git a/api/types/authentication.go b/api/types/authentication.go index 5d1ac8e6188d2..ce89028832b73 100644 --- a/api/types/authentication.go +++ b/api/types/authentication.go @@ -29,6 +29,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/gravitational/teleport/api/constants" + "github.com/gravitational/teleport/api/defaults" "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/api/utils/tlsutils" ) @@ -127,6 +128,11 @@ type AuthPreference interface { // SetSAMLIdPEnabled sets the SAML IdP to enabled. SetSAMLIdPEnabled(bool) + // GetDefaultSessionTTL retrieves the max session ttl + GetDefaultSessionTTL() Duration + // SetDefaultSessionTTL sets the max session ttl + SetDefaultSessionTTL(Duration) + // String represents a human readable version of authentication settings. String() string } @@ -435,6 +441,16 @@ func (c *AuthPreferenceV2) SetSAMLIdPEnabled(enabled bool) { c.Spec.IDP.SAML.Enabled = NewBoolOption(enabled) } +// SetDefaultSessionTTL sets the default session ttl +func (c *AuthPreferenceV2) SetDefaultSessionTTL(sessionTTL Duration) { + c.Spec.DefaultSessionTTL = sessionTTL +} + +// GetDefaultSessionTTL retrieves the default session ttl +func (c *AuthPreferenceV2) GetDefaultSessionTTL() Duration { + return c.Spec.DefaultSessionTTL +} + // setStaticFields sets static resource header and metadata fields. func (c *AuthPreferenceV2) setStaticFields() { c.Kind = KindClusterAuthPreference @@ -468,6 +484,10 @@ func (c *AuthPreferenceV2) CheckAndSetDefaults() error { c.SetOrigin(OriginDynamic) } + if c.Spec.DefaultSessionTTL == 0 { + c.Spec.DefaultSessionTTL = Duration(defaults.CertDuration) + } + switch c.Spec.Type { case constants.Local, constants.OIDC, constants.SAML, constants.Github: // Note that "type:local" and "local_auth:false" is considered a valid diff --git a/api/types/constants.go b/api/types/constants.go index 66ffca553ed3f..eb6a0429478bf 100644 --- a/api/types/constants.go +++ b/api/types/constants.go @@ -155,9 +155,69 @@ const ( // KindKubernetesCluster is a Kubernetes cluster. KindKubernetesCluster = "kube_cluster" - // KindKubePod is an Kubernetes Pod resource type. + // KindKubePod is a Kubernetes Pod resource type. KindKubePod = "pod" + // KindKubeSecret is a Kubernetes Secret resource type. + KindKubeSecret = "secret" + + // KindKubeConfigMap is a Kubernetes Configmap resource type. + KindKubeConfigmap = "configmap" + + // KindKubeNamespace is a Kubernetes namespace resource type. + KindKubeNamespace = "namespace" + + // KindKubeService is a Kubernetes Service resource type. + KindKubeService = "service" + + // KindKubeServiceAccount is an Kubernetes Service Account resource type. + KindKubeServiceAccount = "serviceaccount" + + // KindKubeNode is a Kubernetes Node resource type. + KindKubeNode = "kube_node" + + // KindKubePersistentVolume is a Kubernetes Persistent Volume resource type. + KindKubePersistentVolume = "persistentvolume" + + // KindKubePersistentVolumeClaim is a Kubernetes Persistent Volume Claim resource type. + KindKubePersistentVolumeClaim = "persistentvolumeclaim" + + // KindKubeDeployment is a Kubernetes Deployment resource type. + KindKubeDeployment = "deployment" + + // KindKubeReplicaSet is a Kubernetes Replicaset resource type. + KindKubeReplicaSet = "replicaset" + + // KindKubeStatefulset is a Kubernetes Statefulset resource type. + KindKubeStatefulset = "statefulset" + + // KindKubeDaemonSet is a Kubernetes Daemonset resource type. + KindKubeDaemonSet = "daemonset" + + // KindKubeClusterRole is a Kubernetes ClusterRole resource type. + KindKubeClusterRole = "clusterrole" + + // KindKubeRole is a Kubernetes Role resource type. + KindKubeRole = "role" + + // KindKubeClusterRoleBinding is a Kubernetes Cluster Role Binding resource type. + KindKubeClusterRoleBinding = "clusterrolebinding" + + // KindKubeRoleBinding is a Kubernetes Role Binding resource type. + KindKubeRoleBinding = "rolebinding" + + // KindKubeCronjob is a Kubernetes Cronjob resource type. + KindKubeCronjob = "cronjob" + + // KindKubeJob is a Kubernetes job resource type. + KindKubeJob = "job" + + // KindKubeCertificateSigningRequest is a Certificate Signing Request resource type. + KindKubeCertificateSigningRequest = "certificatesigningrequest" + + // KindKubeIngress is a Kubernetes Ingress resource type. + KindKubeIngress = "ingress" + // KindToken is a provisioning token resource KindToken = "token" @@ -364,6 +424,9 @@ const ( // KindWatchStatus is a kind for WatchStatus resource which contains information about a successful Watch request. KindWatchStatus = "watch_status" + // V7 is the seventh version of resources. + V7 = "v7" + // V6 is the sixth version of resources. V6 = "v6" @@ -437,6 +500,10 @@ const ( // that the resource originates from. OriginLabel = TeleportNamespace + "/origin" + // ClusterLabel is a label that identifies the current cluster when creating resources on another systems. + // Eg, when creating a resource in AWS, this label must be set as a Tag in the resource. + ClusterLabel = TeleportNamespace + "/cluster" + // ADLabel is a resource metadata label name used to identify if resource is part of Active Directory ADLabel = TeleportNamespace + "/ad" @@ -464,6 +531,13 @@ const ( // created from the Okta service. OriginOkta = "okta" + // OriginIntegrationAWSOIDC is an origin value indicating that the resource was + // created from the AWS OIDC Integration. + OriginIntegrationAWSOIDC = "integration_awsoidc" + + // IntegrationLabel is a resource metadata label name used to identify the integration name that created the resource. + IntegrationLabel = TeleportNamespace + "/integration" + // AWSAccountIDLabel is used to identify nodes by AWS account ID // found via automatic discovery, to avoid re-running installation // commands on the node. @@ -562,6 +636,31 @@ const ( // that the discovered resource is owned by. It is used to differentiate resources // that belong to different discovery services that operate on different sets of resources. TeleportInternalDiscoveryGroupName = TeleportInternalLabelPrefix + "discovery-group-name" + + // TeleportDowngradedLabel identifies resources that have been automatically + // downgraded before being returned to clients on older versions that do not + // support one or more features enabled in that resource. + TeleportDowngradedLabel = TeleportInternalLabelPrefix + "downgraded" + + // TeleportInternalResourceType indicates the type of internal Teleport resource a resource is. + // Valid values are: + // - system: These resources will be automatically created and overwritten on startup. Users should + // not change these resources. + // - preset: These resources will be created if they don't exist. Updates may be applied to them, + // but user changes to these resources will be preserved. + TeleportInternalResourceType = TeleportInternalLabelPrefix + "resource-type" + + // TeleportResourceRevision marks a teleport-managed resource with a reversion + // number to aid future migrations. Label value is expected to be a number. + TeleportResourceRevision = TeleportInternalLabelPrefix + "revision" + + // SystemResource are resources that will be automatically created and overwritten on startup. Users + // should not change these resources. + SystemResource = "system" + + // PresetResource are resources resources will be created if they don't exist. Updates may be applied + // to them, but user changes to these resources will be preserved. + PresetResource = "preset" ) // CloudHostnameTag is the name of the tag in a cloud instance used to override a node's hostname. @@ -673,13 +772,64 @@ var RequestableResourceKinds = []string{ KindDatabase, KindApp, KindWindowsDesktop, - KindKubePod, KindUserGroup, + KindKubePod, + KindKubeSecret, + KindKubeConfigmap, + KindKubeNamespace, + KindKubeService, + KindKubeServiceAccount, + KindKubeNode, + KindKubePersistentVolume, + KindKubePersistentVolumeClaim, + KindKubeDeployment, + KindKubeReplicaSet, + KindKubeStatefulset, + KindKubeDaemonSet, + KindKubeClusterRole, + KindKubeRole, + KindKubeClusterRoleBinding, + KindKubeRoleBinding, + KindKubeCronjob, + KindKubeJob, + KindKubeCertificateSigningRequest, + KindKubeIngress, } // KubernetesResourcesKinds lists the supported Kubernetes resource kinds. var KubernetesResourcesKinds = []string{ KindKubePod, + KindKubeSecret, + KindKubeConfigmap, + KindKubeNamespace, + KindKubeService, + KindKubeServiceAccount, + KindKubeNode, + KindKubePersistentVolume, + KindKubePersistentVolumeClaim, + KindKubeDeployment, + KindKubeReplicaSet, + KindKubeStatefulset, + KindKubeDaemonSet, + KindKubeClusterRole, + KindKubeRole, + KindKubeClusterRoleBinding, + KindKubeRoleBinding, + KindKubeCronjob, + KindKubeJob, + KindKubeCertificateSigningRequest, + KindKubeIngress, +} + +// KubernetesClusterWideResourceKinds is the list of supported Kubernetes cluster resource kinds +// that are not namespaced. +var KubernetesClusterWideResourceKinds = []string{ + KindKubeNamespace, + KindKubeNode, + KindKubePersistentVolume, + KindKubeClusterRole, + KindKubeClusterRoleBinding, + KindKubeCertificateSigningRequest, } const ( diff --git a/api/types/database.go b/api/types/database.go index a882b7d97519f..d86c0e4a12c78 100644 --- a/api/types/database.go +++ b/api/types/database.go @@ -26,6 +26,7 @@ import ( "github.com/sirupsen/logrus" "github.com/gravitational/teleport/api/utils" + atlasutils "github.com/gravitational/teleport/api/utils/atlas" awsutils "github.com/gravitational/teleport/api/utils/aws" azureutils "github.com/gravitational/teleport/api/utils/azure" ) @@ -97,6 +98,8 @@ type Database interface { GetManagedUsers() []string // SetManagedUsers sets a list of database users that are managed by Teleport. SetManagedUsers(users []string) + // GetMongoAtlas returns Mongo Atlas database metadata. + GetMongoAtlas() MongoAtlas // IsRDS returns true if this is an RDS/Aurora database. IsRDS() bool // IsRDSProxy returns true if this is an RDS Proxy database. @@ -118,6 +121,9 @@ type Database interface { // RequireAWSIAMRolesAsUsers returns true for database types that require // AWS IAM roles as database users. RequireAWSIAMRolesAsUsers() bool + // SupportAWSIAMRoleARNAsUsers returns true for database types that support + // AWS IAM roles as database users. + SupportAWSIAMRoleARNAsUsers() bool // Copy returns a copy of this database resource. Copy() *DatabaseV3 // GetAdminUser returns database privileged user information. @@ -508,6 +514,10 @@ func (d *DatabaseV3) getAWSType() (string, bool) { // GetType returns the database type. func (d *DatabaseV3) GetType() string { + if d.GetMongoAtlas().Name != "" { + return DatabaseTypeMongoAtlas + } + if awsType, ok := d.getAWSType(); ok { return awsType } @@ -518,6 +528,7 @@ func (d *DatabaseV3) GetType() string { if d.GetAzure().Name != "" { return DatabaseTypeAzure } + return DatabaseTypeSelfHosted } @@ -740,6 +751,12 @@ func (d *DatabaseV3) CheckAndSetDefaults() error { } d.Spec.Azure.Name = name } + case atlasutils.IsAtlasEndpoint(d.Spec.URI): + name, err := atlasutils.ParseAtlasEndpoint(d.Spec.URI) + if err != nil { + return trace.Wrap(err) + } + d.Spec.MongoAtlas.Name = name } // Validate AWS Specific configuration @@ -863,6 +880,11 @@ func (d *DatabaseV3) SetManagedUsers(users []string) { d.Status.ManagedUsers = users } +// GetMongoAtlas returns Mongo Atlas database metadata. +func (d *DatabaseV3) GetMongoAtlas() MongoAtlas { + return d.Spec.MongoAtlas +} + // RequireAWSIAMRolesAsUsers returns true for database types that require AWS // IAM roles as database users. // IMPORTANT: if you add a database that requires AWS IAM Roles as users, @@ -885,6 +907,12 @@ func (d *DatabaseV3) RequireAWSIAMRolesAsUsers() bool { } } +// SupportAWSIAMRoleARNAsUsers returns true for database types that support AWS +// IAM roles as database users. +func (d *DatabaseV3) SupportAWSIAMRoleARNAsUsers() bool { + return d.GetType() == DatabaseTypeMongoAtlas +} + const ( // DatabaseProtocolPostgreSQL is the PostgreSQL database protocol. DatabaseProtocolPostgreSQL = "postgres" @@ -915,6 +943,8 @@ const ( DatabaseTypeDynamoDB = "dynamodb" // DatabaseTypeOpenSearch is AWS-hosted OpenSearch instance. DatabaseTypeOpenSearch = "opensearch" + // DatabaseTypeMongoAtlas + DatabaseTypeMongoAtlas = "mongo-atlas" ) // GetServerName returns the GCP database project and instance as ":". diff --git a/api/types/database_test.go b/api/types/database_test.go index 7e8b9aa0b837c..769fd05bc9607 100644 --- a/api/types/database_test.go +++ b/api/types/database_test.go @@ -28,7 +28,7 @@ import ( // TestDatabaseRDSEndpoint verifies AWS info is correctly populated // based on the RDS endpoint. func TestDatabaseRDSEndpoint(t *testing.T) { - isBadParamErrFn := func(tt require.TestingT, err error, i ...interface{}) { + isBadParamErrFn := func(tt require.TestingT, err error, i ...any) { require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err) } diff --git a/api/types/device.go b/api/types/device.go index e75e139326e62..96d6377a252d3 100644 --- a/api/types/device.go +++ b/api/types/device.go @@ -15,7 +15,6 @@ package types import ( - "encoding/json" "time" "github.com/google/uuid" @@ -86,15 +85,6 @@ func (d *DeviceV1) CheckAndSetDefaults() error { return nil } -// UnmarshalDevice unmarshals a DeviceV1 resource and runs CheckAndSetDefaults. -func UnmarshalDevice(raw []byte) (*DeviceV1, error) { - dev := &DeviceV1{} - if err := json.Unmarshal(raw, dev); err != nil { - return nil, trace.Wrap(err) - } - return dev, trace.Wrap(dev.CheckAndSetDefaults()) -} - // DeviceFromResource converts a resource DeviceV1 to an API devicepb.Device. func DeviceFromResource(res *DeviceV1) (*devicepb.Device, error) { if res == nil { @@ -156,6 +146,9 @@ func DeviceFromResource(res *DeviceV1) (*devicepb.Device, error) { ReportedAssetTag: d.ReportedAssetTag, SystemSerialNumber: d.SystemSerialNumber, BaseBoardSerialNumber: d.BaseBoardSerialNumber, + TpmPlatformAttestation: tpmPlatformAttestationFromResource( + d.TpmPlatformAttestation, + ), } } @@ -180,6 +173,7 @@ func DeviceFromResource(res *DeviceV1) (*devicepb.Device, error) { OsBuild: p.OsBuild, OsUsernames: p.OsUsernames, JamfBinaryVersion: p.JamfBinaryVersion, + ExternalId: p.ExternalId, } } @@ -242,6 +236,9 @@ func DeviceToResource(dev *devicepb.Device) *DeviceV1 { ReportedAssetTag: d.ReportedAssetTag, SystemSerialNumber: d.SystemSerialNumber, BaseBoardSerialNumber: d.BaseBoardSerialNumber, + TpmPlatformAttestation: tpmPlatformAttestationToResource( + d.TpmPlatformAttestation, + ), } } @@ -262,6 +259,7 @@ func DeviceToResource(dev *devicepb.Device) *DeviceV1 { OsBuild: p.OsBuild, OsUsernames: p.OsUsernames, JamfBinaryVersion: p.JamfBinaryVersion, + ExternalId: p.ExternalId, } } @@ -289,6 +287,80 @@ func DeviceToResource(dev *devicepb.Device) *DeviceV1 { return res } +func tpmPlatformAttestationToResource(pa *devicepb.TPMPlatformAttestation) *TPMPlatformAttestation { + if pa == nil { + return nil + } + + var outPlatParams *TPMPlatformParameters + if pa.PlatformParameters != nil { + var quotes []*TPMQuote + for _, q := range pa.PlatformParameters.Quotes { + quotes = append(quotes, &TPMQuote{ + Quote: q.Quote, + Signature: q.Signature, + }) + } + + var pcrs []*TPMPCR + for _, pcr := range pa.PlatformParameters.Pcrs { + pcrs = append(pcrs, &TPMPCR{ + Index: pcr.Index, + Digest: pcr.Digest, + DigestAlg: pcr.DigestAlg, + }) + } + + outPlatParams = &TPMPlatformParameters{ + Quotes: quotes, + Pcrs: pcrs, + EventLog: pa.PlatformParameters.EventLog, + } + } + + return &TPMPlatformAttestation{ + Nonce: pa.Nonce, + PlatformParameters: outPlatParams, + } +} + +func tpmPlatformAttestationFromResource(pa *TPMPlatformAttestation) *devicepb.TPMPlatformAttestation { + if pa == nil { + return nil + } + + var outPlatParams *devicepb.TPMPlatformParameters + if pa.PlatformParameters != nil { + var quotes []*devicepb.TPMQuote + for _, q := range pa.PlatformParameters.Quotes { + quotes = append(quotes, &devicepb.TPMQuote{ + Quote: q.Quote, + Signature: q.Signature, + }) + } + + var pcrs []*devicepb.TPMPCR + for _, pcr := range pa.PlatformParameters.Pcrs { + pcrs = append(pcrs, &devicepb.TPMPCR{ + Index: pcr.Index, + Digest: pcr.Digest, + DigestAlg: pcr.DigestAlg, + }) + } + + outPlatParams = &devicepb.TPMPlatformParameters{ + Quotes: quotes, + EventLog: pa.PlatformParameters.EventLog, + Pcrs: pcrs, + } + } + + return &devicepb.TPMPlatformAttestation{ + Nonce: pa.Nonce, + PlatformParameters: outPlatParams, + } +} + // ResourceOSTypeToString converts OSType to a string representation suitable // for use in resource fields. func ResourceOSTypeToString(osType devicepb.OSType) string { @@ -361,7 +433,8 @@ func ResourceDeviceAttestationTypeToString( ) string { switch attestationType { case devicepb.DeviceAttestationType_DEVICE_ATTESTATION_TYPE_UNSPECIFIED: - return "unspecified" + // Default to empty, so it doesn't show in non-TPM devices. + return "" case devicepb.DeviceAttestationType_DEVICE_ATTESTATION_TYPE_TPM_EKPUB: return "tpm_ekpub" case devicepb.DeviceAttestationType_DEVICE_ATTESTATION_TYPE_TPM_EKCERT: diff --git a/api/types/device.pb.go b/api/types/device.pb.go index 0ef8e9b47935e..57d68d722b622 100644 --- a/api/types/device.pb.go +++ b/api/types/device.pb.go @@ -131,10 +131,10 @@ var xxx_messageInfo_DeviceSpec proto.InternalMessageInfo // teleport.devicetrust.v1.DeviceCredential. type DeviceCredential struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id"` - PublicKeyDer []byte `protobuf:"bytes,2,opt,name=public_key_der,json=publicKeyDer,proto3" json:"public_key_der"` - DeviceAttestationType string `protobuf:"bytes,3,opt,name=device_attestation_type,json=deviceAttestationType,proto3" json:"device_attestation_type"` - TpmEkcertSerial string `protobuf:"bytes,4,opt,name=tpm_ekcert_serial,json=tpmEkcertSerial,proto3" json:"tpm_ekcert_serial"` - TpmAkPublic []byte `protobuf:"bytes,5,opt,name=tpm_ak_public,json=tpmAkPublic,proto3" json:"tpm_ak_public"` + PublicKeyDer []byte `protobuf:"bytes,2,opt,name=public_key_der,json=publicKeyDer,proto3" json:"public_key_der,omitempty"` + DeviceAttestationType string `protobuf:"bytes,3,opt,name=device_attestation_type,json=deviceAttestationType,proto3" json:"device_attestation_type,omitempty"` + TpmEkcertSerial string `protobuf:"bytes,4,opt,name=tpm_ekcert_serial,json=tpmEkcertSerial,proto3" json:"tpm_ekcert_serial,omitempty"` + TpmAkPublic []byte `protobuf:"bytes,5,opt,name=tpm_ak_public,json=tpmAkPublic,proto3" json:"tpm_ak_public,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -176,22 +176,23 @@ var xxx_messageInfo_DeviceCredential proto.InternalMessageInfo // DeviceCollectedData is the resource representation of // teleport.devicetrust.v1.DeviceCollectedData. type DeviceCollectedData struct { - CollectTime *time.Time `protobuf:"bytes,1,opt,name=collect_time,json=collectTime,proto3,stdtime" json:"collect_time"` - RecordTime *time.Time `protobuf:"bytes,2,opt,name=record_time,json=recordTime,proto3,stdtime" json:"record_time"` - OsType string `protobuf:"bytes,3,opt,name=os_type,json=osType,proto3" json:"os_type"` - SerialNumber string `protobuf:"bytes,4,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"` - ModelIdentifier string `protobuf:"bytes,5,opt,name=model_identifier,json=modelIdentifier,proto3" json:"model_identifier,omitempty"` - OsVersion string `protobuf:"bytes,6,opt,name=os_version,json=osVersion,proto3" json:"os_version,omitempty"` - OsBuild string `protobuf:"bytes,7,opt,name=os_build,json=osBuild,proto3" json:"os_build,omitempty"` - OsUsername string `protobuf:"bytes,8,opt,name=os_username,json=osUsername,proto3" json:"os_username,omitempty"` - JamfBinaryVersion string `protobuf:"bytes,9,opt,name=jamf_binary_version,json=jamfBinaryVersion,proto3" json:"jamf_binary_version,omitempty"` - MacosEnrollmentProfiles string `protobuf:"bytes,10,opt,name=macos_enrollment_profiles,json=macosEnrollmentProfiles,proto3" json:"macos_enrollment_profiles,omitempty"` - ReportedAssetTag string `protobuf:"bytes,11,opt,name=reported_asset_tag,json=reportedAssetTag,proto3" json:"reported_asset_tag,omitempty"` - SystemSerialNumber string `protobuf:"bytes,12,opt,name=system_serial_number,json=systemSerialNumber,proto3" json:"system_serial_number,omitempty"` - BaseBoardSerialNumber string `protobuf:"bytes,13,opt,name=base_board_serial_number,json=baseBoardSerialNumber,proto3" json:"base_board_serial_number,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + CollectTime *time.Time `protobuf:"bytes,1,opt,name=collect_time,json=collectTime,proto3,stdtime" json:"collect_time"` + RecordTime *time.Time `protobuf:"bytes,2,opt,name=record_time,json=recordTime,proto3,stdtime" json:"record_time"` + OsType string `protobuf:"bytes,3,opt,name=os_type,json=osType,proto3" json:"os_type"` + SerialNumber string `protobuf:"bytes,4,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"` + ModelIdentifier string `protobuf:"bytes,5,opt,name=model_identifier,json=modelIdentifier,proto3" json:"model_identifier,omitempty"` + OsVersion string `protobuf:"bytes,6,opt,name=os_version,json=osVersion,proto3" json:"os_version,omitempty"` + OsBuild string `protobuf:"bytes,7,opt,name=os_build,json=osBuild,proto3" json:"os_build,omitempty"` + OsUsername string `protobuf:"bytes,8,opt,name=os_username,json=osUsername,proto3" json:"os_username,omitempty"` + JamfBinaryVersion string `protobuf:"bytes,9,opt,name=jamf_binary_version,json=jamfBinaryVersion,proto3" json:"jamf_binary_version,omitempty"` + MacosEnrollmentProfiles string `protobuf:"bytes,10,opt,name=macos_enrollment_profiles,json=macosEnrollmentProfiles,proto3" json:"macos_enrollment_profiles,omitempty"` + ReportedAssetTag string `protobuf:"bytes,11,opt,name=reported_asset_tag,json=reportedAssetTag,proto3" json:"reported_asset_tag,omitempty"` + SystemSerialNumber string `protobuf:"bytes,12,opt,name=system_serial_number,json=systemSerialNumber,proto3" json:"system_serial_number,omitempty"` + BaseBoardSerialNumber string `protobuf:"bytes,13,opt,name=base_board_serial_number,json=baseBoardSerialNumber,proto3" json:"base_board_serial_number,omitempty"` + TpmPlatformAttestation *TPMPlatformAttestation `protobuf:"bytes,14,opt,name=tpm_platform_attestation,json=tpmPlatformAttestation,proto3" json:"tpm_platform_attestation,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *DeviceCollectedData) Reset() { *m = DeviceCollectedData{} } @@ -227,8 +228,180 @@ func (m *DeviceCollectedData) XXX_DiscardUnknown() { var xxx_messageInfo_DeviceCollectedData proto.InternalMessageInfo +// TPMPCR is the resource representation of teleport.devicetrust.v1.TPMPCR. +type TPMPCR struct { + Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index"` + Digest []byte `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest"` + DigestAlg uint64 `protobuf:"varint,3,opt,name=digest_alg,json=digestAlg,proto3" json:"digest_alg"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TPMPCR) Reset() { *m = TPMPCR{} } +func (m *TPMPCR) String() string { return proto.CompactTextString(m) } +func (*TPMPCR) ProtoMessage() {} +func (*TPMPCR) Descriptor() ([]byte, []int) { + return fileDescriptor_aceaef1b58496e7d, []int{4} +} +func (m *TPMPCR) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TPMPCR) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TPMPCR.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TPMPCR) XXX_Merge(src proto.Message) { + xxx_messageInfo_TPMPCR.Merge(m, src) +} +func (m *TPMPCR) XXX_Size() int { + return m.Size() +} +func (m *TPMPCR) XXX_DiscardUnknown() { + xxx_messageInfo_TPMPCR.DiscardUnknown(m) +} + +var xxx_messageInfo_TPMPCR proto.InternalMessageInfo + +// TPMQuote is the resource representation of teleport.devicetrust.v1.TPMQuote. +type TPMQuote struct { + Quote []byte `protobuf:"bytes,1,opt,name=quote,proto3" json:"quote"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TPMQuote) Reset() { *m = TPMQuote{} } +func (m *TPMQuote) String() string { return proto.CompactTextString(m) } +func (*TPMQuote) ProtoMessage() {} +func (*TPMQuote) Descriptor() ([]byte, []int) { + return fileDescriptor_aceaef1b58496e7d, []int{5} +} +func (m *TPMQuote) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TPMQuote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TPMQuote.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TPMQuote) XXX_Merge(src proto.Message) { + xxx_messageInfo_TPMQuote.Merge(m, src) +} +func (m *TPMQuote) XXX_Size() int { + return m.Size() +} +func (m *TPMQuote) XXX_DiscardUnknown() { + xxx_messageInfo_TPMQuote.DiscardUnknown(m) +} + +var xxx_messageInfo_TPMQuote proto.InternalMessageInfo + +// TPMPlatformParameters is the resource representation of +// teleport.devicetrust.v1.TPMPlatformParameters. +type TPMPlatformParameters struct { + Quotes []*TPMQuote `protobuf:"bytes,1,rep,name=quotes,proto3" json:"quotes"` + Pcrs []*TPMPCR `protobuf:"bytes,2,rep,name=pcrs,proto3" json:"pcrs"` + EventLog []byte `protobuf:"bytes,3,opt,name=event_log,json=eventLog,proto3" json:"event_log"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TPMPlatformParameters) Reset() { *m = TPMPlatformParameters{} } +func (m *TPMPlatformParameters) String() string { return proto.CompactTextString(m) } +func (*TPMPlatformParameters) ProtoMessage() {} +func (*TPMPlatformParameters) Descriptor() ([]byte, []int) { + return fileDescriptor_aceaef1b58496e7d, []int{6} +} +func (m *TPMPlatformParameters) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TPMPlatformParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TPMPlatformParameters.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TPMPlatformParameters) XXX_Merge(src proto.Message) { + xxx_messageInfo_TPMPlatformParameters.Merge(m, src) +} +func (m *TPMPlatformParameters) XXX_Size() int { + return m.Size() +} +func (m *TPMPlatformParameters) XXX_DiscardUnknown() { + xxx_messageInfo_TPMPlatformParameters.DiscardUnknown(m) +} + +var xxx_messageInfo_TPMPlatformParameters proto.InternalMessageInfo + +// TPMPlatformAttestation is the resource representation of +// teleport.devicetrust.v1.TPMPlatformAttestation. +type TPMPlatformAttestation struct { + Nonce []byte `protobuf:"bytes,1,opt,name=nonce,proto3" json:"nonce,omitempty"` + PlatformParameters *TPMPlatformParameters `protobuf:"bytes,2,opt,name=platform_parameters,json=platformParameters,proto3" json:"platform_parameters,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TPMPlatformAttestation) Reset() { *m = TPMPlatformAttestation{} } +func (m *TPMPlatformAttestation) String() string { return proto.CompactTextString(m) } +func (*TPMPlatformAttestation) ProtoMessage() {} +func (*TPMPlatformAttestation) Descriptor() ([]byte, []int) { + return fileDescriptor_aceaef1b58496e7d, []int{7} +} +func (m *TPMPlatformAttestation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TPMPlatformAttestation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TPMPlatformAttestation.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TPMPlatformAttestation) XXX_Merge(src proto.Message) { + xxx_messageInfo_TPMPlatformAttestation.Merge(m, src) +} +func (m *TPMPlatformAttestation) XXX_Size() int { + return m.Size() +} +func (m *TPMPlatformAttestation) XXX_DiscardUnknown() { + xxx_messageInfo_TPMPlatformAttestation.DiscardUnknown(m) +} + +var xxx_messageInfo_TPMPlatformAttestation proto.InternalMessageInfo + // DeviceSource is the resource representation of -// teleport.devicetrust.v1.DeviceSource. +// teleport.devicetrust.v1.DeviceSource.. type DeviceSource struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name"` Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin"` @@ -241,7 +414,7 @@ func (m *DeviceSource) Reset() { *m = DeviceSource{} } func (m *DeviceSource) String() string { return proto.CompactTextString(m) } func (*DeviceSource) ProtoMessage() {} func (*DeviceSource) Descriptor() ([]byte, []int) { - return fileDescriptor_aceaef1b58496e7d, []int{4} + return fileDescriptor_aceaef1b58496e7d, []int{8} } func (m *DeviceSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -279,6 +452,7 @@ type DeviceProfile struct { OsBuild string `protobuf:"bytes,4,opt,name=os_build,json=osBuild,proto3" json:"os_build,omitempty"` OsUsernames []string `protobuf:"bytes,5,rep,name=os_usernames,json=osUsernames,proto3" json:"os_usernames,omitempty"` JamfBinaryVersion string `protobuf:"bytes,6,opt,name=jamf_binary_version,json=jamfBinaryVersion,proto3" json:"jamf_binary_version,omitempty"` + ExternalId string `protobuf:"bytes,7,opt,name=external_id,json=externalId,proto3" json:"external_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -288,7 +462,7 @@ func (m *DeviceProfile) Reset() { *m = DeviceProfile{} } func (m *DeviceProfile) String() string { return proto.CompactTextString(m) } func (*DeviceProfile) ProtoMessage() {} func (*DeviceProfile) Descriptor() ([]byte, []int) { - return fileDescriptor_aceaef1b58496e7d, []int{5} + return fileDescriptor_aceaef1b58496e7d, []int{9} } func (m *DeviceProfile) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -322,6 +496,10 @@ func init() { proto.RegisterType((*DeviceSpec)(nil), "types.DeviceSpec") proto.RegisterType((*DeviceCredential)(nil), "types.DeviceCredential") proto.RegisterType((*DeviceCollectedData)(nil), "types.DeviceCollectedData") + proto.RegisterType((*TPMPCR)(nil), "types.TPMPCR") + proto.RegisterType((*TPMQuote)(nil), "types.TPMQuote") + proto.RegisterType((*TPMPlatformParameters)(nil), "types.TPMPlatformParameters") + proto.RegisterType((*TPMPlatformAttestation)(nil), "types.TPMPlatformAttestation") proto.RegisterType((*DeviceSource)(nil), "types.DeviceSource") proto.RegisterType((*DeviceProfile)(nil), "types.DeviceProfile") } @@ -331,77 +509,96 @@ func init() { } var fileDescriptor_aceaef1b58496e7d = []byte{ - // 1113 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0xdb, 0x36, - 0x18, 0xad, 0x7f, 0xea, 0xc4, 0xb4, 0xdd, 0x26, 0x4c, 0xd2, 0xa8, 0x59, 0x6a, 0xa6, 0xde, 0xb0, - 0x15, 0xdb, 0x60, 0xa3, 0x1b, 0xf6, 0x83, 0x0d, 0x05, 0x16, 0x2d, 0x01, 0x56, 0x0c, 0x28, 0x52, - 0x39, 0xeb, 0x45, 0x6f, 0x08, 0x5a, 0x62, 0x3c, 0x2d, 0x92, 0x29, 0x88, 0x74, 0x30, 0xbf, 0xc5, - 0xde, 0x65, 0x7b, 0x88, 0x5c, 0xf6, 0x6a, 0x97, 0xdc, 0x96, 0x4b, 0x3d, 0xc1, 0x2e, 0x07, 0x7d, - 0x94, 0x6d, 0x2a, 0x3f, 0x68, 0x50, 0xec, 0x46, 0x09, 0xcf, 0x39, 0xdf, 0x21, 0x45, 0x7d, 0x87, - 0x34, 0xea, 0x29, 0x1e, 0xf1, 0x44, 0xa4, 0x6a, 0x10, 0xf1, 0x31, 0xf3, 0x67, 0x03, 0x35, 0x4b, - 0xb8, 0x1c, 0x04, 0xfc, 0x2c, 0xf4, 0x79, 0x3f, 0x49, 0x85, 0x12, 0xf8, 0x2e, 0x60, 0x3b, 0x9b, - 0x63, 0x31, 0x16, 0x80, 0x0c, 0xf2, 0xff, 0x0c, 0xb9, 0x43, 0xc6, 0x42, 0x8c, 0x23, 0x3e, 0x80, - 0xd1, 0x68, 0x7a, 0x32, 0x50, 0x61, 0xcc, 0xa5, 0x62, 0x71, 0x52, 0x08, 0x1e, 0x5f, 0x3f, 0x03, - 0x3c, 0x8d, 0xa4, 0xf7, 0x2b, 0x5a, 0x3d, 0x80, 0x09, 0x5f, 0x3d, 0xc5, 0xdf, 0xa2, 0xc6, 0x0f, - 0x9c, 0x05, 0x3c, 0x75, 0x2a, 0x7b, 0x95, 0x27, 0xad, 0xcf, 0xb6, 0xfa, 0x46, 0xe9, 0x71, 0x29, - 0xa6, 0xa9, 0xcf, 0x0d, 0xe9, 0xb6, 0xcf, 0x35, 0xb9, 0xf3, 0x46, 0x93, 0x4a, 0xa6, 0xc9, 0x1d, - 0xaf, 0x28, 0xc1, 0x03, 0x54, 0x97, 0x09, 0xf7, 0x9d, 0xbb, 0x50, 0xba, 0x5e, 0x94, 0x1a, 0xef, - 0x61, 0xc2, 0x7d, 0x77, 0x35, 0xd3, 0x04, 0x24, 0x1e, 0x3c, 0x7b, 0xff, 0xd6, 0x11, 0x5a, 0xd2, - 0xf8, 0x03, 0xb4, 0x22, 0x24, 0xcd, 0xab, 0x60, 0xf6, 0xa6, 0xdb, 0xca, 0x34, 0x99, 0x43, 0x5e, - 0x43, 0xc8, 0xe3, 0x59, 0xc2, 0xf1, 0xc7, 0xa8, 0xc9, 0xa4, 0xe4, 0x8a, 0x2a, 0x36, 0x76, 0xaa, - 0xa0, 0xeb, 0x64, 0x9a, 0x2c, 0x41, 0x6f, 0x15, 0xfe, 0x3d, 0x66, 0x63, 0x7c, 0x84, 0x5a, 0x7e, - 0xca, 0x99, 0xe2, 0x34, 0xdf, 0x17, 0xa7, 0x06, 0x0b, 0xdb, 0xe9, 0x9b, 0x4d, 0xeb, 0xcf, 0x37, - 0xad, 0x7f, 0x3c, 0xdf, 0x34, 0x77, 0x23, 0xd3, 0xc4, 0x2e, 0xf9, 0xed, 0x2f, 0x52, 0xf1, 0x90, - 0x01, 0x72, 0x55, 0xee, 0x38, 0x4d, 0x82, 0x85, 0x63, 0xfd, 0x76, 0x8e, 0x56, 0x89, 0x71, 0x34, - 0x00, 0x38, 0x7e, 0x89, 0x3a, 0x7c, 0x92, 0x8a, 0x28, 0xa2, 0x52, 0x31, 0x35, 0x95, 0xb0, 0x7d, - 0x4d, 0x77, 0x3d, 0xd3, 0xa4, 0x4c, 0x78, 0x6d, 0x33, 0x1c, 0xc2, 0x08, 0xbf, 0x44, 0xf9, 0xba, - 0x02, 0x3e, 0x51, 0x21, 0x8b, 0x9c, 0x06, 0x2c, 0x64, 0xbb, 0xb4, 0xe7, 0xdf, 0x2f, 0x68, 0xd7, - 0xc9, 0x34, 0xd9, 0x5c, 0xca, 0x3f, 0x15, 0x71, 0xa8, 0x78, 0x9c, 0xa8, 0x99, 0x67, 0x99, 0x60, - 0x8a, 0xee, 0xf9, 0x22, 0x8a, 0xb8, 0xaf, 0x78, 0x40, 0x03, 0xa6, 0x98, 0xb3, 0xb2, 0x57, 0x83, - 0xf7, 0x2b, 0xd9, 0xce, 0x25, 0x07, 0x4c, 0x31, 0x77, 0x37, 0xd3, 0xc4, 0x29, 0x57, 0x59, 0xee, - 0x1d, 0xdf, 0x16, 0xe3, 0x7d, 0xd4, 0x30, 0x7d, 0xe4, 0xac, 0xc2, 0x7a, 0x37, 0xca, 0x3d, 0x02, - 0x94, 0xbb, 0x99, 0x69, 0xb2, 0x66, 0x64, 0x96, 0x53, 0x51, 0x88, 0x0f, 0xd1, 0x4a, 0x92, 0x8a, - 0x93, 0x30, 0xe2, 0x4e, 0x13, 0x3c, 0x36, 0x4b, 0x1e, 0x47, 0x86, 0x73, 0xb7, 0x32, 0x4d, 0xd6, - 0x0b, 0xa1, 0xe5, 0x32, 0xaf, 0xed, 0xfd, 0x5e, 0x45, 0x6b, 0x97, 0x77, 0x09, 0x3f, 0x40, 0xd5, - 0x30, 0x28, 0x7a, 0xaf, 0x91, 0x69, 0x52, 0x0d, 0x03, 0xaf, 0x1a, 0x06, 0xf8, 0x6b, 0x74, 0x2f, - 0x99, 0x8e, 0xa2, 0xd0, 0xa7, 0xa7, 0x7c, 0x46, 0xf3, 0x74, 0xe4, 0x7d, 0xd7, 0x76, 0x71, 0xa6, - 0xc9, 0x25, 0xc6, 0x6b, 0x9b, 0xf1, 0x8f, 0x7c, 0x76, 0xc0, 0x53, 0x3c, 0x44, 0xdb, 0x26, 0xcc, - 0x94, 0x29, 0x95, 0x77, 0x84, 0x0a, 0xc5, 0xc4, 0xb4, 0x78, 0x0d, 0xa6, 0x79, 0x2f, 0xd3, 0xe4, - 0x26, 0x89, 0xb7, 0x65, 0x88, 0xfd, 0x25, 0x0e, 0x09, 0xd8, 0x47, 0xeb, 0x2a, 0x89, 0x29, 0x3f, - 0xf5, 0x79, 0xaa, 0xa8, 0xe4, 0x69, 0xde, 0x00, 0x75, 0xb0, 0x83, 0xd7, 0xbe, 0x42, 0x7a, 0xf7, - 0x55, 0x12, 0x1f, 0x02, 0x32, 0x04, 0x00, 0x7f, 0x81, 0x3a, 0xb9, 0x8a, 0x9d, 0x52, 0xb3, 0x5c, - 0x68, 0xba, 0xb6, 0x69, 0xba, 0x12, 0xe1, 0xb5, 0x54, 0x12, 0xef, 0x9f, 0x1e, 0xc1, 0xa0, 0xf7, - 0xe7, 0x0a, 0xda, 0xb8, 0xa6, 0x09, 0xf0, 0x10, 0xb5, 0x8b, 0x0f, 0x6d, 0x62, 0x51, 0x79, 0x6b, - 0x2c, 0xf2, 0x8f, 0x5c, 0xaa, 0x81, 0x5c, 0xb4, 0x0a, 0x64, 0x1e, 0xb5, 0x94, 0xfb, 0x22, 0x0d, - 0x8c, 0x67, 0xf5, 0x76, 0x51, 0xb3, 0x4a, 0x4c, 0xd4, 0x0c, 0x00, 0x8e, 0xd6, 0x01, 0x53, 0xbb, - 0xf9, 0x80, 0xf9, 0x0e, 0x75, 0xcc, 0xb6, 0xd1, 0xc9, 0x34, 0x1e, 0xf1, 0xb4, 0xd8, 0x5a, 0xf8, - 0x52, 0x25, 0xc2, 0xea, 0xab, 0xb6, 0x21, 0x5e, 0x00, 0x8e, 0x9f, 0xa3, 0xb5, 0x58, 0x04, 0x3c, - 0xa2, 0x21, 0x74, 0xd6, 0x49, 0xc8, 0xd3, 0x22, 0xd5, 0xdd, 0x4c, 0x93, 0x9d, 0xcb, 0x9c, 0xe5, - 0x73, 0x1f, 0xb8, 0xe7, 0x0b, 0x0a, 0x7f, 0x85, 0x90, 0x90, 0xf4, 0x8c, 0xa7, 0x32, 0x14, 0x13, - 0x48, 0x79, 0xd3, 0x84, 0x79, 0x89, 0x5a, 0xe5, 0x4d, 0x21, 0x5f, 0x19, 0x10, 0x3f, 0x45, 0xab, - 0x42, 0xd2, 0xd1, 0x34, 0x8c, 0x02, 0x67, 0x05, 0xca, 0x1e, 0x64, 0x9a, 0xe0, 0x39, 0x66, 0x67, - 0x42, 0x48, 0x37, 0x87, 0xf0, 0x37, 0xa8, 0x25, 0x24, 0x9d, 0x4a, 0x9e, 0x4e, 0x58, 0x6c, 0x22, - 0xda, 0x74, 0x1f, 0x66, 0x9a, 0x6c, 0x59, 0xb0, 0x7d, 0x74, 0x08, 0xf9, 0x53, 0x81, 0xe2, 0x97, - 0x68, 0xe3, 0x17, 0x16, 0x9f, 0xd0, 0x51, 0x38, 0x61, 0xe9, 0x6c, 0xb1, 0xe0, 0x26, 0x78, 0x3c, - 0xce, 0x34, 0x79, 0x74, 0x0d, 0x6d, 0x79, 0xad, 0xe7, 0xb4, 0x0b, 0xec, 0xfc, 0x0d, 0x7c, 0xf4, - 0x30, 0x66, 0xbe, 0x90, 0xd4, 0x1c, 0x7b, 0x31, 0x9f, 0x28, 0x5a, 0xc4, 0x57, 0x3a, 0x08, 0x8c, - 0x3f, 0xca, 0x34, 0x79, 0xff, 0x46, 0x91, 0x65, 0xbf, 0x0d, 0xa2, 0xc3, 0x85, 0xa6, 0x38, 0x26, - 0x24, 0x7e, 0x81, 0x70, 0x0a, 0xf7, 0x23, 0x0f, 0xe8, 0xf2, 0x5a, 0x69, 0x81, 0xfb, 0x5e, 0xa6, - 0xc9, 0xee, 0x55, 0xd6, 0xb2, 0x5d, 0x9b, 0xb3, 0xfb, 0xf3, 0x1b, 0xe7, 0x18, 0x6d, 0xca, 0x99, - 0x54, 0x3c, 0xa6, 0xe5, 0x1e, 0x6a, 0x83, 0x63, 0x2f, 0xd3, 0xa4, 0x7b, 0x1d, 0x6f, 0x79, 0x62, - 0xc3, 0x0f, 0xed, 0x86, 0xa2, 0xc8, 0x19, 0x31, 0xc9, 0xe9, 0x48, 0xb0, 0x34, 0xb8, 0xe4, 0xdc, - 0x01, 0xe7, 0x0f, 0x33, 0x4d, 0x7a, 0x37, 0x69, 0x2c, 0xf7, 0xad, 0x5c, 0xe3, 0xe6, 0x12, 0x7b, - 0x82, 0xde, 0x11, 0x6a, 0xdb, 0x67, 0x30, 0xde, 0x45, 0x75, 0xe8, 0x01, 0x73, 0x16, 0xc2, 0xbd, - 0x9d, 0x8f, 0x3d, 0x78, 0xe2, 0x1e, 0x6a, 0x88, 0x34, 0x1c, 0x87, 0x93, 0xe2, 0xfe, 0x45, 0x99, - 0x26, 0x05, 0xe2, 0x15, 0x7f, 0x7b, 0x7f, 0xd4, 0x50, 0xa7, 0x74, 0x24, 0xe3, 0xd7, 0xe5, 0xab, - 0xf3, 0xed, 0x67, 0xc4, 0xa3, 0xbc, 0xf5, 0xac, 0x92, 0xe5, 0x6b, 0x5c, 0xb9, 0x44, 0xaf, 0x4b, - 0x5c, 0xf5, 0xff, 0x48, 0x5c, 0xed, 0xdd, 0x12, 0x57, 0xbf, 0x5d, 0xe2, 0x9e, 0xa1, 0xb6, 0x15, - 0xad, 0xfc, 0xea, 0xaf, 0x3d, 0x69, 0xba, 0x3b, 0x99, 0x26, 0x0f, 0x6c, 0xdc, 0x2a, 0x6d, 0x2d, - 0x33, 0x27, 0x6f, 0x0a, 0x5d, 0xe3, 0xdd, 0x43, 0xe7, 0x3e, 0x3b, 0xff, 0xa7, 0x7b, 0xe7, 0xfc, - 0xa2, 0x5b, 0x79, 0x73, 0xd1, 0xad, 0xfc, 0x7d, 0xd1, 0xad, 0xbc, 0xfe, 0x64, 0x1c, 0xaa, 0x9f, - 0xa7, 0xa3, 0xbe, 0x2f, 0xe2, 0xc1, 0x38, 0x65, 0x67, 0xa1, 0xb9, 0x89, 0x58, 0x34, 0x58, 0xfc, - 0xb4, 0x64, 0x49, 0x68, 0x7e, 0x51, 0x8e, 0x1a, 0xf0, 0x19, 0x3f, 0xff, 0x2f, 0x00, 0x00, 0xff, - 0xff, 0xa1, 0x9e, 0x8d, 0x5b, 0xd9, 0x0a, 0x00, 0x00, + // 1424 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcb, 0x6e, 0xdb, 0x46, + 0x17, 0x8e, 0x2e, 0x96, 0xa5, 0x91, 0xe4, 0xd8, 0xe3, 0x1b, 0xe3, 0x38, 0x9e, 0x44, 0xff, 0x2d, + 0x7f, 0xd3, 0x5a, 0x48, 0x03, 0xb4, 0x40, 0x8a, 0xa0, 0x35, 0x93, 0x00, 0x0d, 0xd2, 0x04, 0x0a, + 0xed, 0x06, 0x45, 0x80, 0x82, 0x18, 0x91, 0x63, 0x96, 0x35, 0xa9, 0x61, 0x39, 0x23, 0x23, 0x02, + 0x0a, 0xf4, 0x15, 0xfa, 0x12, 0x7d, 0x84, 0xbe, 0x43, 0x96, 0xd9, 0x75, 0x51, 0x80, 0x6d, 0xb3, + 0xe4, 0xaa, 0xcb, 0x2e, 0x8b, 0x39, 0x43, 0x49, 0xc3, 0x58, 0x46, 0x82, 0xb6, 0x1b, 0x91, 0xfc, + 0xbe, 0x73, 0xbe, 0x19, 0x1e, 0x9e, 0xcb, 0x08, 0xf5, 0x24, 0x8b, 0x58, 0xc2, 0x53, 0xd9, 0x8f, + 0x58, 0x40, 0xbd, 0x49, 0x5f, 0x4e, 0x12, 0x26, 0xfa, 0x3e, 0x3b, 0x0d, 0x3d, 0xb6, 0x9f, 0xa4, + 0x5c, 0x72, 0xbc, 0x04, 0xd8, 0xce, 0x46, 0xc0, 0x03, 0x0e, 0x48, 0x5f, 0xdd, 0x69, 0x72, 0x87, + 0x04, 0x9c, 0x07, 0x11, 0xeb, 0xc3, 0xd3, 0x70, 0x7c, 0xdc, 0x97, 0x61, 0xcc, 0x84, 0xa4, 0x71, + 0x52, 0x18, 0x5c, 0x5b, 0xbc, 0x02, 0xfc, 0x6a, 0x93, 0xde, 0x73, 0xd4, 0xbc, 0x07, 0x0b, 0x3e, + 0xbd, 0x89, 0x3f, 0x42, 0x8d, 0x4f, 0x19, 0xf5, 0x59, 0x6a, 0x55, 0xae, 0x56, 0xae, 0xb7, 0xdf, + 0xdf, 0xdc, 0xd7, 0x96, 0x0e, 0x13, 0x7c, 0x9c, 0x7a, 0x4c, 0x93, 0x76, 0xe7, 0x45, 0x46, 0x2e, + 0xbc, 0xcc, 0x48, 0x25, 0xcf, 0xc8, 0x05, 0xa7, 0x70, 0xc1, 0x7d, 0x54, 0x17, 0x09, 0xf3, 0xac, + 0x25, 0x70, 0x5d, 0x2b, 0x5c, 0xb5, 0xf6, 0x61, 0xc2, 0x3c, 0xbb, 0x99, 0x67, 0x04, 0x4c, 0x1c, + 0xf8, 0xed, 0xfd, 0x51, 0x47, 0x68, 0x4e, 0xe3, 0x7f, 0xa3, 0x65, 0x2e, 0x5c, 0xe5, 0x05, 0xab, + 0xb7, 0xec, 0x76, 0x9e, 0x91, 0x29, 0xe4, 0x34, 0xb8, 0x38, 0x9a, 0x24, 0x0c, 0xbf, 0x83, 0x5a, + 0x54, 0x08, 0x26, 0x5d, 0x49, 0x03, 0xab, 0x0a, 0x76, 0xdd, 0x3c, 0x23, 0x73, 0xd0, 0x69, 0xc2, + 0xed, 0x11, 0x0d, 0xf0, 0x00, 0xb5, 0xbd, 0x94, 0x51, 0xc9, 0x5c, 0x15, 0x17, 0xab, 0x06, 0x1b, + 0xdb, 0xd9, 0xd7, 0x41, 0xdb, 0x9f, 0x06, 0x6d, 0xff, 0x68, 0x1a, 0x34, 0x7b, 0x3d, 0xcf, 0x88, + 0xe9, 0xf2, 0xfd, 0x2f, 0xa4, 0xe2, 0x20, 0x0d, 0x28, 0x2b, 0xa5, 0x38, 0x4e, 0xfc, 0x99, 0x62, + 0xfd, 0xed, 0x14, 0x0d, 0x17, 0xad, 0xa8, 0x01, 0x50, 0xfc, 0x00, 0x75, 0xd9, 0x28, 0xe5, 0x51, + 0xe4, 0x0a, 0x49, 0xe5, 0x58, 0x40, 0xf8, 0x5a, 0xf6, 0x5a, 0x9e, 0x91, 0x32, 0xe1, 0x74, 0xf4, + 0xe3, 0x21, 0x3c, 0xe1, 0x27, 0x48, 0xed, 0xcb, 0x67, 0x23, 0x19, 0xd2, 0xc8, 0x6a, 0xc0, 0x46, + 0xb6, 0x4b, 0x31, 0xbf, 0x3b, 0xa3, 0x6d, 0x2b, 0xcf, 0xc8, 0xc6, 0xdc, 0xfc, 0x5d, 0x1e, 0x87, + 0x92, 0xc5, 0x89, 0x9c, 0x38, 0x86, 0x08, 0x76, 0xd1, 0x8a, 0xc7, 0xa3, 0x88, 0x79, 0x92, 0xf9, + 0xae, 0x4f, 0x25, 0xb5, 0x96, 0xaf, 0xd6, 0xe0, 0xfd, 0x4a, 0xb2, 0x53, 0x93, 0x7b, 0x54, 0x52, + 0x7b, 0x37, 0xcf, 0x88, 0x55, 0xf6, 0x32, 0xd4, 0xbb, 0x9e, 0x69, 0x8c, 0x0f, 0x50, 0x43, 0xe7, + 0x91, 0xd5, 0x84, 0xfd, 0xae, 0x97, 0x73, 0x04, 0x28, 0x7b, 0x23, 0xcf, 0xc8, 0xaa, 0x36, 0x33, + 0x94, 0x0a, 0x47, 0x7c, 0x1f, 0x2d, 0x27, 0x29, 0x3f, 0x0e, 0x23, 0x66, 0xb5, 0x40, 0x63, 0xa3, + 0xa4, 0x31, 0xd0, 0x9c, 0xbd, 0x99, 0x67, 0x64, 0xad, 0x30, 0x34, 0x54, 0xa6, 0xbe, 0xbd, 0x9f, + 0xab, 0x68, 0xf5, 0xf5, 0x28, 0xe1, 0x2d, 0x54, 0x0d, 0xfd, 0x22, 0xf7, 0x1a, 0x79, 0x46, 0xaa, + 0xa1, 0xef, 0x54, 0x43, 0x1f, 0xdb, 0x68, 0x25, 0x19, 0x0f, 0xa3, 0xd0, 0x73, 0x4f, 0xd8, 0xc4, + 0x55, 0xd5, 0xa1, 0xf2, 0xae, 0xa3, 0xdf, 0xbd, 0xcc, 0x18, 0x6b, 0x75, 0x34, 0xf3, 0x90, 0x4d, + 0xee, 0xb1, 0x14, 0x7f, 0x89, 0xb6, 0x75, 0x59, 0xbb, 0x54, 0x4a, 0x95, 0x1b, 0x32, 0xe4, 0x23, + 0x9d, 0xec, 0x35, 0x58, 0xf0, 0x3f, 0x79, 0x46, 0xae, 0x9d, 0x63, 0x62, 0xa8, 0x6e, 0x6a, 0x93, + 0x83, 0xb9, 0x05, 0x54, 0xc5, 0x43, 0xb4, 0x26, 0x93, 0xd8, 0x65, 0x27, 0x1e, 0x4b, 0xa5, 0x2b, + 0x58, 0xaa, 0x92, 0xa2, 0x0e, 0xc2, 0x24, 0xcf, 0xc8, 0xe5, 0x33, 0xa4, 0x21, 0x79, 0x51, 0x26, + 0xf1, 0x7d, 0xe0, 0x0e, 0x81, 0xc2, 0x1f, 0xa3, 0xae, 0xb2, 0xa7, 0x27, 0xae, 0x7e, 0x05, 0x48, + 0xc9, 0x8e, 0x7d, 0x39, 0xcf, 0xc8, 0x76, 0x89, 0x30, 0x44, 0xda, 0x32, 0x89, 0x0f, 0x4e, 0x06, + 0x00, 0xf7, 0x7e, 0x6a, 0xa2, 0xf5, 0x05, 0xc9, 0x82, 0x0f, 0x51, 0xa7, 0x48, 0x08, 0x5d, 0x3e, + 0x95, 0x37, 0x96, 0x8f, 0x4a, 0x86, 0x92, 0x0f, 0xd4, 0x4f, 0xbb, 0x40, 0xa6, 0x25, 0x99, 0x32, + 0x8f, 0xa7, 0xbe, 0xd6, 0xac, 0xbe, 0x5d, 0x49, 0x1a, 0x2e, 0xba, 0x24, 0x35, 0x00, 0x8a, 0x46, + 0x23, 0xaa, 0x9d, 0xdf, 0x88, 0x3e, 0x41, 0x5d, 0x1d, 0x4a, 0x77, 0x34, 0x8e, 0x87, 0x2c, 0x2d, + 0xc2, 0x0d, 0x51, 0x2a, 0x11, 0x66, 0x4e, 0x68, 0xe2, 0x31, 0xe0, 0xf8, 0x01, 0x5a, 0x8d, 0xb9, + 0xcf, 0x22, 0x37, 0x84, 0x0c, 0x3c, 0x0e, 0x59, 0x5a, 0x54, 0xff, 0x5e, 0x9e, 0x91, 0x9d, 0xd7, + 0x39, 0xf3, 0x93, 0x01, 0xf7, 0x60, 0x46, 0xe1, 0x0f, 0x11, 0xe2, 0xc2, 0x3d, 0x65, 0xa9, 0x08, + 0xf9, 0x08, 0xba, 0x41, 0x4b, 0x17, 0xfd, 0x1c, 0x35, 0xdc, 0x5b, 0x5c, 0x3c, 0xd5, 0x20, 0xbe, + 0x89, 0x9a, 0x5c, 0xb8, 0xc3, 0x71, 0x18, 0xf9, 0xd6, 0x32, 0xb8, 0x6d, 0xe5, 0x19, 0xc1, 0x53, + 0xcc, 0xac, 0x1d, 0x2e, 0x6c, 0x05, 0xe1, 0xdb, 0xa8, 0xcd, 0x85, 0x3b, 0x16, 0x2c, 0x1d, 0xd1, + 0x58, 0x97, 0x72, 0xcb, 0xbe, 0x94, 0x67, 0x64, 0xd3, 0x80, 0xcd, 0x16, 0xc3, 0xc5, 0xe7, 0x05, + 0x8a, 0x9f, 0xa0, 0xf5, 0xaf, 0x69, 0x7c, 0xec, 0x0e, 0xc3, 0x11, 0x4d, 0x27, 0xb3, 0x0d, 0xb7, + 0x40, 0xe3, 0x5a, 0x9e, 0x91, 0x2b, 0x0b, 0x68, 0x43, 0x6b, 0x4d, 0xd1, 0x36, 0xb0, 0xd3, 0x37, + 0xf0, 0xd0, 0xa5, 0x98, 0x7a, 0x5c, 0xb8, 0xba, 0x3d, 0xc6, 0x6c, 0x24, 0xdd, 0xa2, 0xcc, 0x85, + 0x85, 0x40, 0xf8, 0x7f, 0x79, 0x46, 0xfe, 0x75, 0xae, 0x91, 0x21, 0xbf, 0x0d, 0x46, 0xf7, 0x67, + 0x36, 0x45, 0x3b, 0x11, 0xf8, 0x31, 0xc2, 0x29, 0xcc, 0x51, 0xe6, 0xbb, 0xf3, 0xf1, 0xd3, 0x06, + 0xf5, 0xab, 0x79, 0x46, 0x76, 0xcf, 0xb2, 0x86, 0xec, 0xea, 0x94, 0x3d, 0x98, 0x4e, 0xa6, 0x23, + 0xb4, 0x21, 0x26, 0x42, 0xb2, 0xd8, 0x2d, 0xe7, 0x50, 0x07, 0x14, 0x7b, 0x79, 0x46, 0xf6, 0x16, + 0xf1, 0x86, 0x26, 0xd6, 0xfc, 0xa1, 0x99, 0x50, 0x2e, 0xb2, 0x86, 0x54, 0x30, 0x77, 0xc8, 0x69, + 0xea, 0xbf, 0xa6, 0xdc, 0x05, 0xe5, 0xff, 0xe6, 0x19, 0xe9, 0x9d, 0x67, 0x63, 0xb6, 0x19, 0x65, + 0x63, 0x2b, 0x93, 0xd2, 0x02, 0xdf, 0x21, 0x4b, 0x35, 0x80, 0x24, 0xa2, 0xf2, 0x98, 0xa7, 0xb1, + 0xd9, 0xa8, 0xac, 0x15, 0x28, 0xbc, 0x2b, 0x45, 0x3b, 0x3e, 0x1a, 0x3c, 0x1a, 0x14, 0x56, 0x46, + 0xaf, 0xd2, 0xeb, 0x9f, 0x27, 0x61, 0xac, 0xbf, 0x25, 0x93, 0x78, 0x81, 0x7f, 0xef, 0x5b, 0xd4, + 0x50, 0xca, 0x77, 0x1d, 0x4c, 0xd0, 0x52, 0x38, 0xf2, 0xd9, 0x73, 0x68, 0x22, 0x4b, 0x76, 0x2b, + 0xcf, 0x88, 0x06, 0x1c, 0x7d, 0xc1, 0x3d, 0xd4, 0xf0, 0xc3, 0x80, 0x09, 0x59, 0x74, 0x6b, 0x94, + 0x67, 0xa4, 0x40, 0x9c, 0xe2, 0x8a, 0xdf, 0x43, 0x48, 0xdf, 0xb9, 0x34, 0x0a, 0xa0, 0xd8, 0xeb, + 0xf6, 0x4a, 0x9e, 0x11, 0x03, 0x75, 0x5a, 0xfa, 0xfe, 0x20, 0x0a, 0x7a, 0x5f, 0xa0, 0xe6, 0xd1, + 0xe0, 0xd1, 0x93, 0x31, 0x97, 0x4c, 0xad, 0xff, 0x8d, 0xba, 0x81, 0xf5, 0x3b, 0x7a, 0x7d, 0x00, + 0x1c, 0x7d, 0xc1, 0x37, 0x50, 0x4b, 0x84, 0xc1, 0x88, 0xca, 0x71, 0xca, 0x8a, 0x2d, 0xc0, 0x41, + 0x65, 0x06, 0x3a, 0xf3, 0xdb, 0xde, 0x0f, 0x15, 0xb4, 0x69, 0x84, 0x6c, 0x40, 0x53, 0x1a, 0x33, + 0xc9, 0x52, 0x81, 0x6f, 0xa1, 0x06, 0xe8, 0x09, 0xab, 0x02, 0xc3, 0xf8, 0xe2, 0x3c, 0xc0, 0xb0, + 0x11, 0xfd, 0x5e, 0xda, 0xc4, 0x29, 0xae, 0xf8, 0x06, 0xaa, 0x27, 0x5e, 0x2a, 0xac, 0x2a, 0xb8, + 0x74, 0x8d, 0x6f, 0x72, 0xd7, 0xd1, 0xc7, 0x30, 0x45, 0x3b, 0xf0, 0xab, 0x4e, 0x54, 0xec, 0x54, + 0x15, 0x44, 0xc4, 0x75, 0x0c, 0x8a, 0x8d, 0xce, 0x40, 0xa7, 0x09, 0xb7, 0x9f, 0xf1, 0xa0, 0xf7, + 0x63, 0x05, 0x6d, 0x2d, 0xfe, 0xb4, 0xf8, 0xff, 0x68, 0x69, 0xc4, 0x47, 0xde, 0x34, 0x20, 0xaa, + 0xcb, 0x5e, 0x04, 0xc0, 0xf8, 0xac, 0xda, 0x02, 0x27, 0x68, 0x7d, 0xf6, 0xfd, 0x93, 0xd9, 0xab, + 0x16, 0xad, 0x7b, 0xf7, 0x6c, 0x06, 0xcd, 0xc3, 0xa1, 0x7b, 0xc4, 0x02, 0x67, 0xb3, 0x32, 0x92, + 0x33, 0x6e, 0xbd, 0x01, 0xea, 0x98, 0x87, 0x0c, 0xbc, 0x8b, 0xea, 0xd0, 0xbc, 0xf4, 0xb0, 0x87, + 0x88, 0xa8, 0x67, 0x07, 0x7e, 0x55, 0xea, 0xf0, 0x34, 0x0c, 0xc2, 0x51, 0x71, 0xc0, 0x84, 0x10, + 0x6b, 0xc4, 0x29, 0xae, 0xbd, 0xdf, 0x6b, 0xa8, 0x5b, 0x3a, 0x73, 0xe0, 0x67, 0xe5, 0xb3, 0xe1, + 0x9b, 0x87, 0xdb, 0x15, 0xd5, 0x33, 0x0d, 0x97, 0xf9, 0x3b, 0x9c, 0x39, 0x25, 0x2e, 0x1a, 0x15, + 0xd5, 0x7f, 0x62, 0x54, 0xd4, 0xfe, 0xda, 0xa8, 0xa8, 0xbf, 0xdd, 0xa8, 0xb8, 0x83, 0x3a, 0xc6, + 0x4c, 0x50, 0x67, 0xdb, 0xda, 0xf5, 0x96, 0xbd, 0x93, 0x67, 0x64, 0xcb, 0xc4, 0xcd, 0x73, 0xc4, + 0x7c, 0x58, 0x88, 0xf3, 0xa6, 0x45, 0xe3, 0x6f, 0x4c, 0x8b, 0xdb, 0xa8, 0xcd, 0x9e, 0x4b, 0xb5, + 0x80, 0x8a, 0x57, 0x31, 0xf2, 0x60, 0x78, 0x19, 0xb0, 0x39, 0xbc, 0xa6, 0xf0, 0x03, 0xdf, 0xbe, + 0xf3, 0xe2, 0xb7, 0xbd, 0x0b, 0x2f, 0x5e, 0xed, 0x55, 0x5e, 0xbe, 0xda, 0xab, 0xfc, 0xfa, 0x6a, + 0xaf, 0xf2, 0xec, 0x46, 0x10, 0xca, 0xaf, 0xc6, 0xc3, 0x7d, 0x8f, 0xc7, 0xfd, 0x20, 0xa5, 0xa7, + 0xa1, 0xae, 0x05, 0x1a, 0xf5, 0x67, 0xff, 0xbb, 0x68, 0x12, 0xea, 0xbf, 0x5b, 0xc3, 0x06, 0xa4, + 0xc0, 0xad, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc1, 0xeb, 0xe3, 0xf6, 0x0d, 0x00, 0x00, } func (m *DeviceV1) Marshal() (dAtA []byte, err error) { @@ -657,6 +854,18 @@ func (m *DeviceCollectedData) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.TpmPlatformAttestation != nil { + { + size, err := m.TpmPlatformAttestation.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintDevice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 + } if len(m.BaseBoardSerialNumber) > 0 { i -= len(m.BaseBoardSerialNumber) copy(dAtA[i:], m.BaseBoardSerialNumber) @@ -735,29 +944,29 @@ func (m *DeviceCollectedData) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x1a } if m.RecordTime != nil { - n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.RecordTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.RecordTime):]) - if err8 != nil { - return 0, err8 + n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.RecordTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.RecordTime):]) + if err9 != nil { + return 0, err9 } - i -= n8 - i = encodeVarintDevice(dAtA, i, uint64(n8)) + i -= n9 + i = encodeVarintDevice(dAtA, i, uint64(n9)) i-- dAtA[i] = 0x12 } if m.CollectTime != nil { - n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.CollectTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.CollectTime):]) - if err9 != nil { - return 0, err9 + n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.CollectTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.CollectTime):]) + if err10 != nil { + return 0, err10 } - i -= n9 - i = encodeVarintDevice(dAtA, i, uint64(n9)) + i -= n10 + i = encodeVarintDevice(dAtA, i, uint64(n10)) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *DeviceSource) Marshal() (dAtA []byte, err error) { +func (m *TPMPCR) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -767,12 +976,12 @@ func (m *DeviceSource) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *DeviceSource) MarshalTo(dAtA []byte) (int, error) { +func (m *TPMPCR) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *DeviceSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *TPMPCR) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -781,24 +990,27 @@ func (m *DeviceSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if len(m.Origin) > 0 { - i -= len(m.Origin) - copy(dAtA[i:], m.Origin) - i = encodeVarintDevice(dAtA, i, uint64(len(m.Origin))) + if m.DigestAlg != 0 { + i = encodeVarintDevice(dAtA, i, uint64(m.DigestAlg)) + i-- + dAtA[i] = 0x18 + } + if len(m.Digest) > 0 { + i -= len(m.Digest) + copy(dAtA[i:], m.Digest) + i = encodeVarintDevice(dAtA, i, uint64(len(m.Digest))) i-- dAtA[i] = 0x12 } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintDevice(dAtA, i, uint64(len(m.Name))) + if m.Index != 0 { + i = encodeVarintDevice(dAtA, i, uint64(m.Index)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x8 } return len(dAtA) - i, nil } -func (m *DeviceProfile) Marshal() (dAtA []byte, err error) { +func (m *TPMQuote) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -808,12 +1020,12 @@ func (m *DeviceProfile) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *DeviceProfile) MarshalTo(dAtA []byte) (int, error) { +func (m *TPMQuote) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *DeviceProfile) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *TPMQuote) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -822,92 +1034,289 @@ func (m *DeviceProfile) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if len(m.JamfBinaryVersion) > 0 { - i -= len(m.JamfBinaryVersion) - copy(dAtA[i:], m.JamfBinaryVersion) - i = encodeVarintDevice(dAtA, i, uint64(len(m.JamfBinaryVersion))) - i-- - dAtA[i] = 0x32 - } - if len(m.OsUsernames) > 0 { - for iNdEx := len(m.OsUsernames) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.OsUsernames[iNdEx]) - copy(dAtA[i:], m.OsUsernames[iNdEx]) - i = encodeVarintDevice(dAtA, i, uint64(len(m.OsUsernames[iNdEx]))) - i-- - dAtA[i] = 0x2a - } - } - if len(m.OsBuild) > 0 { - i -= len(m.OsBuild) - copy(dAtA[i:], m.OsBuild) - i = encodeVarintDevice(dAtA, i, uint64(len(m.OsBuild))) - i-- - dAtA[i] = 0x22 - } - if len(m.OsVersion) > 0 { - i -= len(m.OsVersion) - copy(dAtA[i:], m.OsVersion) - i = encodeVarintDevice(dAtA, i, uint64(len(m.OsVersion))) - i-- - dAtA[i] = 0x1a - } - if len(m.ModelIdentifier) > 0 { - i -= len(m.ModelIdentifier) - copy(dAtA[i:], m.ModelIdentifier) - i = encodeVarintDevice(dAtA, i, uint64(len(m.ModelIdentifier))) + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintDevice(dAtA, i, uint64(len(m.Signature))) i-- dAtA[i] = 0x12 } - if m.UpdateTime != nil { - n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.UpdateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.UpdateTime):]) - if err10 != nil { - return 0, err10 - } - i -= n10 - i = encodeVarintDevice(dAtA, i, uint64(n10)) + if len(m.Quote) > 0 { + i -= len(m.Quote) + copy(dAtA[i:], m.Quote) + i = encodeVarintDevice(dAtA, i, uint64(len(m.Quote))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func encodeVarintDevice(dAtA []byte, offset int, v uint64) int { - offset -= sovDevice(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *TPMPlatformParameters) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *DeviceV1) Size() (n int) { - if m == nil { - return 0 - } + +func (m *TPMPlatformParameters) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TPMPlatformParameters) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = m.ResourceHeader.Size() - n += 1 + l + sovDevice(uint64(l)) - if m.Spec != nil { - l = m.Spec.Size() - n += 1 + l + sovDevice(uint64(l)) - } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } - return n + if len(m.EventLog) > 0 { + i -= len(m.EventLog) + copy(dAtA[i:], m.EventLog) + i = encodeVarintDevice(dAtA, i, uint64(len(m.EventLog))) + i-- + dAtA[i] = 0x1a + } + if len(m.Pcrs) > 0 { + for iNdEx := len(m.Pcrs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Pcrs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintDevice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Quotes) > 0 { + for iNdEx := len(m.Quotes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Quotes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintDevice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil } -func (m *DeviceSpec) Size() (n int) { - if m == nil { - return 0 +func (m *TPMPlatformAttestation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *TPMPlatformAttestation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TPMPlatformAttestation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.OsType) + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.PlatformParameters != nil { + { + size, err := m.PlatformParameters.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintDevice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Nonce) > 0 { + i -= len(m.Nonce) + copy(dAtA[i:], m.Nonce) + i = encodeVarintDevice(dAtA, i, uint64(len(m.Nonce))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *DeviceSource) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeviceSource) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeviceSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Origin) > 0 { + i -= len(m.Origin) + copy(dAtA[i:], m.Origin) + i = encodeVarintDevice(dAtA, i, uint64(len(m.Origin))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintDevice(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *DeviceProfile) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeviceProfile) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeviceProfile) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.ExternalId) > 0 { + i -= len(m.ExternalId) + copy(dAtA[i:], m.ExternalId) + i = encodeVarintDevice(dAtA, i, uint64(len(m.ExternalId))) + i-- + dAtA[i] = 0x3a + } + if len(m.JamfBinaryVersion) > 0 { + i -= len(m.JamfBinaryVersion) + copy(dAtA[i:], m.JamfBinaryVersion) + i = encodeVarintDevice(dAtA, i, uint64(len(m.JamfBinaryVersion))) + i-- + dAtA[i] = 0x32 + } + if len(m.OsUsernames) > 0 { + for iNdEx := len(m.OsUsernames) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.OsUsernames[iNdEx]) + copy(dAtA[i:], m.OsUsernames[iNdEx]) + i = encodeVarintDevice(dAtA, i, uint64(len(m.OsUsernames[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + if len(m.OsBuild) > 0 { + i -= len(m.OsBuild) + copy(dAtA[i:], m.OsBuild) + i = encodeVarintDevice(dAtA, i, uint64(len(m.OsBuild))) + i-- + dAtA[i] = 0x22 + } + if len(m.OsVersion) > 0 { + i -= len(m.OsVersion) + copy(dAtA[i:], m.OsVersion) + i = encodeVarintDevice(dAtA, i, uint64(len(m.OsVersion))) + i-- + dAtA[i] = 0x1a + } + if len(m.ModelIdentifier) > 0 { + i -= len(m.ModelIdentifier) + copy(dAtA[i:], m.ModelIdentifier) + i = encodeVarintDevice(dAtA, i, uint64(len(m.ModelIdentifier))) + i-- + dAtA[i] = 0x12 + } + if m.UpdateTime != nil { + n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.UpdateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.UpdateTime):]) + if err12 != nil { + return 0, err12 + } + i -= n12 + i = encodeVarintDevice(dAtA, i, uint64(n12)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintDevice(dAtA []byte, offset int, v uint64) int { + offset -= sovDevice(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *DeviceV1) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ResourceHeader.Size() + n += 1 + l + sovDevice(uint64(l)) + if m.Spec != nil { + l = m.Spec.Size() + n += 1 + l + sovDevice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *DeviceSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.OsType) if l > 0 { n += 1 + l + sovDevice(uint64(l)) } @@ -1041,6 +1450,100 @@ func (m *DeviceCollectedData) Size() (n int) { if l > 0 { n += 1 + l + sovDevice(uint64(l)) } + if m.TpmPlatformAttestation != nil { + l = m.TpmPlatformAttestation.Size() + n += 1 + l + sovDevice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *TPMPCR) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Index != 0 { + n += 1 + sovDevice(uint64(m.Index)) + } + l = len(m.Digest) + if l > 0 { + n += 1 + l + sovDevice(uint64(l)) + } + if m.DigestAlg != 0 { + n += 1 + sovDevice(uint64(m.DigestAlg)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *TPMQuote) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Quote) + if l > 0 { + n += 1 + l + sovDevice(uint64(l)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovDevice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *TPMPlatformParameters) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Quotes) > 0 { + for _, e := range m.Quotes { + l = e.Size() + n += 1 + l + sovDevice(uint64(l)) + } + } + if len(m.Pcrs) > 0 { + for _, e := range m.Pcrs { + l = e.Size() + n += 1 + l + sovDevice(uint64(l)) + } + } + l = len(m.EventLog) + if l > 0 { + n += 1 + l + sovDevice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *TPMPlatformAttestation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Nonce) + if l > 0 { + n += 1 + l + sovDevice(uint64(l)) + } + if m.PlatformParameters != nil { + l = m.PlatformParameters.Size() + n += 1 + l + sovDevice(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -1099,6 +1602,10 @@ func (m *DeviceProfile) Size() (n int) { if l > 0 { n += 1 + l + sovDevice(uint64(l)) } + l = len(m.ExternalId) + if l > 0 { + n += 1 + l + sovDevice(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2006,9 +2513,475 @@ func (m *DeviceCollectedData) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OsVersion", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field OsVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OsVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OsBuild", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OsBuild = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OsUsername", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OsUsername = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JamfBinaryVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.JamfBinaryVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MacosEnrollmentProfiles", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MacosEnrollmentProfiles = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ReportedAssetTag", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ReportedAssetTag = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SystemSerialNumber", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SystemSerialNumber = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BaseBoardSerialNumber", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BaseBoardSerialNumber = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TpmPlatformAttestation", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TpmPlatformAttestation == nil { + m.TpmPlatformAttestation = &TPMPlatformAttestation{} + } + if err := m.TpmPlatformAttestation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipDevice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthDevice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TPMPCR) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TPMPCR: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TPMPCR: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Digest", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Digest = append(m.Digest[:0], dAtA[iNdEx:postIndex]...) + if m.Digest == nil { + m.Digest = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DigestAlg", wireType) + } + m.DigestAlg = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DigestAlg |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipDevice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthDevice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TPMQuote) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TPMQuote: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TPMQuote: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Quote", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDevice @@ -2018,29 +2991,31 @@ func (m *DeviceCollectedData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthDevice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthDevice } if postIndex > l { return io.ErrUnexpectedEOF } - m.OsVersion = string(dAtA[iNdEx:postIndex]) + m.Quote = append(m.Quote[:0], dAtA[iNdEx:postIndex]...) + if m.Quote == nil { + m.Quote = []byte{} + } iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OsBuild", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDevice @@ -2050,61 +3025,82 @@ func (m *DeviceCollectedData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthDevice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthDevice } if postIndex > l { return io.ErrUnexpectedEOF } - m.OsBuild = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OsUsername", wireType) + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowDevice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipDevice(dAtA[iNdEx:]) + if err != nil { + return err } - intStringLen := int(stringLen) - if intStringLen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthDevice } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthDevice + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TPMPlatformParameters) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.OsUsername = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 9: + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TPMPlatformParameters: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TPMPlatformParameters: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JamfBinaryVersion", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Quotes", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDevice @@ -2114,29 +3110,31 @@ func (m *DeviceCollectedData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthDevice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthDevice } if postIndex > l { return io.ErrUnexpectedEOF } - m.JamfBinaryVersion = string(dAtA[iNdEx:postIndex]) + m.Quotes = append(m.Quotes, &TPMQuote{}) + if err := m.Quotes[len(m.Quotes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 10: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MacosEnrollmentProfiles", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Pcrs", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDevice @@ -2146,29 +3144,31 @@ func (m *DeviceCollectedData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthDevice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthDevice } if postIndex > l { return io.ErrUnexpectedEOF } - m.MacosEnrollmentProfiles = string(dAtA[iNdEx:postIndex]) + m.Pcrs = append(m.Pcrs, &TPMPCR{}) + if err := m.Pcrs[len(m.Pcrs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 11: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReportedAssetTag", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field EventLog", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDevice @@ -2178,29 +3178,82 @@ func (m *DeviceCollectedData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthDevice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthDevice } if postIndex > l { return io.ErrUnexpectedEOF } - m.ReportedAssetTag = string(dAtA[iNdEx:postIndex]) + m.EventLog = append(m.EventLog[:0], dAtA[iNdEx:postIndex]...) + if m.EventLog == nil { + m.EventLog = []byte{} + } iNdEx = postIndex - case 12: + default: + iNdEx = preIndex + skippy, err := skipDevice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthDevice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TPMPlatformAttestation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TPMPlatformAttestation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TPMPlatformAttestation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SystemSerialNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Nonce", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDevice @@ -2210,29 +3263,31 @@ func (m *DeviceCollectedData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthDevice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthDevice } if postIndex > l { return io.ErrUnexpectedEOF } - m.SystemSerialNumber = string(dAtA[iNdEx:postIndex]) + m.Nonce = append(m.Nonce[:0], dAtA[iNdEx:postIndex]...) + if m.Nonce == nil { + m.Nonce = []byte{} + } iNdEx = postIndex - case 13: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BaseBoardSerialNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PlatformParameters", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowDevice @@ -2242,23 +3297,27 @@ func (m *DeviceCollectedData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthDevice } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthDevice } if postIndex > l { return io.ErrUnexpectedEOF } - m.BaseBoardSerialNumber = string(dAtA[iNdEx:postIndex]) + if m.PlatformParameters == nil { + m.PlatformParameters = &TPMPlatformParameters{} + } + if err := m.PlatformParameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -2622,6 +3681,38 @@ func (m *DeviceProfile) Unmarshal(dAtA []byte) error { } m.JamfBinaryVersion = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExternalId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDevice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDevice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExternalId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipDevice(dAtA[iNdEx:]) diff --git a/api/types/device_test.go b/api/types/device_test.go index 1eba2fa46536e..48479664fd1d0 100644 --- a/api/types/device_test.go +++ b/api/types/device_test.go @@ -15,6 +15,7 @@ package types import ( + "crypto" "testing" "time" @@ -24,80 +25,9 @@ import ( "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/gravitational/teleport/api/defaults" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" ) -// TestUnmarshalDevice tests that devices can be successfully -// unmarshalled from YAML and JSON. -func TestUnmarshalDevice(t *testing.T) { - for _, tc := range []struct { - desc string - input string - errorContains string - expected *DeviceV1 - }{ - { - desc: "success", - input: ` -{ - "kind": "device", - "version": "v1", - "metadata": { - "name": "xaa" - }, - "spec": { - "asset_tag": "mymachine", - "os_type": "macos", - "enroll_status": "enrolled" - } -}`, - expected: &DeviceV1{ - ResourceHeader: ResourceHeader{ - Kind: KindDevice, - Version: "v1", - Metadata: Metadata{ - Namespace: defaults.Namespace, - Name: "xaa", - }, - }, - Spec: &DeviceSpec{ - OsType: "macos", - AssetTag: "mymachine", - EnrollStatus: "enrolled", - }, - }, - }, - { - desc: "fail string as num", - errorContains: `cannot unmarshal number`, - input: ` -{ - "kind": "device", - "version": "v1", - "metadata": { - "name": "secretid" - }, - "spec": { - "asset_tag": 4, - "os_type": "macos", - "enroll_status": "enrolled" - } -}`, - }, - } { - t.Run(tc.desc, func(t *testing.T) { - out, err := UnmarshalDevice([]byte(tc.input)) - if tc.errorContains != "" { - require.ErrorContains(t, err, tc.errorContains, "error from UnmarshalDevice does not contain the expected string") - return - } - require.NoError(t, err, "UnmarshalDevice returned unexpected error") - require.Equal(t, tc.expected, out, "unmarshalled device does not match what was expected") - }) - } -} - func TestDeviceConversions_toAndFrom(t *testing.T) { t1 := time.UnixMilli(1680276526972000) // Fri Mar 31 2023 15:28:46 UTC t11 := t1.Add(100 * time.Millisecond) @@ -142,6 +72,34 @@ func TestDeviceConversions_toAndFrom(t *testing.T) { ReportedAssetTag: assetTag + "-reported", SystemSerialNumber: assetTag + "-system", BaseBoardSerialNumber: assetTag + "-board", + TpmPlatformAttestation: &devicepb.TPMPlatformAttestation{ + Nonce: []byte("foo-bar-bizz"), + PlatformParameters: &devicepb.TPMPlatformParameters{ + EventLog: []byte("dummy-event-log"), + Quotes: []*devicepb.TPMQuote{ + { + Quote: []byte("fake-quote-1"), + Signature: []byte("fake-signature-1"), + }, + { + Quote: []byte("fake-quote-2"), + Signature: []byte("fake-signature-2"), + }, + }, + Pcrs: []*devicepb.TPMPCR{ + { + Index: 0, + Digest: []byte("fake-sha1-digest"), + DigestAlg: uint64(crypto.SHA1), + }, + { + Index: 1, + Digest: []byte("fake-sha256-digest"), + DigestAlg: uint64(crypto.SHA256), + }, + }, + }, + }, }, }, Source: &devicepb.DeviceSource{ @@ -155,6 +113,7 @@ func TestDeviceConversions_toAndFrom(t *testing.T) { OsBuild: "22D68", OsUsernames: []string{"admin", "llama"}, JamfBinaryVersion: "9.27", + ExternalId: "99", }, } @@ -177,10 +136,12 @@ func TestResourceAttestationType_toAndFrom(t *testing.T) { t.Parallel() tests := []struct { attestationType string - errorContains string + wantEmpty bool + wantErr string }{ { attestationType: "unspecified", + wantEmpty: true, }, { attestationType: "tpm_ekpub", @@ -193,18 +154,23 @@ func TestResourceAttestationType_toAndFrom(t *testing.T) { }, { attestationType: "quantum_entanglement", - errorContains: "unknown attestation type", + wantErr: "unknown attestation type", }, } for _, tt := range tests { t.Run(tt.attestationType, func(t *testing.T) { asEnum, err := ResourceDeviceAttestationTypeFromString(tt.attestationType) - if tt.errorContains != "" { - require.ErrorContains(t, err, tt.errorContains) + if tt.wantErr != "" { + require.ErrorContains(t, err, tt.wantErr, "ResourceDeviceAttestationTypeFromString error mismatch") return } + got := ResourceDeviceAttestationTypeToString(asEnum) - require.Equal(t, tt.attestationType, got) + want := tt.attestationType + if tt.wantEmpty { + want = "" + } + require.Equal(t, want, got, "ResourceDeviceAttestationTypeToString mismatch") }) } } diff --git a/api/types/fuzz_test.go b/api/types/fuzz_test.go index 2747376bf45cb..c6a81b668cc54 100644 --- a/api/types/fuzz_test.go +++ b/api/types/fuzz_test.go @@ -23,6 +23,11 @@ import ( ) func FuzzParseDuration(f *testing.F) { + f.Add("") + f.Add("300ms") + f.Add("-1.5h") + f.Add("2h45m") + f.Fuzz(func(t *testing.T, s string) { require.NotPanics(t, func() { parseDuration(s) diff --git a/api/types/headlessauthn.go b/api/types/headlessauthn.go index c37a8cd50d28c..c710c4ebfc849 100644 --- a/api/types/headlessauthn.go +++ b/api/types/headlessauthn.go @@ -22,9 +22,8 @@ import ( "github.com/gravitational/trace" ) -// NewHeadlessAuthenticationStub creates a new a headless authentication resource with limited data. -// The stub is used to initiate headless login. -func NewHeadlessAuthenticationStub(name string, expires time.Time) (*HeadlessAuthentication, error) { +// NewHeadlessAuthentication creates a new a headless authentication resource. +func NewHeadlessAuthentication(username, name string, expires time.Time) (*HeadlessAuthentication, error) { ha := &HeadlessAuthentication{ ResourceHeader: ResourceHeader{ Metadata: Metadata{ @@ -32,6 +31,7 @@ func NewHeadlessAuthenticationStub(name string, expires time.Time) (*HeadlessAut Expires: &expires, }, }, + User: username, } return ha, ha.CheckAndSetDefaults() } @@ -47,12 +47,13 @@ func (h *HeadlessAuthentication) CheckAndSetDefaults() error { return trace.BadParameter("headless authentication resource must have non-zero header.metadata.expires") } + if h.User == "" { + return trace.BadParameter("headless authentication resource must have non-empty user") + } + if h.Version == "" { h.Version = V1 } - if h.State == HeadlessAuthenticationState_HEADLESS_AUTHENTICATION_STATE_UNSPECIFIED { - h.State = HeadlessAuthenticationState_HEADLESS_AUTHENTICATION_STATE_PENDING - } return nil } @@ -75,3 +76,97 @@ func (h HeadlessAuthenticationState) Stringify() string { return "unknown" } } + +// IsUnspecified headless authentication state. This usually means the headless +// authentication resource is a headless authentication stub, with limited data. +func (s HeadlessAuthenticationState) IsUnspecified() bool { + return s == HeadlessAuthenticationState_HEADLESS_AUTHENTICATION_STATE_UNSPECIFIED +} + +// IsPending headless authentication state. +func (s HeadlessAuthenticationState) IsPending() bool { + return s == HeadlessAuthenticationState_HEADLESS_AUTHENTICATION_STATE_PENDING +} + +// headlessStateVariants allows iteration of the expected variants +// of HeadlessAuthenticationState. +var headlessStateVariants = [4]HeadlessAuthenticationState{ + HeadlessAuthenticationState_HEADLESS_AUTHENTICATION_STATE_UNSPECIFIED, + HeadlessAuthenticationState_HEADLESS_AUTHENTICATION_STATE_PENDING, + HeadlessAuthenticationState_HEADLESS_AUTHENTICATION_STATE_DENIED, + HeadlessAuthenticationState_HEADLESS_AUTHENTICATION_STATE_APPROVED, +} + +// Parse attempts to interpret a value as a string representation +// of a HeadlessAuthenticationState. +func (s *HeadlessAuthenticationState) Parse(val string) error { + for _, state := range headlessStateVariants { + if state.String() == val { + *s = state + return nil + } + } + return trace.BadParameter("unknown request state: %q", val) +} + +// HeadlessAuthenticationFilter encodes filter params for headless authentications. +type HeadlessAuthenticationFilter struct { + Name string + Username string + State HeadlessAuthenticationState +} + +// key values for map encoding of headless authn filter. +const ( + headlessFilterKeyName = "name" + headlessFilterKeyUsername = "username" + headlessFilterKeyState = "state" +) + +// IntoMap copies HeadlessAuthenticationFilter values into a map. +func (f *HeadlessAuthenticationFilter) IntoMap() map[string]string { + m := make(map[string]string) + if f.Name != "" { + m[headlessFilterKeyName] = f.Name + } + if f.Username != "" { + m[headlessFilterKeyUsername] = f.Username + } + if !f.State.IsUnspecified() { + m[headlessFilterKeyState] = f.State.String() + } + return m +} + +// FromMap copies values from a map into this HeadlessAuthenticationFilter value. +func (f *HeadlessAuthenticationFilter) FromMap(m map[string]string) error { + for key, val := range m { + switch key { + case headlessFilterKeyName: + f.Name = val + case headlessFilterKeyUsername: + f.Username = val + case headlessFilterKeyState: + if err := f.State.Parse(val); err != nil { + return trace.Wrap(err) + } + default: + return trace.BadParameter("unknown filter key %s", key) + } + } + return nil +} + +// Match checks if a given headless authentication matches this filter. +func (f *HeadlessAuthenticationFilter) Match(req HeadlessAuthentication) bool { + if f.Name != "" && req.GetName() != f.Name { + return false + } + if f.Username != "" && req.User != f.Username { + return false + } + if !f.State.IsUnspecified() && req.State != f.State { + return false + } + return true +} diff --git a/api/types/installers/installer.sh.tmpl b/api/types/installers/installer.sh.tmpl index d44a53d81767f..dc75bc407b325 100644 --- a/api/types/installers/installer.sh.tmpl +++ b/api/types/installers/installer.sh.tmpl @@ -28,15 +28,10 @@ on_azure() { PACKAGE_LIST="${PACKAGE_LIST} {{ .TeleportPackage }}-updater" fi - # old versions of ubuntu require that keys get added by `apt-key add`, without - # adding the key apt shows a key signing error when installing teleport. - LEGACY_UBUNTU=false - if [ "$VERSION_CODENAME" = "xenial" ] || [ "$VERSION_CODENAME" = "trusty" ]; then - LEGACY_UBUNTU=true - fi - if [ "$ID" = "debian" ] || [ "$ID" = "ubuntu" ]; then - if [ "$LEGACY_UBUNTU" = true ]; then + # old versions of ubuntu require that keys get added by `apt-key add`, without + # adding the key apt shows a key signing error when installing teleport. + if [ "$VERSION_CODENAME" = "xenial" ] || [ "$VERSION_CODENAME" = "trusty" ]; then curl -o /tmp/teleport-pubkey.asc https://apt.releases.teleport.dev/gpg sudo apt-key add /tmp/teleport-pubkey.asc echo "deb https://apt.releases.teleport.dev/ubuntu ${VERSION_CODENAME?} {{ .RepoChannel }}" | sudo tee /etc/apt/sources.list.d/teleport.list diff --git a/api/types/jamf.go b/api/types/jamf.go index e731d29ea7991..fb3214dfae324 100644 --- a/api/types/jamf.go +++ b/api/types/jamf.go @@ -17,7 +17,6 @@ package types import ( "net/url" "strings" - "time" "github.com/gravitational/trace" "golang.org/x/exp/slices" @@ -39,15 +38,6 @@ var JamfOnMissingActions = []string{ JamfOnMissingDelete, } -const ( - // JamfSyncPeriodPartialDefault is the default value for sync_period_partial - // in inventory entries. - JamfSyncPeriodPartialDefault = 6 * time.Hour - // JamfSyncPeriodFullDefault is the default value for sync_period_full in - // inventory entries. - JamfSyncPeriodFullDefault = 24 * time.Hour -) - // ValidateJamfSpecV1 validates a [JamfSpecV1] instance. func ValidateJamfSpecV1(s *JamfSpecV1) error { switch { @@ -77,15 +67,9 @@ func ValidateJamfSpecV1(s *JamfSpecV1) error { } syncPartial := e.SyncPeriodPartial - if syncPartial == 0 { - syncPartial = Duration(JamfSyncPeriodPartialDefault) - } syncFull := e.SyncPeriodFull - if syncFull == 0 { - syncFull = Duration(JamfSyncPeriodFullDefault) - } - if syncPartial > syncFull { - return trace.BadParameter("inventory[%v]: sync_period_partial is greater than sync_period_full, partial syncs will never happen", i) + if syncFull > 0 && syncPartial >= syncFull { + return trace.BadParameter("inventory[%v]: sync_period_partial is greater or equal to sync_period_full, partial syncs will never happen", i) } } diff --git a/api/types/jamf_test.go b/api/types/jamf_test.go index 017a9899a14ff..962f2c06cb693 100644 --- a/api/types/jamf_test.go +++ b/api/types/jamf_test.go @@ -148,7 +148,7 @@ func TestValidateJamfSpecV1(t *testing.T) { }, } }), - wantErr: "greater than sync_period_full", + wantErr: "greater or equal to sync_period_full", }, { name: "inventory on_missing invalid", @@ -162,6 +162,42 @@ func TestValidateJamfSpecV1(t *testing.T) { }), wantErr: "on_missing", }, + { + name: "inventory sync_partial disabled", + spec: modify(func(spec *types.JamfSpecV1) { + spec.Inventory = []*types.JamfInventoryEntry{ + validEntry, + { + SyncPeriodPartial: -1, + SyncPeriodFull: types.Duration(8 * time.Hour), + }, + } + }), + }, + { + name: "inventory sync_full disabled", + spec: modify(func(spec *types.JamfSpecV1) { + spec.Inventory = []*types.JamfInventoryEntry{ + validEntry, + { + SyncPeriodPartial: types.Duration(12 * time.Hour), + SyncPeriodFull: -1, + }, + } + }), + }, + { + name: "inventory all syncs disabled", + spec: modify(func(spec *types.JamfSpecV1) { + spec.Inventory = []*types.JamfInventoryEntry{ + validEntry, + { + SyncPeriodPartial: 0, + SyncPeriodFull: 0, + }, + } + }), + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/api/types/plugin.go b/api/types/plugin.go index 8756699f3fb1b..223d6778e6939 100644 --- a/api/types/plugin.go +++ b/api/types/plugin.go @@ -40,6 +40,8 @@ const ( PluginTypeJamf = "jamf" // PluginTypeOpsgenie is the Opsgenie access request plugin PluginTypeOpsgenie = "opsgenie" + // PluginTypePagerDuty is the PagerDuty access plugin + PluginTypePagerDuty = "pagerduty" ) // PluginSubkind represents the type of the plugin, e.g., access request, MDM etc. @@ -133,28 +135,36 @@ func (p *PluginV1) CheckAndSetDefaults() error { } case *PluginSpecV1_Opsgenie: if settings.Opsgenie == nil { - return trace.BadParameter("settings must be set") + return trace.BadParameter("missing opsgenie settings") } if err := settings.Opsgenie.CheckAndSetDefaults(); err != nil { return trace.Wrap(err) } - bearer := p.Credentials.GetBearerToken() - if bearer == nil { - return trace.BadParameter("opsgenie plugin must be used with the bearer token credential type") + staticCreds := p.Credentials.GetStaticCredentialsRef() + if staticCreds == nil { + return trace.BadParameter("opsgenie plugin must be used with the static credentials ref type") } - if bearer.Token == "" { - return trace.BadParameter("Token must be specified") + if len(staticCreds.Labels) == 0 { + return trace.BadParameter("labels must be specified") } case *PluginSpecV1_Jamf: - if settings.Jamf.JamfSpec.ApiEndpoint == "" { - return trace.BadParameter("api endpoint must be set") + // Check Jamf settings. + if settings.Jamf == nil { + return trace.BadParameter("missing Jamf settings") + } + if err := settings.Jamf.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) } if p.Credentials == nil { return trace.BadParameter("credentials must be set") } - if p.Credentials.GetIdSecret().Id == "" || p.Credentials.GetIdSecret().Secret == "" { - return trace.BadParameter("Jamf plugin requires Jamf account username and password") + staticCreds := p.Credentials.GetStaticCredentialsRef() + if staticCreds == nil { + return trace.BadParameter("jamf plugin must be used with the static credentials ref type") + } + if len(staticCreds.Labels) == 0 { + return trace.BadParameter("labels must be specified") } case *PluginSpecV1_Okta: // Check settings. @@ -175,6 +185,13 @@ func (p *PluginV1) CheckAndSetDefaults() error { if len(staticCreds.Labels) == 0 { return trace.BadParameter("labels must be specified") } + case *PluginSpecV1_PagerDuty: + if settings.PagerDuty == nil { + return trace.BadParameter("missing PagerDuty settings") + } + if err := settings.PagerDuty.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } default: return trace.BadParameter("settings are not set or have an unknown type") } @@ -311,6 +328,10 @@ func (p *PluginV1) GetType() PluginType { return PluginTypeOkta case *PluginSpecV1_Jamf: return PluginTypeJamf + case *PluginSpecV1_Opsgenie: + return PluginTypeOpsgenie + case *PluginSpecV1_PagerDuty: + return PluginTypePagerDuty default: return PluginTypeUnknown } @@ -342,6 +363,15 @@ func (s *PluginOpsgenieAccessSettings) CheckAndSetDefaults() error { return nil } +// CheckAndSetDefaults validates and set the default values. +func (s *PluginJamfSettings) CheckAndSetDefaults() error { + if s.JamfSpec.ApiEndpoint == "" { + return trace.BadParameter("api endpoint must be set") + } + + return nil +} + // CheckAndSetDefaults validates and set the default values func (c *PluginOAuth2AuthorizationCodeCredentials) CheckAndSetDefaults() error { if c.AuthorizationCode == "" { @@ -354,6 +384,18 @@ func (c *PluginOAuth2AuthorizationCodeCredentials) CheckAndSetDefaults() error { return nil } +// CheckAndSetDefaults validates and set the default PagerDuty values +func (c *PluginPagerDutySettings) CheckAndSetDefaults() error { + if c.ApiEndpoint == "" { + return trace.BadParameter("api_endpoint must be set") + } + + if c.UserEmail == "" { + return trace.BadParameter("user_email must be set") + } + return nil +} + // CheckAndSetDefaults validates and set the default values func (c *PluginOAuth2AccessTokenCredentials) CheckAndSetDefaults() error { if c.AccessToken == "" { diff --git a/api/types/plugin_test.go b/api/types/plugin_test.go index 5c6cd80f90182..d46f755bc32f6 100644 --- a/api/types/plugin_test.go +++ b/api/types/plugin_test.go @@ -109,6 +109,98 @@ func TestPluginOpenAIValidation(t *testing.T) { } } +func TestPluginOpsgenieValidation(t *testing.T) { + testCases := []struct { + name string + settings *PluginSpecV1_Opsgenie + creds *PluginCredentialsV1 + assertErr require.ErrorAssertionFunc + }{ + { + name: "no settings", + settings: &PluginSpecV1_Opsgenie{ + Opsgenie: nil, + }, + creds: nil, + assertErr: func(t require.TestingT, err error, args ...any) { + require.True(t, trace.IsBadParameter(err)) + require.Contains(t, err.Error(), "missing opsgenie settings") + }, + }, + { + name: "no api endpint", + settings: &PluginSpecV1_Opsgenie{ + Opsgenie: &PluginOpsgenieAccessSettings{}, + }, + creds: nil, + assertErr: func(t require.TestingT, err error, args ...any) { + require.True(t, trace.IsBadParameter(err)) + require.Contains(t, err.Error(), "api endpoint url must be set") + }, + }, + { + name: "no static credentials", + settings: &PluginSpecV1_Opsgenie{ + Opsgenie: &PluginOpsgenieAccessSettings{ + ApiEndpoint: "https://test.opsgenie.com", + }, + }, + assertErr: func(t require.TestingT, err error, args ...any) { + require.True(t, trace.IsBadParameter(err)) + require.Contains(t, err.Error(), "must be used with the static credentials ref type") + }, + }, + { + name: "static credentials labels not defined", + settings: &PluginSpecV1_Opsgenie{ + Opsgenie: &PluginOpsgenieAccessSettings{ + ApiEndpoint: "https://test.opsgenie.com", + }, + }, + creds: &PluginCredentialsV1{ + Credentials: &PluginCredentialsV1_StaticCredentialsRef{ + &PluginStaticCredentialsRef{ + Labels: map[string]string{}, + }, + }, + }, + assertErr: func(t require.TestingT, err error, args ...any) { + require.True(t, trace.IsBadParameter(err)) + require.Contains(t, err.Error(), "labels must be specified") + }, + }, + { + name: "valid credentials (static credentials)", + settings: &PluginSpecV1_Opsgenie{ + Opsgenie: &PluginOpsgenieAccessSettings{ + ApiEndpoint: "https://test.opsgenie.com", + }, + }, + creds: &PluginCredentialsV1{ + Credentials: &PluginCredentialsV1_StaticCredentialsRef{ + &PluginStaticCredentialsRef{ + Labels: map[string]string{ + "label1": "value1", + }, + }, + }, + }, + assertErr: func(t require.TestingT, err error, args ...any) { + require.NoError(t, err) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + plugin := NewPluginV1(Metadata{Name: "foobar"}, PluginSpecV1{ + Settings: tc.settings, + }, tc.creds) + tc.assertErr(t, plugin.CheckAndSetDefaults()) + }) + } +} + func TestPluginOktaValidation(t *testing.T) { testCases := []struct { name string @@ -216,3 +308,121 @@ func TestPluginOktaValidation(t *testing.T) { }) } } + +func TestPluginJamfValidation(t *testing.T) { + testCases := []struct { + name string + settings *PluginSpecV1_Jamf + creds *PluginCredentialsV1 + assertErr require.ErrorAssertionFunc + }{ + { + name: "no settings", + settings: &PluginSpecV1_Jamf{ + Jamf: nil, + }, + creds: nil, + assertErr: func(t require.TestingT, err error, args ...any) { + require.True(t, trace.IsBadParameter(err)) + require.Contains(t, err.Error(), "missing Jamf settings") + }, + }, + { + name: "no api Endpoint", + settings: &PluginSpecV1_Jamf{ + Jamf: &PluginJamfSettings{ + JamfSpec: &JamfSpecV1{}, + }, + }, + creds: nil, + assertErr: func(t require.TestingT, err error, args ...any) { + require.True(t, trace.IsBadParameter(err)) + require.Contains(t, err.Error(), "api endpoint must be set") + }, + }, + { + name: "no credentials inner", + settings: &PluginSpecV1_Jamf{ + Jamf: &PluginJamfSettings{ + JamfSpec: &JamfSpecV1{ + ApiEndpoint: "https://api.testjamfserver.com", + }, + }, + }, + creds: &PluginCredentialsV1{}, + assertErr: func(t require.TestingT, err error, args ...any) { + require.True(t, trace.IsBadParameter(err)) + require.Contains(t, err.Error(), "must be used with the static credentials ref type") + }, + }, + { + name: "invalid credential type (oauth2)", + settings: &PluginSpecV1_Jamf{ + Jamf: &PluginJamfSettings{ + JamfSpec: &JamfSpecV1{ + ApiEndpoint: "https://api.testjamfserver.com", + }, + }, + }, + creds: &PluginCredentialsV1{ + Credentials: &PluginCredentialsV1_Oauth2AccessToken{}, + }, + assertErr: func(t require.TestingT, err error, args ...any) { + require.True(t, trace.IsBadParameter(err)) + require.Contains(t, err.Error(), "must be used with the static credentials ref type") + }, + }, + { + name: "invalid credentials (static credentials)", + settings: &PluginSpecV1_Jamf{ + Jamf: &PluginJamfSettings{ + JamfSpec: &JamfSpecV1{ + ApiEndpoint: "https://api.testjamfserver.com", + }, + }, + }, + creds: &PluginCredentialsV1{ + Credentials: &PluginCredentialsV1_StaticCredentialsRef{ + &PluginStaticCredentialsRef{ + Labels: map[string]string{}, + }, + }, + }, + assertErr: func(t require.TestingT, err error, args ...any) { + require.True(t, trace.IsBadParameter(err)) + require.Contains(t, err.Error(), "labels must be specified") + }, + }, + { + name: "valid credentials (static credentials)", + settings: &PluginSpecV1_Jamf{ + Jamf: &PluginJamfSettings{ + JamfSpec: &JamfSpecV1{ + ApiEndpoint: "https://api.testjamfserver.com", + }, + }, + }, + creds: &PluginCredentialsV1{ + Credentials: &PluginCredentialsV1_StaticCredentialsRef{ + &PluginStaticCredentialsRef{ + Labels: map[string]string{ + "label1": "value1", + }, + }, + }, + }, + assertErr: func(t require.TestingT, err error, args ...any) { + require.NoError(t, err) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + plugin := NewPluginV1(Metadata{Name: "foobar"}, PluginSpecV1{ + Settings: tc.settings, + }, tc.creds) + tc.assertErr(t, plugin.CheckAndSetDefaults()) + }) + } +} diff --git a/api/types/remotecluster.go b/api/types/remotecluster.go index 8e3647c53db48..d96834441e107 100644 --- a/api/types/remotecluster.go +++ b/api/types/remotecluster.go @@ -45,6 +45,13 @@ type RemoteCluster interface { // Clone performs a deep copy. Clone() RemoteCluster + + // GetLabel retrieves the label with the provided key. If not found value + // will be empty and ok will be false. + GetLabel(key string) (value string, ok bool) + + // GetAllLabels returns all labels for the remote cluster + GetAllLabels() map[string]string } // NewRemoteCluster is a convenience way to create a RemoteCluster resource. @@ -164,3 +171,16 @@ func (c *RemoteClusterV3) SetName(e string) { func (c *RemoteClusterV3) String() string { return fmt.Sprintf("RemoteCluster(%v, %v)", c.Metadata.Name, c.Status.Connection) } + +// GetLabel retrieves the label with the provided key. If not found value +// will be empty and ok will be false. +func (c *RemoteClusterV3) GetLabel(key string) (value string, ok bool) { + value, ok = c.Metadata.Labels[key] + return value, ok +} + +// GetAllLabels returns all labels for the remote cluster. Remote clusters only +// have static labels. +func (c *RemoteClusterV3) GetAllLabels() map[string]string { + return c.Metadata.Labels +} diff --git a/api/types/resource.go b/api/types/resource.go index 34bf5d2e422f8..c2eb51e0622b7 100644 --- a/api/types/resource.go +++ b/api/types/resource.go @@ -57,9 +57,21 @@ type Resource interface { CheckAndSetDefaults() error } +// IsSystemResource checks to see if the given resource is considered +// part of the teleport system, as opposed to some user created resource +// or preset. +func IsSystemResource(r Resource) bool { + metadata := r.GetMetadata() + if t, ok := metadata.Labels[TeleportInternalResourceType]; ok { + return t == SystemResource + } + return false +} + // ResourceDetails includes details about the resource type ResourceDetails struct { - Hostname string + Hostname string + FriendlyName string } // ResourceWithSecrets includes additional properties which must diff --git a/api/types/resource_ids.go b/api/types/resource_ids.go index 3f10b99647699..1a2df74b6a931 100644 --- a/api/types/resource_ids.go +++ b/api/types/resource_ids.go @@ -52,13 +52,17 @@ func (id *ResourceID) validateK8sSubResource() error { if id.SubResourceName == "" { return trace.BadParameter("resource of kind %q must include a subresource name", id.Kind) } - + isResourceNamespaceScoped := slices.Contains(KubernetesClusterWideResourceKinds, id.Kind) switch split := strings.Split(id.SubResourceName, "/"); { - case len(split) != 2: + case isResourceNamespaceScoped && len(split) != 1: + return trace.BadParameter("subresource %q must follow the following format: ", id.SubResourceName) + case isResourceNamespaceScoped && split[0] == "": + return trace.BadParameter("subresource %q must include a non-empty name: ", id.SubResourceName) + case !isResourceNamespaceScoped && len(split) != 2: return trace.BadParameter("subresource %q must follow the following format: /", id.SubResourceName) - case split[0] == "": + case !isResourceNamespaceScoped && split[0] == "": return trace.BadParameter("subresource %q must include a non-empty namespace: /", id.SubResourceName) - case split[1] == "": + case !isResourceNamespaceScoped && split[1] == "": return trace.BadParameter("subresource %q must include a non-empty name: /", id.SubResourceName) } @@ -93,6 +97,7 @@ func ResourceIDFromString(raw string) (ResourceID, error) { } switch { case slices.Contains(KubernetesResourcesKinds, resourceID.Kind): + isResourceNamespaceScoped := slices.Contains(KubernetesClusterWideResourceKinds, resourceID.Kind) // Kubernetes forbids slashes "/" in Namespaces and Pod names, so it's safe to // explode the resourceID.Name and extract the last two entries as namespace // and name. @@ -102,9 +107,12 @@ func ResourceIDFromString(raw string) (ResourceID, error) { // will fail because, for kind=pod, it's mandatory to present a non-empty // namespace and name. splits := strings.Split(resourceID.Name, "/") - if len(splits) >= 3 { + if !isResourceNamespaceScoped && len(splits) >= 3 { resourceID.Name = strings.Join(splits[:len(splits)-2], "/") resourceID.SubResourceName = strings.Join(splits[len(splits)-2:], "/") + } else if isResourceNamespaceScoped && len(splits) >= 2 { + resourceID.Name = strings.Join(splits[:len(splits)-1], "/") + resourceID.SubResourceName = strings.Join(splits[len(splits)-1:], "/") } } diff --git a/api/types/resource_ids_test.go b/api/types/resource_ids_test.go index f8d5d0ac3447b..07400e35846ad 100644 --- a/api/types/resource_ids_test.go +++ b/api/types/resource_ids_test.go @@ -144,6 +144,281 @@ func TestResourceIDs(t *testing.T) { expected: `["/one/pod/cluster"]`, expectParseError: true, }, + { + desc: "pod resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubePod, + Name: "cluster", + SubResourceName: "namespace/pod*", + }}, + expected: `["/one/pod/cluster/namespace/pod*"]`, + }, + { + desc: "secret resource name with missing namespace", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeSecret, + Name: "cluster", + SubResourceName: "/secret*", + }}, + expected: `["/one/secret/cluster//secret*"]`, + expectParseError: true, + }, + { + desc: "secret resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeSecret, + Name: "cluster", + }}, + expected: `["/one/secret/cluster"]`, + expectParseError: true, + }, + { + desc: "secret resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeSecret, + Name: "cluster", + SubResourceName: "namespace/secret*", + }}, + expected: `["/one/secret/cluster/namespace/secret*"]`, + }, + { + desc: "configmap resource name with missing namespace", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeConfigmap, + Name: "cluster", + SubResourceName: "/configmap*", + }}, + expected: `["/one/configmap/cluster//configmap*"]`, + expectParseError: true, + }, + { + desc: "configmap resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeConfigmap, + Name: "cluster", + }}, + expected: `["/one/configmap/cluster"]`, + expectParseError: true, + }, + { + desc: "configmap resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeConfigmap, + Name: "cluster", + SubResourceName: "namespace/configmap*", + }}, + expected: `["/one/configmap/cluster/namespace/configmap*"]`, + }, + { + desc: "service resource name with missing namespace", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeService, + Name: "cluster", + SubResourceName: "/service*", + }}, + expected: `["/one/service/cluster//service*"]`, + expectParseError: true, + }, + { + desc: "service resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeService, + Name: "cluster", + }}, + expected: `["/one/service/cluster"]`, + expectParseError: true, + }, + { + desc: "service resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeService, + Name: "cluster", + SubResourceName: "namespace/service*", + }}, + expected: `["/one/service/cluster/namespace/service*"]`, + }, + { + desc: "service_account resource name with missing namespace", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeServiceAccount, + Name: "cluster", + SubResourceName: "/service_account*", + }}, + expected: `["/one/serviceaccount/cluster//service_account*"]`, + expectParseError: true, + }, + { + desc: "service_account resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeServiceAccount, + Name: "cluster", + }}, + expected: `["/one/serviceaccount/cluster"]`, + expectParseError: true, + }, + { + desc: "service_account resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeServiceAccount, + Name: "cluster", + SubResourceName: "namespace/service_account*", + }}, + expected: `["/one/serviceaccount/cluster/namespace/service_account*"]`, + }, + { + desc: "persistent_volume_claim resource name with missing namespace", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubePersistentVolumeClaim, + Name: "cluster", + SubResourceName: "/persistent_volume_claim*", + }}, + expected: `["/one/persistentvolumeclaim/cluster//persistent_volume_claim*"]`, + expectParseError: true, + }, + { + desc: "persistent_volume_claim resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubePersistentVolumeClaim, + Name: "cluster", + }}, + expected: `["/one/persistentvolumeclaim/cluster"]`, + expectParseError: true, + }, + { + desc: "namespace resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeNamespace, + Name: "cluster", + }}, + expected: `["/one/namespace/cluster"]`, + expectParseError: true, + }, + { + desc: "namespace resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeNamespace, + Name: "cluster", + SubResourceName: "namespace*", + }}, + expected: `["/one/namespace/cluster/namespace*"]`, + }, + { + desc: "kube_node resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeNode, + Name: "cluster", + }}, + expected: `["/one/kube_node/cluster"]`, + expectParseError: true, + }, + { + desc: "kube_node resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeNode, + Name: "cluster", + SubResourceName: "kube_node*", + }}, + expected: `["/one/kube_node/cluster/kube_node*"]`, + }, + { + desc: "persistent_volume resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubePersistentVolume, + Name: "cluster", + }}, + expected: `["/one/persistentvolume/cluster"]`, + expectParseError: true, + }, + { + desc: "persistent_volume resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubePersistentVolume, + Name: "cluster", + SubResourceName: "persistent_volume*", + }}, + expected: `["/one/persistentvolume/cluster/persistent_volume*"]`, + }, + { + desc: "cluster_role resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeClusterRole, + Name: "cluster", + }}, + expected: `["/one/clusterrole/cluster"]`, + expectParseError: true, + }, + { + desc: "cluster_role resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeClusterRole, + Name: "cluster", + SubResourceName: "cluster_role*", + }}, + expected: `["/one/clusterrole/cluster/cluster_role*"]`, + }, + { + desc: "cluster_role_binding resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeClusterRoleBinding, + Name: "cluster", + }}, + expected: `["/one/clusterrolebinding/cluster"]`, + expectParseError: true, + }, + { + desc: "cluster_role_binding resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeClusterRoleBinding, + Name: "cluster", + SubResourceName: "cluster_role_binding*", + }}, + expected: `["/one/clusterrolebinding/cluster/cluster_role_binding*"]`, + }, + { + desc: "certificate_signing_request resource name with missing namespace and pod name", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeCertificateSigningRequest, + Name: "cluster", + }}, + expected: `["/one/certificatesigningrequest/cluster"]`, + expectParseError: true, + }, + { + desc: "certificate_signing_request resource name in cluster with slash", + in: []ResourceID{{ + ClusterName: "one", + Kind: KindKubeCertificateSigningRequest, + Name: "cluster", + SubResourceName: "certificate_signing_request*", + }}, + expected: `["/one/certificatesigningrequest/cluster/certificate_signing_request*"]`, + }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { diff --git a/api/types/role.go b/api/types/role.go index 0ed850262709f..c44846abc7ec5 100644 --- a/api/types/role.go +++ b/api/types/role.go @@ -71,6 +71,13 @@ type Role interface { // SetNamespaces sets a list of namespaces this role is allowed or denied access to. SetNamespaces(RoleConditionType, []string) + // GetLabelMatchers gets the LabelMatchers that match labels of resources of + // type [kind] this role is allowed or denied access to. + GetLabelMatchers(rct RoleConditionType, kind string) (LabelMatchers, error) + // SetLabelMatchers sets the LabelMatchers that match labels of resources of + // type [kind] this role is allowed or denied access to. + SetLabelMatchers(rct RoleConditionType, kind string, labelMatchers LabelMatchers) error + // GetNodeLabels gets the map of node labels this role is allowed or denied access to. GetNodeLabels(RoleConditionType) Labels // SetNodeLabels sets the map of node labels this role is allowed or denied access to. @@ -237,11 +244,17 @@ type Role interface { SetGroupLabels(RoleConditionType, Labels) } -// NewRole constructs new standard V6 role. -// This creates a V6 role with V4+ RBAC semantics. +// NewRole constructs new standard V7 role. +// This creates a V7 role with V4+ RBAC semantics. func NewRole(name string, spec RoleSpecV6) (Role, error) { + role, err := NewRoleWithVersion(name, V7, spec) + return role, trace.Wrap(err) +} + +// NewRoleWithVersion constructs new standard role with the version specified. +func NewRoleWithVersion(name string, version string, spec RoleSpecV6) (Role, error) { role := RoleV6{ - Version: V6, + Version: version, Metadata: Metadata{ Name: name, }, @@ -383,11 +396,53 @@ func (r *RoleV6) SetKubeGroups(rct RoleConditionType, groups []string) { // access to. func (r *RoleV6) GetKubeResources(rct RoleConditionType) []KubernetesResource { if rct == Allow { - return r.Spec.Allow.KubernetesResources + return r.convertKubernetesResourcesBetweenRoleVersions(r.Spec.Allow.KubernetesResources) } return r.Spec.Deny.KubernetesResources } +// convertKubeResourcesBetweenRoleVersions converts Kubernetes resources between role versions. +// This is required to keep compatibility between role versions to avoid breaking changes +// when upgrading Teleport. +// For roles v7, it returns the list as it is. +// For older roles 0 { + if len(r.Spec.Allow.KubernetesResources) == 0 && r.HasLabelMatchers(Allow, KindKubernetesCluster) { r.Spec.Allow.KubernetesResources = []KubernetesResource{ { Kind: KindKubePod, @@ -941,12 +997,27 @@ func (r *RoleV6) CheckAndSetDefaults() error { } } - if err := validateRoleSpecKubeResources(r.Spec); err != nil { + if err := validateRoleSpecKubeResources(r.Version, r.Spec); err != nil { return trace.Wrap(err) } case V6: - if err := validateRoleSpecKubeResources(r.Spec); err != nil { + if err := validateRoleSpecKubeResources(r.Version, r.Spec); err != nil { + return trace.Wrap(err) + } + case V7: + // Kubernetes resources default to {kind:*, name:*, namespace:*} for v7 roles. + if len(r.Spec.Allow.KubernetesResources) == 0 && r.HasLabelMatchers(Allow, KindKubernetesCluster) { + r.Spec.Allow.KubernetesResources = []KubernetesResource{ + { + Kind: Wildcard, + Namespace: Wildcard, + Name: Wildcard, + }, + } + } + + if err := validateRoleSpecKubeResources(r.Version, r.Spec); err != nil { return trace.Wrap(err) } default: @@ -1505,11 +1576,11 @@ func (r *RoleV6) SetPreviewAsRoles(rct RoleConditionType, roles []string) { // validateRoleSpecKubeResources validates the Allow/Deny Kubernetes Resources // entries. -func validateRoleSpecKubeResources(spec RoleSpecV6) error { - if err := validateKubeResources(spec.Allow.KubernetesResources); err != nil { +func validateRoleSpecKubeResources(version string, spec RoleSpecV6) error { + if err := validateKubeResources(version, spec.Allow.KubernetesResources); err != nil { return trace.Wrap(err) } - if err := validateKubeResources(spec.Deny.KubernetesResources); err != nil { + if err := validateKubeResources(version, spec.Deny.KubernetesResources); err != nil { return trace.Wrap(err) } return nil @@ -1519,12 +1590,23 @@ func validateRoleSpecKubeResources(spec RoleSpecV6) error { // - Kind belongs to KubernetesResourcesKinds // - Name is not empty // - Namespace is not empty -func validateKubeResources(kubeResources []KubernetesResource) error { +func validateKubeResources(roleVersion string, kubeResources []KubernetesResource) error { for _, kubeResource := range kubeResources { - if !slices.Contains(KubernetesResourcesKinds, kubeResource.Kind) { - return trace.BadParameter("KubernetesResource kind %q is invalid or unsupported; Supported: %v", kubeResource.Kind, KubernetesResourcesKinds) + if !slices.Contains(KubernetesResourcesKinds, kubeResource.Kind) && kubeResource.Kind != Wildcard { + return trace.BadParameter("KubernetesResource kind %q is invalid or unsupported; Supported: %v", kubeResource.Kind, append([]string{Wildcard}, KubernetesResourcesKinds...)) + } + // Only Pod resources are supported in role version <=V6. + // This is mandatory because we must append the other resources to the + // kubernetes resources. + switch roleVersion { + // Teleport does not support role versions < v3. + case V6, V5, V4, V3: + if kubeResource.Kind != KindKubePod { + return trace.BadParameter("KubernetesResource %q is not supported in role version %q. Upgrade the role version to %q", kubeResource.Kind, roleVersion, V7) + } } - if len(kubeResource.Namespace) == 0 { + + if len(kubeResource.Namespace) == 0 && !slices.Contains(KubernetesClusterWideResourceKinds, kubeResource.Kind) { return trace.BadParameter("KubernetesResource must include Namespace") } if len(kubeResource.Name) == 0 { @@ -1557,3 +1639,212 @@ func (a AccessReviewConditions) IsEmpty() bool { len(a.Roles) == 0 && len(a.Where) == 0 } + +// LabelMatchers holds the role label matchers and label expression that are +// used to match resource labels of a specific resource kind and condition +// (allow/deny). +type LabelMatchers struct { + Labels Labels + Expression string +} + +// Empty returns true if all elements of the LabelMatchers are empty/unset. +func (l LabelMatchers) Empty() bool { + return len(l.Labels) == 0 && len(l.Expression) == 0 +} + +// GetLabelMatchers gets the LabelMatchers that match labels of resources of +// type [kind] this role is allowed or denied access to. +func (r *RoleV6) GetLabelMatchers(rct RoleConditionType, kind string) (LabelMatchers, error) { + var cond *RoleConditions + if rct == Allow { + cond = &r.Spec.Allow + } else { + cond = &r.Spec.Deny + } + switch kind { + case KindRemoteCluster: + return LabelMatchers{cond.ClusterLabels, cond.ClusterLabelsExpression}, nil + case KindNode: + return LabelMatchers{cond.NodeLabels, cond.NodeLabelsExpression}, nil + case KindKubernetesCluster: + return LabelMatchers{cond.KubernetesLabels, cond.KubernetesLabelsExpression}, nil + case KindApp: + return LabelMatchers{cond.AppLabels, cond.AppLabelsExpression}, nil + case KindDatabase: + return LabelMatchers{cond.DatabaseLabels, cond.DatabaseLabelsExpression}, nil + case KindDatabaseService: + return LabelMatchers{cond.DatabaseServiceLabels, cond.DatabaseServiceLabelsExpression}, nil + case KindWindowsDesktop: + return LabelMatchers{cond.WindowsDesktopLabels, cond.WindowsDesktopLabelsExpression}, nil + case KindWindowsDesktopService: + return LabelMatchers{cond.WindowsDesktopLabels, cond.WindowsDesktopLabelsExpression}, nil + case KindUserGroup: + return LabelMatchers{cond.GroupLabels, cond.GroupLabelsExpression}, nil + } + return LabelMatchers{}, trace.BadParameter("can't get label matchers for resource kind %q", kind) +} + +// SetLabelMatchers sets the LabelMatchers that match labels of resources of +// type [kind] this role is allowed or denied access to. +func (r *RoleV6) SetLabelMatchers(rct RoleConditionType, kind string, labelMatchers LabelMatchers) error { + var cond *RoleConditions + if rct == Allow { + cond = &r.Spec.Allow + } else { + cond = &r.Spec.Deny + } + switch kind { + case KindRemoteCluster: + cond.ClusterLabels = labelMatchers.Labels + cond.ClusterLabelsExpression = labelMatchers.Expression + return nil + case KindNode: + cond.NodeLabels = labelMatchers.Labels + cond.NodeLabelsExpression = labelMatchers.Expression + return nil + case KindKubernetesCluster: + cond.KubernetesLabels = labelMatchers.Labels + cond.KubernetesLabelsExpression = labelMatchers.Expression + return nil + case KindApp: + cond.AppLabels = labelMatchers.Labels + cond.AppLabelsExpression = labelMatchers.Expression + return nil + case KindDatabase: + cond.DatabaseLabels = labelMatchers.Labels + cond.DatabaseLabelsExpression = labelMatchers.Expression + return nil + case KindDatabaseService: + cond.DatabaseServiceLabels = labelMatchers.Labels + cond.DatabaseServiceLabelsExpression = labelMatchers.Expression + return nil + case KindWindowsDesktop: + cond.WindowsDesktopLabels = labelMatchers.Labels + cond.WindowsDesktopLabelsExpression = labelMatchers.Expression + return nil + case KindWindowsDesktopService: + cond.WindowsDesktopLabels = labelMatchers.Labels + cond.WindowsDesktopLabelsExpression = labelMatchers.Expression + return nil + case KindUserGroup: + cond.GroupLabels = labelMatchers.Labels + cond.GroupLabelsExpression = labelMatchers.Expression + return nil + } + return trace.BadParameter("can't set label matchers for resource kind %q", kind) +} + +// HasLabelMatchers returns true if the role has label matchers for the +// specified resource kind and condition (allow/deny). +// If the kind is not supported, false is returned. +func (r *RoleV6) HasLabelMatchers(rct RoleConditionType, kind string) bool { + lm, err := r.GetLabelMatchers(rct, kind) + return err == nil && !lm.Empty() +} + +// LabelMatcherKinds is the complete list of resource kinds that support label +// matchers. +var LabelMatcherKinds = []string{ + KindRemoteCluster, + KindNode, + KindKubernetesCluster, + KindApp, + KindDatabase, + KindDatabaseService, + KindWindowsDesktop, + KindWindowsDesktopService, + KindUserGroup, +} + +const ( + createHostUserModeOffString = "off" + createHostUserModeDropString = "drop" + createHostUserModeKeepString = "keep" +) + +func (h CreateHostUserMode) encode() (string, error) { + switch h { + case CreateHostUserMode_HOST_USER_MODE_UNSPECIFIED: + return "", nil + case CreateHostUserMode_HOST_USER_MODE_OFF: + return createHostUserModeOffString, nil + case CreateHostUserMode_HOST_USER_MODE_DROP: + return createHostUserModeDropString, nil + case CreateHostUserMode_HOST_USER_MODE_KEEP: + return createHostUserModeKeepString, nil + } + return "", trace.BadParameter("invalid host user mode %v", h) +} + +func (h *CreateHostUserMode) decode(val any) error { + var valS string + switch val := val.(type) { + case string: + valS = val + case bool: + if val { + return trace.BadParameter("create_host_user_mode cannot be true, got %v", val) + } + valS = createHostUserModeOffString + default: + return trace.BadParameter("bad value type %T, expected string", val) + } + + switch valS { + case "": + *h = CreateHostUserMode_HOST_USER_MODE_UNSPECIFIED + case createHostUserModeOffString: + *h = CreateHostUserMode_HOST_USER_MODE_OFF + case createHostUserModeDropString: + *h = CreateHostUserMode_HOST_USER_MODE_DROP + case createHostUserModeKeepString: + *h = CreateHostUserMode_HOST_USER_MODE_KEEP + default: + return trace.BadParameter("invalid host user mode %v", val) + } + return nil +} + +// UnmarshalYAML supports parsing CreateHostUserMode from string. +func (h *CreateHostUserMode) UnmarshalYAML(unmarshal func(interface{}) error) error { + var val interface{} + err := unmarshal(&val) + if err != nil { + return trace.Wrap(err) + } + + err = h.decode(val) + return trace.Wrap(err) +} + +// MarshalYAML marshals CreateHostUserMode to yaml. +func (h *CreateHostUserMode) MarshalYAML() (interface{}, error) { + val, err := h.encode() + if err != nil { + return nil, trace.Wrap(err) + } + return val, nil +} + +// MarshalJSON marshals CreateHostUserMode to json bytes. +func (h *CreateHostUserMode) MarshalJSON() ([]byte, error) { + val, err := h.encode() + if err != nil { + return nil, trace.Wrap(err) + } + out, err := json.Marshal(val) + return out, trace.Wrap(err) +} + +// UnmarshalJSON supports parsing CreateHostUserMode from string. +func (h *CreateHostUserMode) UnmarshalJSON(data []byte) error { + var val interface{} + err := json.Unmarshal(data, &val) + if err != nil { + return trace.Wrap(err) + } + + err = h.decode(val) + return trace.Wrap(err) +} diff --git a/api/types/role_test.go b/api/types/role_test.go index 5441edfccc9fe..073caafbfda68 100644 --- a/api/types/role_test.go +++ b/api/types/role_test.go @@ -17,9 +17,12 @@ limitations under the License. package types import ( + "encoding/json" + "fmt" "testing" "github.com/stretchr/testify/require" + "gopkg.in/yaml.v2" "github.com/gravitational/teleport/api/types/wrappers" ) @@ -143,3 +146,283 @@ func TestAccessReviewConditionsIsEmpty(t *testing.T) { }) } } + +func TestRole_GetKubeResources(t *testing.T) { + kubeLabels := Labels{ + Wildcard: {Wildcard}, + } + labelsExpression := "contains(user.spec.traits[\"groups\"], \"prod\")" + type args struct { + version string + labels Labels + labelsExpression string + resources []KubernetesResource + } + tests := []struct { + name string + args args + want []KubernetesResource + assertErrorCreation require.ErrorAssertionFunc + }{ + { + name: "v7 with error", + args: args{ + version: V7, + labels: kubeLabels, + resources: []KubernetesResource{ + { + Kind: "invalid resource", + Namespace: "test", + Name: "test", + }, + }, + }, + assertErrorCreation: require.Error, + }, + { + name: "v7", + args: args{ + version: V7, + labels: kubeLabels, + resources: []KubernetesResource{ + { + Kind: KindKubePod, + Namespace: "test", + Name: "test", + }, + }, + }, + assertErrorCreation: require.NoError, + want: []KubernetesResource{ + { + Kind: KindKubePod, + Namespace: "test", + Name: "test", + }, + }, + }, + { + name: "v7 with labels expression", + args: args{ + version: V7, + labelsExpression: labelsExpression, + resources: []KubernetesResource{ + { + Kind: KindKubePod, + Namespace: "test", + Name: "test", + }, + }, + }, + assertErrorCreation: require.NoError, + want: []KubernetesResource{ + { + Kind: KindKubePod, + Namespace: "test", + Name: "test", + }, + }, + }, + { + name: "v6 to v7 without wildcard; labels expression", + args: args{ + version: V6, + labelsExpression: labelsExpression, + resources: []KubernetesResource{ + { + Kind: KindKubePod, + Namespace: "test", + Name: "test", + }, + }, + }, + assertErrorCreation: require.NoError, + want: append([]KubernetesResource{ + { + Kind: KindKubePod, + Namespace: "test", + Name: "test", + }, + }, + appendV7KubeResources()...), + }, + { + name: "v6 to v7 with wildcard", + args: args{ + version: V6, + labels: kubeLabels, + resources: []KubernetesResource{ + { + Kind: KindKubePod, + Namespace: Wildcard, + Name: Wildcard, + }, + }, + }, + assertErrorCreation: require.NoError, + want: []KubernetesResource{ + { + Kind: Wildcard, + Namespace: Wildcard, + Name: Wildcard, + }, + }, + }, + { + name: "v6 to v7 without wildcard", + args: args{ + version: V6, + labels: kubeLabels, + resources: []KubernetesResource{ + { + Kind: KindKubePod, + Namespace: "test", + Name: "test", + }, + }, + }, + assertErrorCreation: require.NoError, + want: append([]KubernetesResource{ + { + Kind: KindKubePod, + Namespace: "test", + Name: "test", + }, + }, + appendV7KubeResources()...), + }, + { + name: "v5 to v7: populate with defaults.", + args: args{ + version: V5, + labels: kubeLabels, + resources: nil, + }, + assertErrorCreation: require.NoError, + want: []KubernetesResource{ + { + Kind: Wildcard, + Namespace: Wildcard, + Name: Wildcard, + }, + }, + }, + { + name: "v5 to v7 without kube labels", + args: args{ + version: V5, + resources: nil, + }, + assertErrorCreation: require.NoError, + want: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r, err := NewRoleWithVersion( + "test", + tt.args.version, + RoleSpecV6{ + Allow: RoleConditions{ + Namespaces: []string{"default"}, + KubernetesLabels: tt.args.labels, + KubernetesResources: tt.args.resources, + KubernetesLabelsExpression: tt.args.labelsExpression, + }, + }, + ) + tt.assertErrorCreation(t, err) + if err != nil { + return + } + got := r.GetKubeResources(Allow) + require.Equal(t, tt.want, got) + got = r.GetKubeResources(Deny) + require.Empty(t, got) + }) + } +} + +func appendV7KubeResources() []KubernetesResource { + resources := []KubernetesResource{} + // append other kubernetes resources + for _, resource := range KubernetesResourcesKinds { + if resource == KindKubePod { + continue + } + resources = append(resources, KubernetesResource{ + Kind: resource, + Namespace: Wildcard, + Name: Wildcard, + }, + ) + } + return resources +} + +func TestMarshallCreateHostUserModeJSON(t *testing.T) { + for _, tc := range []struct { + input CreateHostUserMode + expected string + }{ + {input: CreateHostUserMode_HOST_USER_MODE_OFF, expected: "off"}, + {input: CreateHostUserMode_HOST_USER_MODE_UNSPECIFIED, expected: ""}, + {input: CreateHostUserMode_HOST_USER_MODE_DROP, expected: "drop"}, + {input: CreateHostUserMode_HOST_USER_MODE_KEEP, expected: "keep"}, + } { + got, err := json.Marshal(&tc.input) + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("%q", tc.expected), string(got)) + } +} + +func TestMarshallCreateHostUserModeYAML(t *testing.T) { + for _, tc := range []struct { + input CreateHostUserMode + expected string + }{ + {input: CreateHostUserMode_HOST_USER_MODE_OFF, expected: "\"off\""}, + {input: CreateHostUserMode_HOST_USER_MODE_UNSPECIFIED, expected: "\"\""}, + {input: CreateHostUserMode_HOST_USER_MODE_DROP, expected: "drop"}, + {input: CreateHostUserMode_HOST_USER_MODE_KEEP, expected: "keep"}, + } { + got, err := yaml.Marshal(&tc.input) + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("%s\n", tc.expected), string(got)) + } +} + +func TestUnmarshallCreateHostUserModeJSON(t *testing.T) { + for _, tc := range []struct { + expected CreateHostUserMode + input string + }{ + {expected: CreateHostUserMode_HOST_USER_MODE_OFF, input: "off"}, + {expected: CreateHostUserMode_HOST_USER_MODE_UNSPECIFIED, input: ""}, + {expected: CreateHostUserMode_HOST_USER_MODE_DROP, input: "drop"}, + {expected: CreateHostUserMode_HOST_USER_MODE_KEEP, input: "keep"}, + } { + var got CreateHostUserMode + err := json.Unmarshal([]byte(fmt.Sprintf("%q", tc.input)), &got) + require.NoError(t, err) + require.Equal(t, tc.expected, got) + } +} + +func TestUnmarshallCreateHostUserModeYAML(t *testing.T) { + for _, tc := range []struct { + expected CreateHostUserMode + input string + }{ + {expected: CreateHostUserMode_HOST_USER_MODE_OFF, input: "\"off\""}, + {expected: CreateHostUserMode_HOST_USER_MODE_OFF, input: "off"}, + {expected: CreateHostUserMode_HOST_USER_MODE_UNSPECIFIED, input: "\"\""}, + {expected: CreateHostUserMode_HOST_USER_MODE_DROP, input: "drop"}, + {expected: CreateHostUserMode_HOST_USER_MODE_KEEP, input: "keep"}, + } { + var got CreateHostUserMode + err := yaml.Unmarshal([]byte(tc.input), &got) + require.NoError(t, err) + require.Equal(t, tc.expected, got) + } +} diff --git a/api/types/session_tracker.go b/api/types/session_tracker.go index 8c2866c178258..b96428a601c67 100644 --- a/api/types/session_tracker.go +++ b/api/types/session_tracker.go @@ -20,6 +20,7 @@ import ( "time" "github.com/gravitational/trace" + "golang.org/x/exp/slices" "github.com/gravitational/teleport/api/defaults" ) @@ -94,7 +95,7 @@ type SessionTracker interface { RemoveParticipant(string) error // UpdatePresence updates presence timestamp of a participant. - UpdatePresence(string) error + UpdatePresence(string, time.Time) error // GetKubeCluster returns the name of the kubernetes cluster the session is running in. GetKubeCluster() string @@ -302,15 +303,17 @@ func (s *SessionTrackerV1) GetHostUser() string { } // UpdatePresence updates presence timestamp of a participant. -func (s *SessionTrackerV1) UpdatePresence(user string) error { - for _, participant := range s.Spec.Participants { - if participant.User == user { - participant.LastActive = time.Now().UTC() - return nil - } +func (s *SessionTrackerV1) UpdatePresence(user string, t time.Time) error { + idx := slices.IndexFunc(s.Spec.Participants, func(participant Participant) bool { + return participant.User == user + }) + + if idx < 0 { + return trace.NotFound("participant %v not found", user) } - return trace.NotFound("participant %v not found", user) + s.Spec.Participants[idx].LastActive = t + return nil } // GetHostPolicySets returns a list of policy sets held by the host user at the time of session creation. diff --git a/api/types/session_tracker_test.go b/api/types/session_tracker_test.go new file mode 100644 index 0000000000000..59cbb7fbd84fa --- /dev/null +++ b/api/types/session_tracker_test.go @@ -0,0 +1,66 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "testing" + "time" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSessionTrackerV1_UpdatePresence(t *testing.T) { + clock := clockwork.NewFakeClock() + now := clock.Now().UTC() + + s, err := NewSessionTracker(SessionTrackerSpecV1{ + SessionID: "123", + Participants: []Participant{ + { + ID: "1", + User: "llama", + Mode: string(SessionPeerMode), + LastActive: now, + }, + { + ID: "2", + User: "fish", + Mode: string(SessionModeratorMode), + LastActive: now, + }, + }, + }) + require.NoError(t, err) + + // Presence cannot be updated for a non-existent user + err = s.UpdatePresence("alpaca", now.Add(time.Hour)) + require.ErrorIs(t, err, trace.NotFound("participant alpaca not found")) + + // Update presence for just the user fish + require.NoError(t, s.UpdatePresence("fish", now.Add(time.Hour))) + + // Verify that llama has not been active but that fish was + for _, participant := range s.GetParticipants() { + lastActive := now + if participant.User == "fish" { + lastActive = lastActive.Add(time.Hour) + } + + assert.Equal(t, lastActive, participant.LastActive) + } +} diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 80aad7b76aa23..40b0595d85eba 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -232,6 +232,43 @@ func (RequestState) EnumDescriptor() ([]byte, []int) { return fileDescriptor_9198ee693835762e, []int{5} } +// CreateHostUserMode determines whether host user creation should be +// disabled or if host users should be cleaned up or kept after +// sessions end. +type CreateHostUserMode int32 + +const ( + CreateHostUserMode_HOST_USER_MODE_UNSPECIFIED CreateHostUserMode = 0 + // HOST_USER_MODE_OFF disables host user creation. + CreateHostUserMode_HOST_USER_MODE_OFF CreateHostUserMode = 1 + // HOST_USER_MODE_DROP enables host user creation and deletes users at session end. + CreateHostUserMode_HOST_USER_MODE_DROP CreateHostUserMode = 2 + // HOST_USER_MODE_KEEP enables host user creation and leaves users behind at session end. + CreateHostUserMode_HOST_USER_MODE_KEEP CreateHostUserMode = 3 +) + +var CreateHostUserMode_name = map[int32]string{ + 0: "HOST_USER_MODE_UNSPECIFIED", + 1: "HOST_USER_MODE_OFF", + 2: "HOST_USER_MODE_DROP", + 3: "HOST_USER_MODE_KEEP", +} + +var CreateHostUserMode_value = map[string]int32{ + "HOST_USER_MODE_UNSPECIFIED": 0, + "HOST_USER_MODE_OFF": 1, + "HOST_USER_MODE_DROP": 2, + "HOST_USER_MODE_KEEP": 3, +} + +func (x CreateHostUserMode) String() string { + return proto.EnumName(CreateHostUserMode_name, int32(x)) +} + +func (CreateHostUserMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{6} +} + // CertExtensionMode specifies the type of extension to use in the cert. type CertExtensionMode int32 @@ -254,7 +291,7 @@ func (x CertExtensionMode) String() string { } func (CertExtensionMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{6} + return fileDescriptor_9198ee693835762e, []int{7} } // CertExtensionType represents the certificate type the extension is for. @@ -279,7 +316,7 @@ func (x CertExtensionType) String() string { } func (CertExtensionType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{7} + return fileDescriptor_9198ee693835762e, []int{8} } // SessionState represents the state of a session. @@ -313,7 +350,7 @@ func (x SessionState) String() string { } func (SessionState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{8} + return fileDescriptor_9198ee693835762e, []int{9} } // AlertSeverity represents how problematic/urgent an alert is, and is used to assist @@ -343,7 +380,7 @@ func (x AlertSeverity) String() string { } func (AlertSeverity) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{9} + return fileDescriptor_9198ee693835762e, []int{10} } // RequireMFAType is a type of MFA requirement enforced outside of login, @@ -384,7 +421,7 @@ func (x RequireMFAType) String() string { } func (RequireMFAType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{10} + return fileDescriptor_9198ee693835762e, []int{11} } type PluginStatusCode int32 @@ -425,7 +462,7 @@ func (x PluginStatusCode) String() string { } func (PluginStatusCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{11} + return fileDescriptor_9198ee693835762e, []int{12} } // HeadlessAuthenticationState is a headless authentication state. @@ -460,7 +497,7 @@ func (x HeadlessAuthenticationState) String() string { } func (HeadlessAuthenticationState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{12} + return fileDescriptor_9198ee693835762e, []int{13} } // The type of a KeepAlive. When adding a new type, please double-check @@ -543,7 +580,7 @@ func (x CertAuthoritySpecV2_SigningAlgType) String() string { } func (CertAuthoritySpecV2_SigningAlgType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{47, 0} + return fileDescriptor_9198ee693835762e, []int{49, 0} } // FIPSEndpointState represents an AWS FIPS endpoint state. @@ -576,7 +613,7 @@ func (x ClusterAuditConfigSpecV2_FIPSEndpointState) String() string { } func (ClusterAuditConfigSpecV2_FIPSEndpointState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{66, 0} + return fileDescriptor_9198ee693835762e, []int{68, 0} } // TraceType is an identification of the checkpoint. @@ -646,7 +683,7 @@ func (x ConnectionDiagnosticTrace_TraceType) String() string { } func (ConnectionDiagnosticTrace_TraceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{222, 0} + return fileDescriptor_9198ee693835762e, []int{224, 0} } // StatusType describes whether this was a success or a failure. @@ -675,7 +712,7 @@ func (x ConnectionDiagnosticTrace_StatusType) String() string { } func (ConnectionDiagnosticTrace_StatusType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{222, 1} + return fileDescriptor_9198ee693835762e, []int{224, 1} } // OktaAssignmentStatus represents the status of an Okta assignment. @@ -715,7 +752,7 @@ func (x OktaAssignmentSpecV1_OktaAssignmentStatus) String() string { } func (OktaAssignmentSpecV1_OktaAssignmentStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{269, 0} + return fileDescriptor_9198ee693835762e, []int{274, 0} } // OktaAssignmentTargetType is the type of Okta object that an assignment is targeting. @@ -747,7 +784,7 @@ func (x OktaAssignmentTargetV1_OktaAssignmentTargetType) String() string { } func (OktaAssignmentTargetV1_OktaAssignmentTargetType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{270, 0} + return fileDescriptor_9198ee693835762e, []int{275, 0} } type KeepAlive struct { @@ -1258,10 +1295,12 @@ type DatabaseSpecV3 struct { // MySQL is an additional section with MySQL database options. MySQL MySQLOptions `protobuf:"bytes,10,opt,name=MySQL,proto3" json:"mysql,omitempty"` // AdminUser is the database admin user for automatic user provisioning. - AdminUser *DatabaseAdminUser `protobuf:"bytes,11,opt,name=AdminUser,proto3" json:"admin_user,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AdminUser *DatabaseAdminUser `protobuf:"bytes,11,opt,name=AdminUser,proto3" json:"admin_user,omitempty"` + // MongoAtlas contains Atlas metadata about the database. + MongoAtlas MongoAtlas `protobuf:"bytes,12,opt,name=MongoAtlas,proto3" json:"mongo_atlas,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *DatabaseSpecV3) Reset() { *m = DatabaseSpecV3{} } @@ -1414,10 +1453,12 @@ type AWS struct { ExternalID string `protobuf:"bytes,10,opt,name=ExternalID,proto3" json:"external_id,omitempty"` // AssumeRoleARN is an optional AWS role ARN to assume when accessing a database. // Set this field and ExternalID to enable access across AWS accounts. - AssumeRoleARN string `protobuf:"bytes,11,opt,name=AssumeRoleARN,proto3" json:"assume_role_arn,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AssumeRoleARN string `protobuf:"bytes,11,opt,name=AssumeRoleARN,proto3" json:"assume_role_arn,omitempty"` + // OpenSearch contains AWS OpenSearch specific metadata. + OpenSearch OpenSearch `protobuf:"bytes,12,opt,name=OpenSearch,proto3" json:"opensearch,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AWS) Reset() { *m = AWS{} } @@ -1777,6 +1818,52 @@ func (m *RedshiftServerless) XXX_DiscardUnknown() { var xxx_messageInfo_RedshiftServerless proto.InternalMessageInfo +// OpenSearch contains AWS OpenSearch specific metadata. +type OpenSearch struct { + // DomainName is the name of the domain. + DomainName string `protobuf:"bytes,1,opt,name=DomainName,proto3" json:"domain_name,omitempty"` + // DomainID is the ID of the domain. + DomainID string `protobuf:"bytes,2,opt,name=DomainID,proto3" json:"domain_id,omitempty"` + // EndpointType is the type of the endpoint. + EndpointType string `protobuf:"bytes,3,opt,name=EndpointType,proto3" json:"endpoint_type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OpenSearch) Reset() { *m = OpenSearch{} } +func (m *OpenSearch) String() string { return proto.CompactTextString(m) } +func (*OpenSearch) ProtoMessage() {} +func (*OpenSearch) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{20} +} +func (m *OpenSearch) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OpenSearch) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OpenSearch.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *OpenSearch) XXX_Merge(src proto.Message) { + xxx_messageInfo_OpenSearch.Merge(m, src) +} +func (m *OpenSearch) XXX_Size() int { + return m.Size() +} +func (m *OpenSearch) XXX_DiscardUnknown() { + xxx_messageInfo_OpenSearch.DiscardUnknown(m) +} + +var xxx_messageInfo_OpenSearch proto.InternalMessageInfo + // GCPCloudSQL contains parameters specific to GCP Cloud SQL databases. type GCPCloudSQL struct { // ProjectID is the GCP project ID the Cloud SQL instance resides in. @@ -1792,7 +1879,7 @@ func (m *GCPCloudSQL) Reset() { *m = GCPCloudSQL{} } func (m *GCPCloudSQL) String() string { return proto.CompactTextString(m) } func (*GCPCloudSQL) ProtoMessage() {} func (*GCPCloudSQL) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{20} + return fileDescriptor_9198ee693835762e, []int{21} } func (m *GCPCloudSQL) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1840,7 +1927,7 @@ func (m *Azure) Reset() { *m = Azure{} } func (m *Azure) String() string { return proto.CompactTextString(m) } func (*Azure) ProtoMessage() {} func (*Azure) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{21} + return fileDescriptor_9198ee693835762e, []int{22} } func (m *Azure) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1882,7 +1969,7 @@ func (m *AzureRedis) Reset() { *m = AzureRedis{} } func (m *AzureRedis) String() string { return proto.CompactTextString(m) } func (*AzureRedis) ProtoMessage() {} func (*AzureRedis) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{22} + return fileDescriptor_9198ee693835762e, []int{23} } func (m *AzureRedis) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1934,7 +2021,7 @@ func (m *AD) Reset() { *m = AD{} } func (m *AD) String() string { return proto.CompactTextString(m) } func (*AD) ProtoMessage() {} func (*AD) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{23} + return fileDescriptor_9198ee693835762e, []int{24} } func (m *AD) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1982,7 +2069,7 @@ func (m *DatabaseTLS) Reset() { *m = DatabaseTLS{} } func (m *DatabaseTLS) String() string { return proto.CompactTextString(m) } func (*DatabaseTLS) ProtoMessage() {} func (*DatabaseTLS) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{24} + return fileDescriptor_9198ee693835762e, []int{25} } func (m *DatabaseTLS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2025,7 +2112,7 @@ func (m *MySQLOptions) Reset() { *m = MySQLOptions{} } func (m *MySQLOptions) String() string { return proto.CompactTextString(m) } func (*MySQLOptions) ProtoMessage() {} func (*MySQLOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{25} + return fileDescriptor_9198ee693835762e, []int{26} } func (m *MySQLOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2054,6 +2141,48 @@ func (m *MySQLOptions) XXX_DiscardUnknown() { var xxx_messageInfo_MySQLOptions proto.InternalMessageInfo +// MongoAtlas contains Atlas metadata about the database. +type MongoAtlas struct { + // Name is the Atlas database instance name. + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MongoAtlas) Reset() { *m = MongoAtlas{} } +func (m *MongoAtlas) String() string { return proto.CompactTextString(m) } +func (*MongoAtlas) ProtoMessage() {} +func (*MongoAtlas) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{27} +} +func (m *MongoAtlas) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MongoAtlas) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MongoAtlas.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MongoAtlas) XXX_Merge(src proto.Message) { + xxx_messageInfo_MongoAtlas.Merge(m, src) +} +func (m *MongoAtlas) XXX_Size() int { + return m.Size() +} +func (m *MongoAtlas) XXX_DiscardUnknown() { + xxx_messageInfo_MongoAtlas.DiscardUnknown(m) +} + +var xxx_messageInfo_MongoAtlas proto.InternalMessageInfo + // InstanceV1 represents the state of a running teleport instance independent // of the specific services that instance exposes. type InstanceV1 struct { @@ -2068,7 +2197,7 @@ func (m *InstanceV1) Reset() { *m = InstanceV1{} } func (m *InstanceV1) String() string { return proto.CompactTextString(m) } func (*InstanceV1) ProtoMessage() {} func (*InstanceV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{26} + return fileDescriptor_9198ee693835762e, []int{28} } func (m *InstanceV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2120,7 +2249,7 @@ func (m *InstanceSpecV1) Reset() { *m = InstanceSpecV1{} } func (m *InstanceSpecV1) String() string { return proto.CompactTextString(m) } func (*InstanceSpecV1) ProtoMessage() {} func (*InstanceSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{27} + return fileDescriptor_9198ee693835762e, []int{29} } func (m *InstanceSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2190,7 +2319,7 @@ func (m *InstanceControlLogEntry) Reset() { *m = InstanceControlLogEntry func (m *InstanceControlLogEntry) String() string { return proto.CompactTextString(m) } func (*InstanceControlLogEntry) ProtoMessage() {} func (*InstanceControlLogEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{28} + return fileDescriptor_9198ee693835762e, []int{30} } func (m *InstanceControlLogEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2238,7 +2367,7 @@ func (m *InstanceFilter) Reset() { *m = InstanceFilter{} } func (m *InstanceFilter) String() string { return proto.CompactTextString(m) } func (*InstanceFilter) ProtoMessage() {} func (*InstanceFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{29} + return fileDescriptor_9198ee693835762e, []int{31} } func (m *InstanceFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2287,7 +2416,7 @@ type ServerV2 struct { func (m *ServerV2) Reset() { *m = ServerV2{} } func (*ServerV2) ProtoMessage() {} func (*ServerV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{30} + return fileDescriptor_9198ee693835762e, []int{32} } func (m *ServerV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2330,7 +2459,7 @@ func (m *ServerV2List) Reset() { *m = ServerV2List{} } func (m *ServerV2List) String() string { return proto.CompactTextString(m) } func (*ServerV2List) ProtoMessage() {} func (*ServerV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{31} + return fileDescriptor_9198ee693835762e, []int{33} } func (m *ServerV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2396,7 +2525,7 @@ func (m *ServerSpecV2) Reset() { *m = ServerSpecV2{} } func (m *ServerSpecV2) String() string { return proto.CompactTextString(m) } func (*ServerSpecV2) ProtoMessage() {} func (*ServerSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{32} + return fileDescriptor_9198ee693835762e, []int{34} } func (m *ServerSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2445,7 +2574,7 @@ type AppServerV3 struct { func (m *AppServerV3) Reset() { *m = AppServerV3{} } func (*AppServerV3) ProtoMessage() {} func (*AppServerV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{33} + return fileDescriptor_9198ee693835762e, []int{35} } func (m *AppServerV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2497,7 +2626,7 @@ func (m *AppServerSpecV3) Reset() { *m = AppServerSpecV3{} } func (m *AppServerSpecV3) String() string { return proto.CompactTextString(m) } func (*AppServerSpecV3) ProtoMessage() {} func (*AppServerSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{34} + return fileDescriptor_9198ee693835762e, []int{36} } func (m *AppServerSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2539,7 +2668,7 @@ func (m *AppV3List) Reset() { *m = AppV3List{} } func (m *AppV3List) String() string { return proto.CompactTextString(m) } func (*AppV3List) ProtoMessage() {} func (*AppV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{35} + return fileDescriptor_9198ee693835762e, []int{37} } func (m *AppV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2588,7 +2717,7 @@ type AppV3 struct { func (m *AppV3) Reset() { *m = AppV3{} } func (*AppV3) ProtoMessage() {} func (*AppV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{36} + return fileDescriptor_9198ee693835762e, []int{38} } func (m *AppV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2632,7 +2761,9 @@ type AppSpecV3 struct { // AWS contains additional options for AWS applications. AWS *AppAWS `protobuf:"bytes,6,opt,name=AWS,proto3" json:"aws,omitempty"` // Cloud identifies the cloud instance the app represents. - Cloud string `protobuf:"bytes,7,opt,name=Cloud,proto3" json:"cloud,omitempty"` + Cloud string `protobuf:"bytes,7,opt,name=Cloud,proto3" json:"cloud,omitempty"` + // UserGroups are a list of user group IDs that this app is associated with. + UserGroups []string `protobuf:"bytes,8,rep,name=UserGroups,proto3" json:"UserGroups,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2642,7 +2773,7 @@ func (m *AppSpecV3) Reset() { *m = AppSpecV3{} } func (m *AppSpecV3) String() string { return proto.CompactTextString(m) } func (*AppSpecV3) ProtoMessage() {} func (*AppSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{37} + return fileDescriptor_9198ee693835762e, []int{39} } func (m *AppSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2702,7 +2833,7 @@ func (m *App) Reset() { *m = App{} } func (m *App) String() string { return proto.CompactTextString(m) } func (*App) ProtoMessage() {} func (*App) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{38} + return fileDescriptor_9198ee693835762e, []int{40} } func (m *App) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2748,7 +2879,7 @@ func (m *Rewrite) Reset() { *m = Rewrite{} } func (m *Rewrite) String() string { return proto.CompactTextString(m) } func (*Rewrite) ProtoMessage() {} func (*Rewrite) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{39} + return fileDescriptor_9198ee693835762e, []int{41} } func (m *Rewrite) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2792,7 +2923,7 @@ func (m *Header) Reset() { *m = Header{} } func (m *Header) String() string { return proto.CompactTextString(m) } func (*Header) ProtoMessage() {} func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{40} + return fileDescriptor_9198ee693835762e, []int{42} } func (m *Header) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2839,7 +2970,7 @@ func (m *CommandLabelV2) Reset() { *m = CommandLabelV2{} } func (m *CommandLabelV2) String() string { return proto.CompactTextString(m) } func (*CommandLabelV2) ProtoMessage() {} func (*CommandLabelV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{41} + return fileDescriptor_9198ee693835762e, []int{43} } func (m *CommandLabelV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2881,7 +3012,7 @@ func (m *AppAWS) Reset() { *m = AppAWS{} } func (m *AppAWS) String() string { return proto.CompactTextString(m) } func (*AppAWS) ProtoMessage() {} func (*AppAWS) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{42} + return fileDescriptor_9198ee693835762e, []int{44} } func (m *AppAWS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2927,7 +3058,7 @@ func (m *SSHKeyPair) Reset() { *m = SSHKeyPair{} } func (m *SSHKeyPair) String() string { return proto.CompactTextString(m) } func (*SSHKeyPair) ProtoMessage() {} func (*SSHKeyPair) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{43} + return fileDescriptor_9198ee693835762e, []int{45} } func (m *SSHKeyPair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2973,7 +3104,7 @@ func (m *TLSKeyPair) Reset() { *m = TLSKeyPair{} } func (m *TLSKeyPair) String() string { return proto.CompactTextString(m) } func (*TLSKeyPair) ProtoMessage() {} func (*TLSKeyPair) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{44} + return fileDescriptor_9198ee693835762e, []int{46} } func (m *TLSKeyPair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3019,7 +3150,7 @@ func (m *JWTKeyPair) Reset() { *m = JWTKeyPair{} } func (m *JWTKeyPair) String() string { return proto.CompactTextString(m) } func (*JWTKeyPair) ProtoMessage() {} func (*JWTKeyPair) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{45} + return fileDescriptor_9198ee693835762e, []int{47} } func (m *JWTKeyPair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3068,7 +3199,7 @@ type CertAuthorityV2 struct { func (m *CertAuthorityV2) Reset() { *m = CertAuthorityV2{} } func (*CertAuthorityV2) ProtoMessage() {} func (*CertAuthorityV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{46} + return fileDescriptor_9198ee693835762e, []int{48} } func (m *CertAuthorityV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3131,7 +3262,7 @@ func (m *CertAuthoritySpecV2) Reset() { *m = CertAuthoritySpecV2{} } func (m *CertAuthoritySpecV2) String() string { return proto.CompactTextString(m) } func (*CertAuthoritySpecV2) ProtoMessage() {} func (*CertAuthoritySpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{47} + return fileDescriptor_9198ee693835762e, []int{49} } func (m *CertAuthoritySpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3177,7 +3308,7 @@ func (m *CAKeySet) Reset() { *m = CAKeySet{} } func (m *CAKeySet) String() string { return proto.CompactTextString(m) } func (*CAKeySet) ProtoMessage() {} func (*CAKeySet) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{48} + return fileDescriptor_9198ee693835762e, []int{50} } func (m *CAKeySet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3222,7 +3353,7 @@ func (m *RoleMapping) Reset() { *m = RoleMapping{} } func (m *RoleMapping) String() string { return proto.CompactTextString(m) } func (*RoleMapping) ProtoMessage() {} func (*RoleMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{49} + return fileDescriptor_9198ee693835762e, []int{51} } func (m *RoleMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3270,7 +3401,7 @@ type ProvisionTokenV1 struct { func (m *ProvisionTokenV1) Reset() { *m = ProvisionTokenV1{} } func (*ProvisionTokenV1) ProtoMessage() {} func (*ProvisionTokenV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{50} + return fileDescriptor_9198ee693835762e, []int{52} } func (m *ProvisionTokenV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3319,7 +3450,7 @@ type ProvisionTokenV2 struct { func (m *ProvisionTokenV2) Reset() { *m = ProvisionTokenV2{} } func (*ProvisionTokenV2) ProtoMessage() {} func (*ProvisionTokenV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{51} + return fileDescriptor_9198ee693835762e, []int{53} } func (m *ProvisionTokenV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3361,7 +3492,7 @@ func (m *ProvisionTokenV2List) Reset() { *m = ProvisionTokenV2List{} } func (m *ProvisionTokenV2List) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenV2List) ProtoMessage() {} func (*ProvisionTokenV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{52} + return fileDescriptor_9198ee693835762e, []int{54} } func (m *ProvisionTokenV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3413,7 +3544,7 @@ func (m *TokenRule) Reset() { *m = TokenRule{} } func (m *TokenRule) String() string { return proto.CompactTextString(m) } func (*TokenRule) ProtoMessage() {} func (*TokenRule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{53} + return fileDescriptor_9198ee693835762e, []int{55} } func (m *TokenRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3489,7 +3620,7 @@ func (m *ProvisionTokenSpecV2) Reset() { *m = ProvisionTokenSpecV2{} } func (m *ProvisionTokenSpecV2) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2) ProtoMessage() {} func (*ProvisionTokenSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{54} + return fileDescriptor_9198ee693835762e, []int{56} } func (m *ProvisionTokenSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3542,7 +3673,7 @@ func (m *ProvisionTokenSpecV2GitHub) Reset() { *m = ProvisionTokenSpecV2 func (m *ProvisionTokenSpecV2GitHub) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GitHub) ProtoMessage() {} func (*ProvisionTokenSpecV2GitHub) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{55} + return fileDescriptor_9198ee693835762e, []int{57} } func (m *ProvisionTokenSpecV2GitHub) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3604,7 +3735,7 @@ func (m *ProvisionTokenSpecV2GitHub_Rule) Reset() { *m = ProvisionTokenS func (m *ProvisionTokenSpecV2GitHub_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GitHub_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2GitHub_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{55, 0} + return fileDescriptor_9198ee693835762e, []int{57, 0} } func (m *ProvisionTokenSpecV2GitHub_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3652,7 +3783,7 @@ func (m *ProvisionTokenSpecV2GitLab) Reset() { *m = ProvisionTokenSpecV2 func (m *ProvisionTokenSpecV2GitLab) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GitLab) ProtoMessage() {} func (*ProvisionTokenSpecV2GitLab) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{56} + return fileDescriptor_9198ee693835762e, []int{58} } func (m *ProvisionTokenSpecV2GitLab) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3718,7 +3849,7 @@ func (m *ProvisionTokenSpecV2GitLab_Rule) Reset() { *m = ProvisionTokenS func (m *ProvisionTokenSpecV2GitLab_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GitLab_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2GitLab_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{56, 0} + return fileDescriptor_9198ee693835762e, []int{58, 0} } func (m *ProvisionTokenSpecV2GitLab_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3763,7 +3894,7 @@ func (m *ProvisionTokenSpecV2CircleCI) Reset() { *m = ProvisionTokenSpec func (m *ProvisionTokenSpecV2CircleCI) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2CircleCI) ProtoMessage() {} func (*ProvisionTokenSpecV2CircleCI) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{57} + return fileDescriptor_9198ee693835762e, []int{59} } func (m *ProvisionTokenSpecV2CircleCI) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3804,7 +3935,7 @@ func (m *ProvisionTokenSpecV2CircleCI_Rule) Reset() { *m = ProvisionToke func (m *ProvisionTokenSpecV2CircleCI_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2CircleCI_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2CircleCI_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{57, 0} + return fileDescriptor_9198ee693835762e, []int{59, 0} } func (m *ProvisionTokenSpecV2CircleCI_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3848,7 +3979,7 @@ func (m *ProvisionTokenSpecV2Kubernetes) Reset() { *m = ProvisionTokenSp func (m *ProvisionTokenSpecV2Kubernetes) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Kubernetes) ProtoMessage() {} func (*ProvisionTokenSpecV2Kubernetes) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{58} + return fileDescriptor_9198ee693835762e, []int{60} } func (m *ProvisionTokenSpecV2Kubernetes) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3892,7 +4023,7 @@ func (m *ProvisionTokenSpecV2Kubernetes_Rule) Reset() { *m = ProvisionTo func (m *ProvisionTokenSpecV2Kubernetes_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Kubernetes_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2Kubernetes_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{58, 0} + return fileDescriptor_9198ee693835762e, []int{60, 0} } func (m *ProvisionTokenSpecV2Kubernetes_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3936,7 +4067,7 @@ func (m *ProvisionTokenSpecV2Azure) Reset() { *m = ProvisionTokenSpecV2A func (m *ProvisionTokenSpecV2Azure) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Azure) ProtoMessage() {} func (*ProvisionTokenSpecV2Azure) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{59} + return fileDescriptor_9198ee693835762e, []int{61} } func (m *ProvisionTokenSpecV2Azure) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3982,7 +4113,7 @@ func (m *ProvisionTokenSpecV2Azure_Rule) Reset() { *m = ProvisionTokenSp func (m *ProvisionTokenSpecV2Azure_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Azure_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2Azure_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{59, 0} + return fileDescriptor_9198ee693835762e, []int{61, 0} } func (m *ProvisionTokenSpecV2Azure_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4026,7 +4157,7 @@ func (m *ProvisionTokenSpecV2GCP) Reset() { *m = ProvisionTokenSpecV2GCP func (m *ProvisionTokenSpecV2GCP) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GCP) ProtoMessage() {} func (*ProvisionTokenSpecV2GCP) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{60} + return fileDescriptor_9198ee693835762e, []int{62} } func (m *ProvisionTokenSpecV2GCP) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4075,7 +4206,7 @@ func (m *ProvisionTokenSpecV2GCP_Rule) Reset() { *m = ProvisionTokenSpec func (m *ProvisionTokenSpecV2GCP_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GCP_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2GCP_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{60, 0} + return fileDescriptor_9198ee693835762e, []int{62, 0} } func (m *ProvisionTokenSpecV2GCP_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4124,7 +4255,7 @@ type StaticTokensV2 struct { func (m *StaticTokensV2) Reset() { *m = StaticTokensV2{} } func (*StaticTokensV2) ProtoMessage() {} func (*StaticTokensV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{61} + return fileDescriptor_9198ee693835762e, []int{63} } func (m *StaticTokensV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4167,7 +4298,7 @@ func (m *StaticTokensSpecV2) Reset() { *m = StaticTokensSpecV2{} } func (m *StaticTokensSpecV2) String() string { return proto.CompactTextString(m) } func (*StaticTokensSpecV2) ProtoMessage() {} func (*StaticTokensSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{62} + return fileDescriptor_9198ee693835762e, []int{64} } func (m *StaticTokensSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4216,7 +4347,7 @@ type ClusterNameV2 struct { func (m *ClusterNameV2) Reset() { *m = ClusterNameV2{} } func (*ClusterNameV2) ProtoMessage() {} func (*ClusterNameV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{63} + return fileDescriptor_9198ee693835762e, []int{65} } func (m *ClusterNameV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4262,7 +4393,7 @@ func (m *ClusterNameSpecV2) Reset() { *m = ClusterNameSpecV2{} } func (m *ClusterNameSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterNameSpecV2) ProtoMessage() {} func (*ClusterNameSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{64} + return fileDescriptor_9198ee693835762e, []int{66} } func (m *ClusterNameSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4312,7 +4443,7 @@ func (m *ClusterAuditConfigV2) Reset() { *m = ClusterAuditConfigV2{} } func (m *ClusterAuditConfigV2) String() string { return proto.CompactTextString(m) } func (*ClusterAuditConfigV2) ProtoMessage() {} func (*ClusterAuditConfigV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{65} + return fileDescriptor_9198ee693835762e, []int{67} } func (m *ClusterAuditConfigV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4382,7 +4513,7 @@ func (m *ClusterAuditConfigSpecV2) Reset() { *m = ClusterAuditConfigSpec func (m *ClusterAuditConfigSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterAuditConfigSpecV2) ProtoMessage() {} func (*ClusterAuditConfigSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{66} + return fileDescriptor_9198ee693835762e, []int{68} } func (m *ClusterAuditConfigSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4432,7 +4563,7 @@ func (m *ClusterNetworkingConfigV2) Reset() { *m = ClusterNetworkingConf func (m *ClusterNetworkingConfigV2) String() string { return proto.CompactTextString(m) } func (*ClusterNetworkingConfigV2) ProtoMessage() {} func (*ClusterNetworkingConfigV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{67} + return fileDescriptor_9198ee693835762e, []int{69} } func (m *ClusterNetworkingConfigV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4501,7 +4632,7 @@ func (m *ClusterNetworkingConfigSpecV2) Reset() { *m = ClusterNetworking func (m *ClusterNetworkingConfigSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterNetworkingConfigSpecV2) ProtoMessage() {} func (*ClusterNetworkingConfigSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{68} + return fileDescriptor_9198ee693835762e, []int{70} } func (m *ClusterNetworkingConfigSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4545,7 +4676,7 @@ func (m *TunnelStrategyV1) Reset() { *m = TunnelStrategyV1{} } func (m *TunnelStrategyV1) String() string { return proto.CompactTextString(m) } func (*TunnelStrategyV1) ProtoMessage() {} func (*TunnelStrategyV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{69} + return fileDescriptor_9198ee693835762e, []int{71} } func (m *TunnelStrategyV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4630,7 +4761,7 @@ func (m *AgentMeshTunnelStrategy) Reset() { *m = AgentMeshTunnelStrategy func (m *AgentMeshTunnelStrategy) String() string { return proto.CompactTextString(m) } func (*AgentMeshTunnelStrategy) ProtoMessage() {} func (*AgentMeshTunnelStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{70} + return fileDescriptor_9198ee693835762e, []int{72} } func (m *AgentMeshTunnelStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4671,7 +4802,7 @@ func (m *ProxyPeeringTunnelStrategy) Reset() { *m = ProxyPeeringTunnelSt func (m *ProxyPeeringTunnelStrategy) String() string { return proto.CompactTextString(m) } func (*ProxyPeeringTunnelStrategy) ProtoMessage() {} func (*ProxyPeeringTunnelStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{71} + return fileDescriptor_9198ee693835762e, []int{73} } func (m *ProxyPeeringTunnelStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4721,7 +4852,7 @@ func (m *SessionRecordingConfigV2) Reset() { *m = SessionRecordingConfig func (m *SessionRecordingConfigV2) String() string { return proto.CompactTextString(m) } func (*SessionRecordingConfigV2) ProtoMessage() {} func (*SessionRecordingConfigV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{72} + return fileDescriptor_9198ee693835762e, []int{74} } func (m *SessionRecordingConfigV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4767,7 +4898,7 @@ func (m *SessionRecordingConfigSpecV2) Reset() { *m = SessionRecordingCo func (m *SessionRecordingConfigSpecV2) String() string { return proto.CompactTextString(m) } func (*SessionRecordingConfigSpecV2) ProtoMessage() {} func (*SessionRecordingConfigSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{73} + return fileDescriptor_9198ee693835762e, []int{75} } func (m *SessionRecordingConfigSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4816,7 +4947,7 @@ type AuthPreferenceV2 struct { func (m *AuthPreferenceV2) Reset() { *m = AuthPreferenceV2{} } func (*AuthPreferenceV2) ProtoMessage() {} func (*AuthPreferenceV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{74} + return fileDescriptor_9198ee693835762e, []int{76} } func (m *AuthPreferenceV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4883,17 +5014,20 @@ type AuthPreferenceSpecV2 struct { // Headless authentication requires Webauthn to work. // Defaults to true if the Webauthn is configured, defaults to false // otherwise. - AllowHeadless *BoolOption `protobuf:"bytes,15,opt,name=AllowHeadless,proto3,customtype=BoolOption" json:"allow_headless,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + AllowHeadless *BoolOption `protobuf:"bytes,15,opt,name=AllowHeadless,proto3,customtype=BoolOption" json:"allow_headless,omitempty"` + // DefaultSessionTTL is the TTL to use for user certs when + // an explicit TTL is not requested. + DefaultSessionTTL Duration `protobuf:"varint,16,opt,name=DefaultSessionTTL,proto3,casttype=Duration" json:"default_session_ttl,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *AuthPreferenceSpecV2) Reset() { *m = AuthPreferenceSpecV2{} } func (m *AuthPreferenceSpecV2) String() string { return proto.CompactTextString(m) } func (*AuthPreferenceSpecV2) ProtoMessage() {} func (*AuthPreferenceSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{75} + return fileDescriptor_9198ee693835762e, []int{77} } func (m *AuthPreferenceSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4944,7 +5078,7 @@ func (m *U2F) Reset() { *m = U2F{} } func (m *U2F) String() string { return proto.CompactTextString(m) } func (*U2F) ProtoMessage() {} func (*U2F) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{76} + return fileDescriptor_9198ee693835762e, []int{78} } func (m *U2F) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5012,7 +5146,7 @@ func (m *Webauthn) Reset() { *m = Webauthn{} } func (m *Webauthn) String() string { return proto.CompactTextString(m) } func (*Webauthn) ProtoMessage() {} func (*Webauthn) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{77} + return fileDescriptor_9198ee693835762e, []int{79} } func (m *Webauthn) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5083,7 +5217,7 @@ func (m *DeviceTrust) Reset() { *m = DeviceTrust{} } func (m *DeviceTrust) String() string { return proto.CompactTextString(m) } func (*DeviceTrust) ProtoMessage() {} func (*DeviceTrust) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{78} + return fileDescriptor_9198ee693835762e, []int{80} } func (m *DeviceTrust) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5133,7 +5267,7 @@ func (m *Namespace) Reset() { *m = Namespace{} } func (m *Namespace) String() string { return proto.CompactTextString(m) } func (*Namespace) ProtoMessage() {} func (*Namespace) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{79} + return fileDescriptor_9198ee693835762e, []int{81} } func (m *Namespace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5173,7 +5307,7 @@ func (m *NamespaceSpec) Reset() { *m = NamespaceSpec{} } func (m *NamespaceSpec) String() string { return proto.CompactTextString(m) } func (*NamespaceSpec) ProtoMessage() {} func (*NamespaceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{80} + return fileDescriptor_9198ee693835762e, []int{82} } func (m *NamespaceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5221,7 +5355,7 @@ type UserTokenV3 struct { func (m *UserTokenV3) Reset() { *m = UserTokenV3{} } func (*UserTokenV3) ProtoMessage() {} func (*UserTokenV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{81} + return fileDescriptor_9198ee693835762e, []int{83} } func (m *UserTokenV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5268,7 +5402,7 @@ func (m *UserTokenSpecV3) Reset() { *m = UserTokenSpecV3{} } func (m *UserTokenSpecV3) String() string { return proto.CompactTextString(m) } func (*UserTokenSpecV3) ProtoMessage() {} func (*UserTokenSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{82} + return fileDescriptor_9198ee693835762e, []int{84} } func (m *UserTokenSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5316,7 +5450,7 @@ type UserTokenSecretsV3 struct { func (m *UserTokenSecretsV3) Reset() { *m = UserTokenSecretsV3{} } func (*UserTokenSecretsV3) ProtoMessage() {} func (*UserTokenSecretsV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{83} + return fileDescriptor_9198ee693835762e, []int{85} } func (m *UserTokenSecretsV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5361,7 +5495,7 @@ func (m *UserTokenSecretsSpecV3) Reset() { *m = UserTokenSecretsSpecV3{} func (m *UserTokenSecretsSpecV3) String() string { return proto.CompactTextString(m) } func (*UserTokenSecretsSpecV3) ProtoMessage() {} func (*UserTokenSecretsSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{84} + return fileDescriptor_9198ee693835762e, []int{86} } func (m *UserTokenSecretsSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5410,7 +5544,7 @@ type AccessRequestV3 struct { func (m *AccessRequestV3) Reset() { *m = AccessRequestV3{} } func (*AccessRequestV3) ProtoMessage() {} func (*AccessRequestV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{85} + return fileDescriptor_9198ee693835762e, []int{87} } func (m *AccessRequestV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5462,7 +5596,7 @@ func (m *AccessReviewThreshold) Reset() { *m = AccessReviewThreshold{} } func (m *AccessReviewThreshold) String() string { return proto.CompactTextString(m) } func (*AccessReviewThreshold) ProtoMessage() {} func (*AccessReviewThreshold) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{86} + return fileDescriptor_9198ee693835762e, []int{88} } func (m *AccessReviewThreshold) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5518,7 +5652,7 @@ func (m *AccessReview) Reset() { *m = AccessReview{} } func (m *AccessReview) String() string { return proto.CompactTextString(m) } func (*AccessReview) ProtoMessage() {} func (*AccessReview) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{87} + return fileDescriptor_9198ee693835762e, []int{89} } func (m *AccessReview) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5563,7 +5697,7 @@ func (m *AccessReviewSubmission) Reset() { *m = AccessReviewSubmission{} func (m *AccessReviewSubmission) String() string { return proto.CompactTextString(m) } func (*AccessReviewSubmission) ProtoMessage() {} func (*AccessReviewSubmission) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{88} + return fileDescriptor_9198ee693835762e, []int{90} } func (m *AccessReviewSubmission) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5606,7 +5740,7 @@ func (m *ThresholdIndexSet) Reset() { *m = ThresholdIndexSet{} } func (m *ThresholdIndexSet) String() string { return proto.CompactTextString(m) } func (*ThresholdIndexSet) ProtoMessage() {} func (*ThresholdIndexSet) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{89} + return fileDescriptor_9198ee693835762e, []int{91} } func (m *ThresholdIndexSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5649,7 +5783,7 @@ func (m *ThresholdIndexSets) Reset() { *m = ThresholdIndexSets{} } func (m *ThresholdIndexSets) String() string { return proto.CompactTextString(m) } func (*ThresholdIndexSets) ProtoMessage() {} func (*ThresholdIndexSets) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{90} + return fileDescriptor_9198ee693835762e, []int{92} } func (m *ThresholdIndexSets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5742,7 +5876,7 @@ func (m *AccessRequestSpecV3) Reset() { *m = AccessRequestSpecV3{} } func (m *AccessRequestSpecV3) String() string { return proto.CompactTextString(m) } func (*AccessRequestSpecV3) ProtoMessage() {} func (*AccessRequestSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{91} + return fileDescriptor_9198ee693835762e, []int{93} } func (m *AccessRequestSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5788,7 +5922,7 @@ func (m *AccessRequestFilter) Reset() { *m = AccessRequestFilter{} } func (m *AccessRequestFilter) String() string { return proto.CompactTextString(m) } func (*AccessRequestFilter) ProtoMessage() {} func (*AccessRequestFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{92} + return fileDescriptor_9198ee693835762e, []int{94} } func (m *AccessRequestFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5844,7 +5978,7 @@ func (m *AccessCapabilities) Reset() { *m = AccessCapabilities{} } func (m *AccessCapabilities) String() string { return proto.CompactTextString(m) } func (*AccessCapabilities) ProtoMessage() {} func (*AccessCapabilities) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{93} + return fileDescriptor_9198ee693835762e, []int{95} } func (m *AccessCapabilities) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5896,7 +6030,7 @@ func (m *AccessCapabilitiesRequest) Reset() { *m = AccessCapabilitiesReq func (m *AccessCapabilitiesRequest) String() string { return proto.CompactTextString(m) } func (*AccessCapabilitiesRequest) ProtoMessage() {} func (*AccessCapabilitiesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{94} + return fileDescriptor_9198ee693835762e, []int{96} } func (m *AccessCapabilitiesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5948,7 +6082,7 @@ func (m *ResourceID) Reset() { *m = ResourceID{} } func (m *ResourceID) String() string { return proto.CompactTextString(m) } func (*ResourceID) ProtoMessage() {} func (*ResourceID) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{95} + return fileDescriptor_9198ee693835762e, []int{97} } func (m *ResourceID) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5997,7 +6131,7 @@ type PluginDataV3 struct { func (m *PluginDataV3) Reset() { *m = PluginDataV3{} } func (*PluginDataV3) ProtoMessage() {} func (*PluginDataV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{96} + return fileDescriptor_9198ee693835762e, []int{98} } func (m *PluginDataV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6040,7 +6174,7 @@ func (m *PluginDataEntry) Reset() { *m = PluginDataEntry{} } func (m *PluginDataEntry) String() string { return proto.CompactTextString(m) } func (*PluginDataEntry) ProtoMessage() {} func (*PluginDataEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{97} + return fileDescriptor_9198ee693835762e, []int{99} } func (m *PluginDataEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6082,7 +6216,7 @@ func (m *PluginDataSpecV3) Reset() { *m = PluginDataSpecV3{} } func (m *PluginDataSpecV3) String() string { return proto.CompactTextString(m) } func (*PluginDataSpecV3) ProtoMessage() {} func (*PluginDataSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{98} + return fileDescriptor_9198ee693835762e, []int{100} } func (m *PluginDataSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6129,7 +6263,7 @@ func (m *PluginDataFilter) Reset() { *m = PluginDataFilter{} } func (m *PluginDataFilter) String() string { return proto.CompactTextString(m) } func (*PluginDataFilter) ProtoMessage() {} func (*PluginDataFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{99} + return fileDescriptor_9198ee693835762e, []int{101} } func (m *PluginDataFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6180,7 +6314,7 @@ func (m *PluginDataUpdateParams) Reset() { *m = PluginDataUpdateParams{} func (m *PluginDataUpdateParams) String() string { return proto.CompactTextString(m) } func (*PluginDataUpdateParams) ProtoMessage() {} func (*PluginDataUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{100} + return fileDescriptor_9198ee693835762e, []int{102} } func (m *PluginDataUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6229,7 +6363,7 @@ type RoleV6 struct { func (m *RoleV6) Reset() { *m = RoleV6{} } func (*RoleV6) ProtoMessage() {} func (*RoleV6) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{101} + return fileDescriptor_9198ee693835762e, []int{103} } func (m *RoleV6) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6276,7 +6410,7 @@ func (m *RoleSpecV6) Reset() { *m = RoleSpecV6{} } func (m *RoleSpecV6) String() string { return proto.CompactTextString(m) } func (*RoleSpecV6) ProtoMessage() {} func (*RoleSpecV6) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{102} + return fileDescriptor_9198ee693835762e, []int{104} } func (m *RoleSpecV6) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6360,7 +6494,7 @@ type RoleOptions struct { // true. DesktopDirectorySharing *BoolOption `protobuf:"bytes,19,opt,name=DesktopDirectorySharing,proto3,customtype=BoolOption" json:"desktop_directory_sharing"` // CreateHostUser allows users to be automatically created on a host - CreateHostUser *BoolOption `protobuf:"bytes,20,opt,name=CreateHostUser,proto3,customtype=BoolOption" json:"create_host_user"` + CreateHostUser *BoolOption `protobuf:"bytes,20,opt,name=CreateHostUser,proto3,customtype=BoolOption" json:"create_host_user,omitempty"` // PinSourceIP forces the same client IP for certificate generation and usage PinSourceIP Bool `protobuf:"varint,21,opt,name=PinSourceIP,proto3,casttype=Bool" json:"pin_source_ip"` // SSHFileCopy indicates whether remote file operations via SCP or SFTP are allowed @@ -6379,17 +6513,20 @@ type RoleOptions struct { // CreateDesktopUser allows users to be automatically created on a Windows desktop CreateDesktopUser *BoolOption `protobuf:"bytes,26,opt,name=CreateDesktopUser,proto3,customtype=BoolOption" json:"create_desktop_user"` // CreateDatabaseUser enabled automatic database user creation. - CreateDatabaseUser *BoolOption `protobuf:"bytes,27,opt,name=CreateDatabaseUser,proto3,customtype=BoolOption" json:"create_db_user"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + CreateDatabaseUser *BoolOption `protobuf:"bytes,27,opt,name=CreateDatabaseUser,proto3,customtype=BoolOption" json:"create_db_user"` + // CreateHostUserMode allows users to be automatically created on a + // host when not set to off + CreateHostUserMode CreateHostUserMode `protobuf:"varint,28,opt,name=CreateHostUserMode,proto3,enum=types.CreateHostUserMode" json:"create_host_user_mode,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *RoleOptions) Reset() { *m = RoleOptions{} } func (m *RoleOptions) String() string { return proto.CompactTextString(m) } func (*RoleOptions) ProtoMessage() {} func (*RoleOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{103} + return fileDescriptor_9198ee693835762e, []int{105} } func (m *RoleOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6435,7 +6572,7 @@ func (m *RecordSession) Reset() { *m = RecordSession{} } func (m *RecordSession) String() string { return proto.CompactTextString(m) } func (*RecordSession) ProtoMessage() {} func (*RecordSession) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{104} + return fileDescriptor_9198ee693835762e, []int{106} } func (m *RecordSession) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6485,7 +6622,7 @@ func (m *CertExtension) Reset() { *m = CertExtension{} } func (m *CertExtension) String() string { return proto.CompactTextString(m) } func (*CertExtension) ProtoMessage() {} func (*CertExtension) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{105} + return fileDescriptor_9198ee693835762e, []int{107} } func (m *CertExtension) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6612,7 +6749,7 @@ func (m *RoleConditions) Reset() { *m = RoleConditions{} } func (m *RoleConditions) String() string { return proto.CompactTextString(m) } func (*RoleConditions) ProtoMessage() {} func (*RoleConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{106} + return fileDescriptor_9198ee693835762e, []int{108} } func (m *RoleConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6661,7 +6798,7 @@ func (m *KubernetesResource) Reset() { *m = KubernetesResource{} } func (m *KubernetesResource) String() string { return proto.CompactTextString(m) } func (*KubernetesResource) ProtoMessage() {} func (*KubernetesResource) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{107} + return fileDescriptor_9198ee693835762e, []int{109} } func (m *KubernetesResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6714,7 +6851,7 @@ func (m *SessionRequirePolicy) Reset() { *m = SessionRequirePolicy{} } func (m *SessionRequirePolicy) String() string { return proto.CompactTextString(m) } func (*SessionRequirePolicy) ProtoMessage() {} func (*SessionRequirePolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{108} + return fileDescriptor_9198ee693835762e, []int{110} } func (m *SessionRequirePolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6762,7 +6899,7 @@ func (m *SessionJoinPolicy) Reset() { *m = SessionJoinPolicy{} } func (m *SessionJoinPolicy) String() string { return proto.CompactTextString(m) } func (*SessionJoinPolicy) ProtoMessage() {} func (*SessionJoinPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{109} + return fileDescriptor_9198ee693835762e, []int{111} } func (m *SessionJoinPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6828,7 +6965,7 @@ func (m *AccessRequestConditions) Reset() { *m = AccessRequestConditions func (m *AccessRequestConditions) String() string { return proto.CompactTextString(m) } func (*AccessRequestConditions) ProtoMessage() {} func (*AccessRequestConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{110} + return fileDescriptor_9198ee693835762e, []int{112} } func (m *AccessRequestConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6881,7 +7018,7 @@ func (m *AccessReviewConditions) Reset() { *m = AccessReviewConditions{} func (m *AccessReviewConditions) String() string { return proto.CompactTextString(m) } func (*AccessReviewConditions) ProtoMessage() {} func (*AccessReviewConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{111} + return fileDescriptor_9198ee693835762e, []int{113} } func (m *AccessReviewConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6927,7 +7064,7 @@ func (m *ClaimMapping) Reset() { *m = ClaimMapping{} } func (m *ClaimMapping) String() string { return proto.CompactTextString(m) } func (*ClaimMapping) ProtoMessage() {} func (*ClaimMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{112} + return fileDescriptor_9198ee693835762e, []int{114} } func (m *ClaimMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6973,7 +7110,7 @@ func (m *TraitMapping) Reset() { *m = TraitMapping{} } func (m *TraitMapping) String() string { return proto.CompactTextString(m) } func (*TraitMapping) ProtoMessage() {} func (*TraitMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{113} + return fileDescriptor_9198ee693835762e, []int{115} } func (m *TraitMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7022,7 +7159,7 @@ func (m *Rule) Reset() { *m = Rule{} } func (m *Rule) String() string { return proto.CompactTextString(m) } func (*Rule) ProtoMessage() {} func (*Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{114} + return fileDescriptor_9198ee693835762e, []int{116} } func (m *Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7070,7 +7207,7 @@ func (m *ImpersonateConditions) Reset() { *m = ImpersonateConditions{} } func (m *ImpersonateConditions) String() string { return proto.CompactTextString(m) } func (*ImpersonateConditions) ProtoMessage() {} func (*ImpersonateConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{115} + return fileDescriptor_9198ee693835762e, []int{117} } func (m *ImpersonateConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7112,7 +7249,7 @@ func (m *BoolValue) Reset() { *m = BoolValue{} } func (m *BoolValue) String() string { return proto.CompactTextString(m) } func (*BoolValue) ProtoMessage() {} func (*BoolValue) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{116} + return fileDescriptor_9198ee693835762e, []int{118} } func (m *BoolValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7161,7 +7298,7 @@ type UserV2 struct { func (m *UserV2) Reset() { *m = UserV2{} } func (*UserV2) ProtoMessage() {} func (*UserV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{117} + return fileDescriptor_9198ee693835762e, []int{119} } func (m *UserV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7225,7 +7362,7 @@ func (m *UserSpecV2) Reset() { *m = UserSpecV2{} } func (m *UserSpecV2) String() string { return proto.CompactTextString(m) } func (*UserSpecV2) ProtoMessage() {} func (*UserSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{118} + return fileDescriptor_9198ee693835762e, []int{120} } func (m *UserSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7270,7 +7407,7 @@ type ExternalIdentity struct { func (m *ExternalIdentity) Reset() { *m = ExternalIdentity{} } func (*ExternalIdentity) ProtoMessage() {} func (*ExternalIdentity) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{119} + return fileDescriptor_9198ee693835762e, []int{121} } func (m *ExternalIdentity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7322,7 +7459,7 @@ func (m *LoginStatus) Reset() { *m = LoginStatus{} } func (m *LoginStatus) String() string { return proto.CompactTextString(m) } func (*LoginStatus) ProtoMessage() {} func (*LoginStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{120} + return fileDescriptor_9198ee693835762e, []int{122} } func (m *LoginStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7367,7 +7504,7 @@ type CreatedBy struct { func (m *CreatedBy) Reset() { *m = CreatedBy{} } func (*CreatedBy) ProtoMessage() {} func (*CreatedBy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{121} + return fileDescriptor_9198ee693835762e, []int{123} } func (m *CreatedBy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7416,7 +7553,7 @@ func (m *LocalAuthSecrets) Reset() { *m = LocalAuthSecrets{} } func (m *LocalAuthSecrets) String() string { return proto.CompactTextString(m) } func (*LocalAuthSecrets) ProtoMessage() {} func (*LocalAuthSecrets) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{122} + return fileDescriptor_9198ee693835762e, []int{124} } func (m *LocalAuthSecrets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7472,7 +7609,7 @@ func (m *MFADevice) Reset() { *m = MFADevice{} } func (m *MFADevice) String() string { return proto.CompactTextString(m) } func (*MFADevice) ProtoMessage() {} func (*MFADevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{123} + return fileDescriptor_9198ee693835762e, []int{125} } func (m *MFADevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7570,7 +7707,7 @@ func (m *TOTPDevice) Reset() { *m = TOTPDevice{} } func (m *TOTPDevice) String() string { return proto.CompactTextString(m) } func (*TOTPDevice) ProtoMessage() {} func (*TOTPDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{124} + return fileDescriptor_9198ee693835762e, []int{126} } func (m *TOTPDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7616,7 +7753,7 @@ func (m *U2FDevice) Reset() { *m = U2FDevice{} } func (m *U2FDevice) String() string { return proto.CompactTextString(m) } func (*U2FDevice) ProtoMessage() {} func (*U2FDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{125} + return fileDescriptor_9198ee693835762e, []int{127} } func (m *U2FDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7690,7 +7827,7 @@ func (m *WebauthnDevice) Reset() { *m = WebauthnDevice{} } func (m *WebauthnDevice) String() string { return proto.CompactTextString(m) } func (*WebauthnDevice) ProtoMessage() {} func (*WebauthnDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{126} + return fileDescriptor_9198ee693835762e, []int{128} } func (m *WebauthnDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7733,7 +7870,7 @@ func (m *WebauthnLocalAuth) Reset() { *m = WebauthnLocalAuth{} } func (m *WebauthnLocalAuth) String() string { return proto.CompactTextString(m) } func (*WebauthnLocalAuth) ProtoMessage() {} func (*WebauthnLocalAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{127} + return fileDescriptor_9198ee693835762e, []int{129} } func (m *WebauthnLocalAuth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7779,7 +7916,7 @@ func (m *ConnectorRef) Reset() { *m = ConnectorRef{} } func (m *ConnectorRef) String() string { return proto.CompactTextString(m) } func (*ConnectorRef) ProtoMessage() {} func (*ConnectorRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{128} + return fileDescriptor_9198ee693835762e, []int{130} } func (m *ConnectorRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7821,7 +7958,7 @@ func (m *UserRef) Reset() { *m = UserRef{} } func (m *UserRef) String() string { return proto.CompactTextString(m) } func (*UserRef) ProtoMessage() {} func (*UserRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{129} + return fileDescriptor_9198ee693835762e, []int{131} } func (m *UserRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7871,7 +8008,7 @@ func (m *ReverseTunnelV2) Reset() { *m = ReverseTunnelV2{} } func (m *ReverseTunnelV2) String() string { return proto.CompactTextString(m) } func (*ReverseTunnelV2) ProtoMessage() {} func (*ReverseTunnelV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{130} + return fileDescriptor_9198ee693835762e, []int{132} } func (m *ReverseTunnelV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7918,7 +8055,7 @@ func (m *ReverseTunnelSpecV2) Reset() { *m = ReverseTunnelSpecV2{} } func (m *ReverseTunnelSpecV2) String() string { return proto.CompactTextString(m) } func (*ReverseTunnelSpecV2) ProtoMessage() {} func (*ReverseTunnelSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{131} + return fileDescriptor_9198ee693835762e, []int{133} } func (m *ReverseTunnelSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7967,7 +8104,7 @@ type TunnelConnectionV2 struct { func (m *TunnelConnectionV2) Reset() { *m = TunnelConnectionV2{} } func (*TunnelConnectionV2) ProtoMessage() {} func (*TunnelConnectionV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{132} + return fileDescriptor_9198ee693835762e, []int{134} } func (m *TunnelConnectionV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8015,7 +8152,7 @@ func (m *TunnelConnectionSpecV2) Reset() { *m = TunnelConnectionSpecV2{} func (m *TunnelConnectionSpecV2) String() string { return proto.CompactTextString(m) } func (*TunnelConnectionSpecV2) ProtoMessage() {} func (*TunnelConnectionSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{133} + return fileDescriptor_9198ee693835762e, []int{135} } func (m *TunnelConnectionSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8063,7 +8200,7 @@ func (m *SemaphoreFilter) Reset() { *m = SemaphoreFilter{} } func (m *SemaphoreFilter) String() string { return proto.CompactTextString(m) } func (*SemaphoreFilter) ProtoMessage() {} func (*SemaphoreFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{134} + return fileDescriptor_9198ee693835762e, []int{136} } func (m *SemaphoreFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8114,7 +8251,7 @@ func (m *AcquireSemaphoreRequest) Reset() { *m = AcquireSemaphoreRequest func (m *AcquireSemaphoreRequest) String() string { return proto.CompactTextString(m) } func (*AcquireSemaphoreRequest) ProtoMessage() {} func (*AcquireSemaphoreRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{135} + return fileDescriptor_9198ee693835762e, []int{137} } func (m *AcquireSemaphoreRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8162,7 +8299,7 @@ func (m *SemaphoreLease) Reset() { *m = SemaphoreLease{} } func (m *SemaphoreLease) String() string { return proto.CompactTextString(m) } func (*SemaphoreLease) ProtoMessage() {} func (*SemaphoreLease) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{136} + return fileDescriptor_9198ee693835762e, []int{138} } func (m *SemaphoreLease) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8208,7 +8345,7 @@ func (m *SemaphoreLeaseRef) Reset() { *m = SemaphoreLeaseRef{} } func (m *SemaphoreLeaseRef) String() string { return proto.CompactTextString(m) } func (*SemaphoreLeaseRef) ProtoMessage() {} func (*SemaphoreLeaseRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{137} + return fileDescriptor_9198ee693835762e, []int{139} } func (m *SemaphoreLeaseRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8257,7 +8394,7 @@ type SemaphoreV3 struct { func (m *SemaphoreV3) Reset() { *m = SemaphoreV3{} } func (*SemaphoreV3) ProtoMessage() {} func (*SemaphoreV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{138} + return fileDescriptor_9198ee693835762e, []int{140} } func (m *SemaphoreV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8299,7 +8436,7 @@ func (m *SemaphoreSpecV3) Reset() { *m = SemaphoreSpecV3{} } func (m *SemaphoreSpecV3) String() string { return proto.CompactTextString(m) } func (*SemaphoreSpecV3) ProtoMessage() {} func (*SemaphoreSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{139} + return fileDescriptor_9198ee693835762e, []int{141} } func (m *SemaphoreSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8348,7 +8485,7 @@ type WebSessionV2 struct { func (m *WebSessionV2) Reset() { *m = WebSessionV2{} } func (*WebSessionV2) ProtoMessage() {} func (*WebSessionV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{140} + return fileDescriptor_9198ee693835762e, []int{142} } func (m *WebSessionV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8414,7 +8551,7 @@ func (m *WebSessionSpecV2) Reset() { *m = WebSessionSpecV2{} } func (m *WebSessionSpecV2) String() string { return proto.CompactTextString(m) } func (*WebSessionSpecV2) ProtoMessage() {} func (*WebSessionSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{141} + return fileDescriptor_9198ee693835762e, []int{143} } func (m *WebSessionSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8456,7 +8593,7 @@ func (m *WebSessionFilter) Reset() { *m = WebSessionFilter{} } func (m *WebSessionFilter) String() string { return proto.CompactTextString(m) } func (*WebSessionFilter) ProtoMessage() {} func (*WebSessionFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{142} + return fileDescriptor_9198ee693835762e, []int{144} } func (m *WebSessionFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8527,7 +8664,7 @@ func (m *SAMLSessionData) Reset() { *m = SAMLSessionData{} } func (m *SAMLSessionData) String() string { return proto.CompactTextString(m) } func (*SAMLSessionData) ProtoMessage() {} func (*SAMLSessionData) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{143} + return fileDescriptor_9198ee693835762e, []int{145} } func (m *SAMLSessionData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8576,7 +8713,7 @@ func (m *SAMLAttribute) Reset() { *m = SAMLAttribute{} } func (m *SAMLAttribute) String() string { return proto.CompactTextString(m) } func (*SAMLAttribute) ProtoMessage() {} func (*SAMLAttribute) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{144} + return fileDescriptor_9198ee693835762e, []int{146} } func (m *SAMLAttribute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8623,7 +8760,7 @@ func (m *SAMLAttributeValue) Reset() { *m = SAMLAttributeValue{} } func (m *SAMLAttributeValue) String() string { return proto.CompactTextString(m) } func (*SAMLAttributeValue) ProtoMessage() {} func (*SAMLAttributeValue) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{145} + return fileDescriptor_9198ee693835762e, []int{147} } func (m *SAMLAttributeValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8674,7 +8811,7 @@ func (m *SAMLNameID) Reset() { *m = SAMLNameID{} } func (m *SAMLNameID) String() string { return proto.CompactTextString(m) } func (*SAMLNameID) ProtoMessage() {} func (*SAMLNameID) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{146} + return fileDescriptor_9198ee693835762e, []int{148} } func (m *SAMLNameID) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8723,7 +8860,7 @@ type RemoteClusterV3 struct { func (m *RemoteClusterV3) Reset() { *m = RemoteClusterV3{} } func (*RemoteClusterV3) ProtoMessage() {} func (*RemoteClusterV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{147} + return fileDescriptor_9198ee693835762e, []int{149} } func (m *RemoteClusterV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8767,7 +8904,7 @@ func (m *RemoteClusterStatusV3) Reset() { *m = RemoteClusterStatusV3{} } func (m *RemoteClusterStatusV3) String() string { return proto.CompactTextString(m) } func (*RemoteClusterStatusV3) ProtoMessage() {} func (*RemoteClusterStatusV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{148} + return fileDescriptor_9198ee693835762e, []int{150} } func (m *RemoteClusterStatusV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8817,7 +8954,7 @@ func (m *KubernetesCluster) Reset() { *m = KubernetesCluster{} } func (m *KubernetesCluster) String() string { return proto.CompactTextString(m) } func (*KubernetesCluster) ProtoMessage() {} func (*KubernetesCluster) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{149} + return fileDescriptor_9198ee693835762e, []int{151} } func (m *KubernetesCluster) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8866,7 +9003,7 @@ type KubernetesClusterV3 struct { func (m *KubernetesClusterV3) Reset() { *m = KubernetesClusterV3{} } func (*KubernetesClusterV3) ProtoMessage() {} func (*KubernetesClusterV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{150} + return fileDescriptor_9198ee693835762e, []int{152} } func (m *KubernetesClusterV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8917,7 +9054,7 @@ func (m *KubernetesClusterSpecV3) Reset() { *m = KubernetesClusterSpecV3 func (m *KubernetesClusterSpecV3) String() string { return proto.CompactTextString(m) } func (*KubernetesClusterSpecV3) ProtoMessage() {} func (*KubernetesClusterSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{151} + return fileDescriptor_9198ee693835762e, []int{153} } func (m *KubernetesClusterSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8965,7 +9102,7 @@ func (m *KubeAzure) Reset() { *m = KubeAzure{} } func (m *KubeAzure) String() string { return proto.CompactTextString(m) } func (*KubeAzure) ProtoMessage() {} func (*KubeAzure) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{152} + return fileDescriptor_9198ee693835762e, []int{154} } func (m *KubeAzure) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9011,7 +9148,7 @@ func (m *KubeAWS) Reset() { *m = KubeAWS{} } func (m *KubeAWS) String() string { return proto.CompactTextString(m) } func (*KubeAWS) ProtoMessage() {} func (*KubeAWS) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{153} + return fileDescriptor_9198ee693835762e, []int{155} } func (m *KubeAWS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9057,7 +9194,7 @@ func (m *KubeGCP) Reset() { *m = KubeGCP{} } func (m *KubeGCP) String() string { return proto.CompactTextString(m) } func (*KubeGCP) ProtoMessage() {} func (*KubeGCP) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{154} + return fileDescriptor_9198ee693835762e, []int{156} } func (m *KubeGCP) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9099,7 +9236,7 @@ func (m *KubernetesClusterV3List) Reset() { *m = KubernetesClusterV3List func (m *KubernetesClusterV3List) String() string { return proto.CompactTextString(m) } func (*KubernetesClusterV3List) ProtoMessage() {} func (*KubernetesClusterV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{155} + return fileDescriptor_9198ee693835762e, []int{157} } func (m *KubernetesClusterV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9148,7 +9285,7 @@ type KubernetesServerV3 struct { func (m *KubernetesServerV3) Reset() { *m = KubernetesServerV3{} } func (*KubernetesServerV3) ProtoMessage() {} func (*KubernetesServerV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{156} + return fileDescriptor_9198ee693835762e, []int{158} } func (m *KubernetesServerV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9200,7 +9337,7 @@ func (m *KubernetesServerSpecV3) Reset() { *m = KubernetesServerSpecV3{} func (m *KubernetesServerSpecV3) String() string { return proto.CompactTextString(m) } func (*KubernetesServerSpecV3) ProtoMessage() {} func (*KubernetesServerSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{157} + return fileDescriptor_9198ee693835762e, []int{159} } func (m *KubernetesServerSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9252,7 +9389,7 @@ type WebTokenV3 struct { func (m *WebTokenV3) Reset() { *m = WebTokenV3{} } func (*WebTokenV3) ProtoMessage() {} func (*WebTokenV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{158} + return fileDescriptor_9198ee693835762e, []int{160} } func (m *WebTokenV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9296,7 +9433,7 @@ func (m *WebTokenSpecV3) Reset() { *m = WebTokenSpecV3{} } func (m *WebTokenSpecV3) String() string { return proto.CompactTextString(m) } func (*WebTokenSpecV3) ProtoMessage() {} func (*WebTokenSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{159} + return fileDescriptor_9198ee693835762e, []int{161} } func (m *WebTokenSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9340,7 +9477,7 @@ func (m *GetWebSessionRequest) Reset() { *m = GetWebSessionRequest{} } func (m *GetWebSessionRequest) String() string { return proto.CompactTextString(m) } func (*GetWebSessionRequest) ProtoMessage() {} func (*GetWebSessionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{160} + return fileDescriptor_9198ee693835762e, []int{162} } func (m *GetWebSessionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9384,7 +9521,7 @@ func (m *DeleteWebSessionRequest) Reset() { *m = DeleteWebSessionRequest func (m *DeleteWebSessionRequest) String() string { return proto.CompactTextString(m) } func (*DeleteWebSessionRequest) ProtoMessage() {} func (*DeleteWebSessionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{161} + return fileDescriptor_9198ee693835762e, []int{163} } func (m *DeleteWebSessionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9428,7 +9565,7 @@ func (m *GetWebTokenRequest) Reset() { *m = GetWebTokenRequest{} } func (m *GetWebTokenRequest) String() string { return proto.CompactTextString(m) } func (*GetWebTokenRequest) ProtoMessage() {} func (*GetWebTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{162} + return fileDescriptor_9198ee693835762e, []int{164} } func (m *GetWebTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9472,7 +9609,7 @@ func (m *DeleteWebTokenRequest) Reset() { *m = DeleteWebTokenRequest{} } func (m *DeleteWebTokenRequest) String() string { return proto.CompactTextString(m) } func (*DeleteWebTokenRequest) ProtoMessage() {} func (*DeleteWebTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{163} + return fileDescriptor_9198ee693835762e, []int{165} } func (m *DeleteWebTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9514,7 +9651,7 @@ func (m *ResourceRequest) Reset() { *m = ResourceRequest{} } func (m *ResourceRequest) String() string { return proto.CompactTextString(m) } func (*ResourceRequest) ProtoMessage() {} func (*ResourceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{164} + return fileDescriptor_9198ee693835762e, []int{166} } func (m *ResourceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9558,7 +9695,7 @@ func (m *ResourceWithSecretsRequest) Reset() { *m = ResourceWithSecretsR func (m *ResourceWithSecretsRequest) String() string { return proto.CompactTextString(m) } func (*ResourceWithSecretsRequest) ProtoMessage() {} func (*ResourceWithSecretsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{165} + return fileDescriptor_9198ee693835762e, []int{167} } func (m *ResourceWithSecretsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9600,7 +9737,7 @@ func (m *ResourcesWithSecretsRequest) Reset() { *m = ResourcesWithSecret func (m *ResourcesWithSecretsRequest) String() string { return proto.CompactTextString(m) } func (*ResourcesWithSecretsRequest) ProtoMessage() {} func (*ResourcesWithSecretsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{166} + return fileDescriptor_9198ee693835762e, []int{168} } func (m *ResourcesWithSecretsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9644,7 +9781,7 @@ func (m *ResourceInNamespaceRequest) Reset() { *m = ResourceInNamespaceR func (m *ResourceInNamespaceRequest) String() string { return proto.CompactTextString(m) } func (*ResourceInNamespaceRequest) ProtoMessage() {} func (*ResourceInNamespaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{167} + return fileDescriptor_9198ee693835762e, []int{169} } func (m *ResourceInNamespaceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9686,7 +9823,7 @@ func (m *ResourcesInNamespaceRequest) Reset() { *m = ResourcesInNamespac func (m *ResourcesInNamespaceRequest) String() string { return proto.CompactTextString(m) } func (*ResourcesInNamespaceRequest) ProtoMessage() {} func (*ResourcesInNamespaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{168} + return fileDescriptor_9198ee693835762e, []int{170} } func (m *ResourcesInNamespaceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9736,7 +9873,7 @@ func (m *OIDCConnectorV3) Reset() { *m = OIDCConnectorV3{} } func (m *OIDCConnectorV3) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorV3) ProtoMessage() {} func (*OIDCConnectorV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{169} + return fileDescriptor_9198ee693835762e, []int{171} } func (m *OIDCConnectorV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9778,7 +9915,7 @@ func (m *OIDCConnectorV3List) Reset() { *m = OIDCConnectorV3List{} } func (m *OIDCConnectorV3List) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorV3List) ProtoMessage() {} func (*OIDCConnectorV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{170} + return fileDescriptor_9198ee693835762e, []int{172} } func (m *OIDCConnectorV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9857,7 +9994,7 @@ func (m *OIDCConnectorSpecV3) Reset() { *m = OIDCConnectorSpecV3{} } func (m *OIDCConnectorSpecV3) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorSpecV3) ProtoMessage() {} func (*OIDCConnectorSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{171} + return fileDescriptor_9198ee693835762e, []int{173} } func (m *OIDCConnectorSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9943,7 +10080,7 @@ func (m *OIDCAuthRequest) Reset() { *m = OIDCAuthRequest{} } func (m *OIDCAuthRequest) String() string { return proto.CompactTextString(m) } func (*OIDCAuthRequest) ProtoMessage() {} func (*OIDCAuthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{172} + return fileDescriptor_9198ee693835762e, []int{174} } func (m *OIDCAuthRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9993,7 +10130,7 @@ func (m *SAMLConnectorV2) Reset() { *m = SAMLConnectorV2{} } func (m *SAMLConnectorV2) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorV2) ProtoMessage() {} func (*SAMLConnectorV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{173} + return fileDescriptor_9198ee693835762e, []int{175} } func (m *SAMLConnectorV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10035,7 +10172,7 @@ func (m *SAMLConnectorV2List) Reset() { *m = SAMLConnectorV2List{} } func (m *SAMLConnectorV2List) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorV2List) ProtoMessage() {} func (*SAMLConnectorV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{174} + return fileDescriptor_9198ee693835762e, []int{176} } func (m *SAMLConnectorV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10107,7 +10244,7 @@ func (m *SAMLConnectorSpecV2) Reset() { *m = SAMLConnectorSpecV2{} } func (m *SAMLConnectorSpecV2) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorSpecV2) ProtoMessage() {} func (*SAMLConnectorSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{175} + return fileDescriptor_9198ee693835762e, []int{177} } func (m *SAMLConnectorSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10186,7 +10323,7 @@ func (m *SAMLAuthRequest) Reset() { *m = SAMLAuthRequest{} } func (m *SAMLAuthRequest) String() string { return proto.CompactTextString(m) } func (*SAMLAuthRequest) ProtoMessage() {} func (*SAMLAuthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{176} + return fileDescriptor_9198ee693835762e, []int{178} } func (m *SAMLAuthRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10232,7 +10369,7 @@ func (m *AttributeMapping) Reset() { *m = AttributeMapping{} } func (m *AttributeMapping) String() string { return proto.CompactTextString(m) } func (*AttributeMapping) ProtoMessage() {} func (*AttributeMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{177} + return fileDescriptor_9198ee693835762e, []int{179} } func (m *AttributeMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10277,7 +10414,7 @@ func (m *AsymmetricKeyPair) Reset() { *m = AsymmetricKeyPair{} } func (m *AsymmetricKeyPair) String() string { return proto.CompactTextString(m) } func (*AsymmetricKeyPair) ProtoMessage() {} func (*AsymmetricKeyPair) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{178} + return fileDescriptor_9198ee693835762e, []int{180} } func (m *AsymmetricKeyPair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10327,7 +10464,7 @@ func (m *GithubConnectorV3) Reset() { *m = GithubConnectorV3{} } func (m *GithubConnectorV3) String() string { return proto.CompactTextString(m) } func (*GithubConnectorV3) ProtoMessage() {} func (*GithubConnectorV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{179} + return fileDescriptor_9198ee693835762e, []int{181} } func (m *GithubConnectorV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10369,7 +10506,7 @@ func (m *GithubConnectorV3List) Reset() { *m = GithubConnectorV3List{} } func (m *GithubConnectorV3List) String() string { return proto.CompactTextString(m) } func (*GithubConnectorV3List) ProtoMessage() {} func (*GithubConnectorV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{180} + return fileDescriptor_9198ee693835762e, []int{182} } func (m *GithubConnectorV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10429,7 +10566,7 @@ func (m *GithubConnectorSpecV3) Reset() { *m = GithubConnectorSpecV3{} } func (m *GithubConnectorSpecV3) String() string { return proto.CompactTextString(m) } func (*GithubConnectorSpecV3) ProtoMessage() {} func (*GithubConnectorSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{181} + return fileDescriptor_9198ee693835762e, []int{183} } func (m *GithubConnectorSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10505,7 +10642,7 @@ func (m *GithubAuthRequest) Reset() { *m = GithubAuthRequest{} } func (m *GithubAuthRequest) String() string { return proto.CompactTextString(m) } func (*GithubAuthRequest) ProtoMessage() {} func (*GithubAuthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{182} + return fileDescriptor_9198ee693835762e, []int{184} } func (m *GithubAuthRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10549,7 +10686,7 @@ func (m *SSOWarnings) Reset() { *m = SSOWarnings{} } func (m *SSOWarnings) String() string { return proto.CompactTextString(m) } func (*SSOWarnings) ProtoMessage() {} func (*SSOWarnings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{183} + return fileDescriptor_9198ee693835762e, []int{185} } func (m *SSOWarnings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10605,7 +10742,7 @@ func (m *CreateUserParams) Reset() { *m = CreateUserParams{} } func (m *CreateUserParams) String() string { return proto.CompactTextString(m) } func (*CreateUserParams) ProtoMessage() {} func (*CreateUserParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{184} + return fileDescriptor_9198ee693835762e, []int{186} } func (m *CreateUserParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10690,7 +10827,7 @@ func (m *SSODiagnosticInfo) Reset() { *m = SSODiagnosticInfo{} } func (m *SSODiagnosticInfo) String() string { return proto.CompactTextString(m) } func (*SSODiagnosticInfo) ProtoMessage() {} func (*SSODiagnosticInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{185} + return fileDescriptor_9198ee693835762e, []int{187} } func (m *SSODiagnosticInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10734,7 +10871,7 @@ func (m *GithubTokenInfo) Reset() { *m = GithubTokenInfo{} } func (m *GithubTokenInfo) String() string { return proto.CompactTextString(m) } func (*GithubTokenInfo) ProtoMessage() {} func (*GithubTokenInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{186} + return fileDescriptor_9198ee693835762e, []int{188} } func (m *GithubTokenInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10780,7 +10917,7 @@ func (m *GithubClaims) Reset() { *m = GithubClaims{} } func (m *GithubClaims) String() string { return proto.CompactTextString(m) } func (*GithubClaims) ProtoMessage() {} func (*GithubClaims) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{187} + return fileDescriptor_9198ee693835762e, []int{189} } func (m *GithubClaims) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10832,7 +10969,7 @@ func (m *TeamMapping) Reset() { *m = TeamMapping{} } func (m *TeamMapping) String() string { return proto.CompactTextString(m) } func (*TeamMapping) ProtoMessage() {} func (*TeamMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{188} + return fileDescriptor_9198ee693835762e, []int{190} } func (m *TeamMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10878,7 +11015,7 @@ func (m *TeamRolesMapping) Reset() { *m = TeamRolesMapping{} } func (m *TeamRolesMapping) String() string { return proto.CompactTextString(m) } func (*TeamRolesMapping) ProtoMessage() {} func (*TeamRolesMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{189} + return fileDescriptor_9198ee693835762e, []int{191} } func (m *TeamRolesMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10927,7 +11064,7 @@ type TrustedClusterV2 struct { func (m *TrustedClusterV2) Reset() { *m = TrustedClusterV2{} } func (*TrustedClusterV2) ProtoMessage() {} func (*TrustedClusterV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{190} + return fileDescriptor_9198ee693835762e, []int{192} } func (m *TrustedClusterV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10969,7 +11106,7 @@ func (m *TrustedClusterV2List) Reset() { *m = TrustedClusterV2List{} } func (m *TrustedClusterV2List) String() string { return proto.CompactTextString(m) } func (*TrustedClusterV2List) ProtoMessage() {} func (*TrustedClusterV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{191} + return fileDescriptor_9198ee693835762e, []int{193} } func (m *TrustedClusterV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11025,7 +11162,7 @@ func (m *TrustedClusterSpecV2) Reset() { *m = TrustedClusterSpecV2{} } func (m *TrustedClusterSpecV2) String() string { return proto.CompactTextString(m) } func (*TrustedClusterSpecV2) ProtoMessage() {} func (*TrustedClusterSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{192} + return fileDescriptor_9198ee693835762e, []int{194} } func (m *TrustedClusterSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11078,7 +11215,7 @@ func (m *LockV2) Reset() { *m = LockV2{} } func (m *LockV2) String() string { return proto.CompactTextString(m) } func (*LockV2) ProtoMessage() {} func (*LockV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{193} + return fileDescriptor_9198ee693835762e, []int{195} } func (m *LockV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11128,7 +11265,7 @@ func (m *LockSpecV2) Reset() { *m = LockSpecV2{} } func (m *LockSpecV2) String() string { return proto.CompactTextString(m) } func (*LockSpecV2) ProtoMessage() {} func (*LockSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{194} + return fileDescriptor_9198ee693835762e, []int{196} } func (m *LockSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11189,7 +11326,7 @@ type LockTarget struct { func (m *LockTarget) Reset() { *m = LockTarget{} } func (*LockTarget) ProtoMessage() {} func (*LockTarget) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{195} + return fileDescriptor_9198ee693835762e, []int{197} } func (m *LockTarget) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11233,7 +11370,7 @@ func (m *AddressCondition) Reset() { *m = AddressCondition{} } func (m *AddressCondition) String() string { return proto.CompactTextString(m) } func (*AddressCondition) ProtoMessage() {} func (*AddressCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{196} + return fileDescriptor_9198ee693835762e, []int{198} } func (m *AddressCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11276,7 +11413,7 @@ func (m *NetworkRestrictionsSpecV4) Reset() { *m = NetworkRestrictionsSp func (m *NetworkRestrictionsSpecV4) String() string { return proto.CompactTextString(m) } func (*NetworkRestrictionsSpecV4) ProtoMessage() {} func (*NetworkRestrictionsSpecV4) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{197} + return fileDescriptor_9198ee693835762e, []int{199} } func (m *NetworkRestrictionsSpecV4) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11329,7 +11466,7 @@ func (m *NetworkRestrictionsV4) Reset() { *m = NetworkRestrictionsV4{} } func (m *NetworkRestrictionsV4) String() string { return proto.CompactTextString(m) } func (*NetworkRestrictionsV4) ProtoMessage() {} func (*NetworkRestrictionsV4) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{198} + return fileDescriptor_9198ee693835762e, []int{200} } func (m *NetworkRestrictionsV4) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11373,7 +11510,7 @@ func (m *WindowsDesktopServiceV3) Reset() { *m = WindowsDesktopServiceV3 func (m *WindowsDesktopServiceV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopServiceV3) ProtoMessage() {} func (*WindowsDesktopServiceV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{199} + return fileDescriptor_9198ee693835762e, []int{201} } func (m *WindowsDesktopServiceV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11421,7 +11558,7 @@ func (m *WindowsDesktopServiceSpecV3) Reset() { *m = WindowsDesktopServi func (m *WindowsDesktopServiceSpecV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopServiceSpecV3) ProtoMessage() {} func (*WindowsDesktopServiceSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{200} + return fileDescriptor_9198ee693835762e, []int{202} } func (m *WindowsDesktopServiceSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11465,7 +11602,7 @@ func (m *WindowsDesktopFilter) Reset() { *m = WindowsDesktopFilter{} } func (m *WindowsDesktopFilter) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopFilter) ProtoMessage() {} func (*WindowsDesktopFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{201} + return fileDescriptor_9198ee693835762e, []int{203} } func (m *WindowsDesktopFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11509,7 +11646,7 @@ func (m *WindowsDesktopV3) Reset() { *m = WindowsDesktopV3{} } func (m *WindowsDesktopV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopV3) ProtoMessage() {} func (*WindowsDesktopV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{202} + return fileDescriptor_9198ee693835762e, []int{204} } func (m *WindowsDesktopV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11558,7 +11695,7 @@ func (m *WindowsDesktopSpecV3) Reset() { *m = WindowsDesktopSpecV3{} } func (m *WindowsDesktopSpecV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopSpecV3) ProtoMessage() {} func (*WindowsDesktopSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{203} + return fileDescriptor_9198ee693835762e, []int{205} } func (m *WindowsDesktopSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11631,7 +11768,7 @@ func (m *RegisterUsingTokenRequest) Reset() { *m = RegisterUsingTokenReq func (m *RegisterUsingTokenRequest) String() string { return proto.CompactTextString(m) } func (*RegisterUsingTokenRequest) ProtoMessage() {} func (*RegisterUsingTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{204} + return fileDescriptor_9198ee693835762e, []int{206} } func (m *RegisterUsingTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11685,7 +11822,7 @@ func (m *RecoveryCodesV1) Reset() { *m = RecoveryCodesV1{} } func (m *RecoveryCodesV1) String() string { return proto.CompactTextString(m) } func (*RecoveryCodesV1) ProtoMessage() {} func (*RecoveryCodesV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{205} + return fileDescriptor_9198ee693835762e, []int{207} } func (m *RecoveryCodesV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11730,7 +11867,7 @@ func (m *RecoveryCodesSpecV1) Reset() { *m = RecoveryCodesSpecV1{} } func (m *RecoveryCodesSpecV1) String() string { return proto.CompactTextString(m) } func (*RecoveryCodesSpecV1) ProtoMessage() {} func (*RecoveryCodesSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{206} + return fileDescriptor_9198ee693835762e, []int{208} } func (m *RecoveryCodesSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11774,7 +11911,7 @@ func (m *RecoveryCode) Reset() { *m = RecoveryCode{} } func (m *RecoveryCode) String() string { return proto.CompactTextString(m) } func (*RecoveryCode) ProtoMessage() {} func (*RecoveryCode) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{207} + return fileDescriptor_9198ee693835762e, []int{209} } func (m *RecoveryCode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11814,7 +11951,7 @@ func (m *NullableSessionState) Reset() { *m = NullableSessionState{} } func (m *NullableSessionState) String() string { return proto.CompactTextString(m) } func (*NullableSessionState) ProtoMessage() {} func (*NullableSessionState) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{208} + return fileDescriptor_9198ee693835762e, []int{210} } func (m *NullableSessionState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11860,7 +11997,7 @@ func (m *SessionTrackerFilter) Reset() { *m = SessionTrackerFilter{} } func (m *SessionTrackerFilter) String() string { return proto.CompactTextString(m) } func (*SessionTrackerFilter) ProtoMessage() {} func (*SessionTrackerFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{209} + return fileDescriptor_9198ee693835762e, []int{211} } func (m *SessionTrackerFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11904,7 +12041,7 @@ func (m *SessionTrackerV1) Reset() { *m = SessionTrackerV1{} } func (m *SessionTrackerV1) String() string { return proto.CompactTextString(m) } func (*SessionTrackerV1) ProtoMessage() {} func (*SessionTrackerV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{210} + return fileDescriptor_9198ee693835762e, []int{212} } func (m *SessionTrackerV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11998,7 +12135,7 @@ func (m *SessionTrackerSpecV1) Reset() { *m = SessionTrackerSpecV1{} } func (m *SessionTrackerSpecV1) String() string { return proto.CompactTextString(m) } func (*SessionTrackerSpecV1) ProtoMessage() {} func (*SessionTrackerSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{211} + return fileDescriptor_9198ee693835762e, []int{213} } func (m *SessionTrackerSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12045,7 +12182,7 @@ func (m *SessionTrackerPolicySet) Reset() { *m = SessionTrackerPolicySet func (m *SessionTrackerPolicySet) String() string { return proto.CompactTextString(m) } func (*SessionTrackerPolicySet) ProtoMessage() {} func (*SessionTrackerPolicySet) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{212} + return fileDescriptor_9198ee693835762e, []int{214} } func (m *SessionTrackerPolicySet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12093,7 +12230,7 @@ func (m *Participant) Reset() { *m = Participant{} } func (m *Participant) String() string { return proto.CompactTextString(m) } func (*Participant) ProtoMessage() {} func (*Participant) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{213} + return fileDescriptor_9198ee693835762e, []int{215} } func (m *Participant) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12137,7 +12274,7 @@ func (m *UIConfigV1) Reset() { *m = UIConfigV1{} } func (m *UIConfigV1) String() string { return proto.CompactTextString(m) } func (*UIConfigV1) ProtoMessage() {} func (*UIConfigV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{214} + return fileDescriptor_9198ee693835762e, []int{216} } func (m *UIConfigV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12178,7 +12315,7 @@ func (m *UIConfigSpecV1) Reset() { *m = UIConfigSpecV1{} } func (m *UIConfigSpecV1) String() string { return proto.CompactTextString(m) } func (*UIConfigSpecV1) ProtoMessage() {} func (*UIConfigSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{215} + return fileDescriptor_9198ee693835762e, []int{217} } func (m *UIConfigSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12229,7 +12366,7 @@ func (m *InstallerV1) Reset() { *m = InstallerV1{} } func (m *InstallerV1) String() string { return proto.CompactTextString(m) } func (*InstallerV1) ProtoMessage() {} func (*InstallerV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{216} + return fileDescriptor_9198ee693835762e, []int{218} } func (m *InstallerV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12271,7 +12408,7 @@ func (m *InstallerSpecV1) Reset() { *m = InstallerSpecV1{} } func (m *InstallerSpecV1) String() string { return proto.CompactTextString(m) } func (*InstallerSpecV1) ProtoMessage() {} func (*InstallerSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{217} + return fileDescriptor_9198ee693835762e, []int{219} } func (m *InstallerSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12313,7 +12450,7 @@ func (m *InstallerV1List) Reset() { *m = InstallerV1List{} } func (m *InstallerV1List) String() string { return proto.CompactTextString(m) } func (*InstallerV1List) ProtoMessage() {} func (*InstallerV1List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{218} + return fileDescriptor_9198ee693835762e, []int{220} } func (m *InstallerV1List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12357,7 +12494,7 @@ func (m *SortBy) Reset() { *m = SortBy{} } func (m *SortBy) String() string { return proto.CompactTextString(m) } func (*SortBy) ProtoMessage() {} func (*SortBy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{219} + return fileDescriptor_9198ee693835762e, []int{221} } func (m *SortBy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12403,7 +12540,7 @@ func (m *ConnectionDiagnosticV1) Reset() { *m = ConnectionDiagnosticV1{} func (m *ConnectionDiagnosticV1) String() string { return proto.CompactTextString(m) } func (*ConnectionDiagnosticV1) ProtoMessage() {} func (*ConnectionDiagnosticV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{220} + return fileDescriptor_9198ee693835762e, []int{222} } func (m *ConnectionDiagnosticV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12453,7 +12590,7 @@ func (m *ConnectionDiagnosticSpecV1) Reset() { *m = ConnectionDiagnostic func (m *ConnectionDiagnosticSpecV1) String() string { return proto.CompactTextString(m) } func (*ConnectionDiagnosticSpecV1) ProtoMessage() {} func (*ConnectionDiagnosticSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{221} + return fileDescriptor_9198ee693835762e, []int{223} } func (m *ConnectionDiagnosticSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12499,7 +12636,7 @@ func (m *ConnectionDiagnosticTrace) Reset() { *m = ConnectionDiagnosticT func (m *ConnectionDiagnosticTrace) String() string { return proto.CompactTextString(m) } func (*ConnectionDiagnosticTrace) ProtoMessage() {} func (*ConnectionDiagnosticTrace) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{222} + return fileDescriptor_9198ee693835762e, []int{224} } func (m *ConnectionDiagnosticTrace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12542,7 +12679,7 @@ func (m *DatabaseServiceV1) Reset() { *m = DatabaseServiceV1{} } func (m *DatabaseServiceV1) String() string { return proto.CompactTextString(m) } func (*DatabaseServiceV1) ProtoMessage() {} func (*DatabaseServiceV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{223} + return fileDescriptor_9198ee693835762e, []int{225} } func (m *DatabaseServiceV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12584,7 +12721,7 @@ func (m *DatabaseServiceSpecV1) Reset() { *m = DatabaseServiceSpecV1{} } func (m *DatabaseServiceSpecV1) String() string { return proto.CompactTextString(m) } func (*DatabaseServiceSpecV1) ProtoMessage() {} func (*DatabaseServiceSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{224} + return fileDescriptor_9198ee693835762e, []int{226} } func (m *DatabaseServiceSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12615,17 +12752,18 @@ var xxx_messageInfo_DatabaseServiceSpecV1 proto.InternalMessageInfo // DatabaseResourceMatcher is a set of properties that is used to match on resources. type DatabaseResourceMatcher struct { - Labels *Labels `protobuf:"bytes,1,opt,name=Labels,proto3,customtype=Labels" json:"labels"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Labels *Labels `protobuf:"bytes,1,opt,name=Labels,proto3,customtype=Labels" json:"labels"` + AWS ResourceMatcherAWS `protobuf:"bytes,2,opt,name=AWS,proto3" json:"aws"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *DatabaseResourceMatcher) Reset() { *m = DatabaseResourceMatcher{} } func (m *DatabaseResourceMatcher) String() string { return proto.CompactTextString(m) } func (*DatabaseResourceMatcher) ProtoMessage() {} func (*DatabaseResourceMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{225} + return fileDescriptor_9198ee693835762e, []int{227} } func (m *DatabaseResourceMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12654,6 +12792,50 @@ func (m *DatabaseResourceMatcher) XXX_DiscardUnknown() { var xxx_messageInfo_DatabaseResourceMatcher proto.InternalMessageInfo +// ResourceMatcherAWS contains AWS specific settings for resource matcher. +type ResourceMatcherAWS struct { + // AssumeRoleARN is an optional AWS role ARN to assume when accessing a database. + AssumeRoleARN string `protobuf:"bytes,1,opt,name=AssumeRoleARN,proto3" json:"assume_role_arn,omitempty"` + // ExternalID is an optional AWS external ID used to enable assuming an AWS role across accounts. + ExternalID string `protobuf:"bytes,2,opt,name=ExternalID,proto3" json:"external_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ResourceMatcherAWS) Reset() { *m = ResourceMatcherAWS{} } +func (m *ResourceMatcherAWS) String() string { return proto.CompactTextString(m) } +func (*ResourceMatcherAWS) ProtoMessage() {} +func (*ResourceMatcherAWS) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{228} +} +func (m *ResourceMatcherAWS) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceMatcherAWS) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ResourceMatcherAWS.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ResourceMatcherAWS) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceMatcherAWS.Merge(m, src) +} +func (m *ResourceMatcherAWS) XXX_Size() int { + return m.Size() +} +func (m *ResourceMatcherAWS) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceMatcherAWS.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceMatcherAWS proto.InternalMessageInfo + // ClusterAlert is a cluster-level alert message. type ClusterAlert struct { ResourceHeader `protobuf:"bytes,1,opt,name=Header,proto3,embedded=Header" json:""` @@ -12667,7 +12849,7 @@ func (m *ClusterAlert) Reset() { *m = ClusterAlert{} } func (m *ClusterAlert) String() string { return proto.CompactTextString(m) } func (*ClusterAlert) ProtoMessage() {} func (*ClusterAlert) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{226} + return fileDescriptor_9198ee693835762e, []int{229} } func (m *ClusterAlert) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12713,7 +12895,7 @@ func (m *ClusterAlertSpec) Reset() { *m = ClusterAlertSpec{} } func (m *ClusterAlertSpec) String() string { return proto.CompactTextString(m) } func (*ClusterAlertSpec) ProtoMessage() {} func (*ClusterAlertSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{227} + return fileDescriptor_9198ee693835762e, []int{230} } func (m *ClusterAlertSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12766,7 +12948,7 @@ func (m *GetClusterAlertsRequest) Reset() { *m = GetClusterAlertsRequest func (m *GetClusterAlertsRequest) String() string { return proto.CompactTextString(m) } func (*GetClusterAlertsRequest) ProtoMessage() {} func (*GetClusterAlertsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{228} + return fileDescriptor_9198ee693835762e, []int{231} } func (m *GetClusterAlertsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12816,7 +12998,7 @@ func (m *AlertAcknowledgement) Reset() { *m = AlertAcknowledgement{} } func (m *AlertAcknowledgement) String() string { return proto.CompactTextString(m) } func (*AlertAcknowledgement) ProtoMessage() {} func (*AlertAcknowledgement) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{229} + return fileDescriptor_9198ee693835762e, []int{232} } func (m *AlertAcknowledgement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12868,7 +13050,7 @@ func (m *Release) Reset() { *m = Release{} } func (m *Release) String() string { return proto.CompactTextString(m) } func (*Release) ProtoMessage() {} func (*Release) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{230} + return fileDescriptor_9198ee693835762e, []int{233} } func (m *Release) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12926,7 +13108,7 @@ func (m *Asset) Reset() { *m = Asset{} } func (m *Asset) String() string { return proto.CompactTextString(m) } func (*Asset) ProtoMessage() {} func (*Asset) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{231} + return fileDescriptor_9198ee693835762e, []int{234} } func (m *Asset) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12979,7 +13161,7 @@ func (m *PluginV1) Reset() { *m = PluginV1{} } func (m *PluginV1) String() string { return proto.CompactTextString(m) } func (*PluginV1) ProtoMessage() {} func (*PluginV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{232} + return fileDescriptor_9198ee693835762e, []int{235} } func (m *PluginV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13018,6 +13200,7 @@ type PluginSpecV1 struct { // *PluginSpecV1_Openai // *PluginSpecV1_Okta // *PluginSpecV1_Jamf + // *PluginSpecV1_PagerDuty Settings isPluginSpecV1_Settings `protobuf_oneof:"settings"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -13028,7 +13211,7 @@ func (m *PluginSpecV1) Reset() { *m = PluginSpecV1{} } func (m *PluginSpecV1) String() string { return proto.CompactTextString(m) } func (*PluginSpecV1) ProtoMessage() {} func (*PluginSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{233} + return fileDescriptor_9198ee693835762e, []int{236} } func (m *PluginSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13079,12 +13262,16 @@ type PluginSpecV1_Okta struct { type PluginSpecV1_Jamf struct { Jamf *PluginJamfSettings `protobuf:"bytes,5,opt,name=jamf,proto3,oneof" json:"jamf,omitempty"` } +type PluginSpecV1_PagerDuty struct { + PagerDuty *PluginPagerDutySettings `protobuf:"bytes,6,opt,name=pager_duty,json=pagerDuty,proto3,oneof" json:"pager_duty,omitempty"` +} func (*PluginSpecV1_SlackAccessPlugin) isPluginSpecV1_Settings() {} func (*PluginSpecV1_Opsgenie) isPluginSpecV1_Settings() {} func (*PluginSpecV1_Openai) isPluginSpecV1_Settings() {} func (*PluginSpecV1_Okta) isPluginSpecV1_Settings() {} func (*PluginSpecV1_Jamf) isPluginSpecV1_Settings() {} +func (*PluginSpecV1_PagerDuty) isPluginSpecV1_Settings() {} func (m *PluginSpecV1) GetSettings() isPluginSpecV1_Settings { if m != nil { @@ -13128,6 +13315,13 @@ func (m *PluginSpecV1) GetJamf() *PluginJamfSettings { return nil } +func (m *PluginSpecV1) GetPagerDuty() *PluginPagerDutySettings { + if x, ok := m.GetSettings().(*PluginSpecV1_PagerDuty); ok { + return x.PagerDuty + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*PluginSpecV1) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -13136,6 +13330,7 @@ func (*PluginSpecV1) XXX_OneofWrappers() []interface{} { (*PluginSpecV1_Openai)(nil), (*PluginSpecV1_Okta)(nil), (*PluginSpecV1_Jamf)(nil), + (*PluginSpecV1_PagerDuty)(nil), } } @@ -13150,7 +13345,7 @@ func (m *PluginSlackAccessSettings) Reset() { *m = PluginSlackAccessSett func (m *PluginSlackAccessSettings) String() string { return proto.CompactTextString(m) } func (*PluginSlackAccessSettings) ProtoMessage() {} func (*PluginSlackAccessSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{234} + return fileDescriptor_9198ee693835762e, []int{237} } func (m *PluginSlackAccessSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13197,7 +13392,7 @@ func (m *PluginOpsgenieAccessSettings) Reset() { *m = PluginOpsgenieAcce func (m *PluginOpsgenieAccessSettings) String() string { return proto.CompactTextString(m) } func (*PluginOpsgenieAccessSettings) ProtoMessage() {} func (*PluginOpsgenieAccessSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{235} + return fileDescriptor_9198ee693835762e, []int{238} } func (m *PluginOpsgenieAccessSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13226,6 +13421,52 @@ func (m *PluginOpsgenieAccessSettings) XXX_DiscardUnknown() { var xxx_messageInfo_PluginOpsgenieAccessSettings proto.InternalMessageInfo +type PluginPagerDutySettings struct { + // UserEmail is the email address of the PagerDuty user that will be + // listed as the reporter source of incidents, comments, etc + // within PagerDuty. Should usually be the same user the API key + // represents. + UserEmail string `protobuf:"bytes,1,opt,name=user_email,json=userEmail,proto3" json:"user_email,omitempty"` + // APIEndpoint is the address of PagerDuty API. + ApiEndpoint string `protobuf:"bytes,2,opt,name=api_endpoint,json=apiEndpoint,proto3" json:"api_endpoint,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PluginPagerDutySettings) Reset() { *m = PluginPagerDutySettings{} } +func (m *PluginPagerDutySettings) String() string { return proto.CompactTextString(m) } +func (*PluginPagerDutySettings) ProtoMessage() {} +func (*PluginPagerDutySettings) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{239} +} +func (m *PluginPagerDutySettings) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PluginPagerDutySettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PluginPagerDutySettings.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PluginPagerDutySettings) XXX_Merge(src proto.Message) { + xxx_messageInfo_PluginPagerDutySettings.Merge(m, src) +} +func (m *PluginPagerDutySettings) XXX_Size() int { + return m.Size() +} +func (m *PluginPagerDutySettings) XXX_DiscardUnknown() { + xxx_messageInfo_PluginPagerDutySettings.DiscardUnknown(m) +} + +var xxx_messageInfo_PluginPagerDutySettings proto.InternalMessageInfo + // Defines settings for the OpenAI plugin. Currently there are no settings. type PluginOpenAISettings struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -13237,7 +13478,7 @@ func (m *PluginOpenAISettings) Reset() { *m = PluginOpenAISettings{} } func (m *PluginOpenAISettings) String() string { return proto.CompactTextString(m) } func (*PluginOpenAISettings) ProtoMessage() {} func (*PluginOpenAISettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{236} + return fileDescriptor_9198ee693835762e, []int{240} } func (m *PluginOpenAISettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13279,7 +13520,7 @@ func (m *PluginJamfSettings) Reset() { *m = PluginJamfSettings{} } func (m *PluginJamfSettings) String() string { return proto.CompactTextString(m) } func (*PluginJamfSettings) ProtoMessage() {} func (*PluginJamfSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{237} + return fileDescriptor_9198ee693835762e, []int{241} } func (m *PluginJamfSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13321,7 +13562,7 @@ func (m *PluginOktaSettings) Reset() { *m = PluginOktaSettings{} } func (m *PluginOktaSettings) String() string { return proto.CompactTextString(m) } func (*PluginOktaSettings) ProtoMessage() {} func (*PluginOktaSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{238} + return fileDescriptor_9198ee693835762e, []int{242} } func (m *PluginOktaSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13366,7 +13607,7 @@ func (m *PluginBootstrapCredentialsV1) Reset() { *m = PluginBootstrapCre func (m *PluginBootstrapCredentialsV1) String() string { return proto.CompactTextString(m) } func (*PluginBootstrapCredentialsV1) ProtoMessage() {} func (*PluginBootstrapCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{239} + return fileDescriptor_9198ee693835762e, []int{243} } func (m *PluginBootstrapCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13466,7 +13707,7 @@ func (m *PluginIdSecretCredential) Reset() { *m = PluginIdSecretCredenti func (m *PluginIdSecretCredential) String() string { return proto.CompactTextString(m) } func (*PluginIdSecretCredential) ProtoMessage() {} func (*PluginIdSecretCredential) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{240} + return fileDescriptor_9198ee693835762e, []int{244} } func (m *PluginIdSecretCredential) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13509,7 +13750,7 @@ func (m *PluginOAuth2AuthorizationCodeCredentials) Reset() { func (m *PluginOAuth2AuthorizationCodeCredentials) String() string { return proto.CompactTextString(m) } func (*PluginOAuth2AuthorizationCodeCredentials) ProtoMessage() {} func (*PluginOAuth2AuthorizationCodeCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{241} + return fileDescriptor_9198ee693835762e, []int{245} } func (m *PluginOAuth2AuthorizationCodeCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13550,7 +13791,7 @@ func (m *PluginStatusV1) Reset() { *m = PluginStatusV1{} } func (m *PluginStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginStatusV1) ProtoMessage() {} func (*PluginStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{242} + return fileDescriptor_9198ee693835762e, []int{246} } func (m *PluginStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13598,7 +13839,7 @@ func (m *PluginCredentialsV1) Reset() { *m = PluginCredentialsV1{} } func (m *PluginCredentialsV1) String() string { return proto.CompactTextString(m) } func (*PluginCredentialsV1) ProtoMessage() {} func (*PluginCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{243} + return fileDescriptor_9198ee693835762e, []int{247} } func (m *PluginCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13709,7 +13950,7 @@ func (m *PluginOAuth2AccessTokenCredentials) Reset() { *m = PluginOAuth2 func (m *PluginOAuth2AccessTokenCredentials) String() string { return proto.CompactTextString(m) } func (*PluginOAuth2AccessTokenCredentials) ProtoMessage() {} func (*PluginOAuth2AccessTokenCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{244} + return fileDescriptor_9198ee693835762e, []int{248} } func (m *PluginOAuth2AccessTokenCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13750,7 +13991,7 @@ func (m *PluginBearerTokenCredentials) Reset() { *m = PluginBearerTokenC func (m *PluginBearerTokenCredentials) String() string { return proto.CompactTextString(m) } func (*PluginBearerTokenCredentials) ProtoMessage() {} func (*PluginBearerTokenCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{245} + return fileDescriptor_9198ee693835762e, []int{249} } func (m *PluginBearerTokenCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13792,7 +14033,7 @@ func (m *PluginStaticCredentialsRef) Reset() { *m = PluginStaticCredenti func (m *PluginStaticCredentialsRef) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsRef) ProtoMessage() {} func (*PluginStaticCredentialsRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{246} + return fileDescriptor_9198ee693835762e, []int{250} } func (m *PluginStaticCredentialsRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13834,7 +14075,7 @@ func (m *PluginListV1) Reset() { *m = PluginListV1{} } func (m *PluginListV1) String() string { return proto.CompactTextString(m) } func (*PluginListV1) ProtoMessage() {} func (*PluginListV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{247} + return fileDescriptor_9198ee693835762e, []int{251} } func (m *PluginListV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13877,7 +14118,7 @@ type PluginStaticCredentialsV1 struct { func (m *PluginStaticCredentialsV1) Reset() { *m = PluginStaticCredentialsV1{} } func (*PluginStaticCredentialsV1) ProtoMessage() {} func (*PluginStaticCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{248} + return fileDescriptor_9198ee693835762e, []int{252} } func (m *PluginStaticCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13923,7 +14164,7 @@ func (m *PluginStaticCredentialsSpecV1) Reset() { *m = PluginStaticCrede func (m *PluginStaticCredentialsSpecV1) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsSpecV1) ProtoMessage() {} func (*PluginStaticCredentialsSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{249} + return fileDescriptor_9198ee693835762e, []int{253} } func (m *PluginStaticCredentialsSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14025,7 +14266,7 @@ func (m *PluginStaticCredentialsBasicAuth) Reset() { *m = PluginStaticCr func (m *PluginStaticCredentialsBasicAuth) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsBasicAuth) ProtoMessage() {} func (*PluginStaticCredentialsBasicAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{250} + return fileDescriptor_9198ee693835762e, []int{254} } func (m *PluginStaticCredentialsBasicAuth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14071,7 +14312,7 @@ func (m *PluginStaticCredentialsOAuthClientSecret) Reset() { func (m *PluginStaticCredentialsOAuthClientSecret) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsOAuthClientSecret) ProtoMessage() {} func (*PluginStaticCredentialsOAuthClientSecret) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{251} + return fileDescriptor_9198ee693835762e, []int{255} } func (m *PluginStaticCredentialsOAuthClientSecret) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14114,7 +14355,7 @@ type SAMLIdPServiceProviderV1 struct { func (m *SAMLIdPServiceProviderV1) Reset() { *m = SAMLIdPServiceProviderV1{} } func (*SAMLIdPServiceProviderV1) ProtoMessage() {} func (*SAMLIdPServiceProviderV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{252} + return fileDescriptor_9198ee693835762e, []int{256} } func (m *SAMLIdPServiceProviderV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14160,7 +14401,7 @@ func (m *SAMLIdPServiceProviderSpecV1) Reset() { *m = SAMLIdPServiceProv func (m *SAMLIdPServiceProviderSpecV1) String() string { return proto.CompactTextString(m) } func (*SAMLIdPServiceProviderSpecV1) ProtoMessage() {} func (*SAMLIdPServiceProviderSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{253} + return fileDescriptor_9198ee693835762e, []int{257} } func (m *SAMLIdPServiceProviderSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14202,7 +14443,7 @@ func (m *IdPOptions) Reset() { *m = IdPOptions{} } func (m *IdPOptions) String() string { return proto.CompactTextString(m) } func (*IdPOptions) ProtoMessage() {} func (*IdPOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{254} + return fileDescriptor_9198ee693835762e, []int{258} } func (m *IdPOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14244,7 +14485,7 @@ func (m *IdPSAMLOptions) Reset() { *m = IdPSAMLOptions{} } func (m *IdPSAMLOptions) String() string { return proto.CompactTextString(m) } func (*IdPSAMLOptions) ProtoMessage() {} func (*IdPSAMLOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{255} + return fileDescriptor_9198ee693835762e, []int{259} } func (m *IdPSAMLOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14294,7 +14535,7 @@ func (m *KubernetesResourceV1) Reset() { *m = KubernetesResourceV1{} } func (m *KubernetesResourceV1) String() string { return proto.CompactTextString(m) } func (*KubernetesResourceV1) ProtoMessage() {} func (*KubernetesResourceV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{256} + return fileDescriptor_9198ee693835762e, []int{260} } func (m *KubernetesResourceV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14336,7 +14577,7 @@ func (m *KubernetesResourceSpecV1) Reset() { *m = KubernetesResourceSpec func (m *KubernetesResourceSpecV1) String() string { return proto.CompactTextString(m) } func (*KubernetesResourceSpecV1) ProtoMessage() {} func (*KubernetesResourceSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{257} + return fileDescriptor_9198ee693835762e, []int{261} } func (m *KubernetesResourceSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14382,7 +14623,7 @@ func (m *ClusterMaintenanceConfigV1) Reset() { *m = ClusterMaintenanceCo func (m *ClusterMaintenanceConfigV1) String() string { return proto.CompactTextString(m) } func (*ClusterMaintenanceConfigV1) ProtoMessage() {} func (*ClusterMaintenanceConfigV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{258} + return fileDescriptor_9198ee693835762e, []int{262} } func (m *ClusterMaintenanceConfigV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14424,7 +14665,7 @@ func (m *ClusterMaintenanceConfigSpecV1) Reset() { *m = ClusterMaintenan func (m *ClusterMaintenanceConfigSpecV1) String() string { return proto.CompactTextString(m) } func (*ClusterMaintenanceConfigSpecV1) ProtoMessage() {} func (*ClusterMaintenanceConfigSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{259} + return fileDescriptor_9198ee693835762e, []int{263} } func (m *ClusterMaintenanceConfigSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14470,7 +14711,7 @@ func (m *AgentUpgradeWindow) Reset() { *m = AgentUpgradeWindow{} } func (m *AgentUpgradeWindow) String() string { return proto.CompactTextString(m) } func (*AgentUpgradeWindow) ProtoMessage() {} func (*AgentUpgradeWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{260} + return fileDescriptor_9198ee693835762e, []int{264} } func (m *AgentUpgradeWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14517,7 +14758,7 @@ func (m *ScheduledAgentUpgradeWindow) Reset() { *m = ScheduledAgentUpgra func (m *ScheduledAgentUpgradeWindow) String() string { return proto.CompactTextString(m) } func (*ScheduledAgentUpgradeWindow) ProtoMessage() {} func (*ScheduledAgentUpgradeWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{261} + return fileDescriptor_9198ee693835762e, []int{265} } func (m *ScheduledAgentUpgradeWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14560,7 +14801,7 @@ func (m *AgentUpgradeSchedule) Reset() { *m = AgentUpgradeSchedule{} } func (m *AgentUpgradeSchedule) String() string { return proto.CompactTextString(m) } func (*AgentUpgradeSchedule) ProtoMessage() {} func (*AgentUpgradeSchedule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{262} + return fileDescriptor_9198ee693835762e, []int{266} } func (m *AgentUpgradeSchedule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14592,16 +14833,18 @@ var xxx_messageInfo_AgentUpgradeSchedule proto.InternalMessageInfo // UserGroupV1 is a representation of an externally sourced user group. type UserGroupV1 struct { // Header is the resource header for the user group. - ResourceHeader `protobuf:"bytes,1,opt,name=Header,proto3,embedded=Header" json:""` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ResourceHeader `protobuf:"bytes,1,opt,name=Header,proto3,embedded=Header" json:""` + // Spec is the user group resource spec. + Spec UserGroupSpecV1 `protobuf:"bytes,2,opt,name=Spec,proto3" json:"spec"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *UserGroupV1) Reset() { *m = UserGroupV1{} } func (*UserGroupV1) ProtoMessage() {} func (*UserGroupV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{263} + return fileDescriptor_9198ee693835762e, []int{267} } func (m *UserGroupV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14630,6 +14873,48 @@ func (m *UserGroupV1) XXX_DiscardUnknown() { var xxx_messageInfo_UserGroupV1 proto.InternalMessageInfo +// UserGroupSpecV1 is the specification of a user group. +type UserGroupSpecV1 struct { + // Applications are a list of application IDs belonging to this user group. + Applications []string `protobuf:"bytes,1,rep,name=Applications,proto3" json:"Applications,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UserGroupSpecV1) Reset() { *m = UserGroupSpecV1{} } +func (m *UserGroupSpecV1) String() string { return proto.CompactTextString(m) } +func (*UserGroupSpecV1) ProtoMessage() {} +func (*UserGroupSpecV1) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{268} +} +func (m *UserGroupSpecV1) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UserGroupSpecV1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UserGroupSpecV1.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UserGroupSpecV1) XXX_Merge(src proto.Message) { + xxx_messageInfo_UserGroupSpecV1.Merge(m, src) +} +func (m *UserGroupSpecV1) XXX_Size() int { + return m.Size() +} +func (m *UserGroupSpecV1) XXX_DiscardUnknown() { + xxx_messageInfo_UserGroupSpecV1.DiscardUnknown(m) +} + +var xxx_messageInfo_UserGroupSpecV1 proto.InternalMessageInfo + // OktaImportRuleSpecV1 is a Okta import rule specification. type OktaImportRuleSpecV1 struct { // Priority represents the priority of the rule application. Lower numbered rules will be applied first. @@ -14645,7 +14930,7 @@ func (m *OktaImportRuleSpecV1) Reset() { *m = OktaImportRuleSpecV1{} } func (m *OktaImportRuleSpecV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleSpecV1) ProtoMessage() {} func (*OktaImportRuleSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{264} + return fileDescriptor_9198ee693835762e, []int{269} } func (m *OktaImportRuleSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14689,7 +14974,7 @@ func (m *OktaImportRuleMappingV1) Reset() { *m = OktaImportRuleMappingV1 func (m *OktaImportRuleMappingV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleMappingV1) ProtoMessage() {} func (*OktaImportRuleMappingV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{265} + return fileDescriptor_9198ee693835762e, []int{270} } func (m *OktaImportRuleMappingV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14732,7 +15017,7 @@ type OktaImportRuleV1 struct { func (m *OktaImportRuleV1) Reset() { *m = OktaImportRuleV1{} } func (*OktaImportRuleV1) ProtoMessage() {} func (*OktaImportRuleV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{266} + return fileDescriptor_9198ee693835762e, []int{271} } func (m *OktaImportRuleV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14780,7 +15065,7 @@ func (m *OktaImportRuleMatchV1) Reset() { *m = OktaImportRuleMatchV1{} } func (m *OktaImportRuleMatchV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleMatchV1) ProtoMessage() {} func (*OktaImportRuleMatchV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{267} + return fileDescriptor_9198ee693835762e, []int{272} } func (m *OktaImportRuleMatchV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14823,7 +15108,7 @@ type OktaAssignmentV1 struct { func (m *OktaAssignmentV1) Reset() { *m = OktaAssignmentV1{} } func (*OktaAssignmentV1) ProtoMessage() {} func (*OktaAssignmentV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{268} + return fileDescriptor_9198ee693835762e, []int{273} } func (m *OktaAssignmentV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14877,7 +15162,7 @@ func (m *OktaAssignmentSpecV1) Reset() { *m = OktaAssignmentSpecV1{} } func (m *OktaAssignmentSpecV1) String() string { return proto.CompactTextString(m) } func (*OktaAssignmentSpecV1) ProtoMessage() {} func (*OktaAssignmentSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{269} + return fileDescriptor_9198ee693835762e, []int{274} } func (m *OktaAssignmentSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14921,7 +15206,7 @@ func (m *OktaAssignmentTargetV1) Reset() { *m = OktaAssignmentTargetV1{} func (m *OktaAssignmentTargetV1) String() string { return proto.CompactTextString(m) } func (*OktaAssignmentTargetV1) ProtoMessage() {} func (*OktaAssignmentTargetV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{270} + return fileDescriptor_9198ee693835762e, []int{275} } func (m *OktaAssignmentTargetV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14966,7 +15251,7 @@ type IntegrationV1 struct { func (m *IntegrationV1) Reset() { *m = IntegrationV1{} } func (*IntegrationV1) ProtoMessage() {} func (*IntegrationV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{271} + return fileDescriptor_9198ee693835762e, []int{276} } func (m *IntegrationV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15010,7 +15295,7 @@ func (m *IntegrationSpecV1) Reset() { *m = IntegrationSpecV1{} } func (m *IntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*IntegrationSpecV1) ProtoMessage() {} func (*IntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{272} + return fileDescriptor_9198ee693835762e, []int{277} } func (m *IntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15086,7 +15371,7 @@ func (m *AWSOIDCIntegrationSpecV1) Reset() { *m = AWSOIDCIntegrationSpec func (m *AWSOIDCIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*AWSOIDCIntegrationSpecV1) ProtoMessage() {} func (*AWSOIDCIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{273} + return fileDescriptor_9198ee693835762e, []int{278} } func (m *AWSOIDCIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15138,7 +15423,7 @@ func (m *HeadlessAuthentication) Reset() { *m = HeadlessAuthentication{} func (m *HeadlessAuthentication) String() string { return proto.CompactTextString(m) } func (*HeadlessAuthentication) ProtoMessage() {} func (*HeadlessAuthentication) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{274} + return fileDescriptor_9198ee693835762e, []int{279} } func (m *HeadlessAuthentication) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15195,7 +15480,7 @@ func (m *WatchKind) Reset() { *m = WatchKind{} } func (m *WatchKind) String() string { return proto.CompactTextString(m) } func (*WatchKind) ProtoMessage() {} func (*WatchKind) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{275} + return fileDescriptor_9198ee693835762e, []int{280} } func (m *WatchKind) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15245,7 +15530,7 @@ func (m *WatchStatusV1) Reset() { *m = WatchStatusV1{} } func (m *WatchStatusV1) String() string { return proto.CompactTextString(m) } func (*WatchStatusV1) ProtoMessage() {} func (*WatchStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{276} + return fileDescriptor_9198ee693835762e, []int{281} } func (m *WatchStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15286,7 +15571,7 @@ func (m *WatchStatusSpecV1) Reset() { *m = WatchStatusSpecV1{} } func (m *WatchStatusSpecV1) String() string { return proto.CompactTextString(m) } func (*WatchStatusSpecV1) ProtoMessage() {} func (*WatchStatusSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{277} + return fileDescriptor_9198ee693835762e, []int{282} } func (m *WatchStatusSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15336,7 +15621,7 @@ func (m *ServerInfoV1) Reset() { *m = ServerInfoV1{} } func (m *ServerInfoV1) String() string { return proto.CompactTextString(m) } func (*ServerInfoV1) ProtoMessage() {} func (*ServerInfoV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{278} + return fileDescriptor_9198ee693835762e, []int{283} } func (m *ServerInfoV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15378,7 +15663,7 @@ func (m *ServerInfoSpecV1) Reset() { *m = ServerInfoSpecV1{} } func (m *ServerInfoSpecV1) String() string { return proto.CompactTextString(m) } func (*ServerInfoSpecV1) ProtoMessage() {} func (*ServerInfoSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{279} + return fileDescriptor_9198ee693835762e, []int{284} } func (m *ServerInfoSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15422,7 +15707,7 @@ func (m *ServerInfoSpecV1_AWSInfo) Reset() { *m = ServerInfoSpecV1_AWSIn func (m *ServerInfoSpecV1_AWSInfo) String() string { return proto.CompactTextString(m) } func (*ServerInfoSpecV1_AWSInfo) ProtoMessage() {} func (*ServerInfoSpecV1_AWSInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{279, 0} + return fileDescriptor_9198ee693835762e, []int{284, 0} } func (m *ServerInfoSpecV1_AWSInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15463,8 +15748,8 @@ type JamfSpecV1 struct { // Set to negative to perform syncs immediately on startup. // Defaults to a random delay (a few minutes max). SyncDelay Duration `protobuf:"varint,3,opt,name=sync_delay,json=syncDelay,proto3,casttype=Duration" json:"sync_delay,omitempty"` - // Jamf API endpoint. - // Example: "https://yourtenant.jamfcloud.com". + // Jamf Pro API endpoint. + // Example: "https://yourtenant.jamfcloud.com/api". // Required. ApiEndpoint string `protobuf:"bytes,4,opt,name=api_endpoint,json=apiEndpoint,proto3" json:"api_endpoint,omitempty"` // Jamf API username. @@ -15489,7 +15774,7 @@ func (m *JamfSpecV1) Reset() { *m = JamfSpecV1{} } func (m *JamfSpecV1) String() string { return proto.CompactTextString(m) } func (*JamfSpecV1) ProtoMessage() {} func (*JamfSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{280} + return fileDescriptor_9198ee693835762e, []int{285} } func (m *JamfSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15528,14 +15813,12 @@ type JamfInventoryEntry struct { // PARTIAL syncs are scheduled in the time window between FULL syncs, so // sync_period_partial must always be smaller than sync_period_full, otherwise // it would never trigger. - // Set to negative to disable PARTIAL syncs. - // Defaults to 6h. + // Set to zero or negative to disable PARTIAL syncs. SyncPeriodPartial Duration `protobuf:"varint,2,opt,name=sync_period_partial,json=syncPeriodPartial,proto3,casttype=Duration" json:"sync_period_partial,omitempty"` // Sync period for FULL syncs. // Ideally sync_period_full is a multiple of sync_period_partial, so schedules // line up perfectly. - // Set to negative to disable FULL syncs. - // Defaults to 24h. + // Set to zero or negative to disable FULL syncs. SyncPeriodFull Duration `protobuf:"varint,3,opt,name=sync_period_full,json=syncPeriodFull,proto3,casttype=Duration" json:"sync_period_full,omitempty"` // on_missing is the trigger used on devices missing from the MDM view in a // FULL sync. @@ -15553,7 +15836,7 @@ func (m *JamfInventoryEntry) Reset() { *m = JamfInventoryEntry{} } func (m *JamfInventoryEntry) String() string { return proto.CompactTextString(m) } func (*JamfInventoryEntry) ProtoMessage() {} func (*JamfInventoryEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{281} + return fileDescriptor_9198ee693835762e, []int{286} } func (m *JamfInventoryEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15610,7 +15893,7 @@ type MessageWithHeader struct { func (m *MessageWithHeader) Reset() { *m = MessageWithHeader{} } func (*MessageWithHeader) ProtoMessage() {} func (*MessageWithHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{282} + return fileDescriptor_9198ee693835762e, []int{287} } func (m *MessageWithHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15639,6 +15922,304 @@ func (m *MessageWithHeader) XXX_DiscardUnknown() { var xxx_messageInfo_MessageWithHeader proto.InternalMessageInfo +// AWSMatcher matches AWS EC2 instances and AWS Databases +type AWSMatcher struct { + // Types are AWS database types to match, "ec2", "rds", "redshift", "elasticache", + // or "memorydb". + Types []string `protobuf:"bytes,1,rep,name=Types,proto3" json:"types,omitempty"` + // Regions are AWS regions to query for databases. + Regions []string `protobuf:"bytes,2,rep,name=Regions,proto3" json:"regions,omitempty"` + // AssumeRoleARN is the AWS role to assume for database discovery. + AssumeRole *AssumeRole `protobuf:"bytes,3,opt,name=AssumeRole,proto3" json:"assume_role,omitempty"` + // Tags are AWS resource Tags to match. + Tags Labels `protobuf:"bytes,4,opt,name=Tags,proto3,customtype=Labels" json:"tags,omitempty"` + // Params sets the join method when installing on discovered EC2 nodes + Params *InstallerParams `protobuf:"bytes,5,opt,name=Params,proto3" json:"install,omitempty"` + // SSM provides options to use when sending a document command to + // an EC2 node + SSM *AWSSSM `protobuf:"bytes,6,opt,name=SSM,proto3" json:"ssm,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AWSMatcher) Reset() { *m = AWSMatcher{} } +func (m *AWSMatcher) String() string { return proto.CompactTextString(m) } +func (*AWSMatcher) ProtoMessage() {} +func (*AWSMatcher) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{288} +} +func (m *AWSMatcher) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AWSMatcher) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AWSMatcher.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AWSMatcher) XXX_Merge(src proto.Message) { + xxx_messageInfo_AWSMatcher.Merge(m, src) +} +func (m *AWSMatcher) XXX_Size() int { + return m.Size() +} +func (m *AWSMatcher) XXX_DiscardUnknown() { + xxx_messageInfo_AWSMatcher.DiscardUnknown(m) +} + +var xxx_messageInfo_AWSMatcher proto.InternalMessageInfo + +// AssumeRole provides a role ARN and ExternalID to assume an AWS role +// when interacting with AWS resources. +type AssumeRole struct { + // RoleARN is the fully specified AWS IAM role ARN. + RoleARN string `protobuf:"bytes,1,opt,name=RoleARN,proto3" json:"role_arn"` + // ExternalID is the external ID used to assume a role in another account. + ExternalID string `protobuf:"bytes,2,opt,name=ExternalID,proto3" json:"external_id"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AssumeRole) Reset() { *m = AssumeRole{} } +func (m *AssumeRole) String() string { return proto.CompactTextString(m) } +func (*AssumeRole) ProtoMessage() {} +func (*AssumeRole) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{289} +} +func (m *AssumeRole) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AssumeRole) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AssumeRole.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AssumeRole) XXX_Merge(src proto.Message) { + xxx_messageInfo_AssumeRole.Merge(m, src) +} +func (m *AssumeRole) XXX_Size() int { + return m.Size() +} +func (m *AssumeRole) XXX_DiscardUnknown() { + xxx_messageInfo_AssumeRole.DiscardUnknown(m) +} + +var xxx_messageInfo_AssumeRole proto.InternalMessageInfo + +// InstallParams sets join method to use on discovered nodes +type InstallerParams struct { + // JoinMethod is the method to use when joining the cluster + JoinMethod JoinMethod `protobuf:"bytes,1,opt,name=JoinMethod,proto3,casttype=JoinMethod" json:"join_method"` + // JoinToken is the token to use when joining the cluster + JoinToken string `protobuf:"bytes,2,opt,name=JoinToken,proto3" json:"join_token"` + // ScriptName is the name of the teleport installer script + // resource for the cloud instance to execute + ScriptName string `protobuf:"bytes,3,opt,name=ScriptName,proto3" json:"script_name,omitempty"` + // InstallTeleport disables agentless discovery + InstallTeleport bool `protobuf:"varint,4,opt,name=InstallTeleport,proto3" json:"install_teleport,omitempty"` + // SSHDConfig provides the path to write sshd configuration changes + SSHDConfig string `protobuf:"bytes,5,opt,name=SSHDConfig,proto3" json:"sshd_config,omitempty"` + // PublicProxyAddr is the address of the proxy the discovered node should use + // to connect to the cluster. Used only in Azure. + PublicProxyAddr string `protobuf:"bytes,6,opt,name=PublicProxyAddr,proto3" json:"proxy_addr,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InstallerParams) Reset() { *m = InstallerParams{} } +func (m *InstallerParams) String() string { return proto.CompactTextString(m) } +func (*InstallerParams) ProtoMessage() {} +func (*InstallerParams) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{290} +} +func (m *InstallerParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *InstallerParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_InstallerParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *InstallerParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_InstallerParams.Merge(m, src) +} +func (m *InstallerParams) XXX_Size() int { + return m.Size() +} +func (m *InstallerParams) XXX_DiscardUnknown() { + xxx_messageInfo_InstallerParams.DiscardUnknown(m) +} + +var xxx_messageInfo_InstallerParams proto.InternalMessageInfo + +// AWSSSM provides options to use when executing SSM documents +type AWSSSM struct { + // DocumentName is the name of the document to use when executing an + // SSM command + DocumentName string `protobuf:"bytes,1,opt,name=DocumentName,proto3" json:"document_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AWSSSM) Reset() { *m = AWSSSM{} } +func (m *AWSSSM) String() string { return proto.CompactTextString(m) } +func (*AWSSSM) ProtoMessage() {} +func (*AWSSSM) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{291} +} +func (m *AWSSSM) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AWSSSM) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AWSSSM.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AWSSSM) XXX_Merge(src proto.Message) { + xxx_messageInfo_AWSSSM.Merge(m, src) +} +func (m *AWSSSM) XXX_Size() int { + return m.Size() +} +func (m *AWSSSM) XXX_DiscardUnknown() { + xxx_messageInfo_AWSSSM.DiscardUnknown(m) +} + +var xxx_messageInfo_AWSSSM proto.InternalMessageInfo + +// AzureMatcher matches Azure resources. +// It defines which resource types, filters and some configuration params. +type AzureMatcher struct { + // Subscriptions are Azure subscriptions to query for resources. + Subscriptions []string `protobuf:"bytes,1,rep,name=Subscriptions,proto3" json:"subscriptions,omitempty"` + // ResourceGroups are Azure resource groups to query for resources. + ResourceGroups []string `protobuf:"bytes,2,rep,name=ResourceGroups,proto3" json:"resource_groups,omitempty"` + // Types are Azure types to match: "mysql", "postgres", "aks", "vm" + Types []string `protobuf:"bytes,3,rep,name=Types,proto3" json:"types,omitempty"` + // Regions are Azure locations to match for databases. + Regions []string `protobuf:"bytes,4,rep,name=Regions,proto3" json:"regions,omitempty"` + // ResourceTags are Azure tags on resources to match. + ResourceTags Labels `protobuf:"bytes,5,opt,name=ResourceTags,proto3,customtype=Labels" json:"tags,omitempty"` + // Params sets the join method when installing on + // discovered Azure nodes. + Params *InstallerParams `protobuf:"bytes,6,opt,name=Params,proto3" json:"install_params,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AzureMatcher) Reset() { *m = AzureMatcher{} } +func (m *AzureMatcher) String() string { return proto.CompactTextString(m) } +func (*AzureMatcher) ProtoMessage() {} +func (*AzureMatcher) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{292} +} +func (m *AzureMatcher) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AzureMatcher) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AzureMatcher.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AzureMatcher) XXX_Merge(src proto.Message) { + xxx_messageInfo_AzureMatcher.Merge(m, src) +} +func (m *AzureMatcher) XXX_Size() int { + return m.Size() +} +func (m *AzureMatcher) XXX_DiscardUnknown() { + xxx_messageInfo_AzureMatcher.DiscardUnknown(m) +} + +var xxx_messageInfo_AzureMatcher proto.InternalMessageInfo + +// GCPMatcher matches GCP resources. +type GCPMatcher struct { + // Types are GKE resource types to match: "gke". + Types []string `protobuf:"bytes,1,rep,name=Types,proto3" json:"types,omitempty"` + // Locations are GKE locations to search resources for. + Locations []string `protobuf:"bytes,2,rep,name=Locations,proto3" json:"locations,omitempty"` + // Tags are GCP labels to match. + Tags Labels `protobuf:"bytes,3,opt,name=Tags,proto3,customtype=Labels" json:"tags,omitempty"` + // ProjectIDs are the GCP project ID where the resources are deployed. + ProjectIDs []string `protobuf:"bytes,4,rep,name=ProjectIDs,proto3" json:"project_ids,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GCPMatcher) Reset() { *m = GCPMatcher{} } +func (m *GCPMatcher) String() string { return proto.CompactTextString(m) } +func (*GCPMatcher) ProtoMessage() {} +func (*GCPMatcher) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{293} +} +func (m *GCPMatcher) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GCPMatcher) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GCPMatcher.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GCPMatcher) XXX_Merge(src proto.Message) { + xxx_messageInfo_GCPMatcher.Merge(m, src) +} +func (m *GCPMatcher) XXX_Size() int { + return m.Size() +} +func (m *GCPMatcher) XXX_DiscardUnknown() { + xxx_messageInfo_GCPMatcher.DiscardUnknown(m) +} + +var xxx_messageInfo_GCPMatcher proto.InternalMessageInfo + func init() { proto.RegisterEnum("types.DatabaseTLSMode", DatabaseTLSMode_name, DatabaseTLSMode_value) proto.RegisterEnum("types.PrivateKeyType", PrivateKeyType_name, PrivateKeyType_value) @@ -15646,6 +16227,7 @@ func init() { proto.RegisterEnum("types.RoutingStrategy", RoutingStrategy_name, RoutingStrategy_value) proto.RegisterEnum("types.UserTokenUsage", UserTokenUsage_name, UserTokenUsage_value) proto.RegisterEnum("types.RequestState", RequestState_name, RequestState_value) + proto.RegisterEnum("types.CreateHostUserMode", CreateHostUserMode_name, CreateHostUserMode_value) proto.RegisterEnum("types.CertExtensionMode", CertExtensionMode_name, CertExtensionMode_value) proto.RegisterEnum("types.CertExtensionType", CertExtensionType_name, CertExtensionType_value) proto.RegisterEnum("types.SessionState", SessionState_name, SessionState_value) @@ -15683,12 +16265,14 @@ func init() { proto.RegisterType((*ElastiCache)(nil), "types.ElastiCache") proto.RegisterType((*MemoryDB)(nil), "types.MemoryDB") proto.RegisterType((*RedshiftServerless)(nil), "types.RedshiftServerless") + proto.RegisterType((*OpenSearch)(nil), "types.OpenSearch") proto.RegisterType((*GCPCloudSQL)(nil), "types.GCPCloudSQL") proto.RegisterType((*Azure)(nil), "types.Azure") proto.RegisterType((*AzureRedis)(nil), "types.AzureRedis") proto.RegisterType((*AD)(nil), "types.AD") proto.RegisterType((*DatabaseTLS)(nil), "types.DatabaseTLS") proto.RegisterType((*MySQLOptions)(nil), "types.MySQLOptions") + proto.RegisterType((*MongoAtlas)(nil), "types.MongoAtlas") proto.RegisterType((*InstanceV1)(nil), "types.InstanceV1") proto.RegisterType((*InstanceSpecV1)(nil), "types.InstanceSpecV1") proto.RegisterType((*InstanceControlLogEntry)(nil), "types.InstanceControlLogEntry") @@ -15908,6 +16492,7 @@ func init() { proto.RegisterType((*DatabaseServiceV1)(nil), "types.DatabaseServiceV1") proto.RegisterType((*DatabaseServiceSpecV1)(nil), "types.DatabaseServiceSpecV1") proto.RegisterType((*DatabaseResourceMatcher)(nil), "types.DatabaseResourceMatcher") + proto.RegisterType((*ResourceMatcherAWS)(nil), "types.ResourceMatcherAWS") proto.RegisterType((*ClusterAlert)(nil), "types.ClusterAlert") proto.RegisterType((*ClusterAlertSpec)(nil), "types.ClusterAlertSpec") proto.RegisterType((*GetClusterAlertsRequest)(nil), "types.GetClusterAlertsRequest") @@ -15919,6 +16504,7 @@ func init() { proto.RegisterType((*PluginSpecV1)(nil), "types.PluginSpecV1") proto.RegisterType((*PluginSlackAccessSettings)(nil), "types.PluginSlackAccessSettings") proto.RegisterType((*PluginOpsgenieAccessSettings)(nil), "types.PluginOpsgenieAccessSettings") + proto.RegisterType((*PluginPagerDutySettings)(nil), "types.PluginPagerDutySettings") proto.RegisterType((*PluginOpenAISettings)(nil), "types.PluginOpenAISettings") proto.RegisterType((*PluginJamfSettings)(nil), "types.PluginJamfSettings") proto.RegisterType((*PluginOktaSettings)(nil), "types.PluginOktaSettings") @@ -15948,6 +16534,7 @@ func init() { proto.RegisterType((*ScheduledAgentUpgradeWindow)(nil), "types.ScheduledAgentUpgradeWindow") proto.RegisterType((*AgentUpgradeSchedule)(nil), "types.AgentUpgradeSchedule") proto.RegisterType((*UserGroupV1)(nil), "types.UserGroupV1") + proto.RegisterType((*UserGroupSpecV1)(nil), "types.UserGroupSpecV1") proto.RegisterType((*OktaImportRuleSpecV1)(nil), "types.OktaImportRuleSpecV1") proto.RegisterType((*OktaImportRuleMappingV1)(nil), "types.OktaImportRuleMappingV1") proto.RegisterMapType((map[string]string)(nil), "types.OktaImportRuleMappingV1.AddLabelsEntry") @@ -15970,1348 +16557,1405 @@ func init() { proto.RegisterType((*JamfSpecV1)(nil), "types.JamfSpecV1") proto.RegisterType((*JamfInventoryEntry)(nil), "types.JamfInventoryEntry") proto.RegisterType((*MessageWithHeader)(nil), "types.MessageWithHeader") + proto.RegisterType((*AWSMatcher)(nil), "types.AWSMatcher") + proto.RegisterType((*AssumeRole)(nil), "types.AssumeRole") + proto.RegisterType((*InstallerParams)(nil), "types.InstallerParams") + proto.RegisterType((*AWSSSM)(nil), "types.AWSSSM") + proto.RegisterType((*AzureMatcher)(nil), "types.AzureMatcher") + proto.RegisterType((*GCPMatcher)(nil), "types.GCPMatcher") } func init() { proto.RegisterFile("teleport/legacy/types/types.proto", fileDescriptor_9198ee693835762e) } var fileDescriptor_9198ee693835762e = []byte{ - // 21367 bytes of a gzipped FileDescriptorProto + // 22190 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xfd, 0x7d, 0x90, 0x1c, 0x49, - 0x76, 0x18, 0x86, 0xa3, 0xba, 0xe7, 0xa3, 0xe7, 0xcd, 0x57, 0x4f, 0x62, 0x00, 0x0c, 0xb0, 0x1f, - 0x83, 0x2d, 0xec, 0x62, 0x01, 0xec, 0x2e, 0x70, 0x18, 0xdc, 0xe2, 0x6e, 0x6f, 0xbf, 0xae, 0xa7, - 0xbb, 0x81, 0xe9, 0xc5, 0x7c, 0xf4, 0x55, 0xcf, 0xc7, 0xed, 0x7d, 0xd5, 0xd5, 0x74, 0xe7, 0xcc, - 0xd4, 0xa2, 0xbb, 0xab, 0xaf, 0xaa, 0x1a, 0xc0, 0x1c, 0xc9, 0x20, 0x29, 0x91, 0xba, 0x1f, 0x7f, - 0xfc, 0x38, 0x52, 0x3e, 0x92, 0x27, 0x4b, 0xb2, 0x18, 0x0c, 0x49, 0x26, 0x2d, 0x91, 0xa1, 0x90, - 0x14, 0x21, 0x3b, 0x64, 0xd3, 0xa6, 0x42, 0xc1, 0xa0, 0xa4, 0x90, 0x45, 0x47, 0xd8, 0xe1, 0xf0, - 0x59, 0x31, 0x16, 0x49, 0xdb, 0xe1, 0x80, 0x23, 0x14, 0x76, 0x30, 0x42, 0x11, 0x3e, 0x07, 0x6d, - 0x47, 0xbe, 0xcc, 0xac, 0xca, 0xac, 0xae, 0xee, 0xe9, 0x59, 0x60, 0x83, 0xc4, 0xda, 0xff, 0x00, - 0xd3, 0x2f, 0xdf, 0x7b, 0x99, 0x95, 0xf9, 0x32, 0xf3, 0xe5, 0xcb, 0xf7, 0x5e, 0xc2, 0x4b, 0x21, - 0x6d, 0xd2, 0x8e, 0xe7, 0x87, 0x37, 0x9a, 0x74, 0xdf, 0xa9, 0x1f, 0xde, 0x08, 0x0f, 0x3b, 0x34, - 0xe0, 0xff, 0x5e, 0xef, 0xf8, 0x5e, 0xe8, 0x91, 0x51, 0xfc, 0x71, 0x61, 0x7e, 0xdf, 0xdb, 0xf7, - 0x10, 0x72, 0x83, 0xfd, 0xc5, 0x0b, 0x2f, 0x2c, 0xee, 0x7b, 0xde, 0x7e, 0x93, 0xde, 0xc0, 0x5f, - 0xbb, 0xdd, 0xbd, 0x1b, 0xa1, 0xdb, 0xa2, 0x41, 0xe8, 0xb4, 0x3a, 0x02, 0xe1, 0x6a, 0x54, 0x81, - 0x13, 0x86, 0xac, 0x24, 0x74, 0xbd, 0xf6, 0x8d, 0x07, 0x37, 0xd5, 0x9f, 0x02, 0xf5, 0x8d, 0xf4, - 0xb6, 0x3c, 0xf4, 0x9d, 0x4e, 0x87, 0xfa, 0xf1, 0x1f, 0x1c, 0xdd, 0xfc, 0x47, 0x59, 0x98, 0xb8, - 0x47, 0x69, 0xa7, 0xd0, 0x74, 0x1f, 0x50, 0x72, 0x09, 0x46, 0xd6, 0x9d, 0x16, 0x5d, 0x30, 0x2e, - 0x1a, 0x57, 0x26, 0x96, 0x67, 0x1f, 0x1f, 0x2d, 0x4e, 0x06, 0xd4, 0x7f, 0x40, 0x7d, 0xbb, 0xed, - 0xb4, 0xa8, 0x85, 0x85, 0xe4, 0x35, 0x98, 0x60, 0xff, 0x07, 0x1d, 0xa7, 0x4e, 0x17, 0x32, 0x88, - 0x39, 0xfd, 0xf8, 0x68, 0x71, 0xa2, 0x2d, 0x81, 0x56, 0x5c, 0x4e, 0x2e, 0xc3, 0xf8, 0x2a, 0x75, - 0x02, 0x5a, 0x29, 0x2d, 0x64, 0x2f, 0x1a, 0x57, 0xb2, 0xcb, 0x53, 0x8f, 0x8f, 0x16, 0x73, 0x4d, - 0x06, 0xb2, 0xdd, 0x86, 0x25, 0x0b, 0x49, 0x05, 0xc6, 0xcb, 0x8f, 0x3a, 0xae, 0x4f, 0x83, 0x85, - 0x91, 0x8b, 0xc6, 0x95, 0xc9, 0xa5, 0x0b, 0xd7, 0x79, 0xa7, 0x5c, 0x97, 0x9d, 0x72, 0x7d, 0x53, - 0x76, 0xca, 0xf2, 0xe9, 0xdf, 0x3f, 0x5a, 0x3c, 0xf5, 0xf8, 0x68, 0x71, 0x9c, 0x72, 0x92, 0x5f, - 0xfc, 0x1f, 0x16, 0x0d, 0x4b, 0xd2, 0x93, 0x77, 0x60, 0x64, 0xf3, 0xb0, 0x43, 0x17, 0x26, 0x2e, - 0x1a, 0x57, 0x66, 0x96, 0x5e, 0xbc, 0xce, 0x87, 0x21, 0xfa, 0xc8, 0xf8, 0x2f, 0x86, 0xb5, 0x9c, - 0x7b, 0x7c, 0xb4, 0x38, 0xc2, 0x50, 0x2c, 0xa4, 0x22, 0x6f, 0xc0, 0xd8, 0x8a, 0x17, 0x84, 0x95, - 0xd2, 0x02, 0xe0, 0xa7, 0x9d, 0x79, 0x7c, 0xb4, 0x38, 0x77, 0xe0, 0x05, 0xa1, 0xed, 0x36, 0x5e, - 0xf7, 0x5a, 0x6e, 0x48, 0x5b, 0x9d, 0xf0, 0xd0, 0x12, 0x48, 0xe6, 0x23, 0x98, 0xd6, 0xf8, 0x91, - 0x49, 0x18, 0xdf, 0x5a, 0xbf, 0xb7, 0xbe, 0xb1, 0xb3, 0x9e, 0x3f, 0x45, 0x72, 0x30, 0xb2, 0xbe, - 0x51, 0x2a, 0xe7, 0x0d, 0x32, 0x0e, 0xd9, 0x42, 0xb5, 0x9a, 0xcf, 0x90, 0x29, 0xc8, 0x95, 0x0a, - 0x9b, 0x85, 0xe5, 0x42, 0xad, 0x9c, 0xcf, 0x92, 0xd3, 0x30, 0xbb, 0x53, 0x59, 0x2f, 0x6d, 0xec, - 0xd4, 0xec, 0x52, 0xb9, 0x76, 0x6f, 0x73, 0xa3, 0x9a, 0x1f, 0x21, 0x33, 0x00, 0xf7, 0xb6, 0x96, - 0xcb, 0xd6, 0x7a, 0x79, 0xb3, 0x5c, 0xcb, 0x8f, 0x92, 0x79, 0xc8, 0x4b, 0x12, 0xbb, 0x56, 0xb6, - 0xb6, 0x2b, 0xc5, 0x72, 0x7e, 0xcc, 0xfc, 0x4e, 0x16, 0x72, 0x6b, 0x34, 0x74, 0x1a, 0x4e, 0xe8, - 0x90, 0xe7, 0xb5, 0x81, 0xc3, 0x6f, 0x52, 0x46, 0xec, 0x52, 0xef, 0x88, 0x8d, 0x3e, 0x3e, 0x5a, - 0x34, 0xde, 0x50, 0x47, 0xea, 0x6d, 0x98, 0x2c, 0xd1, 0xa0, 0xee, 0xbb, 0x1d, 0x26, 0x4d, 0x38, - 0x5a, 0x13, 0xcb, 0xe7, 0x1f, 0x1f, 0x2d, 0x9e, 0x69, 0xc4, 0x60, 0xa5, 0x07, 0x54, 0x6c, 0x52, - 0x81, 0xb1, 0x55, 0x67, 0x97, 0x36, 0x83, 0x85, 0xd1, 0x8b, 0xd9, 0x2b, 0x93, 0x4b, 0xcf, 0x89, - 0x5e, 0x97, 0x0d, 0xbc, 0xce, 0x4b, 0xcb, 0xed, 0xd0, 0x3f, 0x5c, 0x9e, 0x7f, 0x7c, 0xb4, 0x98, - 0x6f, 0x22, 0x40, 0xed, 0x51, 0x8e, 0x42, 0x6a, 0xb1, 0x24, 0x8c, 0x1d, 0x2b, 0x09, 0x2f, 0xfc, - 0xfe, 0xd1, 0xa2, 0xc1, 0x46, 0x48, 0x48, 0x42, 0xcc, 0x4f, 0x97, 0x89, 0x8b, 0x90, 0xa9, 0x94, - 0x16, 0xc6, 0x51, 0x02, 0xf3, 0x8f, 0x8f, 0x16, 0xa7, 0xb4, 0xc1, 0xcc, 0x54, 0x4a, 0x17, 0xde, - 0x82, 0x49, 0xa5, 0x8d, 0x24, 0x0f, 0xd9, 0xfb, 0xf4, 0x90, 0xf7, 0xa7, 0xc5, 0xfe, 0x24, 0xf3, - 0x30, 0xfa, 0xc0, 0x69, 0x76, 0x45, 0x07, 0x5a, 0xfc, 0xc7, 0x17, 0x32, 0x9f, 0x37, 0xcc, 0xbf, - 0x3c, 0x02, 0x39, 0xcb, 0xe3, 0xb3, 0x90, 0x5c, 0x85, 0xd1, 0x5a, 0xe8, 0x84, 0x72, 0x28, 0x4e, - 0x3f, 0x3e, 0x5a, 0x9c, 0x65, 0x33, 0x94, 0x2a, 0xf5, 0x71, 0x0c, 0x86, 0x5a, 0x3d, 0x70, 0x02, - 0x39, 0x24, 0x88, 0xda, 0x61, 0x00, 0x15, 0x15, 0x31, 0xc8, 0x65, 0x18, 0x59, 0xf3, 0x1a, 0x54, - 0x8c, 0x0a, 0x79, 0x7c, 0xb4, 0x38, 0xd3, 0xf2, 0x1a, 0x2a, 0x22, 0x96, 0x93, 0xd7, 0x61, 0xa2, - 0xd8, 0xf5, 0x7d, 0xda, 0x66, 0x02, 0x3c, 0x82, 0xc8, 0x33, 0x8f, 0x8f, 0x16, 0xa1, 0xce, 0x81, - 0x6c, 0xca, 0xc5, 0x08, 0xac, 0xab, 0x6b, 0xa1, 0xe3, 0x87, 0xb4, 0xb1, 0x30, 0x3a, 0x54, 0x57, - 0xb3, 0x49, 0x37, 0x17, 0x70, 0x92, 0x64, 0x57, 0x0b, 0x4e, 0x64, 0x05, 0x26, 0xef, 0xfa, 0x4e, - 0x9d, 0x56, 0xa9, 0xef, 0x7a, 0x0d, 0x1c, 0xc3, 0xec, 0xf2, 0xe5, 0xc7, 0x47, 0x8b, 0x67, 0xf7, - 0x19, 0xd8, 0xee, 0x20, 0x3c, 0xa6, 0xfe, 0xe1, 0xd1, 0x62, 0xae, 0xd4, 0xf5, 0xb1, 0xf7, 0x2c, - 0x95, 0x94, 0x7c, 0x93, 0x0d, 0x49, 0x10, 0x62, 0xd7, 0xd2, 0x06, 0x8e, 0xde, 0xe0, 0x26, 0x9a, - 0xa2, 0x89, 0x67, 0x9b, 0x4e, 0x10, 0xda, 0x3e, 0xa7, 0x4b, 0xb4, 0x53, 0x65, 0x49, 0x36, 0x20, - 0x57, 0xab, 0x1f, 0xd0, 0x46, 0xb7, 0x49, 0x17, 0x72, 0xc8, 0xfe, 0x9c, 0x10, 0x5c, 0x39, 0x9e, - 0xb2, 0x78, 0xf9, 0x82, 0xe0, 0x4d, 0x02, 0x01, 0x51, 0xfa, 0x3e, 0x62, 0xf2, 0x85, 0xdc, 0xf7, - 0x7f, 0x6d, 0xf1, 0xd4, 0x4f, 0xfc, 0xeb, 0x8b, 0xa7, 0xcc, 0x7f, 0x94, 0x81, 0x7c, 0x92, 0x09, - 0xd9, 0x83, 0xe9, 0xad, 0x4e, 0xc3, 0x09, 0x69, 0xb1, 0xe9, 0xd2, 0x76, 0x18, 0xa0, 0x90, 0x0c, - 0xfe, 0xa6, 0x97, 0x45, 0xbd, 0x0b, 0x5d, 0x24, 0xb4, 0xeb, 0x9c, 0x32, 0xf1, 0x55, 0x3a, 0xdb, - 0xb8, 0x9e, 0x1a, 0xae, 0xde, 0x01, 0x4a, 0xd8, 0xc9, 0xea, 0xe1, 0xeb, 0x7e, 0x9f, 0x7a, 0x04, - 0x5b, 0x21, 0x40, 0xed, 0xc6, 0xee, 0x21, 0x4a, 0xe6, 0xf0, 0x02, 0xc4, 0x48, 0x52, 0x04, 0x88, - 0x81, 0xcd, 0xff, 0xd1, 0x80, 0x19, 0x8b, 0x06, 0x5e, 0xd7, 0xaf, 0xd3, 0x15, 0xea, 0x34, 0xa8, - 0xcf, 0xc4, 0xff, 0x9e, 0xdb, 0x6e, 0x88, 0x39, 0x85, 0xe2, 0x7f, 0xdf, 0x6d, 0xab, 0x53, 0x18, - 0xcb, 0xc9, 0x67, 0x60, 0xbc, 0xd6, 0xdd, 0x45, 0x54, 0x3e, 0xa7, 0xce, 0xe2, 0x88, 0x75, 0x77, - 0xed, 0x04, 0xba, 0x44, 0x23, 0x37, 0x60, 0x7c, 0x9b, 0xfa, 0x41, 0xbc, 0xe2, 0xe1, 0x7a, 0xff, - 0x80, 0x83, 0x54, 0x02, 0x81, 0x45, 0xee, 0xc6, 0xab, 0xae, 0xd8, 0xa9, 0x66, 0x13, 0x6b, 0x5d, - 0x2c, 0x2a, 0x2d, 0x01, 0x51, 0x45, 0x45, 0x62, 0x99, 0xbf, 0x94, 0x81, 0x7c, 0xc9, 0x09, 0x9d, - 0x5d, 0x27, 0x10, 0xfd, 0xb9, 0x7d, 0x8b, 0xad, 0xe3, 0xca, 0x87, 0xe2, 0x3a, 0xce, 0x5a, 0xfe, - 0xb1, 0x3f, 0xef, 0x95, 0xe4, 0xe7, 0x4d, 0xb2, 0x6d, 0x53, 0x7c, 0x5e, 0xfc, 0x51, 0xef, 0x1e, - 0xff, 0x51, 0x79, 0xf1, 0x51, 0x39, 0xf9, 0x51, 0xf1, 0xa7, 0x90, 0x77, 0x61, 0xa4, 0xd6, 0xa1, - 0x75, 0xb1, 0x88, 0xc8, 0xb5, 0x5f, 0xff, 0x38, 0x86, 0xb0, 0x7d, 0x6b, 0x79, 0x4a, 0xb0, 0x19, - 0x09, 0x3a, 0xb4, 0x6e, 0x21, 0x99, 0x32, 0x69, 0xfe, 0xd9, 0x18, 0xcc, 0xa7, 0x91, 0x91, 0x77, - 0xf5, 0xcd, 0x89, 0x77, 0xcf, 0x73, 0x7d, 0x37, 0xa7, 0x05, 0x43, 0xdf, 0x9e, 0xae, 0x41, 0xae, - 0xca, 0x04, 0xb2, 0xee, 0x35, 0x45, 0xcf, 0xb1, 0x55, 0x31, 0xd7, 0x91, 0x30, 0xc3, 0x8a, 0xca, - 0xc9, 0x73, 0x90, 0xdd, 0xb2, 0x2a, 0xa2, 0xbb, 0x26, 0x1e, 0x1f, 0x2d, 0x66, 0xbb, 0xbe, 0xbb, - 0x60, 0x58, 0x0c, 0x4a, 0x6e, 0xc0, 0x58, 0xb1, 0x50, 0xa4, 0x7e, 0x88, 0xdd, 0x34, 0xb5, 0x7c, - 0x8e, 0x49, 0x4b, 0xdd, 0xb1, 0xeb, 0xd4, 0x0f, 0xb5, 0xea, 0x05, 0x1a, 0x79, 0x0d, 0xb2, 0x85, - 0x9d, 0x9a, 0xe8, 0x19, 0x10, 0x3d, 0x53, 0xd8, 0xa9, 0x2d, 0x4f, 0x8b, 0x8e, 0xc8, 0x3a, 0x0f, - 0x03, 0xc6, 0xbd, 0xb0, 0x53, 0x53, 0x47, 0x6b, 0x6c, 0xc0, 0x68, 0x5d, 0x81, 0x1c, 0xd3, 0x3e, - 0xd8, 0x06, 0x8f, 0x8b, 0xe2, 0x04, 0x57, 0xaa, 0x0e, 0x04, 0xcc, 0x8a, 0x4a, 0xc9, 0xa5, 0x48, - 0x99, 0xc9, 0xc5, 0xfc, 0x84, 0x32, 0x23, 0x55, 0x18, 0xf2, 0x08, 0xa6, 0x4b, 0x87, 0x6d, 0xa7, - 0xe5, 0xd6, 0xc5, 0x16, 0x3e, 0x81, 0x5b, 0xf8, 0xf5, 0x01, 0xc3, 0x78, 0x5d, 0x23, 0xe0, 0xbb, - 0xba, 0x5c, 0x7c, 0x17, 0x1a, 0xbc, 0xcc, 0x4e, 0xee, 0xf0, 0x0b, 0x86, 0xa5, 0x57, 0xc4, 0xe6, - 0x92, 0x5c, 0x22, 0x51, 0xdb, 0x8a, 0xc5, 0x4e, 0x82, 0xe3, 0xb9, 0xe4, 0x0b, 0x88, 0x3a, 0x97, - 0xa2, 0x4d, 0xf7, 0x5d, 0xc8, 0xde, 0x2d, 0x56, 0x17, 0x26, 0x91, 0x07, 0x11, 0x3c, 0xee, 0x16, - 0xab, 0xc5, 0xa6, 0xd7, 0x6d, 0xd4, 0xbe, 0xb4, 0xba, 0x7c, 0x4e, 0xb0, 0x99, 0xde, 0xaf, 0x77, - 0xb4, 0x16, 0x31, 0x3a, 0x52, 0x86, 0x9c, 0xfc, 0xca, 0x85, 0x29, 0xe4, 0x31, 0x97, 0xf8, 0xf8, - 0xed, 0x5b, 0x7c, 0xae, 0x35, 0xc4, 0x6f, 0xb5, 0x15, 0x12, 0x87, 0xdc, 0x42, 0x29, 0x7b, 0x74, - 0x58, 0x29, 0x05, 0x0b, 0xd3, 0x17, 0xb3, 0x57, 0x26, 0x50, 0x3c, 0x4e, 0x77, 0x18, 0xcc, 0x76, - 0x1b, 0xaa, 0xb2, 0x13, 0x21, 0x5e, 0xd8, 0x01, 0xd2, 0xdb, 0x99, 0x29, 0xea, 0xc7, 0x6b, 0xaa, - 0xfa, 0x31, 0xb9, 0x74, 0x46, 0x34, 0xb0, 0xe8, 0xb5, 0x5a, 0x4e, 0xbb, 0x81, 0xb4, 0xdb, 0x4b, - 0xaa, 0x56, 0x52, 0x80, 0x99, 0xb8, 0xf5, 0xab, 0x6e, 0x10, 0x92, 0x1b, 0x30, 0x21, 0x21, 0x6c, - 0xe7, 0xc9, 0xa6, 0x7e, 0xa7, 0x15, 0xe3, 0x98, 0xbf, 0x97, 0x01, 0x88, 0x4b, 0x9e, 0xd1, 0xc5, - 0xe9, 0x73, 0xda, 0xe2, 0x74, 0x26, 0x29, 0xd5, 0x7d, 0x97, 0x25, 0xf2, 0x3e, 0x8c, 0x31, 0x3d, - 0xad, 0x2b, 0xf5, 0xd0, 0x73, 0x49, 0x52, 0x2c, 0xdc, 0xbe, 0xb5, 0x3c, 0x23, 0x88, 0xc7, 0x02, - 0x84, 0x58, 0x82, 0x4c, 0x59, 0xd7, 0x7e, 0x6a, 0x2c, 0x1e, 0x0c, 0xb1, 0xa2, 0x5d, 0x51, 0x96, - 0x24, 0x23, 0x9e, 0xc4, 0x72, 0x49, 0x52, 0x16, 0xa4, 0xf3, 0x7c, 0x41, 0xe2, 0x9d, 0x3a, 0x2e, - 0x16, 0xa4, 0xe4, 0x72, 0xc4, 0x3b, 0xf0, 0xd8, 0xe5, 0xa8, 0x93, 0x9c, 0xeb, 0x23, 0x28, 0x06, - 0x57, 0x52, 0x7b, 0x25, 0x6d, 0x96, 0x5f, 0x3c, 0x6e, 0x96, 0x27, 0xe7, 0xf8, 0xad, 0x7e, 0x0b, - 0xe0, 0x19, 0x39, 0x25, 0x9d, 0x87, 0x2a, 0x39, 0x2e, 0x84, 0x6f, 0xf3, 0xf9, 0x3c, 0xd6, 0x77, - 0x3e, 0x9f, 0x49, 0x9d, 0xcf, 0x7c, 0x36, 0xbf, 0x0d, 0xa3, 0x85, 0x6f, 0x77, 0x7d, 0x2a, 0x14, - 0xc6, 0x29, 0x59, 0x27, 0x83, 0x45, 0x0b, 0xc1, 0xac, 0xc3, 0x7e, 0xaa, 0x8a, 0x36, 0x96, 0xb3, - 0x9a, 0x37, 0x57, 0x6b, 0x42, 0x19, 0x24, 0x89, 0x6e, 0xd9, 0x5c, 0x55, 0x9a, 0x1d, 0x6a, 0x5f, - 0xcd, 0xa8, 0xc8, 0x0d, 0xc8, 0x14, 0x4a, 0x78, 0xee, 0x9c, 0x5c, 0x9a, 0x90, 0xd5, 0x96, 0x96, - 0xe7, 0x05, 0xc9, 0x94, 0xa3, 0x1d, 0x3a, 0x0a, 0x25, 0xb2, 0x0c, 0xa3, 0x6b, 0x87, 0xb5, 0x2f, - 0xad, 0x8a, 0xd5, 0xef, 0xb4, 0x94, 0x6b, 0x06, 0xdb, 0xc0, 0xad, 0x2b, 0x88, 0x5b, 0xdc, 0x3a, - 0x0c, 0xbe, 0xd5, 0x54, 0x5b, 0x8c, 0x68, 0xa4, 0x0a, 0x13, 0x85, 0x46, 0xcb, 0x6d, 0x6f, 0x05, - 0xd4, 0x17, 0x2b, 0xe0, 0x42, 0xa2, 0xdd, 0x51, 0xf9, 0xf2, 0xc2, 0xe3, 0xa3, 0xc5, 0x79, 0x87, - 0xfd, 0xb4, 0xbb, 0x01, 0xf5, 0x15, 0x6e, 0x31, 0x93, 0x4f, 0x6e, 0x49, 0xba, 0x09, 0x73, 0x3d, - 0x4d, 0x1a, 0x7c, 0x74, 0x35, 0xff, 0xa6, 0xaa, 0x25, 0x89, 0x09, 0xc7, 0xce, 0xe8, 0x42, 0xec, - 0x8d, 0x58, 0x67, 0xeb, 0x11, 0xfb, 0x48, 0xe8, 0xaf, 0x72, 0x11, 0xcc, 0xf4, 0x88, 0xe0, 0xa4, - 0xb2, 0x07, 0x73, 0xc1, 0x8b, 0x06, 0x24, 0xfb, 0xf1, 0x07, 0xe4, 0x7d, 0x98, 0x5a, 0x73, 0xda, - 0xce, 0x3e, 0x6d, 0xb0, 0xef, 0xe3, 0x53, 0x8c, 0x2b, 0x2b, 0xe7, 0x5a, 0x1c, 0x8e, 0x7d, 0xaf, - 0x4a, 0x8f, 0x46, 0x40, 0x6e, 0x4a, 0x01, 0x1e, 0x4d, 0x11, 0x60, 0xa9, 0x37, 0x8c, 0xa2, 0x00, - 0x0b, 0xb1, 0x35, 0xbf, 0x3f, 0x86, 0xdf, 0x48, 0x5e, 0x87, 0x31, 0x8b, 0xee, 0xc7, 0x2a, 0x12, - 0x1e, 0xb5, 0x7d, 0x84, 0xa8, 0x1d, 0xc3, 0x71, 0x70, 0xff, 0xa5, 0x8d, 0xe0, 0xc0, 0xdd, 0x0b, - 0x45, 0xef, 0x44, 0xfb, 0xaf, 0x00, 0x2b, 0xfb, 0xaf, 0x80, 0x68, 0xfb, 0xaf, 0x80, 0xb1, 0x49, - 0x6e, 0x95, 0x6a, 0xa2, 0xd3, 0x64, 0x0f, 0x5b, 0x25, 0x65, 0xb6, 0xf8, 0xda, 0xf6, 0xc7, 0xb0, - 0xc9, 0x6d, 0x98, 0x28, 0xd4, 0xeb, 0x5e, 0x57, 0x39, 0xab, 0x72, 0xf1, 0xe4, 0x40, 0xdd, 0xde, - 0x12, 0xa3, 0x92, 0x1a, 0x4c, 0x96, 0xd9, 0x01, 0xcf, 0x2d, 0x3a, 0xf5, 0x03, 0xd9, 0x49, 0x72, - 0xaa, 0x2a, 0x25, 0xd1, 0x81, 0xe3, 0x0c, 0x45, 0x60, 0x9d, 0x01, 0x55, 0x03, 0x86, 0x82, 0x4b, - 0x36, 0x61, 0xb2, 0x46, 0xeb, 0x3e, 0x0d, 0x6b, 0xa1, 0xe7, 0xd3, 0xc4, 0xca, 0xa3, 0x94, 0x2c, - 0xbf, 0x28, 0xcf, 0x98, 0x01, 0x02, 0xed, 0x80, 0x41, 0x55, 0xae, 0x0a, 0x32, 0x3f, 0x2c, 0xb4, - 0x3c, 0xff, 0xb0, 0xb4, 0x2c, 0x56, 0xa3, 0x78, 0xeb, 0xe2, 0x60, 0xf5, 0xb0, 0xc0, 0x20, 0x8d, - 0x5d, 0xfd, 0xb0, 0xc0, 0xb1, 0x70, 0xa4, 0x4a, 0x35, 0x54, 0x1a, 0xc4, 0xda, 0x34, 0x1b, 0xf7, - 0x32, 0x82, 0x95, 0x91, 0x6a, 0x04, 0xa8, 0x72, 0x68, 0x23, 0x25, 0xb0, 0x48, 0x07, 0x88, 0x1c, - 0x35, 0xae, 0xd0, 0x35, 0x69, 0x10, 0x88, 0x25, 0xeb, 0x7c, 0x62, 0xf0, 0x63, 0x84, 0xe5, 0x57, - 0x04, 0xf3, 0x17, 0xa4, 0x18, 0x88, 0xf3, 0x21, 0x2b, 0x54, 0xea, 0x49, 0xe1, 0x4d, 0xde, 0x02, - 0x28, 0x3f, 0x0a, 0xa9, 0xdf, 0x76, 0x9a, 0x91, 0x51, 0x0d, 0xcd, 0x4a, 0x54, 0x40, 0xf5, 0x81, - 0x56, 0x90, 0x49, 0x11, 0xa6, 0x0b, 0x41, 0xd0, 0x6d, 0x51, 0xcb, 0x6b, 0xd2, 0x82, 0xb5, 0x8e, - 0xcb, 0xdb, 0xc4, 0xf2, 0x0b, 0x8f, 0x8f, 0x16, 0xcf, 0x3b, 0x58, 0x60, 0xfb, 0x5e, 0x93, 0xda, - 0x8e, 0xaf, 0x4a, 0xb7, 0x4e, 0x63, 0xfe, 0x88, 0x36, 0xb2, 0x4c, 0xea, 0xee, 0xd1, 0xc3, 0xaa, - 0x4f, 0xf7, 0xdc, 0x47, 0x62, 0x92, 0xa0, 0xd4, 0xdd, 0xa7, 0x87, 0x76, 0x07, 0xa1, 0xaa, 0xd4, - 0x45, 0xa8, 0xe4, 0xb3, 0x90, 0xbb, 0xb7, 0x56, 0xbb, 0x47, 0x0f, 0x2b, 0x25, 0xb1, 0x15, 0x73, - 0xb2, 0x56, 0x60, 0x33, 0x52, 0xed, 0x1b, 0x22, 0x4c, 0x73, 0x39, 0x9e, 0x61, 0xac, 0xe6, 0x62, - 0xb3, 0x1b, 0x84, 0xd4, 0xaf, 0x94, 0xd4, 0x9a, 0xeb, 0x1c, 0x98, 0x90, 0xf7, 0x08, 0xd5, 0xfc, - 0xb9, 0x0c, 0xce, 0x2e, 0xd6, 0x91, 0x95, 0x36, 0x3b, 0x3b, 0xd7, 0x69, 0xc4, 0x00, 0x3b, 0xd2, - 0x15, 0xd0, 0x44, 0x47, 0xc6, 0xc8, 0x7a, 0xd5, 0x99, 0xa1, 0xab, 0x66, 0x55, 0xca, 0x93, 0xb8, - 0x30, 0xe0, 0x8a, 0x2a, 0x7d, 0x01, 0x4d, 0x54, 0x19, 0x23, 0x93, 0xcb, 0x30, 0x5e, 0x29, 0xac, - 0x15, 0xba, 0xe1, 0x01, 0xce, 0xed, 0x1c, 0x57, 0x6f, 0x5c, 0xa7, 0x65, 0x3b, 0xdd, 0xf0, 0xc0, - 0x92, 0x85, 0xec, 0x00, 0x5e, 0xeb, 0xee, 0xb6, 0x69, 0xc8, 0x4d, 0x87, 0x62, 0x31, 0x0f, 0x38, - 0x28, 0xa1, 0x35, 0x32, 0x90, 0xf9, 0xbb, 0x46, 0x3c, 0x17, 0xc8, 0x65, 0x6d, 0xf3, 0x40, 0xc3, - 0x00, 0xdb, 0x3c, 0x54, 0xc3, 0x00, 0x5a, 0x40, 0x2d, 0x20, 0xc5, 0x6e, 0x10, 0x7a, 0xad, 0x72, - 0xbb, 0xd1, 0xf1, 0xdc, 0x76, 0x88, 0x54, 0xbc, 0x27, 0xcc, 0xc7, 0x47, 0x8b, 0x2f, 0xd6, 0xb1, - 0xd4, 0xa6, 0xa2, 0xd8, 0x4e, 0x70, 0x49, 0xa1, 0x7e, 0x82, 0xce, 0x31, 0xff, 0x79, 0x46, 0x5b, - 0xc3, 0x58, 0xf3, 0x2c, 0xda, 0x69, 0xba, 0x75, 0x3c, 0xce, 0xdc, 0xf5, 0xbd, 0x6e, 0x27, 0x1a, - 0x62, 0x6c, 0x9e, 0x1f, 0x97, 0xda, 0xfb, 0xac, 0x58, 0xe7, 0x9d, 0x42, 0x4d, 0xbe, 0x08, 0x53, - 0x6c, 0x3b, 0x11, 0x3f, 0x83, 0x85, 0x0c, 0xf6, 0xee, 0xf3, 0x68, 0xe2, 0x09, 0xa8, 0x1f, 0xb1, - 0xd1, 0xf6, 0x21, 0x95, 0x82, 0x34, 0x60, 0x61, 0xd3, 0x77, 0xda, 0x81, 0x1b, 0x96, 0xdb, 0x75, - 0xff, 0x10, 0xb7, 0xbf, 0x72, 0xdb, 0xd9, 0x6d, 0xd2, 0x06, 0x7e, 0x6e, 0x6e, 0xf9, 0xca, 0xe3, - 0xa3, 0xc5, 0x97, 0x43, 0x8e, 0x63, 0xd3, 0x08, 0xc9, 0xa6, 0x1c, 0x4b, 0xe1, 0xdc, 0x97, 0x13, - 0xdb, 0x2e, 0x65, 0xb7, 0xa2, 0xd9, 0x7e, 0x24, 0x3a, 0xdb, 0x9f, 0x8b, 0x46, 0x83, 0xad, 0x4b, - 0x6a, 0x33, 0x55, 0x02, 0xf3, 0xdf, 0x19, 0xf1, 0x2a, 0x4b, 0xde, 0x81, 0x49, 0x21, 0xbe, 0x8a, - 0x5c, 0x5c, 0x60, 0xeb, 0xb5, 0x94, 0xf5, 0xc4, 0xc8, 0xaa, 0xe8, 0xec, 0x0c, 0x53, 0x28, 0xae, - 0x2a, 0xb2, 0x81, 0x67, 0x18, 0xa7, 0xde, 0x4c, 0x52, 0x49, 0x34, 0x26, 0x04, 0x9b, 0xab, 0x35, - 0xbd, 0x57, 0x50, 0x08, 0xc2, 0x66, 0x90, 0xd2, 0x0d, 0x0a, 0xf2, 0x93, 0x7f, 0xf8, 0x7f, 0x6b, - 0xa4, 0x2d, 0xe6, 0x64, 0x19, 0xa6, 0x77, 0x3c, 0xff, 0x3e, 0x8e, 0xaf, 0xd2, 0x09, 0x38, 0xf2, - 0x0f, 0x65, 0x41, 0xf2, 0x83, 0x74, 0x12, 0xb5, 0x6d, 0x4a, 0x6f, 0xe8, 0x6d, 0x4b, 0x70, 0xd0, - 0x08, 0xd8, 0x38, 0x44, 0x1c, 0xa3, 0xd9, 0x81, 0xe3, 0x10, 0x37, 0x41, 0x13, 0x61, 0x15, 0xdd, - 0xfc, 0x09, 0x03, 0x26, 0x15, 0x75, 0x9f, 0xad, 0x5f, 0x55, 0xdf, 0xfb, 0x88, 0xd6, 0x43, 0x7d, - 0xe9, 0xec, 0x70, 0x60, 0x62, 0xfd, 0x8a, 0x50, 0x13, 0x4b, 0x66, 0xe6, 0x04, 0x4b, 0xa6, 0xf9, - 0xbf, 0x1b, 0x42, 0x0b, 0x1b, 0x7a, 0x8d, 0xd1, 0xd7, 0x83, 0xcc, 0x49, 0x16, 0xcb, 0x2f, 0xc2, - 0xa8, 0x45, 0x1b, 0x6e, 0x20, 0x34, 0xa8, 0x39, 0x55, 0xe3, 0xc3, 0x82, 0x58, 0xe9, 0xf4, 0xd9, - 0x4f, 0x55, 0xe9, 0xc4, 0x72, 0xb6, 0x55, 0x56, 0x82, 0x3b, 0x4d, 0xfa, 0xc8, 0xe5, 0x92, 0x20, - 0x16, 0x5d, 0xdc, 0x2a, 0xdd, 0xc0, 0xde, 0x63, 0x25, 0x62, 0xcf, 0x56, 0x47, 0x5d, 0xa3, 0x31, - 0x3f, 0x04, 0x88, 0xab, 0x24, 0xf7, 0x20, 0x2f, 0xe6, 0x86, 0xdb, 0xde, 0xaf, 0x7a, 0x4d, 0xb7, - 0x2e, 0xb4, 0xff, 0xe5, 0xc5, 0xc7, 0x47, 0x8b, 0xcf, 0xd5, 0xa3, 0x32, 0xbb, 0x83, 0x85, 0x0a, - 0xdf, 0x1e, 0x42, 0xf3, 0x3f, 0xcc, 0xb0, 0xb3, 0x11, 0xeb, 0xa3, 0x7b, 0xf4, 0x30, 0x74, 0x76, - 0xef, 0xb8, 0x4d, 0xaa, 0xee, 0x61, 0xf7, 0x11, 0x6a, 0xef, 0xb9, 0x9a, 0x61, 0x5d, 0x41, 0x26, - 0xb7, 0x20, 0x77, 0xcf, 0xdf, 0x7d, 0x13, 0x09, 0x33, 0xd1, 0x69, 0xf7, 0xf4, 0x7d, 0x7f, 0xf7, - 0xcd, 0x24, 0x59, 0x84, 0x48, 0x4c, 0x18, 0x2b, 0x79, 0x2d, 0xc7, 0x95, 0x16, 0x06, 0x60, 0xc7, - 0xf4, 0x06, 0x42, 0x2c, 0x51, 0xc2, 0xce, 0xd7, 0xb5, 0xea, 0xba, 0x98, 0x7e, 0x78, 0xbe, 0x0e, - 0x3a, 0x6d, 0x8b, 0xc1, 0x58, 0x9d, 0xab, 0xa5, 0x42, 0x15, 0x8f, 0x1a, 0xa3, 0x71, 0x9d, 0xcd, - 0x86, 0xd3, 0x49, 0x1e, 0x36, 0x22, 0x44, 0xf2, 0x2e, 0x4c, 0xde, 0x2b, 0x15, 0x57, 0xbc, 0x80, - 0x4f, 0x9d, 0xb1, 0x78, 0xea, 0xdc, 0x6f, 0xd4, 0x6d, 0xb4, 0xbe, 0x25, 0xd7, 0x20, 0x05, 0xdf, - 0xfc, 0x2d, 0x03, 0x26, 0x95, 0x03, 0x27, 0xf9, 0xac, 0xb8, 0xfa, 0x31, 0xf0, 0x3a, 0xf3, 0x6c, - 0xef, 0x91, 0x94, 0x95, 0xf2, 0x73, 0x53, 0xcb, 0x6b, 0x50, 0x71, 0x11, 0x14, 0x1f, 0x91, 0x32, - 0xc3, 0x1c, 0x91, 0xde, 0x02, 0xe0, 0x32, 0x80, 0x4d, 0x56, 0xf6, 0x32, 0xe5, 0xfa, 0x57, 0x1d, - 0x97, 0x18, 0xd9, 0xb4, 0x60, 0x4a, 0x3d, 0x1e, 0xb1, 0xe5, 0x47, 0x98, 0xb3, 0x85, 0x6d, 0x47, - 0x59, 0x7e, 0x04, 0xb7, 0x5e, 0xf3, 0xba, 0x4e, 0x62, 0xfe, 0x05, 0x23, 0x9e, 0xb8, 0xdb, 0x37, - 0xc9, 0xdb, 0x30, 0xc6, 0x2f, 0x02, 0xc4, 0x7d, 0xc9, 0x99, 0x48, 0x51, 0x55, 0x6f, 0x09, 0xb8, - 0x11, 0xe7, 0x0f, 0xf8, 0x85, 0xe0, 0x29, 0x4b, 0x90, 0x44, 0xf6, 0x1f, 0xfd, 0x90, 0x2a, 0xb9, - 0xa3, 0xa5, 0xe3, 0x66, 0x9a, 0xfd, 0xc7, 0xfc, 0x0f, 0xb2, 0x30, 0xa3, 0xa3, 0xa9, 0xb7, 0x05, - 0xc6, 0x50, 0xb7, 0x05, 0x5f, 0x84, 0x1c, 0xfb, 0x32, 0xb7, 0x4e, 0xe5, 0x06, 0xfc, 0x32, 0x5a, - 0xc5, 0x04, 0x4c, 0xbb, 0x05, 0x83, 0xda, 0x61, 0x10, 0xd2, 0x16, 0xd3, 0x5b, 0xad, 0x88, 0x8a, - 0x2c, 0x29, 0xc6, 0xde, 0x6c, 0xbc, 0x27, 0x49, 0x63, 0xaf, 0x2a, 0x81, 0x91, 0xd9, 0xf7, 0x0d, - 0x18, 0x63, 0xba, 0x55, 0x74, 0xac, 0xc2, 0x56, 0x32, 0xb5, 0x2b, 0x71, 0x87, 0xcd, 0x91, 0xc8, - 0x0e, 0xe4, 0x56, 0x9d, 0x20, 0xac, 0x51, 0xda, 0x1e, 0xe2, 0x1e, 0x70, 0x51, 0x74, 0xd5, 0x69, - 0xbc, 0x64, 0x0b, 0x28, 0x6d, 0x27, 0x2e, 0x72, 0x22, 0x66, 0xe4, 0xeb, 0x00, 0x45, 0xaf, 0x1d, - 0xfa, 0x5e, 0x73, 0xd5, 0xdb, 0x5f, 0x18, 0x43, 0x53, 0xd3, 0x8b, 0x89, 0x01, 0x88, 0x11, 0xb8, - 0x81, 0x29, 0x3a, 0xb4, 0xd5, 0x79, 0x81, 0xdd, 0xf4, 0xf6, 0x55, 0xc9, 0x8b, 0xf1, 0xcd, 0x1f, - 0x66, 0xe0, 0x5c, 0x1f, 0x36, 0x6c, 0xd1, 0xc6, 0x4d, 0x55, 0x59, 0xb4, 0x13, 0x7b, 0x29, 0xbf, - 0xee, 0xe7, 0x17, 0xc3, 0x4c, 0x36, 0x46, 0xd2, 0x2f, 0x86, 0xc9, 0x07, 0x30, 0xc2, 0x3e, 0x7e, - 0x88, 0x0b, 0x2e, 0x79, 0x02, 0x9b, 0x09, 0x5d, 0x75, 0x60, 0xb0, 0x53, 0x90, 0x07, 0xf9, 0x2c, - 0x64, 0x37, 0x37, 0x57, 0x71, 0x54, 0xb2, 0xa8, 0xd8, 0x4d, 0x87, 0x61, 0x53, 0x13, 0x82, 0x69, - 0x46, 0x7b, 0x3d, 0xba, 0x0f, 0x65, 0xe8, 0xe4, 0xcb, 0x89, 0xcb, 0xf5, 0x6b, 0x83, 0xbb, 0x70, - 0xf8, 0xbb, 0xf6, 0x27, 0xb9, 0xf4, 0xf6, 0xe3, 0xc9, 0x71, 0xc7, 0x6d, 0x86, 0xd4, 0x27, 0x17, - 0xb8, 0xac, 0xc7, 0xc7, 0x1b, 0x2b, 0xfa, 0x4d, 0x16, 0xe2, 0x89, 0xc3, 0x39, 0x45, 0x33, 0xe4, - 0x9a, 0x32, 0x43, 0xb2, 0x38, 0x43, 0x66, 0xfa, 0xcd, 0x05, 0xf3, 0x27, 0x33, 0xb2, 0x8a, 0xed, - 0xa5, 0x67, 0xd4, 0x1a, 0xfd, 0xa6, 0x66, 0x8d, 0x3e, 0x1d, 0x19, 0x18, 0xa2, 0xbb, 0x95, 0xa5, - 0x63, 0xae, 0xc8, 0xde, 0x82, 0x29, 0xd9, 0x05, 0x68, 0xd4, 0xbf, 0x0a, 0xe3, 0xf2, 0x92, 0x97, - 0x9b, 0xf4, 0x67, 0x35, 0x9e, 0xdb, 0x4b, 0x96, 0x2c, 0x37, 0xff, 0xab, 0x51, 0x49, 0xcb, 0x6b, - 0x62, 0x5d, 0x58, 0x68, 0x34, 0x7c, 0xb5, 0x0b, 0x9d, 0x46, 0xc3, 0xb7, 0x10, 0xca, 0xf6, 0x84, - 0x6a, 0x77, 0xb7, 0xe9, 0xd6, 0x11, 0x47, 0xd1, 0x67, 0x3a, 0x08, 0xb5, 0x19, 0xaa, 0x3a, 0x33, - 0x63, 0x64, 0xed, 0x86, 0x2a, 0x3b, 0xf0, 0x86, 0xea, 0x1b, 0x30, 0x51, 0x6c, 0x35, 0x34, 0x63, - 0xb4, 0x99, 0xd2, 0x29, 0xd7, 0x23, 0x24, 0x2e, 0xd6, 0xcf, 0x8b, 0x3e, 0x9a, 0xaf, 0xb7, 0x1a, - 0xbd, 0x26, 0xe8, 0x98, 0xa5, 0x76, 0xc5, 0x34, 0xfa, 0x24, 0x57, 0x4c, 0xb7, 0x61, 0x62, 0x2b, - 0xa0, 0x9b, 0xdd, 0x76, 0x9b, 0x36, 0x71, 0x4f, 0xcf, 0x71, 0x15, 0xb4, 0x1b, 0x50, 0x3b, 0x44, - 0xa8, 0xda, 0x80, 0x08, 0x55, 0x15, 0xab, 0xf1, 0x01, 0x62, 0xf5, 0x59, 0x18, 0x29, 0x74, 0x3a, - 0xf2, 0xee, 0x2d, 0x32, 0x52, 0x76, 0x3a, 0x38, 0x83, 0x67, 0x9c, 0x4e, 0x47, 0xbf, 0x49, 0x43, - 0x6c, 0xbc, 0x71, 0xa2, 0xd4, 0xc7, 0x01, 0x9a, 0x8c, 0xf5, 0x93, 0x0e, 0xa5, 0x7e, 0x72, 0x78, - 0x22, 0x44, 0xed, 0x9a, 0x6a, 0x6a, 0xc8, 0x6b, 0x2a, 0xf2, 0x12, 0x4c, 0x29, 0xc3, 0x2e, 0xee, - 0xb7, 0xac, 0xc9, 0x4e, 0x34, 0xe6, 0xc1, 0x85, 0x1a, 0xcc, 0xe8, 0xa3, 0xf4, 0x14, 0x4c, 0xc6, - 0x1f, 0x8c, 0xe4, 0x72, 0xf9, 0x89, 0x0f, 0x46, 0x72, 0x90, 0x9f, 0xb4, 0xc8, 0xbd, 0xee, 0x2e, - 0xf5, 0xdb, 0x34, 0xa4, 0x81, 0xd0, 0x2f, 0x03, 0xf3, 0x3b, 0x19, 0x98, 0x2c, 0x74, 0x3a, 0xcf, - 0xf8, 0x05, 0xfa, 0xe7, 0xb5, 0x55, 0xe1, 0x6c, 0x3c, 0xfa, 0x27, 0xb8, 0x3b, 0xff, 0xed, 0x0c, - 0xcc, 0x26, 0x28, 0xd4, 0xd6, 0x1b, 0x43, 0x5e, 0x28, 0x67, 0x86, 0xbc, 0x50, 0xce, 0xf6, 0xbf, - 0x50, 0x56, 0xe7, 0xdc, 0xc8, 0x93, 0xcc, 0xb9, 0x57, 0x21, 0x5b, 0xe8, 0x74, 0x92, 0x66, 0xf0, - 0x4e, 0x67, 0xfb, 0x16, 0xd7, 0xd3, 0x9d, 0x4e, 0xc7, 0x62, 0x18, 0x9a, 0x48, 0x8f, 0x0d, 0x29, - 0xd2, 0xe6, 0x1b, 0x30, 0x81, 0xbc, 0x70, 0x19, 0xbd, 0x28, 0xe6, 0x1f, 0x5f, 0x43, 0xb5, 0xba, - 0xf8, 0x5c, 0x33, 0xff, 0x4f, 0x76, 0x20, 0x64, 0xbf, 0x9f, 0x51, 0x19, 0x5b, 0xd2, 0x64, 0x2c, - 0xaf, 0xc8, 0xd8, 0x30, 0xd2, 0xf5, 0x4b, 0x23, 0xd8, 0x5b, 0x42, 0xae, 0xc4, 0x95, 0xa4, 0x91, - 0x72, 0x25, 0xf9, 0x04, 0xbb, 0xc6, 0xfd, 0xe4, 0xe5, 0x64, 0x16, 0x07, 0xe3, 0x52, 0xb2, 0xa9, - 0x4f, 0xe5, 0x5e, 0x72, 0x05, 0x48, 0xa5, 0x1d, 0xd0, 0x7a, 0xd7, 0xa7, 0xb5, 0xfb, 0x6e, 0x67, - 0x9b, 0xfa, 0xee, 0xde, 0xa1, 0x38, 0x35, 0xe3, 0xc2, 0xee, 0x8a, 0x52, 0x3b, 0xb8, 0xef, 0x76, - 0xd8, 0x91, 0xc5, 0xdd, 0x3b, 0xb4, 0x52, 0x68, 0xc8, 0xfb, 0x30, 0x6e, 0xd1, 0x87, 0xbe, 0x1b, - 0xca, 0xbb, 0x88, 0x99, 0xe8, 0x78, 0x82, 0x50, 0xae, 0x7e, 0xfb, 0xfc, 0x87, 0x3a, 0xfe, 0xa2, - 0x9c, 0x2c, 0xf1, 0xfb, 0x29, 0x7e, 0xe7, 0x30, 0x1d, 0x7f, 0x6d, 0x61, 0xa7, 0xb6, 0x3c, 0xd7, - 0xe7, 0x86, 0xf4, 0x2a, 0x8c, 0xa2, 0x75, 0x44, 0x6c, 0x2a, 0xe8, 0x3b, 0x58, 0x67, 0x00, 0xd5, - 0x34, 0x80, 0x18, 0x9f, 0xdc, 0x75, 0xde, 0xf7, 0x46, 0x71, 0x7e, 0x1e, 0xe3, 0x7c, 0x3a, 0xe0, - 0xfa, 0x5a, 0x97, 0x95, 0xec, 0x49, 0x64, 0x65, 0x1b, 0xa6, 0x6a, 0x6c, 0x95, 0xd0, 0xef, 0xb1, - 0x9f, 0x8f, 0x3b, 0xef, 0xba, 0x5a, 0x3c, 0x48, 0x17, 0xd6, 0xf8, 0x10, 0x3b, 0x29, 0x83, 0x5c, - 0xe5, 0x7e, 0x41, 0x61, 0x9c, 0x22, 0x7d, 0xd1, 0x72, 0x56, 0xe7, 0x9d, 0x75, 0x62, 0xb9, 0x1b, - 0x7b, 0x32, 0xb9, 0x1b, 0xff, 0x58, 0x72, 0x97, 0xf0, 0xf8, 0xcd, 0x9d, 0xc4, 0xe3, 0xf7, 0xc2, - 0xfb, 0x30, 0xd7, 0xd3, 0xc3, 0x27, 0x39, 0x40, 0x7c, 0x72, 0x62, 0xf9, 0x63, 0xa0, 0xcc, 0xac, - 0x9c, 0x45, 0x1b, 0xae, 0x4f, 0xeb, 0x21, 0xae, 0xec, 0x62, 0x31, 0xf6, 0x05, 0x2c, 0x71, 0x97, - 0x89, 0x30, 0xf2, 0x1e, 0x8c, 0x73, 0xcb, 0x01, 0x3f, 0xb1, 0xc7, 0x33, 0x52, 0x58, 0x19, 0xb8, - 0x43, 0x38, 0xc7, 0x50, 0x7b, 0x55, 0x10, 0x99, 0x77, 0xa5, 0xb1, 0xe2, 0x98, 0x79, 0xb1, 0x08, - 0xa3, 0xdb, 0x71, 0xcf, 0xa0, 0xa7, 0x19, 0xff, 0x08, 0x8b, 0xc3, 0xcd, 0x9f, 0x35, 0x60, 0x46, - 0xff, 0x4a, 0x72, 0x1d, 0xc6, 0x84, 0x5b, 0xad, 0x81, 0x47, 0x48, 0xf6, 0x35, 0x63, 0xdc, 0xa1, - 0x56, 0x73, 0xa3, 0x15, 0x58, 0x6c, 0x67, 0x11, 0x1c, 0x84, 0xf5, 0x01, 0x77, 0x16, 0x21, 0xa4, - 0x96, 0x2c, 0x23, 0x26, 0x8c, 0x59, 0x34, 0xe8, 0x36, 0x43, 0xd5, 0x4a, 0xe6, 0x23, 0xc4, 0x12, - 0x25, 0x66, 0x11, 0xc6, 0xf8, 0x92, 0x94, 0xb8, 0xd0, 0x33, 0x4e, 0x70, 0xa1, 0x67, 0x1e, 0x19, - 0x00, 0xb5, 0xda, 0xca, 0x3d, 0x7a, 0x58, 0x75, 0x5c, 0x1f, 0xcd, 0xba, 0x38, 0xa5, 0xef, 0x89, - 0x21, 0x9f, 0x12, 0x66, 0x5d, 0x3e, 0xfd, 0xef, 0xd3, 0x43, 0xcd, 0xac, 0x2b, 0x51, 0x71, 0xdd, - 0xf0, 0xdd, 0x07, 0x4e, 0x48, 0x19, 0x61, 0x06, 0x09, 0xf9, 0xba, 0xc1, 0xa1, 0x09, 0x4a, 0x05, - 0x99, 0x7c, 0x1d, 0x66, 0xe2, 0x5f, 0x68, 0x21, 0xc8, 0xa2, 0x5d, 0x4d, 0x8a, 0x95, 0x5e, 0xb8, - 0xfc, 0xe2, 0xe3, 0xa3, 0xc5, 0x0b, 0x0a, 0xd7, 0xa4, 0x41, 0x3e, 0xc1, 0xcc, 0xfc, 0x75, 0x03, - 0xef, 0x03, 0xe4, 0x07, 0x5e, 0x86, 0x91, 0xc8, 0x4d, 0x61, 0x8a, 0x5b, 0x21, 0x12, 0x06, 0x38, - 0x2c, 0x27, 0x97, 0x20, 0x1b, 0x7f, 0x09, 0x2e, 0xf9, 0xfa, 0x17, 0xb0, 0x52, 0x72, 0x17, 0xc6, - 0x87, 0x6a, 0x33, 0x8a, 0x78, 0x4a, 0x5b, 0x25, 0x35, 0x8e, 0xc2, 0x07, 0x3b, 0x9b, 0x9f, 0xde, - 0x51, 0xf8, 0x6e, 0x06, 0x66, 0x59, 0xbf, 0x16, 0xba, 0xe1, 0x81, 0xe7, 0xbb, 0xe1, 0xe1, 0x33, - 0x6b, 0x2e, 0x78, 0x47, 0x53, 0xda, 0x2e, 0xc8, 0xb5, 0x4f, 0xfd, 0xb6, 0xa1, 0xac, 0x06, 0xbf, - 0x37, 0x0a, 0xa7, 0x53, 0xa8, 0xc8, 0xeb, 0x9a, 0x99, 0x6c, 0x41, 0xc6, 0xc2, 0xfc, 0xf0, 0x68, - 0x71, 0x4a, 0xa2, 0x6f, 0xc6, 0xb1, 0x31, 0x4b, 0xfa, 0xe5, 0x1a, 0xef, 0x29, 0xb4, 0x9a, 0xa9, - 0x97, 0x6b, 0xfa, 0x95, 0xda, 0x55, 0x18, 0xb5, 0xbc, 0x26, 0x95, 0xb7, 0xbb, 0xa8, 0xa8, 0xf8, - 0x0c, 0xa0, 0xdd, 0x61, 0x30, 0x00, 0x59, 0x81, 0x71, 0xf6, 0xc7, 0x9a, 0xd3, 0x11, 0xb6, 0x42, - 0x12, 0x1d, 0x1b, 0x10, 0xda, 0x71, 0xdb, 0xfb, 0xea, 0xc9, 0xa1, 0x49, 0xed, 0x96, 0xd3, 0xd1, - 0x76, 0x36, 0x8e, 0xa8, 0x9d, 0x40, 0x72, 0xfd, 0x4f, 0x20, 0xc6, 0xb1, 0x27, 0x90, 0x06, 0x40, - 0xcd, 0xdd, 0x6f, 0xbb, 0xed, 0xfd, 0x42, 0x73, 0x5f, 0x44, 0x14, 0x5d, 0xed, 0x3f, 0x0a, 0xd7, - 0x63, 0x64, 0x14, 0x5c, 0x6e, 0x42, 0xe7, 0x30, 0xdb, 0x69, 0x6a, 0x86, 0xcc, 0x18, 0x95, 0xac, - 0x03, 0x14, 0xea, 0xa1, 0xfb, 0x80, 0x09, 0x70, 0x20, 0x7c, 0xb8, 0x64, 0x83, 0x8b, 0x85, 0x7b, - 0xf4, 0xb0, 0x46, 0xc3, 0xd8, 0x30, 0xea, 0x20, 0x2a, 0x9b, 0x07, 0x6a, 0x1f, 0x2a, 0x1c, 0x48, - 0x07, 0xce, 0x14, 0x1a, 0x0d, 0x97, 0x7d, 0x81, 0xd3, 0xdc, 0xf4, 0xd9, 0x60, 0x34, 0x90, 0xf5, - 0x54, 0x3a, 0xeb, 0xab, 0x82, 0xf5, 0x4b, 0x4e, 0x44, 0x65, 0x87, 0x9c, 0x2c, 0x59, 0x4d, 0x3a, - 0x63, 0x73, 0x03, 0x66, 0xf4, 0x4f, 0xd7, 0xe3, 0xa0, 0xa6, 0x20, 0x67, 0xd5, 0x0a, 0x76, 0x6d, - 0xa5, 0x70, 0x33, 0x6f, 0x90, 0x3c, 0x4c, 0x89, 0x5f, 0x4b, 0xf6, 0xd2, 0x9b, 0xb7, 0xf3, 0x19, - 0x0d, 0xf2, 0xe6, 0xcd, 0xa5, 0x7c, 0xf6, 0x83, 0x91, 0x5c, 0x36, 0x3f, 0xf2, 0xc1, 0x48, 0x6e, - 0x24, 0x3f, 0xfa, 0xc1, 0x48, 0x6e, 0x3c, 0x9f, 0xe3, 0x36, 0x00, 0xf3, 0xef, 0x1b, 0x90, 0x93, - 0xed, 0x26, 0xb7, 0x21, 0x5b, 0xab, 0xad, 0x24, 0x5c, 0x59, 0xe3, 0xfd, 0x85, 0xaf, 0xa4, 0x41, - 0x70, 0xa0, 0xae, 0xa4, 0xb5, 0xda, 0x0a, 0xa3, 0xdb, 0x5c, 0xad, 0x89, 0xed, 0x5d, 0xd2, 0xc5, - 0xcb, 0x36, 0xa7, 0x4b, 0xf1, 0xef, 0xbb, 0x0d, 0xd9, 0x0f, 0x76, 0x36, 0xc5, 0xb1, 0x44, 0xd2, - 0xc5, 0x2b, 0x29, 0xa7, 0xfb, 0xe8, 0xa1, 0xba, 0xbe, 0x33, 0x02, 0xd3, 0x82, 0x49, 0x45, 0x84, - 0xf9, 0x76, 0xdb, 0xf2, 0xa2, 0x18, 0x21, 0xb1, 0xdd, 0x32, 0x88, 0x25, 0x4a, 0x98, 0x76, 0xb0, - 0xea, 0xd5, 0x9d, 0xa6, 0xd8, 0xb7, 0x51, 0x3b, 0x68, 0x32, 0x80, 0xc5, 0xe1, 0xe6, 0xef, 0x1a, - 0x90, 0xaf, 0xfa, 0xde, 0x03, 0x97, 0x2d, 0x33, 0x9b, 0xde, 0x7d, 0xda, 0xde, 0xbe, 0x49, 0xde, - 0x90, 0x93, 0xcd, 0x88, 0x0e, 0xc1, 0xa3, 0x38, 0xd9, 0x12, 0x26, 0x55, 0x31, 0xe1, 0x94, 0x50, - 0xab, 0xcc, 0xf0, 0xe1, 0x1b, 0xc7, 0x84, 0x5a, 0x2d, 0xc2, 0x28, 0x36, 0x47, 0xf1, 0xa0, 0x1f, - 0x0d, 0x19, 0xc0, 0xe2, 0x70, 0xf5, 0x50, 0x99, 0xe9, 0xf9, 0x86, 0xa5, 0x4f, 0x55, 0x08, 0x84, - 0xfe, 0x71, 0x43, 0xad, 0xd4, 0x1f, 0xc2, 0x7c, 0xb2, 0x4b, 0xd0, 0x40, 0x51, 0x80, 0x59, 0x1d, - 0x2e, 0x6d, 0x15, 0xe7, 0x52, 0xeb, 0xda, 0x5e, 0xb2, 0x92, 0xf8, 0xe6, 0x1f, 0x19, 0x30, 0x81, - 0x7f, 0x5a, 0xdd, 0x26, 0x5e, 0x57, 0x17, 0x76, 0x6a, 0xc2, 0xad, 0x4e, 0x55, 0xe3, 0x9c, 0x87, - 0x81, 0x2d, 0x7c, 0xf0, 0xb4, 0xf5, 0x25, 0x42, 0x16, 0xa4, 0xdc, 0x89, 0x50, 0xde, 0x6b, 0x45, - 0xa4, 0xdc, 0xdb, 0x30, 0x48, 0x90, 0x0a, 0x64, 0xf4, 0xb0, 0xd8, 0xa9, 0x31, 0xf1, 0x53, 0x6f, - 0xb3, 0x90, 0xce, 0x6b, 0xea, 0x1e, 0x16, 0x1c, 0x0d, 0x2f, 0xb3, 0x76, 0x6a, 0x05, 0x6b, 0x5d, - 0xbb, 0xcc, 0x62, 0x6d, 0xd4, 0xbc, 0xbe, 0x04, 0x92, 0xf9, 0x77, 0x72, 0xc9, 0x0e, 0x14, 0x5b, - 0xdd, 0x09, 0xe7, 0xc6, 0xdb, 0x30, 0x5a, 0x68, 0x36, 0xbd, 0x87, 0x62, 0x95, 0x90, 0xf6, 0x92, - 0xa8, 0xff, 0xf8, 0x4e, 0xe6, 0x30, 0x14, 0xcd, 0x8b, 0x98, 0x01, 0x48, 0x11, 0x26, 0x0a, 0x3b, - 0xb5, 0x4a, 0xa5, 0xb4, 0xb9, 0xb9, 0x2a, 0xe2, 0x5e, 0x5f, 0x91, 0xfd, 0xe3, 0xba, 0x0d, 0x3b, - 0x79, 0xeb, 0x13, 0x6b, 0xee, 0x31, 0x1d, 0x79, 0x17, 0xe0, 0x03, 0xcf, 0x6d, 0xaf, 0xd1, 0xf0, - 0xc0, 0x6b, 0x88, 0x8f, 0x7f, 0xe1, 0xf1, 0xd1, 0xe2, 0xe4, 0x47, 0x9e, 0xdb, 0xb6, 0x5b, 0x08, - 0x66, 0x6d, 0x8f, 0x91, 0x2c, 0xe5, 0x6f, 0xd6, 0xd3, 0xcb, 0x1e, 0xbf, 0x82, 0x1e, 0x8d, 0x7b, - 0x7a, 0xd7, 0xeb, 0xb9, 0x7d, 0x96, 0x68, 0xa4, 0x05, 0xb3, 0xb5, 0xee, 0xfe, 0x3e, 0x65, 0xab, - 0xba, 0x38, 0xfd, 0x8e, 0x89, 0x33, 0x57, 0x14, 0x35, 0xcc, 0x4f, 0x22, 0xec, 0x7c, 0x12, 0x2c, - 0xbf, 0xce, 0x04, 0xf9, 0x07, 0x47, 0x8b, 0xe2, 0x36, 0x89, 0x29, 0x69, 0x81, 0xa4, 0xef, 0xb5, - 0xbf, 0x24, 0x79, 0x93, 0x0d, 0x18, 0xbb, 0xeb, 0x86, 0x2b, 0xdd, 0x5d, 0x71, 0x7c, 0x7d, 0x69, - 0xc0, 0xa4, 0xe1, 0x88, 0xfc, 0x04, 0xbf, 0xef, 0x86, 0x07, 0x5d, 0xd5, 0x4d, 0x52, 0xb0, 0x21, - 0x3b, 0x90, 0x2b, 0xba, 0x7e, 0xbd, 0x49, 0x8b, 0x15, 0xb1, 0xeb, 0x5f, 0x1a, 0xc0, 0x52, 0xa2, - 0xf2, 0x7e, 0xa9, 0xe3, 0xaf, 0xba, 0xab, 0x6a, 0x01, 0x12, 0x83, 0xfc, 0x7b, 0x06, 0x3c, 0x17, - 0xb5, 0xbe, 0xb0, 0x4f, 0xdb, 0xe1, 0x9a, 0x13, 0xd6, 0x0f, 0xa8, 0x1f, 0x05, 0xcc, 0x0c, 0xe8, - 0xa5, 0x2f, 0xf4, 0xf4, 0xd2, 0x95, 0xb8, 0x97, 0x1c, 0xc6, 0xcc, 0x6e, 0x71, 0x6e, 0xbd, 0x7d, - 0x36, 0xa8, 0x56, 0x62, 0x03, 0xc4, 0x06, 0x71, 0xe1, 0x41, 0xfe, 0xca, 0x80, 0x0f, 0x8e, 0x91, - 0x85, 0xeb, 0x62, 0xf4, 0x5b, 0xf3, 0xb8, 0x88, 0xa0, 0xe4, 0x9e, 0xf4, 0x43, 0xe6, 0x1a, 0xc9, - 0xc5, 0x01, 0xbc, 0xb9, 0x6f, 0xf2, 0xe9, 0x01, 0x8e, 0xf5, 0x7c, 0xb4, 0x57, 0x9d, 0x5d, 0xa1, - 0x84, 0x1c, 0x33, 0xda, 0xab, 0x4e, 0x3c, 0xda, 0x4d, 0x27, 0x39, 0xda, 0xab, 0xce, 0x2e, 0x29, - 0xf2, 0x18, 0x81, 0x69, 0xe4, 0xf6, 0xe2, 0x20, 0x6e, 0xc5, 0x2a, 0xdf, 0x99, 0x7b, 0x63, 0x05, - 0xcc, 0x7f, 0x3b, 0x02, 0x17, 0xfa, 0xcb, 0x1b, 0xf9, 0x92, 0x5c, 0x04, 0xf8, 0x52, 0x7b, 0xf9, - 0x58, 0x09, 0xbd, 0x7e, 0xec, 0xd2, 0xf0, 0x65, 0x98, 0x2f, 0xb7, 0x43, 0xea, 0x77, 0x7c, 0x57, - 0xc6, 0x54, 0xad, 0x78, 0x81, 0x74, 0xd3, 0x78, 0xf9, 0xf1, 0xd1, 0xe2, 0x45, 0x1a, 0x95, 0x0b, - 0x8f, 0x1d, 0x74, 0x1a, 0x51, 0x58, 0xa5, 0x72, 0xb8, 0xf0, 0xeb, 0x59, 0x18, 0xc1, 0x95, 0xfd, - 0x12, 0x64, 0x6b, 0xdd, 0x5d, 0xb1, 0xa4, 0x73, 0x1d, 0x48, 0x9b, 0x2f, 0xac, 0x94, 0x7c, 0x1e, - 0xc0, 0xa2, 0x1d, 0x2f, 0x70, 0x43, 0xcf, 0x3f, 0x54, 0x7d, 0x42, 0xfd, 0x08, 0xaa, 0x3b, 0x2b, - 0x49, 0x28, 0x59, 0x81, 0xd9, 0xf8, 0xd7, 0xc6, 0xc3, 0x36, 0x95, 0xa6, 0x3b, 0x3c, 0xa6, 0xc5, - 0xe4, 0xb6, 0xc7, 0xca, 0xd4, 0x15, 0x20, 0x41, 0x46, 0x96, 0x20, 0xb7, 0xe3, 0xf9, 0xf7, 0xf7, - 0x58, 0x0f, 0x8f, 0xc4, 0x6b, 0xd4, 0x43, 0x01, 0x53, 0xe7, 0xa2, 0xc4, 0x23, 0x6f, 0xc3, 0x64, - 0xb9, 0xfd, 0xc0, 0xf5, 0xbd, 0x76, 0x8b, 0xb6, 0xa5, 0x57, 0x0e, 0x37, 0x3f, 0xc4, 0x60, 0xcd, - 0xcb, 0x3b, 0x06, 0xb3, 0xc3, 0x48, 0xa1, 0x1e, 0x7a, 0xbe, 0x70, 0xca, 0xe1, 0xe3, 0xc4, 0x00, - 0xda, 0x38, 0x31, 0x00, 0xeb, 0x44, 0x8b, 0xee, 0x09, 0xf3, 0x2a, 0x76, 0xa2, 0x4f, 0xf7, 0x34, - 0x17, 0x76, 0xba, 0xc7, 0xd6, 0x58, 0x8b, 0xee, 0xe1, 0x09, 0x2a, 0x17, 0xb7, 0xdf, 0xa7, 0x7b, - 0x3d, 0x67, 0x6f, 0x81, 0x66, 0xfe, 0x46, 0x7f, 0x81, 0x63, 0x42, 0x7d, 0x32, 0x81, 0x5b, 0x75, - 0x86, 0x10, 0xb8, 0xd7, 0x23, 0x17, 0xa8, 0x4c, 0x1c, 0x12, 0xc0, 0x5d, 0xa0, 0xd4, 0x59, 0xc5, - 0x71, 0x2e, 0xfc, 0xff, 0x4e, 0x24, 0x44, 0xa2, 0x93, 0x32, 0xc3, 0x76, 0x52, 0x76, 0xa8, 0x4e, - 0x22, 0xcb, 0x30, 0x1d, 0xe5, 0x25, 0xa8, 0x3a, 0xc2, 0x83, 0x58, 0xb8, 0x10, 0x45, 0x59, 0x26, - 0xec, 0x8e, 0x13, 0xaa, 0x9a, 0xbd, 0x4e, 0x42, 0xde, 0x81, 0x49, 0xe1, 0x07, 0x88, 0x1c, 0x46, - 0x63, 0x07, 0x44, 0xe9, 0x34, 0x98, 0xa0, 0x57, 0xd1, 0x49, 0x19, 0x66, 0xaa, 0x6e, 0x87, 0x36, - 0xdd, 0x36, 0xad, 0xa1, 0x8b, 0x91, 0x90, 0x18, 0xf4, 0xa7, 0xeb, 0x88, 0x12, 0x9b, 0x7b, 0x1f, - 0x69, 0x86, 0x08, 0x8d, 0x28, 0x29, 0xac, 0xe3, 0x27, 0x11, 0x56, 0xf3, 0xef, 0x67, 0xe0, 0xf9, - 0x41, 0x1b, 0x17, 0xa9, 0xe9, 0xc2, 0x72, 0x65, 0x88, 0xcd, 0xee, 0x78, 0x71, 0x29, 0xc3, 0xcc, - 0x86, 0xbf, 0xef, 0xb4, 0xdd, 0x6f, 0xa3, 0x42, 0x12, 0x79, 0x32, 0xe2, 0x97, 0x7b, 0x4a, 0x89, - 0x6e, 0xe5, 0x4b, 0x10, 0x5d, 0x78, 0x20, 0xc4, 0xe8, 0xe3, 0x7a, 0x6e, 0xde, 0x86, 0x89, 0xa2, - 0xd7, 0x0e, 0xe9, 0xa3, 0x30, 0xe1, 0xb1, 0xce, 0x81, 0x49, 0x8f, 0x75, 0x89, 0x6a, 0xfe, 0x9e, - 0x01, 0x2f, 0x0e, 0xde, 0xfc, 0xc8, 0x96, 0xde, 0x6d, 0xd7, 0x86, 0xda, 0x32, 0x8f, 0xed, 0xb8, - 0x0b, 0x6b, 0xe2, 0x8b, 0xcb, 0x30, 0x23, 0x1c, 0x56, 0x74, 0xdd, 0x1a, 0x3b, 0x50, 0x38, 0x7e, - 0xa5, 0xe8, 0xd7, 0x09, 0x22, 0xf3, 0x4f, 0x0d, 0x38, 0xdf, 0x77, 0xa7, 0x25, 0x55, 0xfd, 0x1b, - 0x5e, 0x39, 0x6e, 0x6b, 0x3e, 0xbe, 0xf9, 0x3f, 0x6f, 0x88, 0xf6, 0xbf, 0x07, 0x53, 0xb5, 0xee, - 0x6e, 0x32, 0xd6, 0x1a, 0x67, 0x4e, 0xa0, 0xc0, 0xb5, 0x1b, 0x14, 0x05, 0xce, 0xbe, 0x5f, 0xfa, - 0xe5, 0xa1, 0x27, 0xb9, 0x3c, 0x20, 0xe0, 0xf7, 0x47, 0xae, 0xb0, 0xe8, 0xe9, 0xab, 0x2a, 0x1e, - 0x09, 0x22, 0xf3, 0xb7, 0x33, 0x70, 0xae, 0xcf, 0x6e, 0x4e, 0xd6, 0xf5, 0xaf, 0xbf, 0x34, 0x78, - 0xf3, 0x3f, 0xfe, 0xdb, 0xff, 0x89, 0xfc, 0x76, 0x34, 0x69, 0x0a, 0x11, 0x94, 0x07, 0x05, 0x61, - 0xd2, 0x94, 0xe2, 0x1a, 0xe8, 0x26, 0x4d, 0x89, 0x4c, 0xde, 0x84, 0x09, 0x76, 0x30, 0x0f, 0x95, - 0x23, 0x11, 0xf7, 0x15, 0x95, 0x40, 0x55, 0x5e, 0x23, 0x4c, 0xb6, 0x99, 0xea, 0x03, 0x2f, 0xbd, - 0xa0, 0x70, 0x33, 0x4d, 0x88, 0x8b, 0xae, 0x4e, 0xeb, 0x64, 0xe6, 0xcf, 0x67, 0x60, 0x86, 0xdf, - 0xc8, 0xf0, 0xe3, 0xde, 0x33, 0x7b, 0x94, 0x7e, 0x5b, 0x3b, 0x4a, 0xcb, 0xa0, 0x24, 0xf5, 0xd3, - 0x86, 0x3a, 0x48, 0x1f, 0x00, 0xe9, 0xa5, 0x21, 0x96, 0xbc, 0x37, 0x1c, 0xe6, 0x0c, 0x7d, 0x33, - 0x8e, 0x5f, 0xc3, 0x24, 0x4b, 0x75, 0x1b, 0x0d, 0x19, 0x81, 0xa5, 0xf1, 0x30, 0x7f, 0x36, 0x03, - 0xd3, 0x8a, 0xc9, 0xf3, 0x99, 0xed, 0xf8, 0x2f, 0x68, 0x1d, 0x2f, 0x83, 0x48, 0x95, 0x2f, 0x1b, - 0xaa, 0xdf, 0xbb, 0x30, 0xd7, 0x43, 0x92, 0xb4, 0x1c, 0x1b, 0xc3, 0x58, 0x8e, 0x5f, 0xef, 0x0d, - 0x5a, 0xe2, 0xb9, 0x6c, 0xa2, 0xa0, 0x25, 0x35, 0x4a, 0xea, 0xbb, 0x19, 0x98, 0x17, 0xbf, 0x0a, - 0xdd, 0x86, 0x1b, 0x16, 0xbd, 0xf6, 0x9e, 0xbb, 0xff, 0xcc, 0x8e, 0x45, 0x41, 0x1b, 0x8b, 0x45, - 0x7d, 0x2c, 0x94, 0x0f, 0xec, 0x3f, 0x24, 0xe6, 0x4f, 0x01, 0x2c, 0xf4, 0x23, 0x18, 0xda, 0x3f, - 0x36, 0x0e, 0x28, 0xcd, 0x0c, 0x11, 0x50, 0xba, 0x0a, 0x79, 0xac, 0xaa, 0x46, 0x03, 0xd6, 0x09, - 0x41, 0x9c, 0x48, 0xe3, 0xe2, 0xe3, 0xa3, 0xc5, 0xe7, 0x1d, 0x56, 0x66, 0x07, 0xa2, 0xd0, 0xee, - 0xfa, 0xea, 0x71, 0xbb, 0x87, 0x92, 0xfc, 0xba, 0x01, 0x33, 0x08, 0x2c, 0x3f, 0xa0, 0xed, 0x10, - 0x99, 0x8d, 0x08, 0x07, 0xa9, 0xe8, 0xa4, 0x5d, 0x0b, 0x7d, 0xb7, 0xbd, 0x2f, 0x8e, 0xda, 0xbb, - 0xe2, 0xa8, 0xfd, 0x0e, 0x37, 0x11, 0x5c, 0xaf, 0x7b, 0xad, 0x1b, 0xfb, 0xbe, 0xf3, 0xc0, 0xe5, - 0xd6, 0x7c, 0xa7, 0x79, 0x23, 0xce, 0xa3, 0xd6, 0x71, 0x13, 0x99, 0xd1, 0x04, 0x2b, 0x34, 0x63, - 0xf0, 0x86, 0x52, 0xac, 0x36, 0xd1, 0xcc, 0x44, 0x8b, 0xc8, 0x57, 0xe0, 0x1c, 0x0f, 0xe8, 0x61, - 0x3a, 0x88, 0xdb, 0xee, 0x7a, 0xdd, 0x60, 0xd9, 0xa9, 0xdf, 0x67, 0xfb, 0x1e, 0xbf, 0xd4, 0xc7, - 0x2f, 0xaf, 0x47, 0x85, 0xf6, 0x2e, 0x2f, 0x55, 0x58, 0xf6, 0x63, 0x40, 0x56, 0x60, 0x8e, 0x17, - 0x15, 0xba, 0xa1, 0x57, 0xab, 0x3b, 0x4d, 0xb7, 0xbd, 0x8f, 0x4a, 0x64, 0x8e, 0xef, 0xc7, 0x4e, - 0x37, 0xf4, 0xec, 0x80, 0xc3, 0x15, 0x7e, 0xbd, 0x44, 0xa4, 0xc2, 0xce, 0x6c, 0x4e, 0x63, 0xcd, - 0x79, 0x54, 0x74, 0x3a, 0x4e, 0xdd, 0x0d, 0x79, 0x18, 0x69, 0x96, 0x87, 0x72, 0xf8, 0xd4, 0x69, - 0xd8, 0x2d, 0xe7, 0x91, 0x5d, 0x17, 0x85, 0xfa, 0xa1, 0x4d, 0xa3, 0x8b, 0x58, 0xb9, 0xed, 0x88, - 0xd5, 0x44, 0x92, 0x95, 0xdb, 0xee, 0xcf, 0x2a, 0xa6, 0x93, 0xac, 0x36, 0x1d, 0x7f, 0x9f, 0x86, - 0xfc, 0x32, 0x1c, 0x2e, 0x1a, 0x57, 0x0c, 0x85, 0x55, 0x88, 0x65, 0x36, 0x5e, 0x8c, 0x27, 0x59, - 0x29, 0x74, 0x4c, 0xf2, 0x76, 0x7c, 0x37, 0xa4, 0xea, 0x17, 0x4e, 0x62, 0xb3, 0xb0, 0xff, 0xd1, - 0x1d, 0xa0, 0xdf, 0x27, 0xf6, 0x50, 0xc6, 0xdc, 0x94, 0x8f, 0x9c, 0xea, 0xe1, 0x96, 0xfe, 0x95, - 0x3d, 0x94, 0x11, 0x37, 0xf5, 0x3b, 0xa7, 0xf1, 0x3b, 0x15, 0x6e, 0x7d, 0x3e, 0xb4, 0x87, 0x92, - 0xac, 0xb3, 0x4e, 0x0b, 0x69, 0x9b, 0x49, 0xb4, 0x70, 0x06, 0x98, 0xc1, 0xa6, 0xbd, 0x2c, 0x6e, - 0xb4, 0xf2, 0xbe, 0x2c, 0xb6, 0x53, 0x5c, 0x03, 0x92, 0xc4, 0xe4, 0x47, 0x61, 0x76, 0x2b, 0xa0, - 0x77, 0x2a, 0xd5, 0x9a, 0x0c, 0xe0, 0x5a, 0x98, 0xc5, 0x7b, 0xae, 0x9b, 0xc7, 0x2c, 0x3a, 0xd7, - 0x55, 0x1a, 0xcc, 0x68, 0xc6, 0xc7, 0xad, 0x1b, 0x50, 0x7b, 0xcf, 0xed, 0x04, 0x51, 0x30, 0xa5, - 0x3a, 0x6e, 0x89, 0xaa, 0xcc, 0x15, 0x98, 0xeb, 0x61, 0x43, 0x66, 0x00, 0x18, 0xd0, 0xde, 0x5a, - 0xaf, 0x95, 0x37, 0xf3, 0xa7, 0x48, 0x1e, 0xa6, 0xf0, 0x77, 0x79, 0xbd, 0xb0, 0xbc, 0x5a, 0x2e, - 0xe5, 0x0d, 0x32, 0x07, 0xd3, 0x08, 0x29, 0x55, 0x6a, 0x1c, 0x94, 0xf9, 0x60, 0x24, 0x37, 0x9a, - 0x1f, 0xb3, 0xf2, 0x7c, 0xea, 0x86, 0x6c, 0x02, 0xe0, 0x9e, 0x62, 0xfe, 0x95, 0x0c, 0x9c, 0x97, - 0xdb, 0x0a, 0x0d, 0x1f, 0x7a, 0xfe, 0x7d, 0xb7, 0xbd, 0xff, 0x8c, 0xef, 0x0e, 0x77, 0xb4, 0xdd, - 0xe1, 0xe5, 0xc4, 0x4e, 0x9d, 0xf8, 0xca, 0x01, 0x5b, 0xc4, 0xaf, 0x8c, 0xc3, 0x0b, 0x03, 0xa9, - 0xc8, 0x97, 0xd8, 0x6e, 0xee, 0xd2, 0x76, 0x58, 0x69, 0x34, 0xe9, 0xa6, 0xdb, 0xa2, 0x5e, 0x37, - 0x14, 0xce, 0x27, 0x97, 0x98, 0x7a, 0xcb, 0xd3, 0x91, 0xd9, 0x6e, 0xa3, 0x49, 0xed, 0x90, 0x17, - 0x6b, 0xe2, 0xd6, 0x4b, 0xcd, 0x58, 0x46, 0x29, 0x13, 0x2b, 0xed, 0x90, 0xfa, 0x0f, 0x1c, 0x9e, - 0x95, 0x49, 0xb0, 0xbc, 0x4f, 0x69, 0xc7, 0x76, 0x58, 0xa9, 0xed, 0x8a, 0x62, 0x9d, 0x65, 0x0f, - 0x35, 0xb9, 0xa3, 0xb0, 0x2c, 0x32, 0x75, 0x78, 0xcd, 0x79, 0x24, 0xec, 0xee, 0x22, 0xb8, 0x3b, - 0x62, 0xc9, 0x73, 0x0b, 0xb4, 0x9c, 0x47, 0x56, 0x2f, 0x09, 0xf9, 0x3a, 0x9c, 0x11, 0x1b, 0x90, - 0x88, 0xa9, 0x90, 0x5f, 0xcc, 0x23, 0x36, 0x5e, 0x7d, 0x7c, 0xb4, 0x78, 0x4e, 0x6c, 0x5f, 0xb6, - 0x8c, 0x4f, 0x49, 0xfb, 0xea, 0x74, 0x2e, 0x64, 0x93, 0x6d, 0xc8, 0x89, 0xee, 0x58, 0xa3, 0x41, - 0xe0, 0xec, 0x4b, 0x1b, 0x3d, 0xf7, 0x00, 0x53, 0x3a, 0xd3, 0x6e, 0xf1, 0x72, 0xab, 0x2f, 0x25, - 0x59, 0x81, 0x99, 0x1d, 0xba, 0xab, 0x8e, 0xcf, 0x58, 0xb4, 0x54, 0xe5, 0x1f, 0xd2, 0xdd, 0xfe, - 0x83, 0x93, 0xa0, 0x23, 0x2e, 0xcc, 0xa1, 0x77, 0xec, 0xaa, 0x1b, 0x84, 0xb4, 0x4d, 0x7d, 0x8c, - 0x3b, 0x1b, 0xc7, 0xc5, 0x60, 0x21, 0xd6, 0x90, 0xf5, 0xf2, 0xe5, 0x97, 0x1e, 0x1f, 0x2d, 0xbe, - 0xc0, 0x3d, 0x6d, 0x9b, 0x02, 0x6e, 0x27, 0x72, 0x13, 0xf6, 0x72, 0x25, 0xdf, 0x84, 0x59, 0xcb, - 0xeb, 0x86, 0x6e, 0x7b, 0xbf, 0x16, 0xfa, 0x4e, 0x48, 0xf7, 0xf9, 0x86, 0x14, 0x07, 0xb8, 0x25, - 0x4a, 0x85, 0x71, 0x91, 0x03, 0xed, 0x40, 0x40, 0xb5, 0x1d, 0x41, 0x27, 0x20, 0xdf, 0x80, 0x19, - 0xee, 0x82, 0x1f, 0x55, 0x30, 0xa1, 0xa5, 0xf1, 0xd1, 0x0b, 0xb7, 0x6f, 0xf2, 0x03, 0x2a, 0x77, - 0xe5, 0x4f, 0xab, 0x20, 0xc1, 0x8d, 0x7c, 0x55, 0x74, 0x56, 0xd5, 0x6d, 0xef, 0x47, 0x62, 0x0c, - 0xd8, 0xf3, 0x6f, 0xc4, 0x5d, 0xd2, 0x61, 0xcd, 0x95, 0x62, 0xdc, 0xe7, 0xce, 0xa7, 0x97, 0x8f, - 0x79, 0x64, 0x40, 0x3e, 0xd9, 0x40, 0xf2, 0x65, 0x98, 0xe0, 0xd7, 0x00, 0x34, 0x38, 0x10, 0x91, - 0x70, 0xd2, 0xee, 0x1d, 0xc1, 0x75, 0x22, 0x91, 0x50, 0x83, 0x5f, 0x32, 0x50, 0xf5, 0x22, 0x7c, - 0xe5, 0x94, 0x15, 0x33, 0x23, 0x0d, 0x98, 0xe2, 0x6d, 0xa0, 0x18, 0xb3, 0x29, 0x6e, 0x83, 0x5f, - 0x52, 0xc7, 0x5c, 0x14, 0x25, 0xf8, 0x63, 0x58, 0xa3, 0xf8, 0x52, 0x8e, 0xa0, 0x55, 0xa1, 0x71, - 0x5d, 0x06, 0xc8, 0x49, 0x42, 0xf3, 0x3c, 0x9c, 0xeb, 0xd3, 0x66, 0xf3, 0x01, 0x5a, 0x48, 0xfb, - 0xd4, 0x48, 0xbe, 0x0c, 0xf3, 0x48, 0x58, 0xf4, 0xda, 0x6d, 0x5a, 0x0f, 0x71, 0x92, 0x49, 0x23, - 0x4b, 0x96, 0xdb, 0xcf, 0xf9, 0xf7, 0xd6, 0x23, 0x04, 0x3b, 0x69, 0x6b, 0x49, 0xe5, 0x60, 0xfe, - 0x6a, 0x06, 0x16, 0xc4, 0xbc, 0xb5, 0x68, 0xdd, 0xf3, 0x1b, 0xcf, 0xfe, 0x3e, 0x51, 0xd6, 0xf6, - 0x89, 0x4b, 0x51, 0x60, 0x4d, 0xda, 0x47, 0x0e, 0xd8, 0x26, 0x7e, 0xdb, 0x80, 0xe7, 0x07, 0x11, - 0xb1, 0xde, 0x89, 0x62, 0x54, 0x27, 0x7a, 0x62, 0x51, 0x3b, 0x70, 0x1a, 0x07, 0xb4, 0x78, 0x40, - 0xeb, 0xf7, 0x83, 0x15, 0x2f, 0x08, 0xd1, 0x19, 0x25, 0xa3, 0x39, 0xa2, 0x2f, 0x7b, 0x1e, 0xbf, - 0x31, 0xc3, 0x6b, 0x45, 0xe3, 0x07, 0x47, 0x8b, 0xc0, 0x40, 0x3c, 0xaa, 0x54, 0x98, 0x6d, 0x1f, - 0x1d, 0xda, 0x75, 0xe4, 0xc1, 0xa3, 0x68, 0xef, 0xd3, 0xc3, 0xc0, 0x4a, 0x63, 0x8d, 0x8e, 0x05, - 0x85, 0x6e, 0x78, 0x50, 0xf5, 0xe9, 0x1e, 0xf5, 0x69, 0xbb, 0x4e, 0x3f, 0x65, 0x8e, 0x05, 0xfa, - 0xc7, 0x0d, 0x75, 0x2e, 0xff, 0x2e, 0xc0, 0x7c, 0x1a, 0x19, 0xeb, 0x17, 0xe5, 0x28, 0x98, 0xcc, - 0x87, 0xfc, 0x17, 0x0d, 0x98, 0xaa, 0xd1, 0xba, 0xd7, 0x6e, 0xdc, 0xc1, 0x9b, 0x12, 0xd1, 0x3b, - 0x36, 0xdf, 0x0a, 0x19, 0xdc, 0xde, 0x4b, 0x5c, 0xa1, 0xfc, 0xf0, 0x68, 0xf1, 0x8b, 0xc3, 0x9d, - 0xc0, 0xea, 0x1e, 0x86, 0x10, 0x86, 0x98, 0x62, 0x27, 0xaa, 0x02, 0x3d, 0xce, 0xb4, 0x4a, 0xc9, - 0x32, 0x4c, 0x8b, 0xe9, 0xea, 0xa9, 0x21, 0xca, 0x78, 0x23, 0x50, 0x97, 0x05, 0x3d, 0x39, 0x0d, - 0x34, 0x12, 0x72, 0x0b, 0xb2, 0x5b, 0x4b, 0x77, 0xc4, 0x18, 0xc8, 0x08, 0xab, 0xad, 0xa5, 0x3b, - 0x68, 0xe4, 0x61, 0x8a, 0xf3, 0x74, 0x77, 0x49, 0xbb, 0xbc, 0xd8, 0x5a, 0xba, 0x43, 0x7e, 0x1c, - 0xce, 0x94, 0xdc, 0x40, 0x54, 0xc1, 0x5d, 0x5c, 0x1a, 0xe8, 0xd2, 0x39, 0xd6, 0x47, 0x7a, 0x3f, - 0x97, 0x2a, 0xbd, 0x2f, 0x35, 0x22, 0x26, 0x36, 0xf7, 0x9f, 0x69, 0x24, 0x43, 0xb1, 0xd3, 0xeb, - 0x21, 0x1f, 0xc1, 0x0c, 0x1a, 0x29, 0xd1, 0xeb, 0x07, 0xd3, 0xa9, 0x8c, 0xf7, 0xa9, 0xf9, 0x33, - 0xa9, 0x35, 0x5f, 0x40, 0x9b, 0xa7, 0x8d, 0xbe, 0x43, 0x98, 0x7a, 0x45, 0x3b, 0xcb, 0x6a, 0x9c, - 0xc9, 0x07, 0x30, 0x2b, 0x94, 0x8a, 0x8d, 0xbd, 0xcd, 0x03, 0x5a, 0x72, 0x0e, 0xc5, 0xb5, 0x16, - 0x9e, 0x53, 0x84, 0x26, 0x62, 0x7b, 0x7b, 0x76, 0x78, 0x40, 0xed, 0x86, 0xa3, 0x6d, 0xbf, 0x09, - 0x42, 0xf2, 0x23, 0x30, 0xb9, 0xea, 0xd5, 0x99, 0x3e, 0x89, 0x2b, 0xc3, 0x04, 0xf2, 0xf9, 0x10, - 0x93, 0xf3, 0x72, 0x70, 0x42, 0x49, 0xf8, 0xe1, 0xd1, 0xe2, 0xdb, 0x27, 0x15, 0x1a, 0xa5, 0x02, - 0x4b, 0xad, 0x8d, 0x14, 0x21, 0xb7, 0x43, 0x77, 0xd9, 0xd7, 0x26, 0x13, 0x4b, 0x4a, 0xb0, 0xb8, - 0x69, 0x14, 0xbf, 0xb4, 0x9b, 0x46, 0x01, 0x23, 0x3e, 0xcc, 0x61, 0xff, 0x54, 0x9d, 0x20, 0x78, - 0xe8, 0xf9, 0x0d, 0xcc, 0x94, 0x34, 0xd9, 0xa7, 0xf3, 0x97, 0x52, 0x3b, 0xff, 0x79, 0xde, 0xf9, - 0x1d, 0x85, 0x83, 0xaa, 0x16, 0xf5, 0xb0, 0x27, 0xdf, 0x84, 0x19, 0x8b, 0x7e, 0xab, 0xeb, 0xfa, - 0x74, 0xed, 0x4e, 0x01, 0x67, 0xe5, 0x94, 0xe6, 0x18, 0xab, 0x17, 0x72, 0xdd, 0xcb, 0xe7, 0x30, - 0x69, 0x57, 0xb1, 0x5b, 0x7b, 0x8e, 0x6e, 0x57, 0x57, 0x49, 0x48, 0x15, 0x26, 0x4b, 0xf4, 0x81, - 0x5b, 0xa7, 0xe8, 0xbe, 0x27, 0xae, 0xcf, 0xa3, 0x44, 0x77, 0x71, 0x09, 0xb7, 0x30, 0x34, 0x10, - 0xc0, 0x9d, 0x01, 0xf5, 0x48, 0x80, 0x08, 0x91, 0xdc, 0x86, 0x6c, 0xa5, 0x54, 0xc5, 0x43, 0x68, - 0xec, 0x15, 0x57, 0x69, 0x54, 0x65, 0xbe, 0x34, 0xbc, 0x17, 0x74, 0x1b, 0xda, 0xdd, 0x7b, 0xa5, - 0x54, 0x25, 0x7b, 0x30, 0x8d, 0x1d, 0xb0, 0x42, 0x1d, 0xde, 0xb7, 0xb3, 0x7d, 0xfa, 0xf6, 0x7a, - 0x6a, 0xdf, 0x2e, 0xf0, 0xbe, 0x3d, 0x10, 0xd4, 0x5a, 0x02, 0x28, 0x95, 0xad, 0x38, 0x18, 0xce, - 0x89, 0x7e, 0x10, 0xfb, 0xd8, 0xda, 0x9d, 0x82, 0xf9, 0x9f, 0x18, 0xb8, 0x22, 0x90, 0x6b, 0x18, - 0xd8, 0x15, 0xdd, 0x4f, 0xa1, 0x89, 0xcb, 0xe9, 0x24, 0xf2, 0x93, 0x70, 0x14, 0xf2, 0x3a, 0x8c, - 0xdd, 0x71, 0xea, 0x34, 0x94, 0x36, 0x7e, 0x44, 0xde, 0x43, 0x88, 0x6a, 0x0f, 0xe3, 0x38, 0x4c, - 0x59, 0xe1, 0x3d, 0x55, 0x88, 0xf3, 0xf4, 0x17, 0x0b, 0xd2, 0xc4, 0x8f, 0xca, 0x8a, 0xe8, 0x61, - 0x25, 0x91, 0xbf, 0x5d, 0x77, 0x54, 0x5e, 0xa9, 0x1c, 0xcc, 0xff, 0xcd, 0x88, 0x45, 0x9c, 0xbc, - 0x0a, 0x23, 0x56, 0x35, 0x6a, 0x3f, 0x77, 0xb1, 0x4d, 0x34, 0x1f, 0x11, 0xc8, 0x57, 0xe1, 0x8c, - 0xc2, 0x07, 0xbb, 0x89, 0x36, 0x58, 0x83, 0xf8, 0xc7, 0xbc, 0x82, 0x3e, 0xa0, 0x4a, 0x4b, 0x1c, - 0x8e, 0x91, 0x68, 0x51, 0x3a, 0x0f, 0xd4, 0xcc, 0xe2, 0x82, 0x12, 0x6d, 0xbb, 0x9c, 0xb7, 0xf2, - 0xb1, 0x2a, 0xef, 0x06, 0x22, 0x24, 0x3f, 0x36, 0x8d, 0x03, 0x77, 0x03, 0x35, 0x7f, 0xc7, 0xd0, - 0x44, 0x37, 0xca, 0x89, 0x6e, 0x1c, 0x93, 0x13, 0xfd, 0x2d, 0x80, 0x42, 0x37, 0xf4, 0xca, 0x6d, - 0xdf, 0x6b, 0xf2, 0x83, 0xa6, 0x48, 0xd1, 0x83, 0xe6, 0x33, 0x8a, 0x60, 0xcd, 0x5b, 0x2d, 0x42, - 0x26, 0xab, 0x90, 0x2f, 0xdf, 0x43, 0x3f, 0xdf, 0xb8, 0xab, 0xf8, 0xe7, 0xe0, 0x8a, 0x48, 0xef, - 0xb3, 0x35, 0xbc, 0x4f, 0x2f, 0xf5, 0x50, 0x9a, 0xff, 0x87, 0xa1, 0xe4, 0xe1, 0x7f, 0x46, 0xd5, - 0x91, 0xdb, 0x9a, 0x3a, 0x32, 0x2f, 0x48, 0xa3, 0xaf, 0x62, 0x65, 0xa9, 0x2a, 0xe4, 0xac, 0x72, - 0xa5, 0x8f, 0x80, 0xef, 0x64, 0x60, 0x72, 0x2b, 0xa0, 0x3e, 0xbf, 0x69, 0xf9, 0x74, 0x05, 0xee, - 0x46, 0xdf, 0x35, 0x54, 0x68, 0xe5, 0x1f, 0x1a, 0x68, 0x81, 0x53, 0x29, 0x58, 0x6f, 0x60, 0x3e, - 0x4f, 0xa5, 0x37, 0xba, 0x01, 0xf5, 0x2d, 0x84, 0xf2, 0x90, 0xba, 0x55, 0x3d, 0xa4, 0xae, 0x69, - 0x31, 0x18, 0xf9, 0x22, 0x8c, 0x6e, 0xa1, 0x3d, 0x41, 0x0f, 0xa8, 0x88, 0xf8, 0x63, 0x21, 0x5f, - 0x22, 0xba, 0xec, 0x4f, 0x75, 0x85, 0xc3, 0x32, 0x52, 0x83, 0xf1, 0xa2, 0x4f, 0x31, 0xe3, 0xfe, - 0xc8, 0xf0, 0x4e, 0xc1, 0x75, 0x4e, 0x92, 0x74, 0x0a, 0x16, 0x9c, 0xcc, 0x5f, 0xce, 0x00, 0x89, - 0xbf, 0x11, 0xd3, 0xf1, 0x05, 0xcf, 0xec, 0xa0, 0xbf, 0xaf, 0x0d, 0xfa, 0x0b, 0x3d, 0x83, 0xce, - 0x3f, 0x6f, 0xa8, 0xb1, 0xff, 0x5d, 0x03, 0xce, 0xa6, 0x13, 0x92, 0x4b, 0x30, 0xb6, 0xb1, 0x59, - 0x95, 0x31, 0x39, 0xe2, 0x53, 0xbc, 0x0e, 0x1e, 0x7b, 0x2c, 0x51, 0x44, 0xde, 0x80, 0xb1, 0x2f, - 0x59, 0x45, 0xb6, 0x0a, 0x2a, 0x69, 0x7e, 0xbe, 0xe5, 0xdb, 0x75, 0x7d, 0x21, 0x14, 0x48, 0xea, - 0xd8, 0x66, 0x9f, 0xda, 0xd8, 0x7e, 0x37, 0x03, 0xb3, 0x85, 0x7a, 0x9d, 0x06, 0x01, 0xdb, 0x62, - 0x69, 0x10, 0x3e, 0xb3, 0x03, 0x9b, 0x1e, 0x6d, 0xa3, 0x7d, 0xdb, 0x50, 0xa3, 0xfa, 0x7b, 0x06, - 0x9c, 0x91, 0x54, 0x0f, 0x5c, 0xfa, 0x70, 0xf3, 0xc0, 0xa7, 0xc1, 0x81, 0xd7, 0x6c, 0x0c, 0x9d, - 0x4b, 0x8c, 0xa9, 0x19, 0x98, 0x55, 0x45, 0xbd, 0x76, 0xdb, 0x43, 0x88, 0xa6, 0x66, 0xf0, 0xcc, - 0x2b, 0x37, 0x60, 0xbc, 0xd0, 0xe9, 0xf8, 0xde, 0x03, 0x3e, 0xed, 0xa7, 0x85, 0x8f, 0x34, 0x07, - 0x69, 0x3e, 0xd5, 0x1c, 0xc4, 0x9a, 0x51, 0xa2, 0x6d, 0x1e, 0xee, 0x3c, 0xcd, 0x9b, 0xd1, 0xa0, - 0x6d, 0x55, 0x9f, 0xc7, 0x72, 0xf3, 0x17, 0x46, 0x60, 0x4a, 0xfd, 0x10, 0x62, 0xf2, 0xcc, 0x42, - 0x9e, 0xaf, 0x86, 0x2e, 0x38, 0x08, 0xb1, 0x44, 0x49, 0x1c, 0xf1, 0x93, 0x39, 0x36, 0xe2, 0x67, - 0x07, 0xa6, 0xab, 0xbe, 0xd7, 0xf1, 0x02, 0xda, 0xe0, 0x8f, 0xa6, 0xf0, 0x55, 0xeb, 0xb4, 0xa2, - 0xed, 0xb2, 0x3e, 0xc7, 0xbb, 0x05, 0x3c, 0xeb, 0x75, 0x04, 0xb6, 0x9d, 0x7c, 0x52, 0x45, 0xe7, - 0xc3, 0xaf, 0x2d, 0x9d, 0x40, 0x24, 0x20, 0x88, 0xae, 0x2d, 0x19, 0x44, 0xbf, 0xb6, 0x64, 0x10, - 0x75, 0x5a, 0x8c, 0x3e, 0xad, 0x69, 0x41, 0x7e, 0xd9, 0x80, 0xc9, 0x42, 0xbb, 0x2d, 0x22, 0x89, - 0x8e, 0x71, 0xa5, 0xfe, 0x9a, 0xb8, 0xb9, 0x7c, 0xfb, 0x63, 0xdd, 0x5c, 0x6e, 0xfa, 0x8e, 0x1b, - 0x06, 0xa8, 0xd2, 0xc4, 0x15, 0xaa, 0xea, 0xba, 0xd2, 0x0e, 0xf2, 0x36, 0xe4, 0x23, 0x79, 0xac, - 0xb4, 0x1b, 0xf4, 0x11, 0x0d, 0x16, 0xc6, 0x2f, 0x66, 0xaf, 0x4c, 0xf3, 0xf7, 0x9e, 0xb4, 0x2b, - 0xd9, 0x24, 0xa2, 0xf9, 0x5d, 0x03, 0xce, 0xaa, 0x02, 0x51, 0xeb, 0xee, 0xb6, 0x5c, 0x54, 0xa8, - 0xc9, 0x75, 0x98, 0x10, 0xe3, 0x15, 0x69, 0xa2, 0xbd, 0x09, 0x95, 0x62, 0x14, 0x52, 0x66, 0x43, - 0xc4, 0x78, 0x08, 0x43, 0xd0, 0xe9, 0xc4, 0x74, 0x63, 0x45, 0xcb, 0x0b, 0xa2, 0xb3, 0xf3, 0x3e, - 0xfe, 0xd6, 0xc7, 0x8e, 0x41, 0xcc, 0xf7, 0x60, 0x4e, 0x6f, 0x65, 0x8d, 0x62, 0x52, 0x1c, 0xf9, - 0x69, 0x46, 0xfa, 0xa7, 0xc9, 0x72, 0x73, 0x07, 0x48, 0x0f, 0x7d, 0x80, 0xd7, 0xef, 0x34, 0x94, - 0xee, 0x21, 0xd2, 0xf8, 0xdd, 0x83, 0x18, 0xbd, 0x44, 0x35, 0xa9, 0x76, 0x37, 0x92, 0x9a, 0xff, - 0x62, 0x12, 0x4e, 0xa7, 0x2c, 0x1d, 0xc7, 0x6c, 0xed, 0x8b, 0xfa, 0xe4, 0x99, 0x88, 0xa2, 0x14, - 0xe4, 0x94, 0x79, 0x4f, 0xbe, 0x2f, 0x34, 0x60, 0xaa, 0x0c, 0x7a, 0x74, 0xe8, 0x93, 0xd8, 0xde, - 0xd5, 0x40, 0xa2, 0xd1, 0xa7, 0x16, 0x48, 0xb4, 0x0c, 0xd3, 0xe2, 0xab, 0xc4, 0x54, 0x1e, 0x8b, - 0x6d, 0x3e, 0x3e, 0x2f, 0xb0, 0x7b, 0xa6, 0xb4, 0x4e, 0xc2, 0x79, 0x04, 0x5e, 0xf3, 0x01, 0x15, - 0x3c, 0xc6, 0x55, 0x1e, 0x58, 0x90, 0xca, 0x43, 0x21, 0x21, 0x7f, 0x07, 0xd3, 0x6c, 0x22, 0x44, - 0x9d, 0xcf, 0xb9, 0x41, 0xf3, 0xb9, 0xf1, 0x74, 0xe6, 0xf3, 0x0b, 0xb2, 0x8d, 0xe9, 0xf3, 0x3a, - 0xa5, 0x59, 0xe4, 0x37, 0x0c, 0x98, 0xe3, 0xd1, 0x2c, 0x6a, 0x63, 0x07, 0x46, 0x28, 0xd4, 0x9f, - 0x4e, 0x63, 0x9f, 0x0f, 0xb0, 0xda, 0x3e, 0x6d, 0xed, 0x6d, 0x14, 0xf9, 0x0a, 0x40, 0x34, 0xa3, - 0x82, 0x05, 0xd0, 0x33, 0x38, 0xa4, 0x6d, 0x9f, 0x71, 0xda, 0xa7, 0x30, 0xa2, 0xd3, 0x92, 0xab, - 0x46, 0x50, 0xf2, 0xe3, 0x30, 0xcf, 0xe6, 0x4b, 0x04, 0x11, 0xb1, 0x77, 0x0b, 0x93, 0x58, 0xcb, - 0x67, 0xfb, 0x6f, 0xed, 0xd7, 0xd3, 0xc8, 0x78, 0x96, 0x87, 0x38, 0x99, 0x79, 0xd8, 0x52, 0xcf, - 0xac, 0x69, 0x14, 0x18, 0xcc, 0x8a, 0xad, 0xe7, 0x49, 0x96, 0xfa, 0xac, 0x6f, 0xe7, 0xe5, 0x5c, - 0xe0, 0xeb, 0x5b, 0xa0, 0x7b, 0x43, 0x23, 0x88, 0x7c, 0x09, 0x48, 0x14, 0x06, 0xc2, 0x61, 0x54, - 0x26, 0x60, 0xe2, 0x06, 0xa0, 0x38, 0x9c, 0xc4, 0x97, 0xc5, 0xaa, 0x90, 0xf4, 0x12, 0x13, 0x0a, - 0xf3, 0xe2, 0xa3, 0x19, 0x54, 0xa6, 0x21, 0x0d, 0x16, 0x66, 0xb4, 0xc8, 0xc6, 0xb8, 0x24, 0xce, - 0x7a, 0xae, 0xe4, 0x32, 0xd5, 0xce, 0xed, 0x69, 0xec, 0xc8, 0x6d, 0x98, 0x58, 0xf5, 0xf6, 0xdd, - 0xf6, 0x8a, 0x74, 0x2a, 0x10, 0x17, 0x9c, 0x4d, 0x06, 0xb4, 0x0f, 0x74, 0xd7, 0x80, 0x18, 0x95, - 0x69, 0xb5, 0x25, 0xff, 0xd0, 0xea, 0xb6, 0x17, 0xf2, 0x78, 0x5a, 0x47, 0x75, 0xa6, 0xe1, 0x1f, - 0xda, 0x7e, 0x57, 0xf7, 0x59, 0x47, 0xa4, 0x0b, 0xbb, 0x70, 0xbe, 0xef, 0xa0, 0xa5, 0x24, 0x94, - 0xb8, 0xa1, 0x27, 0x94, 0x38, 0xdf, 0x6f, 0x71, 0x0f, 0xd4, 0xa4, 0x12, 0x7f, 0xc3, 0x48, 0xac, - 0xe6, 0x42, 0xf5, 0xe2, 0xf9, 0x03, 0xfb, 0x6d, 0x77, 0x19, 0x4c, 0x84, 0xcd, 0xd7, 0xfb, 0x4c, - 0xac, 0xf2, 0x25, 0x9e, 0x5e, 0xe0, 0x2b, 0xff, 0x13, 0x2e, 0xec, 0xe6, 0xbf, 0xce, 0x02, 0xe1, - 0x2d, 0x2c, 0x3a, 0x1d, 0x67, 0xd7, 0x6d, 0xba, 0xa1, 0x8b, 0x41, 0x3c, 0x79, 0xc1, 0xc2, 0xd9, - 0x6d, 0x52, 0x35, 0x02, 0x4e, 0x38, 0xd9, 0x44, 0x65, 0x76, 0x52, 0x49, 0xeb, 0x21, 0xec, 0x23, - 0x8a, 0x99, 0x27, 0x11, 0xc5, 0x6f, 0xc2, 0x73, 0x85, 0x0e, 0x26, 0xaf, 0x96, 0xb5, 0xdc, 0xf1, - 0x7c, 0x29, 0x44, 0x9a, 0x33, 0xac, 0x13, 0xa1, 0xf5, 0xb4, 0x74, 0x10, 0x0b, 0x65, 0x1f, 0xa9, - 0xfa, 0x5e, 0xab, 0x13, 0xaa, 0xd1, 0x04, 0x72, 0x1f, 0xe9, 0x60, 0x49, 0xca, 0x3e, 0xc2, 0x49, - 0x24, 0x0f, 0xd7, 0x97, 0xfb, 0xc8, 0x28, 0x0a, 0x66, 0xc4, 0xc3, 0xf5, 0x69, 0x9f, 0xbd, 0x28, - 0x22, 0x21, 0xef, 0xc0, 0x64, 0xa1, 0x1b, 0x7a, 0x82, 0xb1, 0xf0, 0x0e, 0x8b, 0xfd, 0xb8, 0x44, - 0x53, 0x34, 0xb5, 0x2d, 0x46, 0x37, 0xff, 0xe3, 0x0c, 0x9c, 0xef, 0x1d, 0x5e, 0x51, 0x1a, 0x09, - 0x99, 0x71, 0x8c, 0x90, 0xa5, 0x49, 0x03, 0xb7, 0x88, 0x3d, 0x35, 0x69, 0xe0, 0x39, 0xb0, 0x3f, - 0xa6, 0x34, 0xd4, 0x60, 0x52, 0x5d, 0x8f, 0x46, 0x3e, 0xee, 0x7a, 0xa4, 0x72, 0x31, 0xff, 0x33, - 0x43, 0xcd, 0xcc, 0x4c, 0xde, 0x48, 0xf3, 0x45, 0xe5, 0x89, 0x51, 0x38, 0x58, 0x77, 0x43, 0x95, - 0x47, 0xd9, 0x4c, 0xea, 0x51, 0x56, 0xe6, 0x78, 0xc9, 0xa6, 0xe6, 0x78, 0x29, 0xc1, 0x6c, 0xad, - 0xbb, 0x2b, 0xeb, 0x46, 0xc4, 0x11, 0xcd, 0x9d, 0xde, 0x96, 0xed, 0xd7, 0x03, 0x25, 0x35, 0x12, - 0xf3, 0x67, 0x32, 0x30, 0x55, 0x6d, 0x76, 0xf7, 0xdd, 0x76, 0xc9, 0x09, 0x9d, 0x67, 0xf6, 0x74, - 0xfd, 0x96, 0x76, 0xba, 0x8e, 0x5c, 0xae, 0xa3, 0x0f, 0x1b, 0xea, 0x68, 0xfd, 0x3d, 0x03, 0x66, - 0x63, 0x12, 0xbe, 0xc4, 0xaf, 0xc0, 0x08, 0xfb, 0x21, 0x94, 0xf5, 0x8b, 0x3d, 0x8c, 0x79, 0x56, - 0xd4, 0xe8, 0x2f, 0x71, 0xde, 0xd5, 0xdf, 0xe5, 0x43, 0x0e, 0x17, 0x3e, 0xc7, 0x5f, 0xc8, 0x3a, - 0x79, 0x36, 0xd4, 0x7f, 0x60, 0x40, 0x3e, 0xf9, 0x25, 0xe4, 0x1e, 0x8c, 0x33, 0x4e, 0x6e, 0xf4, - 0xda, 0xd6, 0xcb, 0x7d, 0xbe, 0xf9, 0xba, 0x40, 0xe3, 0xcd, 0xc3, 0xce, 0xa7, 0x1c, 0x62, 0x49, - 0x0e, 0x17, 0x2c, 0x98, 0x52, 0xb1, 0x52, 0x5a, 0xf7, 0xba, 0xbe, 0xaf, 0x9d, 0x4d, 0xef, 0x07, - 0xb5, 0xd5, 0x7f, 0x4d, 0x6b, 0xb5, 0xd8, 0xd1, 0x86, 0x7d, 0x6b, 0x11, 0x73, 0x2b, 0x71, 0x29, - 0x55, 0xe5, 0x2c, 0x45, 0xa0, 0x23, 0x3c, 0x76, 0x2c, 0xe7, 0xf5, 0x09, 0x39, 0xc3, 0x63, 0x79, - 0x07, 0x21, 0xea, 0xbe, 0xce, 0x71, 0xcc, 0xbf, 0x9e, 0x85, 0xb3, 0x71, 0xf3, 0xf8, 0xcb, 0x93, - 0x55, 0xc7, 0x77, 0x5a, 0xc1, 0x31, 0x33, 0xe0, 0x4a, 0x4f, 0xd3, 0x30, 0x9f, 0xa1, 0x6c, 0x9a, - 0xd2, 0x20, 0x33, 0xd1, 0x20, 0xb4, 0x67, 0xf0, 0x06, 0xc9, 0x66, 0x90, 0x7b, 0x90, 0xad, 0xd1, - 0x50, 0xac, 0x45, 0x97, 0x7b, 0x7a, 0x55, 0x6d, 0xd7, 0xf5, 0x1a, 0x0d, 0xf9, 0x20, 0xf2, 0x88, - 0x39, 0xaa, 0xa5, 0x82, 0x60, 0x27, 0xd3, 0x1d, 0x18, 0x2b, 0x3f, 0xea, 0xd0, 0x7a, 0x28, 0x12, - 0x8b, 0x5d, 0x1d, 0xcc, 0x8f, 0xe3, 0x2a, 0xe9, 0xcb, 0x28, 0x02, 0xd4, 0xce, 0xe2, 0x28, 0x17, - 0x6e, 0x43, 0x4e, 0x56, 0x7e, 0xa2, 0x34, 0x5c, 0x6f, 0xc1, 0xa4, 0x52, 0xc9, 0x89, 0x84, 0xfe, - 0x4f, 0x0d, 0x18, 0x63, 0x3b, 0xc1, 0xf6, 0xed, 0x67, 0x74, 0x45, 0xba, 0xa5, 0xad, 0x48, 0x73, - 0x4a, 0xb6, 0x19, 0x9c, 0x97, 0xb7, 0x8f, 0x59, 0x8b, 0x8e, 0xd8, 0xbe, 0x12, 0x21, 0x93, 0xbb, - 0x30, 0x2e, 0xae, 0x3c, 0x85, 0x73, 0x96, 0x9a, 0xbe, 0x46, 0x5e, 0x86, 0x46, 0x0a, 0xbf, 0xd7, - 0x49, 0x9e, 0x90, 0x24, 0x35, 0x29, 0xc5, 0xa9, 0x07, 0xb4, 0x6c, 0xe7, 0x1e, 0xfa, 0x88, 0xf3, - 0xf4, 0x2b, 0xca, 0x8b, 0x00, 0x7d, 0x02, 0xf9, 0x0a, 0xc2, 0xc6, 0x97, 0x1d, 0xc4, 0xe4, 0xac, - 0x4c, 0x59, 0x9d, 0x6a, 0xfe, 0xfb, 0x5f, 0xe7, 0x78, 0xe2, 0x12, 0xd9, 0xb0, 0x77, 0x61, 0xea, - 0x8e, 0xe7, 0x3f, 0x74, 0x7c, 0x1e, 0x8e, 0x8e, 0x9f, 0xc9, 0xef, 0xd2, 0xa6, 0xf7, 0x38, 0x9c, - 0x07, 0xb4, 0xff, 0xf0, 0x68, 0x71, 0x64, 0xd9, 0xf3, 0x9a, 0x96, 0x86, 0x4e, 0x36, 0x60, 0x7a, - 0xcd, 0x79, 0x24, 0x2e, 0x60, 0x37, 0x37, 0x57, 0x85, 0xd3, 0xe7, 0xd5, 0xc7, 0x47, 0x8b, 0xe7, - 0x5b, 0xce, 0xa3, 0xe8, 0x02, 0xbb, 0x7f, 0x76, 0x04, 0x9d, 0x9e, 0xb8, 0x30, 0x53, 0xf5, 0xfc, - 0x50, 0x54, 0xc2, 0x8e, 0x77, 0xd9, 0x3e, 0x57, 0xc8, 0x37, 0x52, 0xaf, 0x90, 0xcf, 0xb3, 0x33, - 0xad, 0xbd, 0x17, 0x91, 0x6b, 0x91, 0x9c, 0x1a, 0x63, 0xf2, 0x2e, 0xcc, 0x15, 0xa9, 0x1f, 0xba, - 0x7b, 0x6e, 0xdd, 0x09, 0xe9, 0x1d, 0xcf, 0x6f, 0x39, 0x52, 0x91, 0x44, 0xdb, 0x12, 0x5e, 0x04, - 0xee, 0x21, 0xd8, 0xea, 0xc5, 0x24, 0x5f, 0x4d, 0x73, 0xa3, 0x1d, 0x8d, 0x9d, 0x05, 0x53, 0xdc, - 0x68, 0xfb, 0x39, 0x0b, 0xf6, 0x3a, 0xd4, 0xee, 0x0f, 0xf2, 0x51, 0xc9, 0x2d, 0xdf, 0x14, 0xee, - 0x2d, 0xc7, 0xfb, 0xa0, 0x44, 0xe3, 0xd6, 0xc7, 0x17, 0x65, 0x09, 0xb2, 0xcb, 0xd5, 0x3b, 0x68, - 0x2d, 0x94, 0x37, 0xa0, 0xed, 0x03, 0xa7, 0x5d, 0x47, 0x05, 0x4f, 0xf8, 0x85, 0xa9, 0x0b, 0xde, - 0x72, 0xf5, 0x0e, 0x71, 0xe0, 0x74, 0x95, 0xfa, 0x2d, 0x37, 0xfc, 0xf2, 0xcd, 0x9b, 0xca, 0x40, - 0xe5, 0xb0, 0x69, 0x37, 0x44, 0xd3, 0x16, 0x3b, 0x88, 0x62, 0x3f, 0xba, 0x79, 0x33, 0x75, 0x38, - 0xa2, 0x86, 0xa5, 0xf1, 0x22, 0x65, 0x98, 0x59, 0x73, 0x1e, 0xc5, 0xee, 0x7c, 0x81, 0x08, 0x48, - 0x78, 0x41, 0x0a, 0x56, 0xec, 0x0a, 0xa8, 0x45, 0x1c, 0xea, 0x44, 0x4c, 0x3f, 0x8f, 0xc5, 0x2b, - 0x10, 0xae, 0x9c, 0xa8, 0xa8, 0x29, 0xc2, 0xa9, 0x29, 0x99, 0x0a, 0x3a, 0xd9, 0x8a, 0x4e, 0x19, - 0x5c, 0x4b, 0x17, 0xf9, 0x98, 0x6f, 0xa8, 0xa7, 0x0c, 0x07, 0x4b, 0xb4, 0xcf, 0x9a, 0x8d, 0xce, - 0x77, 0xdc, 0xbf, 0xd1, 0xd2, 0xb9, 0xf4, 0x1e, 0x5e, 0xa6, 0x4e, 0x7e, 0x78, 0xa1, 0x30, 0xb2, - 0xea, 0xd5, 0xef, 0xa3, 0x87, 0xc6, 0xc4, 0xf2, 0x97, 0xd8, 0x74, 0x6f, 0x7a, 0xf5, 0xfb, 0x4f, - 0xcf, 0xf7, 0x06, 0xd9, 0x93, 0x75, 0xd6, 0x54, 0x26, 0x05, 0xa2, 0x4f, 0x84, 0x3f, 0xc7, 0x7c, - 0xa4, 0xbd, 0x2b, 0x65, 0x5c, 0xaf, 0xe0, 0x42, 0x23, 0xbb, 0xd6, 0xd2, 0xc9, 0x09, 0x85, 0x7c, - 0x89, 0x06, 0xf7, 0x43, 0xaf, 0x53, 0x6c, 0xba, 0x9d, 0x5d, 0xcf, 0xf1, 0x1b, 0x68, 0x0f, 0x48, - 0x9b, 0xdf, 0xaf, 0xa6, 0xce, 0xef, 0xb9, 0x06, 0xa7, 0xb7, 0xeb, 0x92, 0x81, 0xd5, 0xc3, 0x92, - 0x7c, 0x15, 0x66, 0x98, 0x70, 0x97, 0x1f, 0x85, 0xb4, 0xcd, 0x47, 0x7e, 0x0e, 0x77, 0xe6, 0x79, - 0x25, 0xcd, 0x57, 0x54, 0xc8, 0x65, 0x0a, 0x27, 0x3b, 0x8d, 0x08, 0x54, 0x99, 0xd2, 0x59, 0x91, - 0x06, 0x2c, 0xac, 0x39, 0x8f, 0x94, 0xbc, 0xd5, 0x8a, 0x90, 0x12, 0x14, 0x30, 0x7c, 0x42, 0x89, - 0x09, 0x58, 0x9c, 0x8e, 0xa3, 0x8f, 0xbc, 0xf6, 0xe5, 0x44, 0x7e, 0x04, 0xce, 0x89, 0xcf, 0x2a, - 0x61, 0x0e, 0x4b, 0xcf, 0x3f, 0xac, 0x1d, 0x38, 0xe8, 0xc9, 0x7b, 0xfa, 0x64, 0x0b, 0xa2, 0xec, - 0xb0, 0x86, 0xe4, 0x63, 0x07, 0x9c, 0x91, 0xd5, 0xaf, 0x06, 0xf2, 0x4d, 0x98, 0xe1, 0x66, 0xe0, - 0x15, 0x2f, 0x08, 0xf1, 0x10, 0x3a, 0xdf, 0xa7, 0xce, 0xcb, 0xa9, 0x75, 0xe6, 0xb9, 0x6d, 0x99, - 0xbb, 0x74, 0xa2, 0x25, 0x3c, 0xc1, 0x8f, 0xbc, 0x0d, 0x93, 0x55, 0xb7, 0xcd, 0x43, 0xea, 0x2b, - 0xd5, 0x85, 0x33, 0xf1, 0xae, 0xd3, 0x71, 0xdb, 0xb6, 0x3c, 0xff, 0x75, 0xa2, 0x45, 0x42, 0xc5, - 0x26, 0x3b, 0x30, 0x59, 0xab, 0xad, 0xdc, 0x71, 0xd9, 0xb6, 0xd7, 0x39, 0x5c, 0x38, 0xdb, 0xa7, - 0x6d, 0x97, 0x52, 0xdb, 0x36, 0x1d, 0x04, 0x07, 0xf8, 0xb8, 0x8c, 0x5d, 0xf7, 0x3a, 0x87, 0x96, - 0xca, 0x29, 0xc5, 0x55, 0xeb, 0xdc, 0x53, 0x76, 0xd5, 0xaa, 0xc0, 0xac, 0xe2, 0xef, 0x82, 0xbe, - 0x2e, 0x0b, 0xf1, 0xfb, 0x3b, 0xaa, 0x6b, 0x56, 0xd2, 0xe1, 0x3e, 0x49, 0x27, 0x7d, 0xb4, 0xce, - 0x9f, 0xd4, 0x47, 0xcb, 0x85, 0x39, 0x3e, 0x18, 0x62, 0xf4, 0x71, 0x7c, 0x2f, 0xf4, 0xe9, 0xc3, - 0xab, 0xa9, 0x7d, 0x78, 0x5a, 0x8c, 0xaf, 0x14, 0x2d, 0x1c, 0xe2, 0x5e, 0xae, 0x64, 0x0f, 0x88, - 0x00, 0x8a, 0xa7, 0x6d, 0xb0, 0xae, 0xe7, 0xfa, 0xd4, 0xf5, 0x72, 0x6a, 0x5d, 0x33, 0xb2, 0xae, - 0x5d, 0x5e, 0x4d, 0x0a, 0xc7, 0x0f, 0x46, 0x72, 0xd3, 0xf9, 0x99, 0x34, 0x77, 0xb0, 0xff, 0x22, - 0x93, 0x58, 0xc0, 0x48, 0x05, 0xc6, 0x45, 0x0b, 0x85, 0x46, 0xd7, 0xdb, 0x8e, 0x17, 0x52, 0xdb, - 0x31, 0x2e, 0x3e, 0xd6, 0x92, 0xf4, 0xe4, 0x21, 0x63, 0xb5, 0xe7, 0x74, 0x9b, 0x32, 0xd3, 0xcb, - 0xd7, 0xf9, 0xfa, 0x84, 0x20, 0x6d, 0x25, 0x2e, 0x9d, 0xdc, 0x75, 0x56, 0xf7, 0xcc, 0xc6, 0x25, - 0x59, 0xd6, 0x46, 0xee, 0xf3, 0x1c, 0x79, 0xd9, 0xc8, 0xff, 0x52, 0x4f, 0x88, 0xf7, 0xd4, 0x2a, - 0x64, 0xb5, 0x98, 0xbf, 0x63, 0xc0, 0xb4, 0xb6, 0x02, 0x92, 0xdb, 0x8a, 0x73, 0x71, 0x1c, 0x45, - 0xa2, 0xe1, 0xe0, 0xf4, 0x48, 0xba, 0x1d, 0xdf, 0x16, 0xce, 0x5d, 0x99, 0xfe, 0x74, 0xa9, 0xef, - 0x1e, 0x0d, 0xb6, 0xc7, 0x44, 0x39, 0x77, 0x47, 0xfa, 0xe4, 0xdc, 0xfd, 0xcd, 0xf3, 0x30, 0xa3, - 0xab, 0xc8, 0xec, 0xcc, 0x8a, 0x96, 0x69, 0x69, 0x36, 0xe5, 0x59, 0xa4, 0x11, 0xa2, 0xbd, 0xa8, - 0x82, 0x10, 0xf2, 0x0a, 0x40, 0xe4, 0xe7, 0x24, 0x2d, 0xa3, 0xa3, 0x8f, 0x8f, 0x16, 0x8d, 0x37, - 0x2c, 0xa5, 0x80, 0x7c, 0x03, 0x60, 0xdd, 0x6b, 0xd0, 0x28, 0xcf, 0xf9, 0x80, 0xdb, 0x99, 0x57, - 0x7b, 0xf2, 0x47, 0x9d, 0x69, 0x7b, 0x0d, 0xda, 0x9b, 0x2c, 0x4a, 0xe1, 0x48, 0xbe, 0x00, 0xa3, - 0x56, 0xb7, 0x49, 0xa5, 0x05, 0x6d, 0x52, 0xae, 0x49, 0xdd, 0xa6, 0xf2, 0x04, 0xb2, 0xdf, 0x4d, - 0x5e, 0xca, 0x33, 0x00, 0x79, 0x9f, 0xe7, 0x95, 0x12, 0xc9, 0x1b, 0x46, 0x63, 0x5b, 0xb1, 0xb2, - 0x43, 0xf5, 0xa4, 0x6f, 0x50, 0x48, 0xc8, 0x06, 0x8c, 0xab, 0x46, 0x4e, 0x25, 0x4a, 0x45, 0x35, - 0xa0, 0x2b, 0xa7, 0x10, 0x91, 0xa8, 0x3a, 0x69, 0xff, 0x94, 0x5c, 0xc8, 0x3b, 0x30, 0xc1, 0xd8, - 0xf3, 0xe7, 0x74, 0xc7, 0x63, 0x8b, 0xb0, 0xd2, 0xa0, 0xe4, 0x8b, 0xba, 0x31, 0x01, 0xf9, 0x2a, - 0x66, 0xae, 0x17, 0x5d, 0x3d, 0xf0, 0xd6, 0xee, 0x72, 0x4f, 0x57, 0xcf, 0x3b, 0x9d, 0x4e, 0xca, - 0xfb, 0x22, 0x11, 0x3f, 0xb2, 0x1f, 0x85, 0xfe, 0x0f, 0x93, 0x0b, 0xec, 0x5a, 0x4f, 0x05, 0x0b, - 0x32, 0x9a, 0xbd, 0x37, 0x5f, 0xbd, 0xc6, 0x97, 0x74, 0x20, 0x1f, 0x6f, 0xfe, 0xa2, 0x2e, 0x18, - 0x54, 0xd7, 0x1b, 0x3d, 0x75, 0xa9, 0x03, 0xd8, 0x53, 0x5d, 0x0f, 0x77, 0xd2, 0x88, 0xdf, 0x2c, - 0x17, 0xf5, 0x4d, 0x0e, 0xaa, 0xef, 0x95, 0x9e, 0xfa, 0x4e, 0x37, 0x76, 0x7b, 0xeb, 0x49, 0xf0, - 0x24, 0xef, 0xc0, 0xb4, 0x84, 0xe0, 0xfc, 0x10, 0x4f, 0x92, 0xf0, 0xd7, 0xf6, 0x77, 0xd1, 0xa5, - 0x5f, 0xcf, 0xa6, 0xae, 0x22, 0xab, 0xd4, 0x5c, 0x3a, 0xa6, 0x35, 0xea, 0xa4, 0x54, 0xe8, 0xc8, - 0xe4, 0x43, 0x98, 0xac, 0xb4, 0xd8, 0x87, 0x78, 0x6d, 0x27, 0xa4, 0xc2, 0x83, 0x59, 0xde, 0x40, - 0x2a, 0x25, 0x8a, 0xa8, 0xf2, 0xd7, 0x03, 0xe3, 0x22, 0xf5, 0x38, 0xa0, 0x50, 0xb0, 0xce, 0xe3, - 0x56, 0x6d, 0x21, 0xc3, 0xd2, 0xbb, 0xf9, 0x85, 0x94, 0x5b, 0x40, 0x85, 0xbd, 0x48, 0x92, 0xc2, - 0xa0, 0xf2, 0x42, 0x20, 0x91, 0x24, 0x45, 0xe5, 0x49, 0xde, 0x85, 0x49, 0x91, 0x26, 0xb1, 0x60, - 0xad, 0x07, 0x0b, 0xf9, 0xf8, 0xa5, 0x69, 0x99, 0x51, 0xd1, 0x76, 0xfc, 0x84, 0x2b, 0x48, 0x8c, - 0x4f, 0xbe, 0x0c, 0xf3, 0x3b, 0x6e, 0xbb, 0xe1, 0x3d, 0x0c, 0xc4, 0x36, 0x25, 0x16, 0xba, 0xb9, - 0xd8, 0x63, 0xf7, 0x21, 0x2f, 0x8f, 0x76, 0xef, 0x9e, 0x85, 0x2f, 0x95, 0x03, 0xf9, 0xb1, 0x1e, - 0xce, 0x5c, 0x82, 0xc8, 0x20, 0x09, 0x5a, 0xea, 0x91, 0xa0, 0xde, 0xea, 0x93, 0xe2, 0x94, 0x5a, - 0x0d, 0xf1, 0x80, 0xe8, 0xfb, 0xfb, 0x07, 0x9e, 0xdb, 0x5e, 0x38, 0x8d, 0x6b, 0xe1, 0x73, 0xc9, - 0x28, 0x28, 0xc4, 0xe3, 0xcf, 0x14, 0xca, 0xc7, 0x56, 0x75, 0x2d, 0xed, 0x23, 0x4f, 0x33, 0x4f, - 0xa6, 0xb0, 0x26, 0x1f, 0xc2, 0x14, 0xfb, 0x3f, 0x3a, 0x3c, 0xce, 0x6b, 0x7e, 0x23, 0x0a, 0xa6, - 0xa8, 0x07, 0xc7, 0x08, 0xf3, 0x38, 0xa6, 0x9c, 0x2b, 0x35, 0x56, 0xe4, 0x2d, 0x00, 0xa6, 0x09, - 0x8b, 0xe5, 0xf8, 0x4c, 0x9c, 0x93, 0x06, 0x15, 0xe6, 0xde, 0x85, 0x38, 0x46, 0x66, 0x27, 0x5a, - 0xf6, 0xab, 0xd6, 0x6d, 0x78, 0x6c, 0x6e, 0x9c, 0x45, 0x5a, 0x3c, 0xd1, 0x22, 0x6d, 0xc0, 0xe1, - 0xaa, 0x74, 0x28, 0xe8, 0x64, 0x05, 0x66, 0x31, 0x77, 0x50, 0xa5, 0x41, 0xdb, 0x21, 0xde, 0x36, - 0x2d, 0x9c, 0x53, 0x6e, 0xe3, 0x58, 0x91, 0xed, 0x46, 0x65, 0xaa, 0xf6, 0x99, 0x20, 0x23, 0x01, - 0x9c, 0x8e, 0x57, 0x97, 0xf8, 0x6e, 0x6f, 0x01, 0x3b, 0x49, 0xde, 0xbf, 0xf6, 0x62, 0xf0, 0xf5, - 0x98, 0x8d, 0x88, 0xb2, 0x70, 0x49, 0x23, 0xae, 0x5a, 0x61, 0x1a, 0x77, 0x62, 0x01, 0xb9, 0x5b, - 0xac, 0x26, 0x93, 0xeb, 0x9c, 0xc7, 0x2f, 0xc0, 0x61, 0xde, 0xaf, 0x77, 0xec, 0x01, 0x09, 0x76, - 0x52, 0xa8, 0xc9, 0xb7, 0xe1, 0x4c, 0xf4, 0x18, 0x3d, 0x2f, 0x12, 0x72, 0x7d, 0xe1, 0x84, 0x2b, - 0x71, 0x63, 0x37, 0xaa, 0xba, 0x47, 0xa4, 0xd3, 0xab, 0x20, 0x0e, 0x4c, 0xe2, 0xb0, 0x8a, 0x1a, - 0x9f, 0x1b, 0x54, 0xe3, 0x95, 0x9e, 0x1a, 0xcf, 0xf2, 0x27, 0x57, 0x7b, 0x2a, 0x53, 0x79, 0x92, - 0x65, 0x98, 0x16, 0xf3, 0x48, 0x48, 0xdb, 0xf3, 0xf1, 0x9b, 0xc1, 0x72, 0x06, 0xf6, 0x08, 0x9c, - 0x4e, 0xa2, 0xae, 0xc8, 0xfc, 0x7a, 0xf1, 0x05, 0x6d, 0x45, 0x4e, 0xde, 0x2a, 0xea, 0xc8, 0x6c, - 0x45, 0x8a, 0xb5, 0x98, 0xf2, 0xa3, 0x8e, 0x2f, 0x4c, 0x09, 0x2f, 0xc6, 0xd9, 0x11, 0x15, 0xe5, - 0xc7, 0xa6, 0x11, 0x86, 0xba, 0x24, 0xa4, 0x71, 0x20, 0x5b, 0x70, 0x3a, 0xda, 0xb5, 0x15, 0xc6, - 0x8b, 0xc8, 0xf8, 0xd2, 0xe3, 0xa3, 0xc5, 0xc5, 0x78, 0xab, 0x4f, 0xe7, 0x9b, 0x46, 0x4f, 0x1c, - 0x38, 0xa7, 0xed, 0xd3, 0x0a, 0xeb, 0x8b, 0xc8, 0xfa, 0xd5, 0xc7, 0x47, 0x8b, 0x97, 0xf4, 0x4d, - 0x3e, 0x9d, 0x7d, 0x3f, 0x3e, 0xe4, 0x23, 0xb8, 0x90, 0xdc, 0x9b, 0x95, 0x5a, 0x5e, 0xc2, 0x5a, - 0xae, 0x3d, 0x3e, 0x5a, 0xbc, 0xdc, 0xb3, 0xbd, 0xa7, 0x57, 0x34, 0x80, 0x1b, 0xf9, 0x06, 0x2c, - 0xe8, 0xfb, 0xb3, 0x52, 0x93, 0x19, 0x3f, 0x47, 0x1d, 0x6d, 0xec, 0xe9, 0x35, 0xf4, 0xe5, 0x41, - 0x42, 0x58, 0x4c, 0x95, 0x6e, 0xa5, 0x9a, 0x4b, 0xf1, 0x07, 0xf5, 0xcc, 0x92, 0xf4, 0xea, 0x8e, - 0x63, 0x49, 0x1e, 0xc2, 0x8b, 0x69, 0xdb, 0x84, 0x52, 0xe9, 0xcb, 0x91, 0xb1, 0xee, 0xb5, 0xf4, - 0x2d, 0x27, 0xbd, 0xe6, 0x63, 0xd8, 0x92, 0xaf, 0xc2, 0x19, 0x65, 0x7e, 0x29, 0xf5, 0xbd, 0x82, - 0xf5, 0x61, 0xbc, 0x8d, 0x3a, 0x31, 0xd3, 0x6b, 0x49, 0xe7, 0x61, 0xfe, 0x55, 0x03, 0x48, 0xef, - 0xc2, 0x37, 0xf4, 0xfd, 0xdd, 0x9b, 0x4a, 0x30, 0x8a, 0xfa, 0xa0, 0x6e, 0x94, 0x60, 0x51, 0x55, - 0x78, 0xe3, 0xb0, 0x95, 0xcb, 0xda, 0x01, 0xab, 0xaf, 0x07, 0xb3, 0xf9, 0xc7, 0x06, 0xcc, 0xa7, - 0x6d, 0xb1, 0xc7, 0xbc, 0x8a, 0x62, 0x26, 0x1c, 0x9f, 0xf1, 0x42, 0x8e, 0x3b, 0x3e, 0x47, 0xee, - 0xce, 0x8b, 0x30, 0xca, 0xbe, 0x40, 0x3a, 0x87, 0xe0, 0x29, 0x8e, 0x7d, 0x62, 0x60, 0x71, 0x38, - 0x43, 0xe0, 0x41, 0xe1, 0xec, 0x98, 0x37, 0xca, 0x11, 0x70, 0x05, 0xb7, 0x38, 0x9c, 0x21, 0xb0, - 0xd3, 0xa2, 0x3c, 0xdd, 0x20, 0x02, 0x3b, 0x44, 0x06, 0x16, 0x87, 0x93, 0xcb, 0x30, 0xbe, 0xd1, - 0x5e, 0xa5, 0xce, 0x03, 0x99, 0xf8, 0x11, 0x2f, 0x10, 0xbd, 0xb6, 0xdd, 0x64, 0x30, 0x4b, 0x16, - 0x9a, 0xdf, 0x33, 0x60, 0xae, 0x67, 0x77, 0x3f, 0xfe, 0xe1, 0x97, 0xc1, 0x2e, 0x9e, 0xc3, 0x7c, - 0x1f, 0x6f, 0xfe, 0x48, 0x7a, 0xf3, 0xcd, 0xdf, 0x1e, 0x81, 0x73, 0x7d, 0x0e, 0x5b, 0xb1, 0x7b, - 0xb6, 0x71, 0xac, 0x7b, 0xf6, 0xd7, 0xd8, 0xe1, 0xc6, 0x71, 0x5b, 0xc1, 0xa6, 0x17, 0xb7, 0x38, - 0xf6, 0x64, 0xc3, 0x32, 0xf9, 0x2e, 0xc3, 0x4b, 0x62, 0xaf, 0x3e, 0x5f, 0x47, 0x0a, 0x3b, 0xf4, - 0x7a, 0xd7, 0x7a, 0x8d, 0x59, 0x8f, 0x83, 0x74, 0xf6, 0xcf, 0x89, 0x83, 0xb4, 0xee, 0x96, 0x38, - 0xf2, 0x54, 0xdd, 0x12, 0xd3, 0x5d, 0x66, 0x46, 0x9f, 0xc4, 0x81, 0xaa, 0x08, 0xd3, 0x35, 0xea, - 0xf8, 0xf5, 0x83, 0x42, 0xc0, 0x07, 0x69, 0x2c, 0x4e, 0xb7, 0x18, 0x60, 0x81, 0xed, 0x04, 0xbd, - 0x63, 0xa1, 0xd1, 0x98, 0xdf, 0xcb, 0xe8, 0x7e, 0xdd, 0x7f, 0x1e, 0xe5, 0xe5, 0x2a, 0x8c, 0xee, - 0x1c, 0x50, 0x5f, 0x2e, 0x3d, 0xd8, 0x90, 0x87, 0x0c, 0xa0, 0x36, 0x04, 0x31, 0xc8, 0x1d, 0x98, - 0xa9, 0xf2, 0xfe, 0x93, 0x9d, 0x32, 0x12, 0x6b, 0xae, 0x1d, 0x71, 0xbe, 0x4a, 0xe9, 0x95, 0x04, - 0x95, 0xf9, 0x23, 0x30, 0xa5, 0x36, 0x1a, 0x17, 0x16, 0xf6, 0x5b, 0xcc, 0x6c, 0xbe, 0xb0, 0x30, - 0x80, 0xc5, 0xe1, 0xc7, 0x3e, 0xea, 0x14, 0xf7, 0x66, 0xf6, 0xb8, 0xde, 0x64, 0x95, 0xa3, 0xdc, - 0x2a, 0x95, 0xe3, 0x6f, 0xb5, 0xf2, 0x90, 0x01, 0x2c, 0x0e, 0x7f, 0xaa, 0x95, 0xff, 0x53, 0x99, - 0x12, 0xf3, 0x4d, 0x98, 0x88, 0x35, 0xf6, 0x38, 0x75, 0xfe, 0xe9, 0x34, 0x3d, 0x3c, 0xc6, 0x64, - 0x55, 0x6d, 0x53, 0x7f, 0x57, 0x0b, 0x02, 0x79, 0xc0, 0x00, 0x6a, 0x55, 0x88, 0x71, 0x92, 0x71, - 0xbd, 0x01, 0xe3, 0x05, 0x71, 0x7b, 0xc2, 0x07, 0x94, 0x07, 0xba, 0xf4, 0x5c, 0x95, 0x48, 0x2c, - 0xf3, 0xfb, 0x06, 0x9c, 0x49, 0x3d, 0xc8, 0xb3, 0x5a, 0xb9, 0xc5, 0x40, 0x11, 0xeb, 0xa4, 0xb9, - 0x80, 0x63, 0x9c, 0x24, 0xa0, 0x65, 0xf8, 0x6f, 0x31, 0x5f, 0x82, 0x89, 0xc8, 0x8c, 0x4c, 0xe6, - 0xe5, 0xd0, 0xe1, 0x95, 0xba, 0xb4, 0x46, 0xfe, 0xa9, 0x01, 0x63, 0xac, 0x09, 0xcf, 0x6c, 0xf2, - 0x8a, 0x74, 0x07, 0x0b, 0xf6, 0x49, 0x43, 0xa5, 0xac, 0xf8, 0xf5, 0x31, 0x80, 0x18, 0x99, 0xec, - 0xc2, 0xcc, 0x46, 0xa5, 0x54, 0x54, 0xce, 0xa3, 0x7a, 0xf6, 0xce, 0xe8, 0xa1, 0x31, 0x8e, 0x70, - 0x18, 0xaf, 0x31, 0x9e, 0xdb, 0xa8, 0xa7, 0x9f, 0x55, 0x13, 0x1c, 0x59, 0x1d, 0xb5, 0xc2, 0xda, - 0xaa, 0x52, 0x47, 0x66, 0xc8, 0x3a, 0x02, 0xa7, 0xd5, 0xec, 0x53, 0x87, 0xce, 0x91, 0x1c, 0x40, - 0xfe, 0x2e, 0xee, 0x62, 0x4a, 0x2d, 0xd9, 0xc1, 0xb5, 0x5c, 0x12, 0xb5, 0x3c, 0xc7, 0xb7, 0xbf, - 0xf4, 0x7a, 0x7a, 0xb8, 0xc6, 0x92, 0x3b, 0x72, 0xac, 0xe4, 0xfe, 0x25, 0x03, 0xc6, 0xf8, 0x36, - 0x29, 0x46, 0xab, 0xcf, 0x46, 0xbc, 0xf3, 0x74, 0x36, 0xe2, 0x3c, 0xae, 0x5c, 0x9a, 0x05, 0x9d, - 0x97, 0x91, 0x12, 0x8c, 0xd5, 0x42, 0x27, 0xec, 0xca, 0x88, 0x29, 0xe9, 0x45, 0x83, 0x96, 0x25, - 0x5e, 0x12, 0x87, 0x05, 0x05, 0xf8, 0x5b, 0xe5, 0xc2, 0x31, 0x48, 0x25, 0x8e, 0x48, 0x19, 0x3f, - 0x36, 0x22, 0x45, 0x46, 0xf1, 0x8c, 0x8b, 0x88, 0x14, 0x3d, 0x0e, 0x65, 0x15, 0x26, 0x44, 0x9c, - 0xcb, 0xf2, 0xa1, 0xb0, 0x1f, 0xcb, 0x7b, 0xa0, 0x08, 0xae, 0x3c, 0x48, 0xcd, 0x41, 0xf6, 0xae, - 0xf6, 0x6a, 0x5a, 0x84, 0x48, 0x36, 0x78, 0x9e, 0x60, 0x9e, 0xca, 0x43, 0xcf, 0x48, 0x15, 0xc1, - 0x45, 0x20, 0xa8, 0x74, 0x96, 0x4f, 0xc9, 0xdc, 0x11, 0xf3, 0x30, 0x7f, 0xc1, 0x80, 0x7c, 0x52, - 0x5e, 0xc8, 0x3b, 0x30, 0x19, 0x25, 0x3f, 0x89, 0xfc, 0xd3, 0xd1, 0xf2, 0x13, 0x67, 0x4b, 0xd1, - 0x3c, 0xd5, 0x55, 0x74, 0xb2, 0x04, 0x39, 0x36, 0xed, 0x94, 0xf7, 0x80, 0x71, 0x3d, 0xe9, 0x0a, - 0x98, 0xea, 0xda, 0x27, 0xf1, 0x94, 0x59, 0xfb, 0xaf, 0xb2, 0x30, 0xa9, 0x0c, 0x16, 0xb9, 0x0a, - 0xb9, 0x4a, 0xb0, 0xea, 0xd5, 0xef, 0xd3, 0x86, 0xf0, 0x18, 0x9a, 0x7e, 0x7c, 0xb4, 0x38, 0xe1, - 0x06, 0x76, 0x13, 0x81, 0x56, 0x54, 0x4c, 0x96, 0x61, 0x9a, 0xff, 0x25, 0xb3, 0xa2, 0x65, 0x62, - 0x6f, 0x07, 0x8e, 0x2c, 0xf3, 0xa1, 0xa9, 0x6a, 0x82, 0x46, 0x42, 0xbe, 0x0e, 0xc0, 0x01, 0x43, - 0xbe, 0xda, 0x2f, 0x27, 0xf0, 0x19, 0x51, 0x41, 0xca, 0xe3, 0xfd, 0x0a, 0x43, 0xf2, 0x4d, 0x9e, - 0xd7, 0x44, 0x0a, 0xd7, 0xf1, 0x31, 0x54, 0xa6, 0x74, 0x55, 0x66, 0xfc, 0xed, 0xf4, 0x98, 0x27, - 0x95, 0x25, 0xf9, 0xae, 0x01, 0x17, 0x2c, 0x5a, 0xf7, 0x1e, 0x50, 0xff, 0xb0, 0x10, 0x22, 0x96, - 0x5a, 0xe3, 0xf1, 0x01, 0x56, 0xb7, 0x44, 0x8d, 0xaf, 0xfa, 0x82, 0x0b, 0x66, 0x97, 0x68, 0x75, - 0x42, 0x7b, 0x40, 0x13, 0x06, 0x54, 0x69, 0xfe, 0x77, 0x86, 0x32, 0x05, 0xc8, 0x3a, 0xa6, 0x66, - 0xe7, 0xc2, 0x22, 0xee, 0x45, 0x23, 0x0d, 0x4f, 0xc2, 0x2d, 0xba, 0xb7, 0xfc, 0x9c, 0x70, 0xee, - 0x39, 0x1d, 0x89, 0x5c, 0x22, 0x65, 0x3b, 0x07, 0x92, 0x2f, 0xc2, 0x08, 0x0e, 0xd5, 0xf1, 0x4f, - 0x50, 0xc9, 0xad, 0x66, 0x84, 0x8d, 0x11, 0xb6, 0x1a, 0x29, 0xc9, 0x67, 0x84, 0xf7, 0x7b, 0x56, - 0x7b, 0x06, 0x95, 0x81, 0x58, 0x3b, 0xa2, 0x3d, 0x26, 0x0e, 0xb3, 0x53, 0xa4, 0xf5, 0x57, 0x32, - 0x90, 0x4f, 0x4e, 0x3c, 0xf2, 0x3e, 0x4c, 0xc9, 0xb4, 0x2c, 0x2b, 0x8e, 0x48, 0xb6, 0x36, 0x25, - 0x92, 0x9d, 0x09, 0xb8, 0x7d, 0xe0, 0x68, 0x0f, 0x8b, 0x69, 0x04, 0x6c, 0x43, 0xde, 0x14, 0xd1, - 0xdb, 0xca, 0x04, 0x0a, 0xbd, 0xb0, 0x93, 0x78, 0x15, 0x51, 0xa2, 0x91, 0x37, 0x21, 0xbb, 0x76, - 0xa7, 0x20, 0xbc, 0x42, 0xe5, 0xfa, 0xb2, 0x76, 0xa7, 0xc0, 0x6f, 0xf2, 0xf9, 0x05, 0xbd, 0xee, - 0x2e, 0xc0, 0xf0, 0xc9, 0xaa, 0x92, 0xe9, 0x66, 0x4c, 0xcb, 0xdb, 0x2c, 0xc1, 0xd1, 0xc7, 0x1d, - 0x9f, 0xf2, 0x46, 0x7d, 0x75, 0xcd, 0xfc, 0xcd, 0x2c, 0x4c, 0x44, 0xf5, 0x13, 0x02, 0xa8, 0x6f, - 0x08, 0xc7, 0x50, 0xfc, 0x9b, 0x9c, 0x87, 0x9c, 0x54, 0x31, 0x84, 0x73, 0xe8, 0x78, 0x20, 0xd4, - 0x8b, 0x05, 0x90, 0xba, 0x04, 0x57, 0x2f, 0x2c, 0xf9, 0x93, 0xdc, 0x84, 0x48, 0x51, 0xe8, 0xa7, - 0x51, 0x8c, 0xb0, 0x01, 0xb3, 0x22, 0x34, 0x32, 0x03, 0x19, 0x97, 0x47, 0xe6, 0x4e, 0x58, 0x19, - 0xb7, 0x41, 0xde, 0x87, 0x9c, 0xd3, 0x68, 0xd0, 0x86, 0xed, 0xc8, 0x0b, 0xc6, 0x41, 0x42, 0x93, - 0x63, 0xdc, 0xf8, 0x8a, 0x8e, 0x54, 0x85, 0x90, 0x14, 0x60, 0xa2, 0xe9, 0x70, 0x6f, 0x93, 0xc6, - 0x10, 0xdb, 0x43, 0xcc, 0x21, 0xc7, 0xc8, 0xb6, 0x02, 0xda, 0x20, 0xaf, 0xc2, 0x08, 0x1b, 0x4d, - 0xb1, 0x1f, 0x44, 0x6f, 0xc8, 0x6d, 0x6c, 0x56, 0x79, 0x87, 0xad, 0x9c, 0xb2, 0x10, 0x81, 0xbc, - 0x0c, 0xd9, 0xee, 0xd2, 0x9e, 0x58, 0xe9, 0xf3, 0x71, 0xd6, 0xa9, 0x08, 0x8d, 0x15, 0x93, 0x5b, - 0x90, 0x7b, 0xa8, 0x27, 0x2c, 0x3a, 0x93, 0x18, 0xc6, 0x08, 0x3f, 0x42, 0x5c, 0xce, 0xc1, 0x18, - 0x77, 0x02, 0x31, 0x5f, 0x04, 0x88, 0xab, 0xee, 0xf5, 0xe1, 0x35, 0xbf, 0x0e, 0x13, 0x51, 0x95, - 0xe4, 0x05, 0x80, 0xfb, 0xf4, 0xd0, 0x3e, 0x70, 0xda, 0x8d, 0x26, 0x57, 0x38, 0xa7, 0xac, 0x89, - 0xfb, 0xf4, 0x70, 0x05, 0x01, 0xe4, 0x1c, 0x8c, 0x77, 0xd8, 0xa8, 0xca, 0x37, 0x3d, 0xad, 0xb1, - 0x4e, 0x77, 0x97, 0x49, 0xe8, 0x02, 0x8c, 0xa3, 0x11, 0x45, 0x4c, 0xb4, 0x69, 0x4b, 0xfe, 0x34, - 0xff, 0x59, 0x06, 0x53, 0x50, 0x2a, 0xed, 0x24, 0x97, 0x60, 0xba, 0xee, 0x53, 0xdc, 0x8e, 0xf0, - 0x41, 0x58, 0x51, 0xcf, 0x54, 0x0c, 0xac, 0x34, 0xc8, 0x65, 0x98, 0x8d, 0x1f, 0x19, 0xb5, 0xeb, - 0xbb, 0x22, 0xbb, 0xd8, 0x94, 0x35, 0xdd, 0x91, 0xaf, 0x8c, 0x16, 0x77, 0x31, 0xa2, 0x3c, 0xaf, - 0x66, 0x8e, 0x09, 0xa3, 0xa7, 0x44, 0xac, 0x59, 0x05, 0x8e, 0x7e, 0x03, 0x67, 0x61, 0xcc, 0x71, - 0xf6, 0xbb, 0x2e, 0x8f, 0x6e, 0x9d, 0xb2, 0xc4, 0x2f, 0xf2, 0x1a, 0xcc, 0x05, 0xee, 0x7e, 0xdb, - 0x09, 0xbb, 0xbe, 0xc8, 0x01, 0x4a, 0x7d, 0x14, 0xa9, 0x69, 0x2b, 0x1f, 0x15, 0x14, 0x39, 0x9c, - 0xbc, 0x01, 0x44, 0xad, 0xcf, 0xdb, 0xfd, 0x88, 0xd6, 0xb9, 0xa8, 0x4d, 0x59, 0x73, 0x4a, 0xc9, - 0x06, 0x16, 0x90, 0x97, 0x60, 0xca, 0xa7, 0x01, 0xaa, 0x64, 0xd8, 0x6d, 0x98, 0xa1, 0xd9, 0x9a, - 0x94, 0x30, 0xd6, 0x77, 0x57, 0x20, 0xaf, 0x74, 0x07, 0x26, 0xe7, 0xe1, 0xa9, 0xb5, 0xac, 0x99, - 0x18, 0x6e, 0x75, 0x2a, 0x0d, 0x73, 0x19, 0xe6, 0x7a, 0x66, 0x2e, 0x79, 0x83, 0x9f, 0x03, 0xc4, - 0x4e, 0x3e, 0xc5, 0x8f, 0x3d, 0x6c, 0x39, 0xd3, 0x37, 0x71, 0x81, 0x64, 0xb6, 0x61, 0x4a, 0x5d, - 0x89, 0x8f, 0xc9, 0xf0, 0x76, 0x16, 0x43, 0xd8, 0xf8, 0x32, 0x35, 0xf6, 0xf8, 0x68, 0x31, 0xe3, - 0x36, 0x30, 0x70, 0xed, 0x0a, 0xe4, 0xa4, 0x3e, 0x21, 0xce, 0x08, 0x68, 0x04, 0x13, 0xaa, 0xe7, - 0xa1, 0x15, 0x95, 0x9a, 0xaf, 0xc2, 0xb8, 0x58, 0x6c, 0x07, 0x9b, 0xbe, 0xcc, 0x9f, 0xce, 0xc0, - 0xac, 0x45, 0xd9, 0x52, 0x40, 0x79, 0x5a, 0xc7, 0x4f, 0xd9, 0xc3, 0xac, 0xda, 0xb7, 0x0d, 0x48, - 0xa8, 0xf8, 0x5b, 0x06, 0x9c, 0x4e, 0xc1, 0xfd, 0x58, 0x69, 0xf2, 0x6f, 0xc3, 0x44, 0xc9, 0x75, - 0x9a, 0x85, 0x46, 0x23, 0x0a, 0xc5, 0x43, 0xbd, 0xb1, 0xc1, 0x24, 0xcd, 0x61, 0x50, 0x75, 0xdb, - 0x8d, 0x50, 0xc9, 0x35, 0x21, 0x14, 0xf1, 0x9b, 0x3c, 0xf2, 0xe9, 0x57, 0xe0, 0x6d, 0x8a, 0x1f, - 0x7e, 0xc5, 0xf4, 0x2d, 0x1c, 0x18, 0xbb, 0x1d, 0x3e, 0xb3, 0x43, 0x97, 0x9e, 0xbe, 0x25, 0xf9, - 0x79, 0x43, 0x1d, 0x50, 0x7f, 0x21, 0x03, 0x67, 0xd3, 0x09, 0x3f, 0xee, 0x8b, 0x07, 0x98, 0xcd, - 0x52, 0x79, 0x5d, 0x17, 0x5f, 0x3c, 0xe0, 0xa9, 0x2f, 0x11, 0x3f, 0x46, 0x20, 0x7b, 0x30, 0xbd, - 0xea, 0x04, 0xe1, 0x0a, 0x75, 0xfc, 0x70, 0x97, 0x3a, 0xe1, 0x10, 0xba, 0xee, 0xcb, 0xe2, 0x6b, - 0x16, 0x70, 0xfb, 0x3b, 0x90, 0x94, 0x09, 0x55, 0x50, 0x67, 0x1b, 0x09, 0xca, 0xc8, 0x10, 0x82, - 0xf2, 0x2d, 0x98, 0xad, 0xd1, 0x96, 0xd3, 0x39, 0xf0, 0x7c, 0x2a, 0xac, 0xf5, 0xd7, 0x61, 0x3a, - 0x02, 0xa5, 0x4a, 0x8b, 0x5e, 0xac, 0xe1, 0x2b, 0x1d, 0x11, 0x2f, 0x25, 0x7a, 0xb1, 0xf9, 0x57, - 0x32, 0x70, 0xae, 0x50, 0x17, 0x37, 0xf2, 0xa2, 0x40, 0x3a, 0x0e, 0x7d, 0xc2, 0x75, 0x93, 0x1b, - 0x30, 0xb1, 0xe6, 0x3c, 0x5a, 0xa5, 0x4e, 0x40, 0x03, 0x91, 0x6f, 0x9a, 0x2b, 0x6a, 0xce, 0xa3, - 0xf8, 0xa2, 0xda, 0x8a, 0x71, 0xd4, 0x63, 0xe9, 0xc8, 0x13, 0x1e, 0x4b, 0x4d, 0x18, 0x5b, 0xf1, - 0x9a, 0x0d, 0xb1, 0x8d, 0x89, 0x9b, 0x92, 0x03, 0x84, 0x58, 0xa2, 0xc4, 0xfc, 0x63, 0x03, 0x66, - 0xa2, 0x16, 0x63, 0x13, 0x3e, 0xf1, 0x2e, 0xb9, 0x0c, 0xe3, 0x58, 0x51, 0xa5, 0xa4, 0x6e, 0x1a, - 0x4d, 0x06, 0xb2, 0xdd, 0x86, 0x25, 0x0b, 0xd5, 0x9e, 0x18, 0x7d, 0xb2, 0x9e, 0x30, 0xff, 0x23, - 0xbc, 0x84, 0x51, 0xbf, 0x92, 0xed, 0x44, 0x4a, 0x43, 0x8c, 0x21, 0x1b, 0x92, 0x79, 0x6a, 0x43, - 0x92, 0xed, 0x3b, 0x24, 0xdf, 0xc9, 0xc0, 0x64, 0xd4, 0xd8, 0x4f, 0x59, 0xde, 0xb3, 0xe8, 0xbb, - 0x86, 0x0a, 0xe5, 0xac, 0x29, 0x6b, 0x85, 0x88, 0x98, 0xfc, 0x22, 0x8c, 0x89, 0xc9, 0x64, 0x24, - 0x1c, 0x68, 0x12, 0xa3, 0xbb, 0x3c, 0x23, 0x58, 0x8f, 0xe1, 0x80, 0x06, 0x96, 0xa0, 0xc3, 0x58, - 0xd9, 0x1d, 0xba, 0x2b, 0xee, 0xe4, 0x9e, 0xd9, 0x3d, 0x2a, 0x3d, 0x56, 0x36, 0xfe, 0xb0, 0xa1, - 0x76, 0xa7, 0xa3, 0x51, 0xc8, 0x27, 0x49, 0x8e, 0xcf, 0x2c, 0x57, 0xed, 0xee, 0x8a, 0xc7, 0xfc, - 0x31, 0xb3, 0x5c, 0xa7, 0xbb, 0x6b, 0x31, 0x18, 0xb9, 0x0c, 0x23, 0x55, 0xdf, 0x7d, 0x80, 0x5f, - 0x3d, 0xc5, 0x2f, 0x7e, 0x3b, 0xbe, 0xfb, 0x40, 0xbd, 0xf8, 0x65, 0xe5, 0x78, 0xf4, 0x5d, 0xad, - 0x61, 0xfc, 0x11, 0xaa, 0xe0, 0xe2, 0xe8, 0xdb, 0x0c, 0x92, 0x09, 0x6f, 0x25, 0x1a, 0xdb, 0x2a, - 0x97, 0xa9, 0xe3, 0x8b, 0x2c, 0x68, 0x62, 0x39, 0xc3, 0xad, 0x72, 0x17, 0xc1, 0xfc, 0xd5, 0x25, - 0x4b, 0x45, 0x22, 0x4d, 0x20, 0xca, 0x4f, 0x39, 0x81, 0x8f, 0x3f, 0x0d, 0x5e, 0x94, 0x76, 0x3a, - 0x95, 0xb5, 0xad, 0xce, 0xe6, 0x14, 0xbe, 0x4f, 0xd3, 0x9a, 0x58, 0x15, 0x39, 0x31, 0xd0, 0xe4, - 0x91, 0x3b, 0x96, 0x99, 0x0c, 0xd0, 0x03, 0x9e, 0x33, 0x23, 0x32, 0x7c, 0xc4, 0x4c, 0xc8, 0x7b, - 0x30, 0xa9, 0x46, 0x95, 0xf1, 0xd8, 0xa7, 0xe7, 0x79, 0x2e, 0x8a, 0x3e, 0x89, 0xff, 0x55, 0x02, - 0xb2, 0x0b, 0xe7, 0x8a, 0x5e, 0x3b, 0xe8, 0xb6, 0x68, 0x43, 0xbb, 0x33, 0xae, 0x94, 0xf0, 0x28, - 0x3a, 0xc1, 0x43, 0x54, 0xea, 0x02, 0x45, 0x04, 0x31, 0x49, 0xef, 0x44, 0xfd, 0x00, 0xd2, 0x8f, - 0x11, 0xd9, 0x84, 0xc9, 0x5a, 0x61, 0x6d, 0x55, 0x46, 0x06, 0x4d, 0xea, 0xcb, 0x46, 0x5c, 0x52, - 0x62, 0x13, 0x83, 0x07, 0xc7, 0x3b, 0xad, 0xa6, 0x74, 0x8e, 0x53, 0xed, 0x94, 0x0a, 0xb2, 0xf9, - 0x19, 0x55, 0xbe, 0x85, 0xba, 0x31, 0x50, 0xbe, 0xcd, 0xff, 0x66, 0x0c, 0x66, 0x13, 0xd5, 0x89, - 0xf3, 0x8f, 0xd1, 0x73, 0xfe, 0xa9, 0x01, 0x70, 0xa3, 0xd7, 0x90, 0xd6, 0x29, 0xe9, 0x57, 0x3d, - 0x29, 0x82, 0x10, 0xa2, 0xb1, 0x52, 0xd8, 0x30, 0xa6, 0x5c, 0x12, 0x86, 0xb4, 0x4e, 0x46, 0x4c, - 0xb9, 0x30, 0x29, 0x4c, 0x63, 0x36, 0x64, 0x11, 0x46, 0x31, 0x69, 0x89, 0xea, 0xd6, 0xee, 0x32, - 0x80, 0xc5, 0xe1, 0xe4, 0x12, 0x8c, 0xb1, 0xcd, 0xb9, 0x52, 0x12, 0x93, 0x0b, 0xd7, 0x2c, 0xb6, - 0x7b, 0xb3, 0x9d, 0x50, 0x14, 0x91, 0xdb, 0x30, 0xc5, 0xff, 0x12, 0xd1, 0x8d, 0x63, 0xba, 0x87, - 0x87, 0xed, 0x36, 0x64, 0x80, 0xa3, 0x86, 0xc7, 0xb4, 0xd6, 0x5a, 0x77, 0x57, 0x3c, 0xf1, 0x38, - 0x1e, 0x6b, 0xad, 0x01, 0x07, 0xe2, 0x3b, 0x5d, 0x11, 0x02, 0xdb, 0x23, 0x85, 0x73, 0x59, 0x0e, - 0xcf, 0x2a, 0xb8, 0x47, 0x72, 0xa7, 0x32, 0x4b, 0x94, 0x90, 0xab, 0xdc, 0xfe, 0x8c, 0xea, 0x06, - 0x4f, 0x1c, 0x8d, 0x16, 0x63, 0x3c, 0xf0, 0xa2, 0xce, 0x11, 0x15, 0xb3, 0xca, 0xd9, 0xdf, 0xe5, - 0x96, 0xe3, 0x36, 0x85, 0xb8, 0x62, 0xe5, 0x88, 0x4b, 0x19, 0xd4, 0x8a, 0x11, 0xc8, 0x3b, 0x30, - 0xc3, 0x7e, 0x14, 0xbd, 0x56, 0xcb, 0x6b, 0x23, 0xfb, 0xc9, 0x38, 0x0e, 0x1d, 0x49, 0xea, 0x58, - 0xc4, 0x6b, 0x49, 0xe0, 0xb2, 0x75, 0x0a, 0x6f, 0xa3, 0xba, 0xdc, 0x32, 0x3e, 0x15, 0xaf, 0x53, - 0x48, 0x1a, 0x70, 0xb8, 0xa5, 0x22, 0x91, 0xb7, 0x60, 0x9a, 0xfd, 0xbc, 0xeb, 0x3e, 0xa0, 0xbc, - 0xc2, 0xe9, 0xf8, 0x62, 0x10, 0xa9, 0xf6, 0x59, 0x09, 0xaf, 0x4f, 0xc7, 0x24, 0x5f, 0x82, 0x33, - 0xc8, 0xa9, 0xee, 0x75, 0x68, 0xa3, 0xb0, 0xb7, 0xe7, 0x36, 0x5d, 0x9c, 0xbd, 0x22, 0x8e, 0x0f, - 0xad, 0x91, 0xbc, 0x62, 0xc4, 0xb0, 0x9d, 0x18, 0xc5, 0x4a, 0xa7, 0x24, 0x3b, 0x90, 0x2f, 0x76, - 0x83, 0xd0, 0x6b, 0x15, 0xc2, 0xd0, 0x77, 0x77, 0xbb, 0x21, 0x0d, 0x16, 0x66, 0xb5, 0x68, 0x37, - 0x36, 0x39, 0xa2, 0x42, 0x6e, 0x67, 0xa8, 0x23, 0x85, 0xed, 0x44, 0x24, 0x56, 0x0f, 0x13, 0xf3, - 0xbf, 0x36, 0x60, 0x5a, 0x23, 0x25, 0x6f, 0xc2, 0xd4, 0x1d, 0xdf, 0xa5, 0xed, 0x46, 0xf3, 0x50, - 0x39, 0x00, 0xa1, 0x76, 0xbc, 0x27, 0xe0, 0xfc, 0xab, 0x35, 0xb4, 0xc8, 0x7e, 0x90, 0x49, 0x75, - 0x9d, 0xb9, 0xc1, 0xa3, 0x2b, 0x84, 0x80, 0x66, 0xe3, 0xf0, 0x5b, 0x14, 0x50, 0x21, 0x9d, 0x0a, - 0x0a, 0x79, 0x17, 0xc6, 0xf8, 0xbd, 0x95, 0xf0, 0xe3, 0x38, 0x9f, 0xf6, 0x99, 0x3c, 0x92, 0x07, - 0x05, 0x11, 0xaf, 0xcb, 0x03, 0x4b, 0x10, 0x99, 0xbf, 0x6c, 0x00, 0xe9, 0x45, 0x3d, 0xc6, 0x9e, - 0x72, 0xec, 0x35, 0xfc, 0x17, 0xa3, 0xd9, 0x98, 0xd5, 0xac, 0x87, 0xac, 0x26, 0x5e, 0xc0, 0x3b, - 0x5e, 0xcc, 0x3a, 0xd5, 0xc0, 0xc3, 0x8b, 0xcd, 0x9f, 0xca, 0x00, 0xc4, 0xd8, 0xe4, 0xf3, 0x3c, - 0xb9, 0xee, 0x97, 0xba, 0x4e, 0xd3, 0xdd, 0x73, 0xf5, 0x34, 0x30, 0xc8, 0xe4, 0x5b, 0xb2, 0xc4, - 0xd2, 0x11, 0xc9, 0xfb, 0x30, 0x5b, 0xab, 0xea, 0xb4, 0x4a, 0x22, 0xd1, 0xa0, 0x63, 0x27, 0xc8, - 0x93, 0xd8, 0xe8, 0xaf, 0xa5, 0x8e, 0x06, 0xf7, 0xd7, 0xe2, 0x03, 0x21, 0x4a, 0xd8, 0xc2, 0x52, - 0xab, 0xe2, 0xd3, 0x8a, 0x0d, 0xda, 0xa8, 0x94, 0xc4, 0x2a, 0x85, 0xad, 0x0b, 0x3a, 0x76, 0x87, - 0x17, 0xe0, 0x7b, 0x7e, 0x1a, 0x5e, 0xdc, 0x91, 0xa3, 0x7d, 0xa2, 0x75, 0x7e, 0x15, 0xcd, 0x49, - 0x2d, 0x2f, 0xa4, 0xe2, 0x14, 0xfd, 0xcc, 0xea, 0xd3, 0xf1, 0xa5, 0xe7, 0xa8, 0x16, 0x84, 0xa0, - 0x7d, 0x1d, 0xc7, 0xd8, 0xbe, 0x15, 0x2b, 0xbf, 0xfc, 0xfa, 0x53, 0x5e, 0x7a, 0x2a, 0xaa, 0xdf, - 0xdf, 0x32, 0xe0, 0x4c, 0x2a, 0x2d, 0xb9, 0x0e, 0x10, 0xdb, 0x2a, 0x44, 0x2f, 0xf1, 0x67, 0x15, - 0x23, 0xa8, 0xa5, 0x60, 0x90, 0xaf, 0x25, 0xad, 0x0c, 0xc7, 0x6f, 0x84, 0x17, 0x64, 0x52, 0x01, - 0xdd, 0xca, 0x90, 0x62, 0x5b, 0x30, 0x7f, 0x2b, 0x0b, 0x73, 0x4a, 0x4c, 0x2b, 0x6f, 0xeb, 0x31, - 0xfe, 0x73, 0xf7, 0xe5, 0x13, 0x9e, 0xc2, 0x13, 0x3a, 0xa3, 0x3d, 0xe3, 0xdb, 0xc3, 0xed, 0xba, - 0x8a, 0xcc, 0x33, 0x69, 0xe0, 0xd2, 0x29, 0x5e, 0xf4, 0xec, 0xf1, 0x88, 0xd6, 0x98, 0x93, 0x00, - 0xa6, 0x4b, 0x87, 0x6d, 0xa7, 0x15, 0xd5, 0xc6, 0x2f, 0xea, 0x5f, 0xeb, 0x5b, 0x9b, 0x86, 0xcd, - 0xab, 0x93, 0x3a, 0xe7, 0x42, 0x83, 0x97, 0xa5, 0xc4, 0xfa, 0x68, 0x54, 0x17, 0xde, 0x87, 0xb9, - 0x9e, 0x46, 0x9f, 0x28, 0xa9, 0xc7, 0x0e, 0x90, 0xde, 0x76, 0xa4, 0x70, 0x78, 0x4d, 0x4f, 0x19, - 0x73, 0x26, 0xba, 0xc6, 0x6b, 0xb5, 0x9c, 0x76, 0x83, 0x5f, 0xfb, 0x2f, 0xa9, 0x29, 0x3f, 0x7e, - 0x35, 0xa3, 0xba, 0xf2, 0x3f, 0xeb, 0xb3, 0xee, 0x8b, 0xda, 0x29, 0xeb, 0xc5, 0x7e, 0x63, 0x3a, - 0xd4, 0x69, 0xf6, 0x07, 0x59, 0x38, 0xd7, 0x87, 0x92, 0x1c, 0x26, 0x85, 0x88, 0x9f, 0x6e, 0x6f, - 0x0e, 0xae, 0xf0, 0x69, 0x88, 0x12, 0xf9, 0x3c, 0x0f, 0xe6, 0xab, 0xe3, 0x6b, 0x3d, 0xe2, 0x5c, - 0xc7, 0x9f, 0x44, 0x8b, 0xa0, 0xc9, 0x28, 0x3e, 0x0e, 0x25, 0xef, 0xc3, 0x28, 0xc6, 0x71, 0x24, - 0x72, 0x6a, 0x30, 0x0c, 0x84, 0x2b, 0x09, 0x48, 0xd8, 0x4f, 0x2d, 0x01, 0x09, 0xbe, 0x51, 0xfd, - 0x39, 0xc8, 0x16, 0x76, 0x6a, 0x62, 0x5c, 0x66, 0x54, 0xf2, 0x9d, 0x5a, 0x9c, 0x4b, 0xd1, 0xd1, - 0x92, 0x1e, 0x32, 0x0a, 0x46, 0x78, 0xb7, 0x58, 0x15, 0xa3, 0xa2, 0x12, 0xde, 0x2d, 0x56, 0x63, - 0xc2, 0xfd, 0xba, 0x16, 0xad, 0x7c, 0xb7, 0x58, 0xfd, 0xe4, 0xc4, 0xfe, 0xe7, 0x32, 0x3c, 0x02, - 0x91, 0x7f, 0xd8, 0xfb, 0x30, 0xa5, 0xa5, 0xf4, 0x32, 0x62, 0x7d, 0x2c, 0x4a, 0x47, 0x96, 0xf0, - 0x93, 0xd0, 0x08, 0x64, 0x56, 0xd2, 0xe8, 0xb5, 0x6b, 0xd5, 0xcd, 0x41, 0x7f, 0x21, 0x3b, 0x99, - 0x95, 0x34, 0x22, 0x21, 0xb7, 0x20, 0xb7, 0x49, 0xdb, 0x4e, 0x3b, 0x8c, 0x0c, 0x6d, 0xe8, 0x96, - 0x17, 0x22, 0x4c, 0xd7, 0x1a, 0x22, 0x44, 0x7c, 0x9b, 0x5c, 0x79, 0xab, 0x3b, 0xda, 0x8b, 0xb9, - 0xb3, 0xa8, 0x52, 0x92, 0x78, 0xdc, 0x5d, 0x27, 0x32, 0x7f, 0xd5, 0x80, 0x71, 0x31, 0x90, 0xca, - 0x03, 0xb1, 0xc6, 0x10, 0x0f, 0xc4, 0xde, 0x86, 0x09, 0x11, 0x4c, 0xa3, 0x3f, 0xeb, 0x2e, 0xe2, - 0x6f, 0x12, 0xcf, 0xba, 0x47, 0xa8, 0x43, 0x7b, 0x9d, 0xff, 0x75, 0xd1, 0xb2, 0xbb, 0xc5, 0x2a, - 0x59, 0x82, 0x9c, 0x7c, 0x67, 0x5b, 0xb4, 0x0d, 0x97, 0x1d, 0xf9, 0x20, 0xb7, 0xda, 0x41, 0x12, - 0x4f, 0x7f, 0xae, 0x3e, 0x33, 0xfc, 0x73, 0xf5, 0xc3, 0xb6, 0x8f, 0xa6, 0x2c, 0x12, 0xdb, 0xb7, - 0x56, 0xdd, 0x20, 0x24, 0x1f, 0xa8, 0xde, 0xfc, 0xa2, 0x48, 0xae, 0x14, 0x17, 0xfa, 0xad, 0x14, - 0xdb, 0xb7, 0xac, 0x14, 0x2a, 0xbc, 0xaf, 0x89, 0xc1, 0x35, 0xea, 0x3f, 0x78, 0x86, 0x57, 0xe9, - 0xf4, 0xfb, 0x9a, 0xe4, 0xe7, 0x0d, 0xb5, 0x48, 0xff, 0xab, 0x0c, 0x9c, 0x4d, 0x27, 0x54, 0xbf, - 0xc5, 0x18, 0xf0, 0x2d, 0x57, 0x20, 0xb7, 0xe2, 0x05, 0xa1, 0xe2, 0x1a, 0x85, 0x66, 0xe5, 0x03, - 0x01, 0xb3, 0xa2, 0x52, 0x76, 0xe6, 0x66, 0x7f, 0x47, 0xd3, 0x13, 0xf9, 0x61, 0xdc, 0x1d, 0x3b, - 0x73, 0xf3, 0x22, 0x72, 0x17, 0x72, 0x96, 0x70, 0x3c, 0x4f, 0x74, 0x8d, 0x04, 0x47, 0xda, 0x14, - 0xf1, 0x05, 0x44, 0xcb, 0xac, 0x26, 0x60, 0xa4, 0x00, 0xe3, 0x62, 0xf4, 0x13, 0x57, 0x92, 0x29, - 0x22, 0xa3, 0x27, 0x3b, 0x94, 0x74, 0x6c, 0x45, 0xc1, 0xcb, 0xa5, 0x4a, 0x49, 0xfa, 0x90, 0xe3, - 0x8a, 0xc2, 0x2f, 0x9f, 0xf4, 0xf4, 0x8a, 0x11, 0xa2, 0xf9, 0xd3, 0x19, 0x80, 0x1d, 0xba, 0xfb, - 0x6c, 0xbf, 0xe2, 0xf1, 0x39, 0x4d, 0xc2, 0x14, 0xcf, 0x8b, 0xe1, 0x1f, 0xf1, 0xd8, 0x40, 0x0f, - 0x88, 0xe1, 0x9f, 0xf0, 0x58, 0x84, 0x51, 0x6e, 0xed, 0x54, 0x0e, 0x89, 0xdc, 0xcc, 0xc9, 0xe1, - 0xe6, 0x2e, 0xcc, 0xdf, 0xa5, 0x61, 0x6c, 0xde, 0x92, 0x57, 0x5a, 0x83, 0xd9, 0xbe, 0x0e, 0x13, - 0x02, 0x5f, 0x7f, 0x33, 0x5d, 0x86, 0xb2, 0xa2, 0x2d, 0x46, 0x22, 0xb0, 0xd5, 0xa8, 0x44, 0x9b, - 0x34, 0xa4, 0x9f, 0x6c, 0x35, 0x35, 0x20, 0xfc, 0x53, 0xf0, 0xcb, 0x86, 0xab, 0xe1, 0xd8, 0xfe, - 0xd9, 0x86, 0x33, 0x51, 0xdb, 0x9f, 0x26, 0xdf, 0x1b, 0xec, 0x48, 0x29, 0xf2, 0x04, 0xc6, 0x1c, - 0x07, 0xf8, 0x34, 0x3c, 0x82, 0x0b, 0x92, 0x60, 0xc7, 0x8d, 0x5c, 0xc8, 0x86, 0xa2, 0x25, 0xef, - 0xc0, 0xa4, 0x42, 0x23, 0x32, 0xb1, 0xa2, 0xf9, 0xf3, 0xa1, 0x1b, 0x1e, 0xd8, 0x01, 0x87, 0xab, - 0xe6, 0x4f, 0x05, 0xdd, 0xfc, 0x2a, 0x3c, 0x17, 0x39, 0xdc, 0xa7, 0x54, 0x9d, 0x60, 0x6e, 0x9c, - 0x8c, 0xf9, 0x7a, 0xfc, 0x59, 0x95, 0x76, 0x14, 0xfe, 0x25, 0x79, 0x13, 0xf5, 0xb3, 0xc4, 0xc7, - 0x3c, 0xdf, 0x13, 0x50, 0xa6, 0xc4, 0x8d, 0x99, 0x6f, 0x2b, 0x8d, 0x4d, 0x61, 0xa8, 0x11, 0x1b, - 0x49, 0xe2, 0x9f, 0xce, 0xc0, 0xec, 0x46, 0xa5, 0x54, 0x8c, 0xbc, 0x5a, 0x3e, 0x65, 0x4f, 0x8c, - 0x68, 0xdf, 0xd6, 0x7f, 0xbd, 0x31, 0xb7, 0xe0, 0x74, 0xa2, 0x1b, 0x50, 0x75, 0x78, 0x8f, 0x3b, - 0xc6, 0x47, 0x60, 0xa9, 0x36, 0x9c, 0x4d, 0x63, 0xbf, 0x7d, 0xcb, 0x4a, 0x60, 0x9b, 0x7f, 0x2f, - 0x97, 0xe0, 0x2b, 0x96, 0xb0, 0xd7, 0x61, 0xa2, 0x12, 0x04, 0x5d, 0xea, 0x6f, 0x59, 0xab, 0xaa, - 0xa9, 0xc0, 0x45, 0xa0, 0xdd, 0xf5, 0x9b, 0x56, 0x8c, 0x40, 0xae, 0x42, 0x4e, 0xe4, 0xa6, 0x93, - 0x6b, 0x02, 0x5a, 0x6d, 0xa3, 0xd4, 0x76, 0x56, 0x54, 0x4c, 0xde, 0x84, 0x29, 0xfe, 0x37, 0x97, - 0x36, 0xd1, 0xe1, 0x68, 0x1c, 0x14, 0xe8, 0x5c, 0x3a, 0x2d, 0x0d, 0x8d, 0x5c, 0x83, 0x6c, 0xa1, - 0x68, 0xa9, 0x4f, 0x25, 0x3b, 0x75, 0x9f, 0x3f, 0x99, 0xae, 0x1f, 0x22, 0x8a, 0x16, 0xd3, 0xfe, - 0x84, 0x29, 0xc9, 0x17, 0x96, 0x6c, 0x94, 0x00, 0x69, 0x6d, 0x4a, 0x6c, 0x66, 0x08, 0x23, 0x37, - 0x60, 0xbc, 0xe4, 0x06, 0x9d, 0xa6, 0x73, 0x28, 0xec, 0xd8, 0x3c, 0xf1, 0x38, 0x07, 0xa9, 0x32, - 0x23, 0xb0, 0xc8, 0x55, 0x18, 0x45, 0x23, 0xab, 0xb0, 0x65, 0xf3, 0xf4, 0xdc, 0x0c, 0xa0, 0xa5, - 0xe7, 0x66, 0x00, 0x4c, 0x7d, 0xca, 0x33, 0xb8, 0x4d, 0x28, 0xa9, 0x4f, 0x93, 0x99, 0xdb, 0x04, - 0x4e, 0x6f, 0x24, 0x15, 0x3c, 0xcd, 0x48, 0xaa, 0x5d, 0x38, 0x77, 0x17, 0xad, 0x37, 0x7a, 0x7c, - 0xfb, 0x96, 0x55, 0x11, 0xf6, 0x70, 0xbc, 0xf1, 0xe1, 0x06, 0x9e, 0x64, 0x88, 0xbc, 0xdd, 0xf5, - 0xd5, 0x77, 0x34, 0xfa, 0x31, 0x22, 0x5f, 0x86, 0xf9, 0xb4, 0x22, 0x61, 0x35, 0xc7, 0x48, 0xee, - 0xf4, 0x0a, 0xd4, 0x48, 0xee, 0x34, 0x0e, 0x64, 0x15, 0xf2, 0x1c, 0x5e, 0x68, 0xb4, 0xdc, 0x36, - 0xb7, 0xfc, 0x4f, 0xc7, 0xcf, 0x54, 0x0a, 0xae, 0x0e, 0x2b, 0xe4, 0x37, 0x00, 0x5a, 0x88, 0x44, - 0x82, 0x92, 0xfc, 0xa2, 0xc1, 0x4e, 0x73, 0x3c, 0xdf, 0xd9, 0x96, 0xb5, 0x1a, 0x88, 0x2c, 0x20, - 0x67, 0xe3, 0xe8, 0x87, 0x5a, 0xe8, 0xbb, 0xed, 0x7d, 0x11, 0xfe, 0xb0, 0x29, 0xc2, 0x1f, 0xde, - 0xf9, 0x58, 0xe1, 0x0f, 0x9c, 0x55, 0xf0, 0xf8, 0x68, 0x71, 0xca, 0x17, 0x75, 0xe2, 0x2c, 0xd2, - 0x5a, 0x80, 0x0f, 0xe9, 0x35, 0x9b, 0xde, 0xc3, 0xad, 0xf6, 0x03, 0xea, 0xbb, 0x7b, 0x2e, 0x6d, - 0xf0, 0x8f, 0x9c, 0xc5, 0x15, 0x9c, 0x3f, 0xa4, 0x87, 0x6f, 0x1f, 0x76, 0x23, 0x84, 0x9e, 0x0f, - 0x4d, 0xe5, 0xc0, 0x0e, 0x9e, 0xd2, 0x61, 0x9f, 0xc7, 0xb1, 0xe5, 0xe3, 0x83, 0xa7, 0xf4, 0xee, - 0xb7, 0x51, 0x8c, 0x54, 0xe1, 0xd1, 0x48, 0x84, 0x77, 0xf0, 0xaf, 0x4c, 0xf0, 0x15, 0xb9, 0xd0, - 0x0d, 0x0f, 0xe4, 0x1a, 0xbe, 0x94, 0x16, 0x74, 0xc0, 0x5d, 0x9e, 0x94, 0xa0, 0x03, 0x3d, 0xd4, - 0x40, 0x9a, 0xd2, 0x33, 0xa9, 0xa6, 0xf4, 0xd7, 0x61, 0x02, 0x5f, 0xf6, 0x8d, 0xbc, 0xbb, 0x73, - 0xc2, 0x56, 0xc9, 0x80, 0x3c, 0xc5, 0x57, 0x8c, 0x40, 0x6e, 0x00, 0x60, 0x2a, 0x7c, 0xbe, 0xc1, - 0x2b, 0xc9, 0x39, 0x31, 0x63, 0xbe, 0xb8, 0x45, 0x56, 0x50, 0x90, 0x7d, 0xcd, 0xba, 0xa3, 0x5e, - 0x3b, 0x73, 0xf6, 0x81, 0xbf, 0x27, 0xd0, 0x63, 0x04, 0xf6, 0x79, 0xca, 0x30, 0x89, 0x45, 0x25, - 0xdf, 0x33, 0x96, 0x2a, 0x12, 0x7a, 0x74, 0x49, 0x57, 0x56, 0x5c, 0x53, 0xa6, 0x84, 0x47, 0x57, - 0xe4, 0xf6, 0x6a, 0xc5, 0x08, 0xe4, 0x73, 0x30, 0x5e, 0xa4, 0x7e, 0xb8, 0xb9, 0xb9, 0x8a, 0x37, - 0xc3, 0x3c, 0x83, 0x65, 0x0e, 0xb3, 0x0d, 0x86, 0x61, 0xf3, 0x87, 0x47, 0x8b, 0xd3, 0xa1, 0xdb, - 0xa2, 0xd7, 0xa3, 0x6b, 0x5c, 0x89, 0x4d, 0x96, 0x21, 0xcf, 0xef, 0x18, 0x63, 0x45, 0x0e, 0x97, - 0x99, 0x1c, 0x5f, 0xf4, 0xc4, 0x85, 0xe4, 0x43, 0xba, 0x1b, 0xe5, 0x5a, 0xec, 0xc1, 0x27, 0x65, - 0x99, 0xa2, 0x54, 0xfd, 0x48, 0x88, 0x2d, 0x0b, 0x62, 0x61, 0xd6, 0xbe, 0xb5, 0x97, 0x82, 0x14, - 0x60, 0xba, 0xe8, 0xb5, 0x3a, 0x4e, 0xe8, 0x62, 0x8e, 0xfa, 0x43, 0xb1, 0xa2, 0xa0, 0x75, 0xa4, - 0xae, 0x16, 0xe8, 0x0f, 0xf5, 0x2a, 0x05, 0xe4, 0x0e, 0xcc, 0x58, 0x5e, 0x97, 0x0d, 0x92, 0x3c, - 0xd2, 0xf0, 0x45, 0x23, 0x7a, 0x02, 0x9e, 0x8d, 0xa5, 0x2d, 0xce, 0x2f, 0x5a, 0x76, 0x1c, 0x8d, - 0x8a, 0xac, 0xa7, 0xd8, 0x96, 0xd5, 0x95, 0x42, 0xcd, 0xb8, 0xd8, 0xc3, 0x2c, 0xc5, 0x2c, 0x7d, - 0x0b, 0x26, 0x6b, 0xb5, 0x8d, 0x4d, 0x1a, 0x84, 0x77, 0x9a, 0xde, 0x43, 0x5c, 0x28, 0x72, 0x22, - 0xd1, 0x73, 0xe0, 0xd9, 0x21, 0x0d, 0x42, 0x7b, 0xaf, 0xe9, 0x3d, 0xb4, 0x54, 0x2c, 0xf2, 0x0d, - 0xe5, 0xe5, 0x62, 0xdc, 0xf9, 0x67, 0x8f, 0xdd, 0xf9, 0x13, 0xaf, 0x1a, 0xb3, 0xfd, 0x3f, 0xf5, - 0x55, 0x63, 0x86, 0x8e, 0xa1, 0x0a, 0xec, 0x30, 0x56, 0x68, 0x34, 0x7c, 0x1a, 0x04, 0x62, 0x46, - 0x2b, 0xef, 0xb2, 0x3b, 0xbc, 0x40, 0x0b, 0x55, 0x50, 0x08, 0xc8, 0x77, 0x0c, 0x38, 0xa3, 0x7a, - 0x3b, 0xe3, 0x64, 0x69, 0xd1, 0x76, 0xb8, 0x30, 0x87, 0x2d, 0x7d, 0xe3, 0xba, 0x5c, 0xd1, 0xae, - 0x2b, 0x68, 0xd7, 0x1f, 0xdc, 0xbc, 0xae, 0xbc, 0xd5, 0x59, 0x93, 0x44, 0x22, 0x95, 0x46, 0x1a, - 0x3f, 0x75, 0x75, 0x72, 0x52, 0x48, 0x49, 0x91, 0x6d, 0x7a, 0x4c, 0x9e, 0xd0, 0xb7, 0xa1, 0x52, - 0xc5, 0x6c, 0x41, 0xc2, 0x38, 0x25, 0xa4, 0x8f, 0x7b, 0x41, 0xb8, 0x1d, 0x7d, 0x6f, 0x53, 0x68, - 0x50, 0x55, 0xac, 0x15, 0xd6, 0x56, 0x63, 0x7d, 0xe7, 0xd3, 0xe5, 0x62, 0xac, 0x7d, 0xdb, 0x00, - 0x17, 0xe3, 0x2d, 0x38, 0x9d, 0xe8, 0x06, 0xa9, 0x2a, 0x6a, 0xe0, 0xa4, 0xaa, 0x98, 0xa0, 0xb1, - 0x12, 0xd8, 0xe6, 0xdf, 0x1d, 0x4f, 0xf0, 0x15, 0x6e, 0x45, 0x26, 0x8c, 0x71, 0x4d, 0x50, 0x7d, - 0x18, 0x8e, 0xeb, 0x89, 0x96, 0x28, 0x21, 0xe7, 0x21, 0x5b, 0xab, 0x6d, 0xa8, 0xcf, 0x56, 0x06, - 0x81, 0x67, 0x31, 0x18, 0x1b, 0x21, 0xf4, 0x18, 0x52, 0xd2, 0xf6, 0xb1, 0x65, 0xcf, 0x42, 0x28, - 0xeb, 0x6f, 0xa9, 0x97, 0x8d, 0xc4, 0xfd, 0x2d, 0xf4, 0xb2, 0x58, 0x1b, 0x2b, 0xc2, 0x42, 0x21, - 0x08, 0xa8, 0xcf, 0x9f, 0xf4, 0x47, 0x47, 0x14, 0x5f, 0xe8, 0x0e, 0x62, 0x75, 0xc7, 0x4a, 0x9d, - 0x7a, 0x60, 0xf5, 0x45, 0x24, 0x57, 0x20, 0x57, 0xe8, 0x36, 0x5c, 0xda, 0xae, 0x6b, 0xa9, 0x1f, - 0x1c, 0x01, 0xb3, 0xa2, 0x52, 0xf2, 0x25, 0x38, 0x23, 0x88, 0xa4, 0x02, 0x29, 0x7a, 0x60, 0x3c, - 0x9e, 0x82, 0x52, 0xb7, 0x89, 0x2f, 0x39, 0x79, 0x97, 0xa4, 0x53, 0x92, 0x02, 0xe4, 0xcb, 0xe8, - 0x52, 0x5f, 0xa2, 0xdc, 0xde, 0xea, 0xf9, 0xe2, 0x05, 0x6e, 0xd4, 0x44, 0xb9, 0xbb, 0xbd, 0xdd, - 0x88, 0x0a, 0xad, 0x1e, 0x74, 0x72, 0x0f, 0x4e, 0x27, 0x61, 0x6c, 0x21, 0xe7, 0x4a, 0x27, 0xe6, - 0x8d, 0xea, 0xe1, 0x82, 0x4b, 0x79, 0x1a, 0x15, 0xd9, 0x85, 0xb9, 0xf8, 0x92, 0x5f, 0x57, 0x45, - 0xa5, 0x4f, 0x5a, 0x54, 0x2e, 0xd5, 0xd1, 0xe7, 0x84, 0x30, 0x9e, 0x8e, 0x1d, 0x06, 0x22, 0x95, - 0xd4, 0xea, 0x65, 0x47, 0x1a, 0x30, 0x53, 0x73, 0xf7, 0xdb, 0x6e, 0x7b, 0xff, 0x1e, 0x3d, 0xac, - 0x3a, 0xae, 0x2f, 0xbc, 0x83, 0xa4, 0xef, 0x5f, 0x21, 0x38, 0x6c, 0xb5, 0x68, 0xe8, 0xe3, 0x16, - 0xc9, 0xca, 0x31, 0xa2, 0xce, 0x60, 0x7b, 0x41, 0xc0, 0xe9, 0x30, 0x7a, 0xa4, 0xe3, 0xb8, 0xda, - 0x5e, 0xa0, 0xf3, 0xd4, 0x8e, 0x03, 0x53, 0x43, 0x1e, 0x07, 0x9a, 0x30, 0x57, 0x6e, 0xd7, 0xfd, - 0x43, 0x34, 0x7b, 0xcb, 0xc6, 0x4d, 0x1f, 0xd3, 0xb8, 0x97, 0x45, 0xe3, 0x9e, 0x77, 0xa4, 0x84, - 0xa5, 0x35, 0xaf, 0x97, 0x31, 0xa9, 0x89, 0xe7, 0xc6, 0x2b, 0xa5, 0x6a, 0xa5, 0xed, 0x86, 0x2e, - 0x3e, 0xd1, 0xc6, 0xf7, 0x98, 0x57, 0x04, 0xcf, 0x17, 0xb8, 0xda, 0xe7, 0x36, 0x3a, 0xb6, 0x2b, - 0x51, 0x7a, 0xde, 0x13, 0x57, 0xe9, 0xcd, 0xff, 0x34, 0xc7, 0x57, 0x43, 0x55, 0x4d, 0xeb, 0xe7, - 0xef, 0x94, 0x50, 0xdf, 0x32, 0x27, 0x51, 0xdf, 0xb2, 0xc7, 0xab, 0x6f, 0x23, 0xc7, 0xa9, 0x6f, - 0x09, 0xfd, 0x6a, 0xf4, 0xc4, 0xfa, 0xd5, 0xd8, 0x09, 0xf4, 0xab, 0xf1, 0x13, 0xe9, 0x57, 0x9a, - 0xa2, 0x98, 0x3b, 0x4e, 0x51, 0xfc, 0xff, 0xb4, 0xb1, 0x67, 0x55, 0x1b, 0x4b, 0xdb, 0x5c, 0x4f, - 0xa4, 0x8d, 0xf5, 0x57, 0xa6, 0xf2, 0x7f, 0xd6, 0xca, 0xd4, 0xdc, 0xc7, 0x50, 0xa6, 0x7e, 0x14, - 0xf2, 0xc9, 0xf5, 0xfd, 0xf8, 0xe4, 0x46, 0x4f, 0x2d, 0x07, 0x09, 0xdb, 0x7d, 0x92, 0xeb, 0x2b, - 0x3b, 0xe4, 0x55, 0x7d, 0xf7, 0x81, 0x13, 0xd2, 0xf8, 0x69, 0x64, 0x3c, 0xe4, 0x75, 0x38, 0x14, - 0xe7, 0xbc, 0x82, 0x12, 0xa9, 0x16, 0x99, 0x34, 0xd5, 0xc2, 0xfc, 0x99, 0x0c, 0xcc, 0xf1, 0xb4, - 0x09, 0xcf, 0xbe, 0x6d, 0xf1, 0x3d, 0x4d, 0x61, 0x94, 0x2e, 0x44, 0x89, 0xaf, 0x1b, 0x60, 0x5d, - 0xfc, 0x3a, 0x9c, 0xe9, 0xe9, 0x0a, 0x54, 0x1a, 0x4b, 0x32, 0x61, 0x45, 0x8f, 0xda, 0xb8, 0x90, - 0x5e, 0xc9, 0xf6, 0x2d, 0xab, 0x87, 0xc2, 0xfc, 0xb7, 0xd9, 0x1e, 0xfe, 0xc2, 0xce, 0xa8, 0x5a, - 0x0e, 0x8d, 0x93, 0x59, 0x0e, 0x33, 0xc3, 0x59, 0x0e, 0x13, 0x7b, 0x4b, 0x76, 0x98, 0xbd, 0xe5, - 0x4b, 0x30, 0xbd, 0x49, 0x9d, 0x56, 0xb0, 0xe9, 0x89, 0xb4, 0xa8, 0xdc, 0x85, 0x50, 0xe6, 0xa3, - 0x60, 0x65, 0x52, 0xe7, 0x89, 0x5c, 0x21, 0x42, 0x46, 0xc0, 0xd6, 0x43, 0x9e, 0x27, 0xd5, 0xd2, - 0x39, 0xa8, 0x8a, 0xec, 0xe8, 0x00, 0x45, 0xb6, 0x06, 0x53, 0x82, 0x2e, 0xce, 0xe8, 0x14, 0x6b, - 0x5c, 0xac, 0x08, 0xe1, 0xb2, 0xf6, 0xe8, 0x11, 0x97, 0xa8, 0x76, 0xae, 0x6c, 0x69, 0x4c, 0x58, - 0x17, 0x94, 0xdb, 0x8d, 0x8e, 0xe7, 0xb6, 0xb1, 0x0b, 0xc6, 0xe3, 0x2e, 0xa0, 0x02, 0xcc, 0xbb, - 0x40, 0x41, 0x22, 0xef, 0xc0, 0x4c, 0xa1, 0x5a, 0x51, 0xc9, 0x72, 0xb1, 0xf1, 0xd2, 0xe9, 0xb8, - 0xb6, 0x46, 0x9a, 0xc0, 0x35, 0x7f, 0x62, 0x42, 0xce, 0xad, 0x4f, 0xd6, 0x4a, 0xa4, 0xdb, 0x7d, - 0xb2, 0x27, 0xb4, 0xfb, 0x8c, 0x1c, 0xb7, 0x9d, 0x6b, 0x3a, 0xc6, 0xe8, 0x09, 0x74, 0x8c, 0xb1, - 0x27, 0xb6, 0xe1, 0x8c, 0x9f, 0x50, 0x6b, 0x48, 0x88, 0x79, 0x6e, 0x18, 0x31, 0x4f, 0xd5, 0x34, - 0x26, 0x9e, 0x5c, 0xd3, 0x80, 0x13, 0x6b, 0x1a, 0xca, 0x2b, 0xc2, 0x93, 0x43, 0xbd, 0x22, 0x6c, - 0x0c, 0xf1, 0x8a, 0xf0, 0xa7, 0x4a, 0x7d, 0xf9, 0x66, 0xba, 0xfa, 0x32, 0x78, 0xa9, 0xff, 0x7f, - 0xb3, 0x02, 0xe3, 0x63, 0x2f, 0xef, 0x38, 0x3e, 0x3b, 0x0b, 0x06, 0xe4, 0x06, 0x8c, 0xcb, 0xcc, - 0x32, 0x46, 0x7c, 0xac, 0xee, 0x4d, 0x29, 0x23, 0xb1, 0xd8, 0xb1, 0x51, 0x12, 0x8b, 0xd8, 0x6a, - 0x9e, 0x44, 0x43, 0xc0, 0xb4, 0x24, 0x1a, 0x02, 0x66, 0xfe, 0xed, 0x11, 0x39, 0x93, 0xd9, 0xb1, - 0x46, 0x3c, 0x58, 0xb7, 0xac, 0x8c, 0x9c, 0xa2, 0x3e, 0x25, 0xc6, 0x26, 0xe1, 0x33, 0xa4, 0x93, - 0x7c, 0x9c, 0xb4, 0x3c, 0xca, 0xeb, 0x05, 0xd9, 0x21, 0x5e, 0x2f, 0x78, 0x4b, 0x4b, 0xfd, 0x3f, - 0x12, 0xe7, 0x9a, 0x66, 0xd2, 0x3d, 0x38, 0xe9, 0xff, 0x6d, 0x35, 0x47, 0xff, 0x68, 0x1c, 0x86, - 0x8e, 0x94, 0x03, 0xb2, 0xf3, 0x47, 0xfa, 0xe0, 0xd8, 0x49, 0x52, 0x54, 0x8d, 0xff, 0x99, 0xa6, - 0xa8, 0x2a, 0x03, 0x28, 0xaf, 0x98, 0x71, 0x53, 0xfd, 0x2b, 0xac, 0x9b, 0x8e, 0x7f, 0xc1, 0x4c, - 0x21, 0x34, 0xff, 0x39, 0x81, 0xb9, 0x5a, 0x6d, 0xa3, 0xe4, 0x3a, 0xfb, 0x6d, 0x2f, 0x08, 0xdd, - 0x7a, 0xa5, 0xbd, 0xe7, 0x31, 0x65, 0x28, 0x5a, 0x15, 0x94, 0x74, 0x49, 0xf1, 0x8a, 0x10, 0x15, - 0x33, 0x65, 0xbb, 0xec, 0xfb, 0x9e, 0xaf, 0x2a, 0xdb, 0x94, 0x01, 0x2c, 0x0e, 0x67, 0xfa, 0x46, - 0xad, 0xcb, 0x9f, 0xa3, 0xe2, 0xb7, 0x27, 0xa8, 0x6f, 0x04, 0x1c, 0x64, 0xc9, 0x32, 0x42, 0x7b, - 0x05, 0x56, 0xe8, 0x9f, 0xe7, 0xb4, 0x44, 0x57, 0x71, 0x31, 0x5f, 0xf3, 0xc4, 0x9e, 0x84, 0x41, - 0x28, 0x1d, 0x84, 0xab, 0x57, 0x6d, 0x3d, 0x73, 0xe0, 0x10, 0xce, 0x68, 0xc1, 0x14, 0xc3, 0x5a, - 0x94, 0xae, 0x09, 0xfd, 0xc6, 0xc4, 0x98, 0xb0, 0x14, 0xb3, 0x92, 0x9a, 0x2b, 0x37, 0xb5, 0x06, - 0xf2, 0x33, 0x06, 0xbc, 0x90, 0x5a, 0x12, 0xcd, 0xee, 0x49, 0x2d, 0xd9, 0x98, 0xb2, 0x68, 0xf0, - 0xac, 0xc0, 0xfd, 0xaa, 0xb6, 0x53, 0x96, 0x82, 0xc1, 0x35, 0x91, 0x7f, 0x6c, 0xc0, 0x39, 0x0d, - 0x23, 0x5a, 0xf3, 0x02, 0xdc, 0x9b, 0xfa, 0xca, 0xf5, 0x47, 0x4f, 0x47, 0xae, 0x2f, 0xe9, 0xdf, - 0x12, 0x2f, 0xc9, 0xea, 0x37, 0xf4, 0x6b, 0x21, 0x79, 0x00, 0x73, 0x58, 0x24, 0xad, 0x5b, 0x4c, - 0x66, 0x85, 0x51, 0x6c, 0x3e, 0x6e, 0x36, 0x0f, 0x10, 0xc2, 0x97, 0x5d, 0x96, 0x7e, 0x70, 0xb4, - 0x38, 0xad, 0xa1, 0x63, 0x9e, 0x53, 0x6c, 0x43, 0x64, 0x22, 0x73, 0xdb, 0x7b, 0x9e, 0xf6, 0x58, - 0x7c, 0xb2, 0x0a, 0xf2, 0x9f, 0x1b, 0xb0, 0xc0, 0xa0, 0xfc, 0x33, 0xee, 0xf8, 0x5e, 0x2b, 0x2a, - 0x97, 0x77, 0xb6, 0x7d, 0xba, 0xad, 0xf9, 0x74, 0xba, 0xed, 0x15, 0x6c, 0x32, 0x5f, 0x13, 0xec, - 0x3d, 0xdf, 0x6b, 0xc5, 0xcd, 0xd7, 0x5e, 0xe9, 0xea, 0xd7, 0x48, 0xf2, 0x93, 0x06, 0x9c, 0xd7, - 0x0c, 0x0c, 0x6a, 0x76, 0x4f, 0x11, 0x86, 0x25, 0x2f, 0xf8, 0xd5, 0xa2, 0xe5, 0xeb, 0x42, 0xfe, - 0x2f, 0x63, 0x0b, 0xe2, 0xdd, 0x02, 0xdb, 0x62, 0xb7, 0x38, 0x96, 0xd2, 0x84, 0xfe, 0xb5, 0x10, - 0x17, 0xe6, 0xf0, 0xc6, 0x49, 0xf3, 0x2d, 0x98, 0xef, 0xef, 0x5b, 0x10, 0x65, 0xe0, 0xc7, 0x0c, - 0x8a, 0xfd, 0x1d, 0x0c, 0x7a, 0xb9, 0x92, 0x1f, 0x83, 0xf3, 0x3d, 0xc0, 0x68, 0xb6, 0x9d, 0xe9, - 0x3b, 0xdb, 0x5e, 0x7b, 0x7c, 0xb4, 0xf8, 0x6a, 0x5a, 0x6d, 0x69, 0x33, 0xad, 0x7f, 0x0d, 0xc4, - 0x01, 0x88, 0x0b, 0xc5, 0xb3, 0x5f, 0xe9, 0x02, 0xfa, 0x9a, 0x90, 0x0f, 0x05, 0x9f, 0xad, 0xe5, - 0x4a, 0x1b, 0xd4, 0x2d, 0x2f, 0x46, 0x22, 0x14, 0xa6, 0x94, 0xec, 0x91, 0x87, 0xf8, 0xfe, 0x57, - 0xdf, 0x4a, 0x7e, 0x70, 0xb4, 0xa8, 0x61, 0x33, 0xbd, 0x58, 0x4d, 0x4b, 0xa9, 0xea, 0xc5, 0x1a, - 0x22, 0xf9, 0x07, 0x06, 0xcc, 0x33, 0x40, 0x2c, 0x54, 0xe2, 0xa3, 0x16, 0x06, 0x49, 0xfd, 0xc1, - 0xd3, 0x91, 0xfa, 0x97, 0xb0, 0x8d, 0xaa, 0xd4, 0xf7, 0x74, 0x49, 0x6a, 0xe3, 0x50, 0xda, 0xb5, - 0xcb, 0x4d, 0x4d, 0xda, 0xcf, 0x0f, 0x21, 0xed, 0x7c, 0x00, 0x8e, 0x97, 0xf6, 0xbe, 0xb5, 0x90, - 0x4d, 0x98, 0x12, 0x2a, 0x31, 0xef, 0xb0, 0x17, 0xb5, 0x64, 0x75, 0x6a, 0x11, 0x3f, 0xa7, 0x88, - 0xe4, 0x9a, 0x3d, 0x5f, 0xa8, 0x71, 0x21, 0x6d, 0x38, 0xcd, 0x7f, 0xeb, 0xd6, 0x81, 0xc5, 0xbe, - 0xd6, 0x81, 0x2b, 0xe2, 0x8b, 0x2e, 0x0a, 0xfe, 0x09, 0x23, 0x81, 0xfa, 0xc4, 0x40, 0x0a, 0x63, - 0xd2, 0x01, 0xa2, 0x81, 0xf9, 0xa4, 0xbd, 0x38, 0xd8, 0x26, 0xf0, 0xaa, 0xa8, 0x73, 0x31, 0x59, - 0x67, 0x72, 0xe6, 0xa6, 0xf0, 0x26, 0x0e, 0xcc, 0x0a, 0x28, 0x3b, 0x00, 0xe3, 0x0a, 0xff, 0x92, - 0x16, 0xb1, 0x9d, 0x28, 0xe5, 0xcf, 0x43, 0xc9, 0x9a, 0x30, 0xa2, 0x3e, 0xb1, 0xa0, 0x27, 0xf9, - 0x91, 0x0d, 0x98, 0xc3, 0x37, 0xfb, 0x69, 0x03, 0xbf, 0x92, 0x3f, 0x56, 0x65, 0xc6, 0x79, 0xb0, - 0x1d, 0x5e, 0x28, 0x54, 0xfc, 0xe4, 0x4b, 0x55, 0xbd, 0xb4, 0xe6, 0x77, 0x8c, 0x9e, 0x46, 0xb3, - 0x93, 0x3b, 0xfe, 0x50, 0x82, 0x35, 0xf1, 0xe4, 0xce, 0x9b, 0x88, 0x16, 0x84, 0x18, 0x81, 0x29, - 0x4b, 0x6a, 0x22, 0x90, 0xac, 0x78, 0x88, 0x9b, 0x83, 0xe2, 0x03, 0xe5, 0xa2, 0xf4, 0xf9, 0xca, - 0xc6, 0x4a, 0x17, 0xfa, 0x7c, 0x09, 0x4f, 0x2f, 0xf3, 0x27, 0x33, 0xba, 0xd8, 0x91, 0x2b, 0x8a, - 0xde, 0xae, 0xa4, 0x22, 0x91, 0x7a, 0xbb, 0xa2, 0xad, 0xff, 0x2d, 0x03, 0x4e, 0x6f, 0xf8, 0xfb, - 0x4e, 0xdb, 0xfd, 0x36, 0x4f, 0x69, 0xe6, 0xe1, 0xb8, 0x44, 0x71, 0x2a, 0x9f, 0x68, 0x6a, 0x74, - 0x4f, 0xa9, 0x98, 0x49, 0x0a, 0x8a, 0x8c, 0x95, 0xd6, 0x1e, 0xf4, 0xa2, 0xc5, 0x86, 0x29, 0x19, - 0xea, 0x39, 0x3a, 0x87, 0x9b, 0xbf, 0x90, 0x81, 0x49, 0x65, 0x0a, 0x90, 0xcf, 0xc2, 0x94, 0xca, - 0x47, 0xb5, 0xfa, 0xa8, 0xd5, 0x5a, 0x1a, 0x16, 0x9a, 0x7d, 0xa8, 0xd3, 0xd2, 0xcc, 0x3e, 0x4c, - 0xd0, 0x11, 0x7a, 0xc2, 0xa3, 0xcd, 0xfb, 0x29, 0x47, 0x9b, 0x13, 0xbd, 0x6a, 0xf6, 0x4e, 0xef, - 0x01, 0x67, 0xf8, 0x47, 0xc8, 0xcc, 0x5f, 0x32, 0x20, 0x9f, 0x9c, 0xa4, 0x9f, 0x48, 0xaf, 0x9c, - 0xc0, 0xbe, 0xfe, 0xf3, 0x19, 0xc8, 0xe3, 0x13, 0x91, 0xb4, 0x21, 0x63, 0x03, 0x9e, 0x55, 0x5f, - 0x89, 0x77, 0x35, 0xd3, 0xf7, 0x73, 0xd1, 0xbe, 0xa2, 0x7e, 0xdc, 0x80, 0x9c, 0x29, 0x23, 0xdf, - 0xff, 0xb5, 0xc5, 0x53, 0xe6, 0x87, 0x30, 0x9f, 0xec, 0x0e, 0x34, 0x7f, 0x17, 0x60, 0x56, 0x87, - 0x27, 0x13, 0x4f, 0x27, 0xa9, 0xac, 0x24, 0xbe, 0xf9, 0x07, 0x99, 0x24, 0x6f, 0xe1, 0x37, 0xc1, - 0x16, 0x9d, 0xb6, 0xb3, 0xdb, 0x8c, 0x72, 0xe3, 0x8a, 0xd7, 0xff, 0x11, 0x64, 0xc9, 0xb2, 0x93, - 0xa4, 0x20, 0x8f, 0x3c, 0xdc, 0xb3, 0xe9, 0x1e, 0xee, 0xe4, 0x76, 0xc2, 0x63, 0x48, 0x09, 0xc7, - 0x7e, 0x48, 0x77, 0xed, 0xd8, 0x6b, 0x28, 0xe1, 0x28, 0x54, 0x84, 0x79, 0x2d, 0x67, 0x9d, 0xa4, - 0x1f, 0x8d, 0x0d, 0xae, 0x21, 0x16, 0x70, 0xe2, 0x54, 0x64, 0xb2, 0x02, 0xe3, 0xac, 0x99, 0x6b, - 0x4e, 0x47, 0x58, 0xb5, 0xd5, 0x47, 0xd2, 0xe5, 0xe6, 0xa5, 0x84, 0xbc, 0x34, 0x29, 0xdb, 0xf2, - 0xb5, 0x47, 0x01, 0x39, 0xa2, 0xf9, 0x27, 0x06, 0x9b, 0xff, 0xf5, 0xfb, 0x9f, 0xb2, 0xe4, 0xe8, - 0xec, 0x93, 0x06, 0xb8, 0xf5, 0xfc, 0x61, 0x86, 0xa7, 0x37, 0x16, 0xe2, 0xf3, 0x16, 0x8c, 0x6d, - 0x3a, 0xfe, 0x3e, 0x0d, 0x45, 0x22, 0x5e, 0x95, 0x0b, 0x2f, 0x88, 0x83, 0xc5, 0x43, 0xfc, 0x6d, - 0x09, 0x02, 0xd5, 0x16, 0x96, 0x19, 0xca, 0x16, 0xa6, 0x98, 0x67, 0xb3, 0x4f, 0xcd, 0x3c, 0xfb, - 0x95, 0x28, 0xb3, 0x70, 0x21, 0x1c, 0x22, 0x25, 0xda, 0xc5, 0x64, 0x9a, 0xed, 0x9e, 0xe4, 0x75, - 0x31, 0x3b, 0x72, 0x5b, 0x4d, 0xdc, 0xad, 0x38, 0x8d, 0x1f, 0x93, 0xa2, 0xdb, 0xfc, 0xc3, 0x2c, - 0xef, 0x63, 0xd1, 0x51, 0x97, 0xb5, 0x80, 0x12, 0x9c, 0x27, 0x6c, 0xa1, 0x57, 0x63, 0xfb, 0xd0, - 0x7f, 0xe1, 0x32, 0x8c, 0x30, 0xd9, 0x14, 0xbd, 0xc9, 0x1f, 0xb8, 0xf6, 0x9a, 0x5a, 0x0c, 0x20, - 0x2b, 0x67, 0x73, 0x19, 0xf7, 0x24, 0xf5, 0x8d, 0x00, 0xdc, 0xb6, 0xd4, 0xb9, 0x8c, 0x18, 0xe4, - 0x0a, 0x8c, 0xac, 0x7b, 0x0d, 0x99, 0x7a, 0x6f, 0x1e, 0xc3, 0x0a, 0xb5, 0x97, 0x7e, 0x17, 0x0c, - 0x0b, 0x31, 0xd8, 0xb7, 0x46, 0xc9, 0x7a, 0xd5, 0x6f, 0x6d, 0xed, 0x39, 0x36, 0x4f, 0x12, 0xab, - 0x7e, 0x6b, 0x9c, 0xd7, 0xb7, 0x0c, 0x33, 0xfa, 0x1b, 0x46, 0xc2, 0xe9, 0x09, 0xcd, 0xac, 0x89, - 0xa7, 0x90, 0x54, 0xeb, 0xb8, 0x4e, 0x44, 0x96, 0x61, 0x5a, 0x4b, 0xf9, 0x23, 0xae, 0x97, 0xd0, - 0xbc, 0xa9, 0x27, 0x0c, 0x52, 0xcd, 0x9b, 0x1a, 0x09, 0xdb, 0xcf, 0x45, 0xfb, 0x95, 0x4b, 0xa6, - 0x9e, 0xb6, 0x0b, 0x1c, 0x72, 0x0b, 0x72, 0x3c, 0x7e, 0xaf, 0x52, 0x52, 0x6f, 0x2b, 0x02, 0x84, - 0x25, 0xe2, 0x5f, 0x25, 0xa2, 0x12, 0xaf, 0xf5, 0x19, 0xc8, 0x8b, 0x25, 0x29, 0x7a, 0x13, 0x02, - 0x6f, 0x8a, 0x2b, 0x25, 0x4b, 0x5d, 0x46, 0xea, 0x6e, 0xc3, 0xb7, 0x10, 0x6a, 0x7e, 0xcf, 0x80, - 0xf3, 0xeb, 0x34, 0x7c, 0xe8, 0xf9, 0xf7, 0x2d, 0x1a, 0x84, 0xbe, 0xcb, 0x9f, 0x98, 0xc0, 0x89, - 0xf8, 0x59, 0xf2, 0x0e, 0x8c, 0xa2, 0xf7, 0x4d, 0x62, 0x67, 0x48, 0xd6, 0xb1, 0x3c, 0x2d, 0x04, - 0x78, 0x14, 0x5d, 0x79, 0x2c, 0x4e, 0x44, 0xde, 0x82, 0x91, 0x12, 0x6d, 0x1f, 0x26, 0xde, 0x1a, - 0xe8, 0x21, 0x8e, 0x16, 0x84, 0x06, 0x6d, 0x1f, 0x5a, 0x48, 0x62, 0xfe, 0x52, 0x06, 0xce, 0xa4, - 0x34, 0x6b, 0xfb, 0xb3, 0xcf, 0xe8, 0xaa, 0xb8, 0xac, 0xad, 0x8a, 0x17, 0x05, 0x69, 0xdf, 0x8e, - 0x4f, 0x5d, 0x24, 0xff, 0x9a, 0x01, 0xe7, 0x74, 0x01, 0x15, 0xee, 0x76, 0xdb, 0xb7, 0xc8, 0xdb, - 0x30, 0xb6, 0x42, 0x9d, 0x06, 0x95, 0xa9, 0xcb, 0xe3, 0xe7, 0xba, 0x79, 0x70, 0x12, 0x2f, 0xe4, - 0x6c, 0xff, 0x80, 0xaf, 0x61, 0xa7, 0x2c, 0x41, 0x42, 0x4a, 0xa2, 0x71, 0x5c, 0x1f, 0x37, 0x65, - 0xa0, 0x60, 0x5a, 0x55, 0x03, 0xee, 0xd9, 0x7f, 0x60, 0xc0, 0x73, 0x03, 0x68, 0xd8, 0xc0, 0xb1, - 0xa1, 0x57, 0x07, 0x0e, 0x77, 0x54, 0x84, 0x92, 0xf7, 0x60, 0x76, 0x53, 0xe8, 0xf3, 0x72, 0x38, - 0x32, 0xf1, 0x7c, 0x91, 0xaa, 0xbe, 0x2d, 0xc7, 0x25, 0x89, 0xac, 0x45, 0xb0, 0x66, 0x07, 0x46, - 0xb0, 0xaa, 0x01, 0xa1, 0x23, 0xc3, 0x06, 0x84, 0x7e, 0x98, 0x7c, 0xf9, 0x53, 0xe4, 0xe5, 0x8a, - 0xc3, 0x61, 0x8d, 0xfe, 0xe1, 0xb0, 0x03, 0xb3, 0xff, 0xe0, 0x4b, 0x07, 0x3a, 0xef, 0x27, 0x1d, - 0xcf, 0x77, 0xb5, 0xf1, 0x7c, 0x2e, 0x7d, 0x3c, 0xfb, 0x0f, 0xe4, 0xdf, 0x30, 0x92, 0x1f, 0x3b, - 0xd4, 0x08, 0x9a, 0x30, 0x56, 0xf2, 0x5a, 0x8e, 0xdb, 0x56, 0xdf, 0x38, 0x6b, 0x20, 0xc4, 0x12, - 0x25, 0xc3, 0x45, 0x0f, 0x5f, 0x84, 0xd1, 0x75, 0xaf, 0x5d, 0x28, 0x09, 0xdf, 0x3a, 0xe4, 0xd3, - 0xf6, 0xda, 0xb6, 0xd3, 0xb0, 0x78, 0x81, 0xf9, 0x33, 0xa3, 0x70, 0xde, 0xa2, 0xfb, 0x2e, 0xd3, - 0x38, 0xb7, 0x02, 0xb7, 0xbd, 0xaf, 0x85, 0x4a, 0x9a, 0x89, 0x31, 0x11, 0xf9, 0x2a, 0x19, 0x24, - 0xaa, 0xe3, 0x2a, 0xe4, 0xd8, 0x06, 0xa3, 0x0c, 0x0b, 0x5e, 0x47, 0xe0, 0x2b, 0x8c, 0x5c, 0x5e, - 0x64, 0x31, 0xb9, 0x26, 0x36, 0x40, 0x25, 0xa3, 0x30, 0xdb, 0x00, 0x7f, 0x78, 0xb4, 0x08, 0xb5, - 0xc3, 0x20, 0xa4, 0x78, 0xf8, 0x11, 0x9b, 0x60, 0xa4, 0xa5, 0x8e, 0xf4, 0xd1, 0x52, 0xd7, 0x60, - 0xbe, 0xd0, 0xe0, 0xeb, 0x9e, 0xd3, 0xac, 0xfa, 0x6e, 0xbb, 0xee, 0x76, 0x9c, 0xa6, 0x3c, 0x79, - 0xe1, 0xa5, 0x94, 0x13, 0x95, 0xdb, 0x9d, 0x08, 0xc1, 0x4a, 0x25, 0x63, 0x9f, 0x51, 0x5a, 0xaf, - 0xf1, 0x17, 0x86, 0xf9, 0x4d, 0x13, 0x7e, 0x46, 0xa3, 0x1d, 0xf0, 0x27, 0x86, 0xad, 0xa8, 0x18, - 0xf5, 0x63, 0xbc, 0xce, 0xdf, 0x5c, 0xad, 0xc5, 0x61, 0x1b, 0x3c, 0xe1, 0x21, 0xbf, 0xf2, 0x0f, - 0x9b, 0x01, 0x5e, 0xfb, 0x6b, 0x78, 0x31, 0x5d, 0xad, 0xb6, 0xc2, 0xe8, 0x72, 0x3d, 0x74, 0x41, - 0x70, 0xa0, 0xd2, 0x71, 0x3c, 0x72, 0x03, 0x80, 0xa7, 0xea, 0x41, 0x91, 0x99, 0x88, 0xb5, 0x69, - 0x1f, 0xa1, 0x5c, 0x9b, 0x56, 0x50, 0xc8, 0x3b, 0x70, 0xba, 0x5c, 0x5c, 0x92, 0xf6, 0xc1, 0x92, - 0x57, 0xef, 0xe2, 0x05, 0x2d, 0x60, 0x7d, 0x38, 0x86, 0xb4, 0xbe, 0xc4, 0xe4, 0x24, 0x0d, 0x8d, - 0x5c, 0x86, 0xf1, 0x4a, 0x89, 0xf7, 0xfd, 0xa4, 0x9a, 0xd5, 0x5b, 0x38, 0x3e, 0xc8, 0x42, 0xb2, - 0x11, 0xab, 0x7b, 0x53, 0xc7, 0xea, 0x65, 0xe7, 0x8f, 0x57, 0xf5, 0x44, 0xf2, 0x6f, 0xfe, 0xc8, - 0x44, 0xd1, 0x6b, 0xd0, 0x60, 0xfb, 0xe6, 0xa7, 0x2c, 0xf9, 0xb7, 0xf2, 0x6d, 0xb8, 0x10, 0xdc, - 0x4c, 0x5d, 0x35, 0xfe, 0x7d, 0x4c, 0xfe, 0xdd, 0x83, 0x4b, 0x3e, 0x0f, 0xa3, 0xf8, 0x53, 0xa8, - 0x10, 0xa7, 0x53, 0xd8, 0xc6, 0xea, 0x43, 0x9d, 0x3f, 0xf7, 0x87, 0x04, 0xa4, 0x02, 0xe3, 0x42, - 0x7b, 0x3d, 0x49, 0x0a, 0x5b, 0xa1, 0x06, 0xf3, 0x41, 0x12, 0xf4, 0x66, 0x03, 0xa6, 0xd4, 0x0a, - 0x99, 0x70, 0xae, 0x38, 0xc1, 0x01, 0x6d, 0xb0, 0x5f, 0x22, 0xfb, 0x3c, 0x0a, 0xe7, 0x01, 0x42, - 0x6d, 0xd6, 0x0e, 0x4b, 0x41, 0x61, 0x0b, 0x57, 0x25, 0xd8, 0x0a, 0x44, 0x53, 0xc4, 0x79, 0xd6, - 0x45, 0xdb, 0x48, 0xc3, 0x12, 0x45, 0xe6, 0x57, 0x60, 0x7e, 0xbd, 0xdb, 0x6c, 0xb2, 0xb3, 0xad, - 0xcc, 0x4e, 0x1a, 0x3a, 0x21, 0x25, 0xcb, 0x30, 0x8a, 0x7f, 0x60, 0x45, 0x33, 0x51, 0x17, 0xa8, - 0x38, 0xe8, 0x6b, 0x65, 0x60, 0xa0, 0x65, 0xa8, 0xbf, 0xbf, 0xcd, 0x49, 0xcd, 0xdf, 0x8f, 0x1f, - 0x9e, 0xdc, 0xf4, 0x9d, 0xfa, 0x7d, 0xea, 0x8b, 0x1d, 0x68, 0xd8, 0x87, 0x31, 0x3f, 0x90, 0x8d, - 0xd0, 0x77, 0x85, 0xb4, 0x06, 0x1f, 0xd7, 0x18, 0xf2, 0x0e, 0x4c, 0x8a, 0x9d, 0x41, 0x49, 0x0f, - 0x82, 0x31, 0xd8, 0xf2, 0x79, 0xd1, 0xc4, 0xcd, 0xbd, 0x8a, 0x8e, 0x1b, 0x9e, 0xfe, 0x29, 0xdb, - 0x37, 0x3f, 0x89, 0x0d, 0x4f, 0xaf, 0x63, 0x80, 0xe8, 0xfe, 0x43, 0x48, 0xf6, 0xad, 0x90, 0xdd, - 0xdb, 0x6a, 0x42, 0x00, 0x23, 0x3e, 0x7e, 0xc4, 0x09, 0x01, 0xd4, 0xe3, 0x47, 0x84, 0x1a, 0x8d, - 0x49, 0xe6, 0x98, 0x31, 0x79, 0x4f, 0x8e, 0x49, 0xb6, 0xbf, 0x60, 0x9c, 0x1e, 0x30, 0x0e, 0xb5, - 0x78, 0x86, 0x8c, 0x0c, 0x75, 0x76, 0x3d, 0x85, 0x99, 0x0f, 0x39, 0x49, 0x72, 0x41, 0x13, 0x9c, - 0xd4, 0x03, 0xf1, 0xe8, 0xf0, 0x4c, 0x8f, 0x39, 0x10, 0x7f, 0x01, 0xa6, 0x0a, 0x61, 0xe8, 0xd4, - 0x0f, 0x68, 0xa3, 0xc4, 0x96, 0x27, 0x25, 0x76, 0xd9, 0x11, 0x70, 0xf5, 0x66, 0x42, 0xc5, 0xe5, - 0xb9, 0x78, 0x9c, 0x40, 0x38, 0x8e, 0x45, 0xb9, 0x78, 0x18, 0x44, 0xcf, 0xc5, 0xc3, 0x20, 0xe4, - 0x06, 0x8c, 0x57, 0xda, 0x0f, 0x5c, 0xd6, 0x27, 0xb9, 0xf8, 0x31, 0x3d, 0x97, 0x83, 0xd4, 0xc5, - 0x55, 0x60, 0x91, 0xb7, 0x14, 0xcd, 0x71, 0x22, 0x3e, 0x25, 0x72, 0xbb, 0x82, 0x2d, 0x15, 0x48, - 0x55, 0x2b, 0x8c, 0x54, 0xc9, 0xdb, 0x30, 0x2e, 0xcd, 0x45, 0x10, 0x9f, 0x0c, 0x05, 0x65, 0x6f, - 0x84, 0x9a, 0x44, 0xc6, 0x77, 0xac, 0x94, 0x2c, 0xfa, 0x93, 0xca, 0x3b, 0x56, 0x4a, 0x16, 0x7d, - 0xed, 0x1d, 0x2b, 0x25, 0x9f, 0x7e, 0x74, 0xd2, 0x9e, 0x3a, 0xf6, 0xa4, 0xbd, 0x0d, 0x53, 0x55, - 0xc7, 0x0f, 0x5d, 0xa6, 0x2e, 0xb4, 0xc3, 0x60, 0x61, 0x5a, 0x33, 0x4e, 0x29, 0x45, 0xcb, 0x2f, - 0xca, 0xf7, 0x9c, 0x3a, 0x0a, 0xbe, 0xfe, 0x10, 0x50, 0x0c, 0x4f, 0x77, 0x1b, 0x9b, 0x79, 0x12, - 0xb7, 0x31, 0xec, 0x54, 0x34, 0x48, 0xcc, 0xc6, 0xc7, 0x5e, 0xd4, 0x0c, 0x13, 0x56, 0x89, 0x08, - 0x91, 0x7c, 0x0d, 0xa6, 0xd8, 0xdf, 0xf8, 0x3a, 0xad, 0x4b, 0x83, 0x85, 0x3c, 0x7e, 0xdc, 0x8b, - 0xa9, 0xb3, 0x9f, 0x3f, 0x61, 0x5b, 0xa3, 0x21, 0x9f, 0xc0, 0xc8, 0x38, 0x69, 0x69, 0xd4, 0xb8, - 0x91, 0xf7, 0x61, 0x4a, 0x3e, 0xc0, 0x8c, 0x83, 0x34, 0x17, 0x3b, 0xfe, 0x35, 0x04, 0xbc, 0x27, - 0x1d, 0x96, 0x4a, 0xc0, 0xb6, 0xf9, 0x42, 0x87, 0x2f, 0x90, 0x44, 0x91, 0xf6, 0x4e, 0xcf, 0xe2, - 0x28, 0xd1, 0xc8, 0x17, 0x61, 0xaa, 0xd0, 0xe9, 0xc4, 0x2b, 0xce, 0x69, 0xc5, 0xda, 0xd0, 0xe9, - 0xd8, 0xa9, 0xab, 0x8e, 0x46, 0x91, 0x5c, 0x98, 0xe7, 0x4f, 0xb4, 0x30, 0x93, 0x37, 0x22, 0xc5, - 0xf9, 0x4c, 0x6c, 0x3a, 0x13, 0xda, 0xb9, 0x3a, 0xd3, 0x38, 0x92, 0xf9, 0xc7, 0x06, 0x9c, 0xeb, - 0xd3, 0xcb, 0x51, 0xe6, 0x28, 0x63, 0x70, 0xe6, 0x28, 0x36, 0x5b, 0xf5, 0xe3, 0x1e, 0xd6, 0x29, - 0x34, 0x1b, 0xb5, 0x8f, 0xa4, 0x8e, 0xe3, 0x01, 0x11, 0x0f, 0x2f, 0x2b, 0x0f, 0x14, 0x8b, 0xf4, - 0x85, 0x89, 0x85, 0x5f, 0x7b, 0xa0, 0x99, 0xbf, 0xf0, 0xed, 0x73, 0x50, 0xd4, 0x95, 0x1f, 0x79, - 0xda, 0xac, 0x49, 0x61, 0x6d, 0x1e, 0x19, 0x30, 0xa9, 0xc8, 0x3e, 0xb9, 0xa8, 0xc4, 0x19, 0xe5, - 0x79, 0x3a, 0x6a, 0x85, 0x43, 0x86, 0xaf, 0xfe, 0x28, 0xc8, 0x99, 0xe3, 0x2d, 0x6b, 0x6b, 0x4c, - 0xfd, 0x50, 0xb2, 0x6b, 0xb5, 0x34, 0x33, 0x98, 0x85, 0xe5, 0xf8, 0xf4, 0x9b, 0x13, 0x84, 0x85, - 0x7a, 0xe8, 0x3e, 0xa0, 0x43, 0x2c, 0xf4, 0xf1, 0xd3, 0x6f, 0x4e, 0x10, 0xda, 0x0e, 0x92, 0xf5, - 0x3c, 0xfd, 0x16, 0x31, 0x34, 0xff, 0x82, 0x01, 0xb0, 0x55, 0x29, 0x62, 0x7a, 0xbc, 0x27, 0xdd, - 0x88, 0xd3, 0x53, 0x0e, 0x49, 0xee, 0x03, 0xb6, 0xe0, 0x2a, 0xcc, 0xe8, 0x58, 0xe4, 0x3d, 0x98, - 0xad, 0xd5, 0x7d, 0xaf, 0xd9, 0xdc, 0x75, 0xea, 0xf7, 0x57, 0xdd, 0x36, 0xe5, 0xb9, 0x5e, 0x46, - 0xf9, 0xf2, 0x1f, 0x44, 0x45, 0x76, 0x93, 0x95, 0x59, 0x49, 0x64, 0xf3, 0x4f, 0x0d, 0x98, 0xac, - 0xb4, 0x83, 0xd0, 0x69, 0x36, 0x51, 0xc1, 0xf8, 0x34, 0xbd, 0x48, 0x10, 0x7d, 0xd7, 0x80, 0x1e, - 0x7d, 0x13, 0x66, 0x13, 0x68, 0xec, 0x60, 0x5c, 0xc3, 0x30, 0x48, 0xf5, 0x60, 0xcc, 0x03, 0x23, - 0x2d, 0x51, 0x62, 0x96, 0x15, 0xb2, 0xed, 0x9b, 0x78, 0x51, 0xb4, 0x04, 0xe0, 0x4a, 0x90, 0x54, - 0xe3, 0x49, 0xb2, 0x25, 0xdb, 0x37, 0x2d, 0x05, 0xcb, 0x5c, 0x87, 0xb1, 0x9a, 0xe7, 0x87, 0xcb, - 0x87, 0x5c, 0x73, 0x2e, 0xd1, 0xa0, 0xae, 0xde, 0x04, 0xb9, 0x68, 0x7d, 0xad, 0x5b, 0xa2, 0x88, - 0x9d, 0x9b, 0xef, 0xb8, 0xb4, 0xd9, 0x50, 0x5d, 0xfe, 0xf6, 0x18, 0xc0, 0xe2, 0x70, 0x76, 0xba, - 0x38, 0x1b, 0xa7, 0x6f, 0x8d, 0x7d, 0x0b, 0x9f, 0x54, 0x60, 0x8b, 0x5a, 0xff, 0xbe, 0xa4, 0x3f, - 0xf8, 0xa7, 0xd5, 0x34, 0xa0, 0xab, 0xff, 0x9e, 0x01, 0x17, 0xfa, 0x93, 0xa8, 0xee, 0x8a, 0xc6, - 0x00, 0x77, 0xc5, 0x57, 0x92, 0x37, 0x17, 0x88, 0x26, 0x6e, 0x2e, 0xe2, 0xfb, 0x8a, 0x12, 0x7a, - 0x8b, 0xd6, 0xa3, 0xc7, 0x55, 0x2f, 0x0e, 0x68, 0x33, 0x22, 0xf2, 0x61, 0x0e, 0x91, 0xc6, 0x12, - 0xb4, 0xe6, 0xef, 0x8c, 0xc0, 0xf9, 0xbe, 0x14, 0x64, 0x45, 0xc9, 0x04, 0x3d, 0x13, 0xe5, 0xa0, - 0xed, 0x8b, 0x7f, 0x1d, 0xff, 0x45, 0x87, 0xa0, 0x64, 0x10, 0xc3, 0x46, 0x94, 0x01, 0x38, 0x83, - 0xbc, 0x5e, 0x3b, 0x96, 0x17, 0x47, 0x47, 0x66, 0xd0, 0x9b, 0x0c, 0x18, 0x63, 0x4d, 0x68, 0xe8, - 0xb8, 0xcd, 0x40, 0x9d, 0x76, 0x0d, 0x0e, 0xb2, 0x64, 0x59, 0xec, 0x43, 0x3a, 0x92, 0xee, 0x43, - 0x6a, 0xfe, 0x5f, 0x06, 0x4c, 0x44, 0xcd, 0x26, 0x17, 0xe0, 0xec, 0xa6, 0x55, 0x28, 0x96, 0xed, - 0xcd, 0x0f, 0xab, 0x65, 0x7b, 0x6b, 0xbd, 0x56, 0x2d, 0x17, 0x2b, 0x77, 0x2a, 0xe5, 0x52, 0xfe, - 0x14, 0x99, 0x83, 0xe9, 0xad, 0xf5, 0x7b, 0xeb, 0x1b, 0x3b, 0xeb, 0x76, 0xd9, 0xb2, 0x36, 0xac, - 0xbc, 0x41, 0xa6, 0x61, 0xc2, 0x5a, 0x2e, 0x14, 0xed, 0xf5, 0x8d, 0x52, 0x39, 0x9f, 0x21, 0x79, - 0x98, 0x2a, 0x6e, 0xac, 0xaf, 0x97, 0x8b, 0x9b, 0x95, 0xed, 0xca, 0xe6, 0x87, 0xf9, 0x2c, 0x21, - 0x30, 0x83, 0x08, 0x55, 0xab, 0xb2, 0x5e, 0xac, 0x54, 0x0b, 0xab, 0xf9, 0x11, 0x06, 0x63, 0xf8, - 0x0a, 0x6c, 0x34, 0x62, 0x74, 0x6f, 0x6b, 0xb9, 0x9c, 0x1f, 0x63, 0x28, 0xec, 0x2f, 0x05, 0x65, - 0x9c, 0x55, 0x8f, 0x28, 0xa5, 0xc2, 0x66, 0x61, 0xb9, 0x50, 0x2b, 0xe7, 0x73, 0xe4, 0x1c, 0x9c, - 0xd6, 0x40, 0xf6, 0xea, 0xc6, 0xdd, 0xca, 0x7a, 0x7e, 0x82, 0xcc, 0x43, 0x3e, 0x82, 0x95, 0x96, - 0xed, 0xad, 0x5a, 0xd9, 0xca, 0x43, 0x12, 0xba, 0x5e, 0x58, 0x2b, 0xe7, 0x27, 0xcd, 0x77, 0x79, - 0x78, 0x09, 0xef, 0x6a, 0x72, 0x16, 0x48, 0x6d, 0xb3, 0xb0, 0xb9, 0x55, 0x4b, 0x7c, 0xfc, 0x24, - 0x8c, 0xd7, 0xb6, 0x8a, 0xc5, 0x72, 0xad, 0x96, 0x37, 0x08, 0xc0, 0xd8, 0x9d, 0x42, 0x65, 0xb5, - 0x5c, 0xca, 0x67, 0xcc, 0x5f, 0x34, 0x60, 0x4e, 0xaa, 0x3b, 0xd2, 0x0c, 0xfd, 0x84, 0x73, 0xf1, - 0x3d, 0xed, 0x14, 0x27, 0xbd, 0xff, 0x13, 0x95, 0x0c, 0x98, 0x86, 0x3e, 0x9c, 0x49, 0x45, 0x26, - 0x1f, 0x42, 0x5e, 0x36, 0x60, 0xcd, 0x09, 0xeb, 0x07, 0xf1, 0x32, 0xf6, 0x62, 0xa2, 0x92, 0x04, - 0x1a, 0xb7, 0xa6, 0xc5, 0x4f, 0x1e, 0xf5, 0xb0, 0x31, 0xbf, 0x01, 0xe7, 0xfa, 0xd0, 0x92, 0x22, - 0x8c, 0x45, 0x79, 0x71, 0x07, 0xf8, 0xb9, 0xcc, 0xff, 0xe0, 0x68, 0x51, 0x20, 0xe2, 0xc3, 0x2f, - 0xf8, 0x97, 0x25, 0x20, 0xe6, 0x5f, 0x32, 0x60, 0x4a, 0x28, 0xc9, 0x85, 0x26, 0xf5, 0xc3, 0x27, - 0xeb, 0xe1, 0xb7, 0xb4, 0x1e, 0x8e, 0xbc, 0xa0, 0x15, 0xfe, 0xac, 0x38, 0xb5, 0x73, 0xff, 0x4b, - 0x03, 0xf2, 0x49, 0x44, 0xf2, 0x1e, 0xe4, 0x6a, 0xf4, 0x01, 0xf5, 0xdd, 0xf0, 0x50, 0xac, 0x15, - 0x32, 0xe1, 0x3e, 0xc7, 0x11, 0x65, 0xdc, 0x16, 0x17, 0x88, 0x5f, 0x56, 0x44, 0x33, 0xec, 0x92, - 0xa7, 0x1c, 0x73, 0xb3, 0x4f, 0xeb, 0x98, 0x6b, 0xfe, 0x9b, 0x0c, 0x9c, 0xbb, 0x4b, 0x43, 0xf5, - 0x9b, 0xa2, 0x3b, 0xbb, 0xcf, 0x0c, 0xf7, 0x5d, 0xca, 0x97, 0x2c, 0xc0, 0x38, 0x16, 0xc9, 0x08, - 0x73, 0x4b, 0xfe, 0x24, 0xcb, 0x91, 0x18, 0x64, 0xb5, 0x8c, 0xde, 0x7d, 0xea, 0xbe, 0xae, 0xe4, - 0xf8, 0x95, 0x52, 0x40, 0x2e, 0xc3, 0x0c, 0x26, 0xb1, 0xeb, 0x32, 0xe9, 0xa1, 0x0d, 0x71, 0xdc, - 0xcf, 0x59, 0x09, 0x28, 0xb9, 0x06, 0x79, 0x06, 0x29, 0xd4, 0xef, 0xb7, 0xbd, 0x87, 0x4d, 0xda, - 0xd8, 0xa7, 0xfc, 0x81, 0xd1, 0x9c, 0xd5, 0x03, 0x97, 0x3c, 0xb7, 0xda, 0xfc, 0xb8, 0x4a, 0x1b, - 0x78, 0x26, 0x17, 0x3c, 0x63, 0xe8, 0x85, 0xb7, 0x60, 0xf2, 0x63, 0xe6, 0xeb, 0x36, 0xff, 0x7b, - 0x03, 0xe6, 0xf1, 0xe3, 0x94, 0x8a, 0xd1, 0x58, 0xfb, 0x99, 0xb8, 0xb7, 0x94, 0x14, 0xb6, 0x0e, - 0x03, 0xe9, 0x47, 0x8d, 0xa8, 0x17, 0x63, 0x1b, 0x40, 0x66, 0x08, 0x1b, 0x40, 0xed, 0x24, 0xef, - 0x91, 0x0d, 0x69, 0xc2, 0xe0, 0xaf, 0xc8, 0xc6, 0x43, 0x6e, 0xfe, 0xc5, 0x0c, 0x8c, 0x5b, 0x14, - 0x1f, 0x6a, 0x22, 0x97, 0x61, 0x7c, 0xdd, 0x0b, 0x69, 0xb0, 0xa6, 0xbd, 0xca, 0xd5, 0x66, 0x20, - 0xbb, 0xd5, 0xb0, 0x64, 0x21, 0x13, 0xf8, 0xaa, 0xef, 0x35, 0xba, 0xf5, 0x50, 0x15, 0xf8, 0x0e, - 0x07, 0x59, 0xb2, 0x8c, 0xbc, 0x0e, 0x13, 0x82, 0x73, 0x74, 0x53, 0x82, 0x1e, 0x7e, 0x3e, 0x8d, - 0x1e, 0xfa, 0x8a, 0x11, 0x50, 0xad, 0xe3, 0x7b, 0xec, 0x88, 0xa2, 0xd6, 0xf5, 0x6c, 0x9b, 0x52, - 0x5b, 0x1d, 0x1d, 0xa0, 0xad, 0x7e, 0x06, 0xc6, 0x0a, 0x41, 0x40, 0x43, 0x19, 0x9c, 0x39, 0x15, - 0x25, 0x84, 0x08, 0x68, 0xc8, 0x19, 0x3b, 0x58, 0x6e, 0x09, 0x3c, 0xf3, 0x4f, 0x32, 0x30, 0x8a, - 0x7f, 0xe2, 0xed, 0x90, 0x5f, 0x3f, 0xd0, 0x6e, 0x87, 0xfc, 0xfa, 0x81, 0x85, 0x50, 0x72, 0x13, - 0x4f, 0xa6, 0x32, 0xdb, 0xb2, 0xf8, 0x7a, 0x34, 0xb9, 0x36, 0x62, 0xb0, 0xa5, 0xe2, 0x44, 0xd7, - 0x66, 0xd9, 0xd4, 0x90, 0xec, 0xb3, 0x90, 0xd9, 0xa8, 0x89, 0x2f, 0xc6, 0x7c, 0x0f, 0x5e, 0x60, - 0x65, 0x36, 0x6a, 0xd8, 0x1b, 0x2b, 0x85, 0xa5, 0x37, 0x6f, 0xab, 0x0f, 0xc8, 0x05, 0x07, 0xce, - 0xd2, 0x9b, 0xb7, 0x2d, 0x51, 0xc2, 0xfa, 0x17, 0xdb, 0x5c, 0x73, 0xbf, 0x4d, 0x45, 0x3c, 0x23, - 0xf6, 0x2f, 0x7e, 0x9b, 0x1d, 0xb8, 0xdf, 0xa6, 0x56, 0x8c, 0x40, 0x96, 0x60, 0x52, 0x84, 0xb0, - 0x22, 0xbe, 0x12, 0x62, 0x2a, 0x42, 0x5c, 0x39, 0x85, 0x8a, 0xc4, 0x6f, 0x3f, 0xc4, 0x00, 0xc9, - 0x37, 0x61, 0xc4, 0xed, 0x87, 0x1c, 0xc2, 0xc0, 0x52, 0x50, 0xe2, 0x70, 0xcc, 0x38, 0x4e, 0x51, - 0x0d, 0xc7, 0xc4, 0xa4, 0x84, 0x11, 0x82, 0xf9, 0x1b, 0x19, 0xc8, 0x55, 0x9b, 0xdd, 0x7d, 0xb7, - 0xbd, 0x7d, 0xf3, 0xcf, 0xf4, 0x11, 0xe3, 0x37, 0x00, 0x37, 0x09, 0xa1, 0x3f, 0x4b, 0x03, 0x26, - 0x6f, 0x9a, 0xd8, 0xaa, 0x39, 0x09, 0xa2, 0x91, 0x5b, 0x20, 0x04, 0x53, 0xbc, 0x69, 0x75, 0x46, - 0x27, 0xe0, 0xaf, 0x39, 0x48, 0x12, 0x81, 0x4a, 0xde, 0x81, 0xc9, 0xf8, 0x35, 0xd9, 0xf8, 0xa9, - 0x2a, 0x95, 0xb2, 0x18, 0x97, 0x6f, 0xdf, 0xb4, 0x54, 0x74, 0xf3, 0x0f, 0x32, 0x30, 0xa5, 0xb6, - 0x87, 0x58, 0x70, 0x3a, 0x68, 0xb2, 0x83, 0xa3, 0xf0, 0xe0, 0xe8, 0x60, 0xa1, 0xd8, 0x4e, 0x2f, - 0xea, 0x0d, 0x62, 0x78, 0xdc, 0x9d, 0xa3, 0x46, 0xc3, 0xd0, 0x6d, 0xef, 0x07, 0x2b, 0xa7, 0xac, - 0xb9, 0x20, 0x06, 0x73, 0x3c, 0x52, 0x80, 0x9c, 0xd7, 0x09, 0xf6, 0x69, 0xdb, 0x95, 0xf6, 0xf5, - 0x4b, 0x1a, 0xa3, 0x0d, 0x51, 0xd8, 0xc3, 0x2b, 0x22, 0x23, 0x6f, 0xc2, 0x98, 0xd7, 0xa1, 0x6d, - 0xc7, 0x15, 0x7b, 0xdc, 0x73, 0x09, 0x06, 0xb4, 0x5d, 0xa8, 0x28, 0x84, 0x02, 0x99, 0xdc, 0x80, - 0x11, 0xef, 0x7e, 0x34, 0x5e, 0xe7, 0x75, 0xa2, 0xfb, 0xa1, 0xa3, 0x90, 0x20, 0x22, 0x23, 0xf8, - 0xc8, 0x69, 0xed, 0x89, 0x11, 0xd3, 0x09, 0x3e, 0x70, 0x5a, 0x7b, 0x2a, 0x01, 0x43, 0xfc, 0xc2, - 0xc8, 0xff, 0xf2, 0x6b, 0x8b, 0xc6, 0x32, 0x40, 0x2e, 0x10, 0x25, 0xe6, 0x2a, 0x9c, 0xef, 0xdb, - 0x3f, 0xe4, 0x2a, 0xe4, 0xf7, 0x1c, 0x71, 0x34, 0xaf, 0x1f, 0x38, 0xed, 0x36, 0x6d, 0x0a, 0xc9, - 0x9c, 0x95, 0xf0, 0x22, 0x07, 0x73, 0xce, 0xe6, 0x3f, 0x36, 0xe0, 0xf9, 0x41, 0xbd, 0x44, 0x2e, - 0x40, 0xae, 0xe3, 0xbb, 0x1e, 0xee, 0xc6, 0x5c, 0x96, 0xa3, 0xdf, 0xe4, 0x05, 0x00, 0xbe, 0x6d, - 0x84, 0xce, 0xbe, 0x70, 0x0e, 0xb5, 0x26, 0x10, 0xb2, 0xe9, 0xec, 0x07, 0xe4, 0x35, 0x98, 0x6b, - 0xd0, 0x3d, 0xa7, 0xdb, 0x0c, 0xed, 0xa0, 0x7e, 0x40, 0x1b, 0xe8, 0x8f, 0x8d, 0x97, 0xfe, 0x56, - 0x5e, 0x14, 0xd4, 0x24, 0x9c, 0xbc, 0x04, 0x53, 0x6a, 0xf0, 0xb7, 0x78, 0x9a, 0x7b, 0xd2, 0xe9, - 0xb8, 0x32, 0xfc, 0x9b, 0xb7, 0xf8, 0x83, 0x91, 0x9c, 0x91, 0xcf, 0x58, 0x78, 0xf7, 0x6d, 0x3e, - 0x0f, 0xf3, 0x69, 0x23, 0x24, 0xbe, 0xed, 0x03, 0x20, 0xbd, 0x3d, 0x4b, 0xae, 0xc3, 0x04, 0xeb, - 0x59, 0x8c, 0x59, 0x4d, 0x78, 0xb8, 0x21, 0x1e, 0xca, 0xa9, 0x95, 0xfb, 0x48, 0xfc, 0x2d, 0x78, - 0xdd, 0x92, 0xbc, 0xd4, 0x61, 0x25, 0xe7, 0x60, 0xdc, 0xf3, 0xf7, 0xd9, 0xfa, 0x20, 0x7a, 0x79, - 0xcc, 0xf3, 0xf7, 0xb7, 0x7c, 0xd9, 0xb9, 0x7f, 0x3b, 0x23, 0x3b, 0x77, 0xd9, 0xf3, 0xc2, 0x20, - 0xf4, 0x9d, 0x8e, 0x36, 0x57, 0x48, 0x0b, 0xce, 0x7b, 0x4e, 0x37, 0x3c, 0x58, 0xb2, 0xd9, 0xbf, - 0x9e, 0x2f, 0x3d, 0xa5, 0xeb, 0xf2, 0x62, 0x6c, 0x72, 0xe9, 0x86, 0x2e, 0x54, 0x05, 0x86, 0x5d, - 0x50, 0x91, 0x8b, 0x5e, 0x83, 0x2a, 0x5c, 0x57, 0x4e, 0x59, 0xe7, 0x38, 0xcf, 0x1e, 0x2c, 0xb2, - 0x02, 0xda, 0xeb, 0x77, 0xa9, 0x93, 0x45, 0x79, 0xa9, 0x4e, 0xe7, 0x3a, 0xb9, 0xab, 0x3c, 0x95, - 0xf7, 0x1e, 0x4c, 0xb8, 0x0d, 0x91, 0x16, 0x41, 0x4c, 0x99, 0x45, 0x8d, 0x4d, 0xa5, 0xc1, 0xb3, - 0x24, 0xc4, 0x3c, 0xd8, 0x7c, 0x73, 0x05, 0x74, 0x79, 0x5a, 0x5b, 0x55, 0xcc, 0x65, 0x58, 0xe8, - 0x47, 0x26, 0x5e, 0x6a, 0x37, 0xa2, 0x97, 0xda, 0xcf, 0xc2, 0x58, 0xa0, 0xe4, 0x69, 0xb0, 0xc4, - 0x2f, 0xf3, 0x47, 0xe1, 0xca, 0xb0, 0x7d, 0x84, 0x8f, 0x71, 0xa7, 0x77, 0xf8, 0x84, 0x35, 0xe7, - 0xf4, 0xf4, 0x1b, 0x3e, 0xc6, 0x1d, 0x85, 0xaa, 0xbb, 0xa2, 0xe2, 0x49, 0x09, 0xdb, 0xf2, 0x5d, - 0xf3, 0x5d, 0x98, 0xd1, 0x97, 0x51, 0xf2, 0x1a, 0x8c, 0x44, 0x5c, 0x67, 0x22, 0x75, 0x5f, 0x45, - 0x62, 0xbc, 0x2d, 0x44, 0x32, 0xff, 0xe7, 0x0c, 0x9c, 0x4e, 0x59, 0x4c, 0xc9, 0x57, 0xe1, 0xb4, - 0x14, 0x10, 0xbe, 0x5e, 0xf2, 0x81, 0xe3, 0xa2, 0x71, 0x35, 0x4d, 0x34, 0x10, 0x2d, 0x65, 0xf8, - 0xe6, 0x84, 0x50, 0xc4, 0xe5, 0x7f, 0x7e, 0xc4, 0x81, 0x7c, 0x08, 0x67, 0xc5, 0xd3, 0x39, 0x8a, - 0x54, 0xd8, 0x3e, 0xdd, 0x13, 0x2b, 0xeb, 0x4b, 0x3d, 0xbd, 0xe7, 0xd6, 0x95, 0xe6, 0x58, 0x74, - 0x6f, 0xe5, 0x94, 0x35, 0x1f, 0xa4, 0xc0, 0x93, 0x92, 0xf6, 0x77, 0x0d, 0x30, 0x8f, 0xef, 0x2f, - 0x5c, 0x8d, 0x92, 0x1d, 0xce, 0x56, 0x23, 0xa5, 0xf7, 0x2e, 0xc1, 0xb4, 0x4f, 0xf7, 0x7c, 0x1a, - 0x1c, 0x28, 0xdd, 0x37, 0x61, 0x4d, 0x09, 0xa0, 0xec, 0x18, 0x19, 0xec, 0x31, 0xc4, 0xe1, 0x29, - 0xc7, 0x36, 0x5e, 0xae, 0xf6, 0x0a, 0x22, 0xf3, 0x4e, 0xb4, 0x80, 0xa4, 0x8e, 0x03, 0x53, 0xff, - 0xd5, 0x06, 0xf2, 0x1f, 0x1f, 0x8c, 0xe4, 0x32, 0xf9, 0xac, 0x25, 0x42, 0x52, 0xf6, 0xdc, 0x26, - 0x35, 0xff, 0xa1, 0x01, 0x17, 0xfa, 0x77, 0x1e, 0xf9, 0xaa, 0x72, 0x5a, 0xce, 0xf2, 0x88, 0xfc, - 0x63, 0xfa, 0x5b, 0x3d, 0x29, 0x89, 0x28, 0x89, 0xe4, 0xab, 0x31, 0x82, 0xe5, 0x93, 0x9c, 0x61, - 0xde, 0x92, 0xda, 0xc3, 0xaa, 0x1b, 0x84, 0xdb, 0x37, 0xc9, 0x55, 0x18, 0xe7, 0x0a, 0x83, 0x6c, - 0xe8, 0xac, 0xd6, 0xd0, 0xed, 0x9b, 0x96, 0x2c, 0x37, 0xbf, 0x6f, 0x44, 0xfb, 0x64, 0xb2, 0xf9, - 0xdb, 0x37, 0xc9, 0xe7, 0x86, 0x3b, 0xc8, 0xe7, 0xe4, 0x41, 0x3e, 0x3a, 0xc4, 0x7f, 0x5e, 0x3b, - 0xc4, 0xbf, 0x3c, 0xb8, 0x9f, 0xc4, 0x5e, 0x92, 0xcc, 0xeb, 0xff, 0xef, 0x0c, 0x78, 0x61, 0x20, - 0x05, 0x79, 0x1e, 0x72, 0x85, 0x6a, 0x65, 0x33, 0x1e, 0x59, 0x36, 0x5b, 0x24, 0x84, 0xdc, 0x85, - 0x89, 0x65, 0x27, 0x70, 0xeb, 0x4c, 0x80, 0x45, 0x43, 0x5e, 0x1d, 0xdc, 0x90, 0x08, 0x7d, 0xe5, - 0x94, 0x15, 0xd3, 0x12, 0x1b, 0xe6, 0x70, 0x16, 0xf4, 0xe4, 0xcd, 0x4e, 0x6e, 0x3b, 0x3d, 0x0c, - 0x7b, 0xc8, 0xd8, 0x0a, 0xd3, 0x03, 0x4c, 0x4e, 0xbe, 0x07, 0x70, 0xf1, 0xb8, 0x06, 0x9e, 0x20, - 0xb0, 0xe9, 0x0a, 0xe4, 0xaa, 0x4e, 0x10, 0x3c, 0xf4, 0xfc, 0x86, 0xfa, 0x6c, 0x46, 0x47, 0xc0, - 0xac, 0xa8, 0xd4, 0xfc, 0x39, 0x43, 0xee, 0x0d, 0xc7, 0x7f, 0x88, 0x92, 0x38, 0xa8, 0x31, 0x38, - 0x71, 0x50, 0xe3, 0x63, 0x26, 0x0e, 0x32, 0x7f, 0x43, 0x84, 0x1d, 0x57, 0x1a, 0xd5, 0x44, 0xca, - 0xc6, 0x27, 0x35, 0xe2, 0x95, 0x35, 0xe9, 0xbc, 0xa4, 0x64, 0x20, 0xeb, 0xad, 0xab, 0xbf, 0x2d, - 0x4f, 0x11, 0xd5, 0x9f, 0x33, 0xe0, 0xf9, 0x41, 0xe4, 0xa9, 0xd9, 0x25, 0x8d, 0x93, 0x65, 0x97, - 0xbc, 0x0a, 0x39, 0x0e, 0xd3, 0x73, 0xbc, 0x0b, 0x52, 0xd6, 0xe1, 0xb2, 0xd8, 0x2c, 0x00, 0x54, - 0x1a, 0xd5, 0x8d, 0x0e, 0x0f, 0x7e, 0xbe, 0x05, 0x23, 0xac, 0x6d, 0x89, 0x8e, 0x62, 0x4d, 0x2d, - 0xac, 0xad, 0x0a, 0x24, 0x7e, 0x72, 0x0d, 0x9c, 0x56, 0xd3, 0x42, 0x64, 0x73, 0x07, 0x66, 0x74, - 0x0c, 0x52, 0xd6, 0xc3, 0x65, 0xe2, 0x67, 0xa9, 0x96, 0x3d, 0x8f, 0xdb, 0x09, 0x97, 0xcf, 0xff, - 0xe0, 0x68, 0x11, 0xd8, 0x4f, 0x4e, 0x93, 0x16, 0x4e, 0x63, 0x7e, 0x37, 0x03, 0xf3, 0xf1, 0xdd, - 0xba, 0x1c, 0xae, 0x67, 0xf6, 0xee, 0xab, 0xa0, 0xdd, 0xcd, 0x2c, 0xf6, 0xbc, 0xfc, 0x22, 0x3f, - 0x70, 0x80, 0x49, 0xf8, 0x2e, 0x2c, 0xf4, 0xc3, 0x27, 0xaf, 0xf5, 0xbc, 0xcd, 0x20, 0x7c, 0x40, - 0xa3, 0x47, 0x1c, 0x94, 0xa7, 0x1a, 0xfe, 0xa5, 0x01, 0x17, 0x84, 0xb9, 0x6e, 0xcd, 0x71, 0xdb, - 0xf8, 0x1e, 0x55, 0x9d, 0x3e, 0x9d, 0x4b, 0xd3, 0xbb, 0xda, 0x94, 0x79, 0x45, 0xb7, 0xca, 0xf6, - 0xd4, 0xd6, 0xff, 0x6b, 0xc9, 0x55, 0x74, 0x9c, 0xad, 0x73, 0x8b, 0xc9, 0x08, 0x77, 0x0c, 0x69, - 0x33, 0x80, 0xea, 0x18, 0x82, 0x18, 0xe6, 0x8f, 0xc3, 0x8b, 0x83, 0x2b, 0x20, 0x5f, 0x87, 0xe9, - 0xc2, 0x3e, 0x6d, 0x87, 0x5b, 0x9d, 0x7d, 0xdf, 0x69, 0x50, 0x69, 0xc5, 0x96, 0x07, 0x46, 0xb5, - 0x8c, 0x3b, 0x0b, 0x0b, 0x47, 0x05, 0x06, 0xb7, 0xbb, 0x82, 0x48, 0x0b, 0x8b, 0x50, 0xb9, 0x99, - 0x3f, 0x61, 0x00, 0xe9, 0xe5, 0x41, 0x6e, 0xc3, 0xd4, 0xd6, 0x66, 0xb1, 0x16, 0x3a, 0x7e, 0xb8, - 0xe2, 0x75, 0x79, 0x77, 0x4e, 0x8b, 0x3b, 0xf4, 0xb0, 0x6e, 0x07, 0xac, 0xc0, 0x3e, 0xf0, 0xba, - 0xbe, 0xa5, 0xe1, 0x61, 0x46, 0x1b, 0x4a, 0xef, 0x37, 0x9c, 0x43, 0x3d, 0xa3, 0x8d, 0x80, 0x69, - 0x19, 0x6d, 0x04, 0xcc, 0xfc, 0x9b, 0x06, 0x3c, 0x27, 0x4f, 0x7f, 0x8d, 0x94, 0xb6, 0x14, 0xd1, - 0x3b, 0xcb, 0x97, 0x41, 0x48, 0x83, 0xf4, 0xa6, 0x39, 0xe9, 0xc0, 0x88, 0x0d, 0x44, 0x05, 0x8a, - 0xd3, 0xe2, 0x63, 0x7c, 0xa1, 0xd7, 0x19, 0xc2, 0x83, 0x31, 0x1f, 0x8d, 0x68, 0xe8, 0x75, 0x90, - 0x05, 0x52, 0x9a, 0x14, 0xe6, 0xd5, 0xc6, 0xc9, 0x16, 0x93, 0x35, 0x18, 0x17, 0x5e, 0xda, 0x42, - 0x13, 0x91, 0x8e, 0xfb, 0x03, 0xbe, 0x69, 0x79, 0x56, 0xba, 0x49, 0x8a, 0x20, 0x18, 0x4b, 0xf2, - 0x30, 0x37, 0xf9, 0x33, 0xc0, 0x18, 0x16, 0xfa, 0x84, 0x12, 0xad, 0xac, 0xde, 0xff, 0x7f, 0x03, - 0xe6, 0xd9, 0x79, 0xb5, 0xd2, 0xea, 0x78, 0x7e, 0x68, 0x75, 0x9b, 0x72, 0xf6, 0xb1, 0xad, 0x53, - 0x1e, 0xea, 0xf9, 0xbd, 0x3e, 0xdf, 0x3a, 0x05, 0xcc, 0x8a, 0x4a, 0xc9, 0x0a, 0xe4, 0x44, 0x04, - 0x9d, 0x7c, 0x14, 0x53, 0xde, 0xda, 0xe8, 0x8c, 0x05, 0x12, 0x9b, 0x1b, 0xb8, 0xa0, 0x08, 0x1a, - 0x2b, 0xa2, 0x36, 0xff, 0xc4, 0x80, 0x73, 0x7d, 0x68, 0xc8, 0xbb, 0x30, 0x8a, 0x17, 0x37, 0xa2, - 0x2f, 0x9f, 0xef, 0x53, 0x45, 0x58, 0x3f, 0xd8, 0xbe, 0xc9, 0xaf, 0x13, 0x5b, 0xec, 0x87, 0xc5, - 0xa9, 0xc8, 0x57, 0x61, 0xa2, 0xd0, 0x68, 0x68, 0x4f, 0x77, 0xbe, 0x31, 0xb8, 0x95, 0xd7, 0x23, - 0x7c, 0xae, 0xc1, 0x72, 0x03, 0x64, 0xa3, 0x21, 0xde, 0x3e, 0xb4, 0x62, 0x7e, 0x17, 0xde, 0x81, - 0x19, 0x1d, 0xf9, 0x44, 0x1a, 0xec, 0xf7, 0x0d, 0xc8, 0xeb, 0x6d, 0xf8, 0x64, 0xdc, 0x2d, 0xd3, - 0x86, 0xf9, 0x98, 0xbd, 0xfd, 0x97, 0x32, 0x70, 0x26, 0xb5, 0x87, 0xc9, 0x1b, 0x30, 0x56, 0xe8, - 0x74, 0x2a, 0x25, 0x2e, 0xdb, 0x62, 0x2b, 0x77, 0x3a, 0x9d, 0x44, 0x80, 0x86, 0x40, 0x22, 0xb7, - 0x20, 0x87, 0x82, 0xcb, 0x08, 0x32, 0x71, 0x4c, 0x07, 0x46, 0x3e, 0x27, 0x63, 0x3a, 0x24, 0x22, - 0xb9, 0x03, 0x33, 0xc2, 0xf3, 0xca, 0xa2, 0xfb, 0xf4, 0x51, 0x14, 0x5c, 0x8c, 0xf1, 0xcf, 0xd2, - 0x4f, 0xcb, 0xf6, 0x79, 0x99, 0x1a, 0x25, 0xa6, 0x53, 0xe1, 0xcb, 0x1d, 0x8c, 0xa7, 0xca, 0x89, - 0x07, 0x96, 0xf0, 0x97, 0x3b, 0xb0, 0x11, 0x7d, 0x78, 0xf5, 0x50, 0x46, 0xc3, 0x55, 0x08, 0x02, - 0x77, 0xbf, 0xdd, 0xa2, 0xed, 0xf0, 0x93, 0x1b, 0xae, 0xb8, 0x8e, 0xa1, 0x86, 0xeb, 0x7b, 0x23, - 0x7c, 0x32, 0x27, 0xc9, 0x8e, 0x79, 0x9c, 0xaa, 0x04, 0xe3, 0x3c, 0xe6, 0x50, 0xce, 0x8c, 0x17, - 0x52, 0x9b, 0xc0, 0x71, 0xb6, 0x6f, 0x72, 0x65, 0x82, 0xdf, 0x3f, 0x05, 0x96, 0x24, 0x25, 0xdb, - 0x30, 0x59, 0x6c, 0x52, 0xa7, 0xdd, 0xed, 0x0c, 0xf9, 0xc6, 0xfc, 0x82, 0xf8, 0x96, 0xa9, 0x3a, - 0x27, 0x8b, 0x1f, 0x99, 0x57, 0x19, 0x91, 0xcd, 0xc8, 0x24, 0x3d, 0x82, 0x66, 0x92, 0xcf, 0x0c, - 0xe8, 0x9f, 0x24, 0x10, 0xe9, 0xf4, 0xfb, 0x16, 0x61, 0xb3, 0xb6, 0x61, 0x66, 0xd5, 0x09, 0xc2, - 0x4d, 0xdf, 0x69, 0x07, 0x18, 0xb6, 0x31, 0x84, 0x2f, 0xad, 0x4c, 0x31, 0x3e, 0x8b, 0x7e, 0x5b, - 0x61, 0x44, 0x8a, 0x6d, 0x4e, 0xb0, 0x63, 0xda, 0xcb, 0x1d, 0xb7, 0xed, 0x34, 0xdd, 0x6f, 0xcb, - 0x9b, 0x3b, 0xae, 0xbd, 0xec, 0x49, 0xa0, 0x15, 0x97, 0x9b, 0x5f, 0xeb, 0x19, 0x37, 0xde, 0xca, - 0x49, 0x18, 0x17, 0xae, 0x0d, 0xfc, 0xaa, 0xbf, 0x5a, 0x5e, 0x2f, 0x55, 0xd6, 0xef, 0xe6, 0x0d, - 0x32, 0x03, 0x50, 0xb5, 0x36, 0x8a, 0xe5, 0x5a, 0x8d, 0xfd, 0xce, 0xb0, 0xdf, 0xc2, 0x0f, 0xe0, - 0xce, 0xd6, 0x6a, 0x3e, 0xab, 0xb8, 0x02, 0x8c, 0x98, 0xff, 0xc2, 0x80, 0xb3, 0xe9, 0x43, 0x49, - 0x36, 0x01, 0x9d, 0x41, 0x84, 0x05, 0xea, 0xf6, 0xc0, 0x71, 0x4f, 0x05, 0x27, 0x9d, 0x4a, 0x42, - 0xee, 0xac, 0x90, 0x71, 0xa5, 0xae, 0x1a, 0xa5, 0xfa, 0x76, 0x1b, 0x66, 0x11, 0x16, 0xfa, 0xf1, - 0xd0, 0x3f, 0x75, 0x16, 0x26, 0x0b, 0xd5, 0xea, 0x6a, 0xa5, 0x58, 0xd8, 0xac, 0x6c, 0xac, 0xe7, - 0x0d, 0x32, 0x01, 0xa3, 0x77, 0xad, 0x8d, 0xad, 0x6a, 0x3e, 0x63, 0xfe, 0x65, 0x03, 0xa6, 0x2b, - 0xed, 0x90, 0xee, 0xf3, 0xd4, 0x66, 0x4f, 0x3a, 0xf9, 0xbe, 0xa0, 0x4d, 0xbe, 0x85, 0xc8, 0x6d, - 0x2a, 0xaa, 0x60, 0xa8, 0x99, 0xf7, 0x10, 0xe6, 0x7a, 0x48, 0x48, 0x0d, 0xc6, 0x0b, 0x3b, 0xb5, - 0x8d, 0x4a, 0xa9, 0x28, 0x1a, 0x26, 0x55, 0x64, 0x01, 0xed, 0xad, 0x84, 0x5f, 0xb3, 0x3e, 0x0c, - 0x6c, 0xcf, 0x6d, 0x28, 0xd9, 0x12, 0x57, 0x4e, 0x59, 0x92, 0x13, 0x3b, 0x2f, 0x0b, 0x2d, 0x1f, - 0x15, 0xe8, 0x55, 0x58, 0xe8, 0xc7, 0x8d, 0x9d, 0x1b, 0x2c, 0xaf, 0x49, 0x0b, 0xd6, 0xba, 0x7a, - 0x8b, 0x8b, 0xc1, 0xed, 0x8e, 0xdf, 0x4e, 0x06, 0xb7, 0x17, 0xac, 0x75, 0xf3, 0xaf, 0x66, 0xe0, - 0x2c, 0xeb, 0x97, 0x26, 0x0d, 0x02, 0x76, 0xea, 0x65, 0x07, 0x2c, 0xf1, 0x44, 0xe9, 0xe7, 0x60, - 0xec, 0xe0, 0x64, 0xe6, 0x10, 0x8e, 0x4e, 0x08, 0xe0, 0x5a, 0x23, 0xf6, 0x3d, 0xfc, 0x9b, 0xbc, - 0x00, 0x4a, 0x1a, 0x53, 0x5c, 0x2a, 0xa6, 0xac, 0x89, 0x4e, 0x94, 0xcc, 0xf4, 0xf3, 0x30, 0x8a, - 0x0e, 0xf5, 0x62, 0xc6, 0x4b, 0xbd, 0x29, 0xbd, 0x65, 0xe8, 0x69, 0x6f, 0x71, 0x02, 0x72, 0x03, - 0x20, 0x0e, 0x3d, 0x16, 0x53, 0x5a, 0x9e, 0xd5, 0xa2, 0xe8, 0x63, 0x6b, 0xa2, 0xb5, 0xe7, 0x88, - 0x78, 0xde, 0x6b, 0x30, 0x27, 0x8f, 0xed, 0x1d, 0xe9, 0x11, 0xce, 0x9d, 0xdf, 0xad, 0x59, 0x5e, - 0x50, 0xe9, 0x08, 0xaf, 0x70, 0xf3, 0x7f, 0xca, 0xc0, 0xc4, 0x0e, 0xdb, 0xff, 0xf0, 0x8c, 0x35, - 0xf8, 0xcc, 0xb6, 0x04, 0x93, 0xab, 0x9e, 0xd3, 0xd0, 0x9f, 0xd8, 0xc3, 0x3b, 0xc9, 0xa6, 0xe7, - 0x48, 0x3b, 0x68, 0x60, 0xa9, 0x48, 0xc7, 0xdc, 0xa7, 0x7e, 0x00, 0x63, 0x3c, 0xa2, 0x44, 0x24, - 0x04, 0x96, 0x1a, 0x50, 0xd4, 0xa2, 0xeb, 0xbc, 0x58, 0xb1, 0xb7, 0xed, 0x21, 0x40, 0xdd, 0x8e, - 0x45, 0x4c, 0x8a, 0x72, 0xa2, 0x1c, 0x1d, 0xee, 0x44, 0xa9, 0xf8, 0x01, 0x8f, 0x0d, 0xe3, 0x07, - 0x7c, 0xe1, 0x2d, 0x98, 0x54, 0xda, 0x73, 0x22, 0x85, 0xe8, 0x27, 0x33, 0x30, 0x8d, 0x5f, 0x15, - 0x19, 0xca, 0x9f, 0xcd, 0xf3, 0xf1, 0x17, 0xb4, 0xf3, 0xf1, 0x82, 0x3a, 0x5e, 0xfc, 0xcb, 0x06, - 0x1c, 0x8c, 0x3f, 0x80, 0xb9, 0x1e, 0x44, 0xf2, 0x26, 0x8c, 0xb2, 0xe6, 0xcb, 0xf3, 0x44, 0x3e, - 0x29, 0x01, 0x71, 0x9c, 0x16, 0xfb, 0xf0, 0xc0, 0xe2, 0xd8, 0xe6, 0xff, 0x6d, 0xc0, 0x94, 0x88, - 0x45, 0x6f, 0xef, 0x79, 0xcf, 0x6c, 0x77, 0xbe, 0xa5, 0x75, 0xe7, 0xb9, 0xc8, 0x97, 0x5c, 0x7e, - 0xd8, 0x80, 0xde, 0xfc, 0x27, 0x18, 0xd1, 0xa4, 0x23, 0x92, 0x12, 0x7f, 0x28, 0x5c, 0x5f, 0x9a, - 0x93, 0x58, 0x6c, 0xad, 0xc6, 0x5c, 0x53, 0x73, 0xe9, 0xaf, 0x86, 0x5f, 0x38, 0xc0, 0x45, 0x5e, - 0xe6, 0x7d, 0x8a, 0x5f, 0x99, 0x56, 0xf2, 0x3e, 0xc5, 0xaf, 0x4c, 0xab, 0x6f, 0x4b, 0xdf, 0x00, - 0x40, 0xe7, 0xdc, 0x76, 0x9d, 0x46, 0x56, 0x2d, 0xf4, 0x40, 0x70, 0x05, 0x94, 0xe1, 0x2b, 0x28, - 0xe6, 0x6f, 0x66, 0x01, 0xe2, 0xeb, 0x47, 0x36, 0x23, 0xa9, 0x96, 0xc2, 0x45, 0x58, 0xd3, 0x10, - 0xa4, 0x8e, 0x92, 0x00, 0x91, 0xcb, 0x30, 0xa2, 0xe4, 0x70, 0x4d, 0x75, 0xf9, 0x47, 0xa3, 0x69, - 0x11, 0x20, 0x38, 0x6c, 0xd7, 0xed, 0x06, 0x6d, 0x3a, 0x7c, 0x71, 0xce, 0xe2, 0xeb, 0x6f, 0xf3, - 0x31, 0xb4, 0x4f, 0x96, 0xd1, 0x09, 0x86, 0x51, 0x62, 0x08, 0xe4, 0xdd, 0xc4, 0x5d, 0xed, 0x48, - 0x1c, 0xe9, 0xa0, 0xc2, 0xd5, 0x48, 0x07, 0xe5, 0x1e, 0x97, 0x2c, 0x41, 0x64, 0xce, 0x55, 0x57, - 0xa8, 0xb4, 0x9c, 0xb3, 0x12, 0xc6, 0x68, 0xa4, 0x61, 0x57, 0x7b, 0x7a, 0x51, 0xc0, 0x54, 0x1a, - 0x09, 0x23, 0x55, 0x98, 0x70, 0xdb, 0x0f, 0x68, 0x3b, 0xf4, 0xfc, 0xc3, 0x85, 0x71, 0x9c, 0x55, - 0xe7, 0x95, 0x9b, 0xde, 0x8a, 0x2c, 0xe3, 0x8b, 0x2a, 0x9e, 0x59, 0x22, 0x7c, 0x35, 0xb4, 0x2c, - 0x02, 0x8a, 0x6b, 0xdd, 0x7f, 0x9a, 0x01, 0xd2, 0xcb, 0x80, 0x7c, 0x01, 0x26, 0xf9, 0x9a, 0x6c, - 0xfb, 0xc1, 0xb7, 0xc4, 0x85, 0x30, 0x0f, 0x2a, 0x56, 0xc0, 0x6a, 0x22, 0x28, 0x0e, 0xb6, 0x82, - 0x6f, 0x35, 0xc9, 0xd7, 0xe1, 0x34, 0x0e, 0x40, 0x87, 0xfa, 0xae, 0xd7, 0xb0, 0x31, 0x0c, 0xc8, - 0x69, 0x8a, 0x9c, 0x61, 0x6f, 0x60, 0x72, 0xcb, 0xde, 0xe2, 0x3e, 0x03, 0x35, 0xc7, 0x50, 0xab, - 0x88, 0x59, 0xe5, 0x88, 0x64, 0x13, 0xf2, 0x2a, 0xfd, 0x5e, 0xb7, 0xd9, 0x14, 0x63, 0x7f, 0x0d, - 0xdf, 0xbc, 0x49, 0x94, 0xf5, 0x61, 0x3c, 0x13, 0x33, 0xbe, 0xd3, 0x6d, 0x36, 0xc9, 0xe7, 0x00, - 0xbc, 0xb6, 0xdd, 0x72, 0x83, 0xc0, 0x6d, 0xef, 0x0b, 0x21, 0xc0, 0x00, 0x9f, 0x18, 0xaa, 0x76, - 0xa3, 0xd7, 0x5e, 0xe3, 0x40, 0xd1, 0x8d, 0x5f, 0x81, 0x39, 0xe1, 0x63, 0xb8, 0xe3, 0x86, 0x07, - 0x42, 0x63, 0x7b, 0x3a, 0x96, 0x8f, 0x6b, 0xef, 0xc3, 0xac, 0xf4, 0x0c, 0xdd, 0x5c, 0xad, 0x61, - 0x20, 0xc7, 0x2c, 0x4c, 0x6e, 0x97, 0xad, 0xca, 0x9d, 0x0f, 0xed, 0x3b, 0x5b, 0xab, 0xab, 0xf9, - 0x53, 0x64, 0x1a, 0x26, 0x04, 0xa0, 0x58, 0xc8, 0x1b, 0x64, 0x0a, 0x72, 0x95, 0xf5, 0x5a, 0xb9, - 0xb8, 0x65, 0x95, 0xf3, 0x99, 0x6b, 0x4b, 0x30, 0x13, 0xbf, 0xf7, 0x80, 0x3a, 0xec, 0x38, 0x64, - 0xad, 0xc2, 0x4e, 0xfe, 0x14, 0xd3, 0xbe, 0xab, 0xf7, 0x8a, 0xb5, 0x9b, 0x37, 0xf3, 0x06, 0x53, - 0x6c, 0xef, 0x16, 0xab, 0xf6, 0xbd, 0xb5, 0x5a, 0x3e, 0x73, 0xed, 0x33, 0x30, 0x87, 0x29, 0x0b, - 0x56, 0xdd, 0x20, 0xa4, 0x6d, 0xea, 0x63, 0xb5, 0x53, 0x90, 0xab, 0xd1, 0x8e, 0xe3, 0x3b, 0x21, - 0xe5, 0x75, 0xae, 0x75, 0x9b, 0xa1, 0xdb, 0x69, 0xd2, 0x47, 0x79, 0xe3, 0xda, 0x5b, 0x30, 0x6b, - 0x79, 0xdd, 0xd0, 0x6d, 0xef, 0xd7, 0x42, 0x86, 0xb1, 0x7f, 0x48, 0xce, 0xc0, 0xdc, 0xd6, 0x7a, - 0x61, 0x6d, 0xb9, 0x72, 0x77, 0x6b, 0x63, 0xab, 0x66, 0xaf, 0x15, 0x36, 0x8b, 0x2b, 0x5c, 0x69, - 0x5e, 0xdb, 0xa8, 0x6d, 0xda, 0x56, 0xb9, 0x58, 0x5e, 0xdf, 0xcc, 0x1b, 0xd7, 0x7e, 0xd6, 0x80, - 0x19, 0x76, 0xc0, 0xc3, 0x2b, 0xa1, 0x2d, 0xf4, 0xd4, 0xbc, 0x08, 0xcf, 0x6f, 0xd5, 0xca, 0x96, - 0xbd, 0xb9, 0x71, 0xaf, 0xbc, 0x6e, 0x6f, 0xd5, 0x0a, 0x77, 0x93, 0xde, 0xd4, 0x8b, 0xf0, 0x9c, - 0x82, 0x61, 0x95, 0x8b, 0x1b, 0xdb, 0x65, 0xcb, 0xae, 0x16, 0x6a, 0xb5, 0x9d, 0x0d, 0xab, 0x94, - 0x37, 0xc8, 0x05, 0x38, 0x9b, 0x82, 0xb0, 0x76, 0xa7, 0x90, 0xcf, 0xf4, 0x94, 0xad, 0x97, 0x77, - 0x0a, 0xab, 0xf6, 0xf2, 0xc6, 0x66, 0x3e, 0x7b, 0xed, 0x7d, 0x98, 0x12, 0x2e, 0x94, 0x3c, 0x36, - 0x32, 0x07, 0x23, 0xeb, 0x1b, 0xeb, 0xe5, 0xe4, 0xc1, 0x66, 0x0a, 0x72, 0x85, 0x6a, 0xd5, 0xda, - 0xd8, 0x2e, 0x97, 0xf2, 0x19, 0xd6, 0x91, 0xa5, 0xf2, 0x3a, 0x6b, 0x59, 0xf6, 0x9a, 0x09, 0x73, - 0x45, 0xea, 0x87, 0xe5, 0x47, 0x21, 0x6d, 0xb3, 0xfd, 0x04, 0xfb, 0x6e, 0x1a, 0x26, 0xca, 0x5f, - 0xde, 0x2c, 0xaf, 0xd7, 0xd8, 0x39, 0xe1, 0xd4, 0xb5, 0xe7, 0x13, 0x38, 0x72, 0x58, 0x6a, 0xb5, - 0x95, 0xfc, 0xa9, 0x6b, 0x5f, 0x63, 0xfb, 0xa0, 0x12, 0xf7, 0x7b, 0x0e, 0x4e, 0xab, 0xbf, 0xab, - 0xb4, 0xdd, 0x70, 0xdb, 0xfb, 0xf9, 0x53, 0xc9, 0x02, 0xab, 0xdb, 0x6e, 0xb3, 0x02, 0xfc, 0x78, - 0xb5, 0x60, 0x93, 0xfa, 0x2d, 0xb7, 0xed, 0x84, 0xb4, 0x91, 0xcf, 0x5c, 0xbb, 0x0e, 0xd3, 0x9a, - 0xf7, 0x29, 0xab, 0x77, 0x75, 0x43, 0x88, 0xc3, 0x5a, 0xb9, 0x54, 0xd9, 0x5a, 0xcb, 0x8f, 0xb2, - 0xcf, 0x5e, 0xa9, 0xdc, 0x5d, 0xc9, 0xc3, 0xb5, 0xaf, 0xc1, 0x8c, 0x08, 0x67, 0x5a, 0xbb, 0x53, - 0x90, 0x0d, 0xdd, 0xb8, 0x73, 0x47, 0x78, 0x75, 0xb3, 0xa3, 0x1d, 0x9e, 0x7d, 0x9e, 0x87, 0x05, - 0xf1, 0xc3, 0x2e, 0xac, 0x97, 0xec, 0x95, 0x82, 0x55, 0xda, 0x29, 0x58, 0x65, 0xfb, 0x5e, 0xf9, - 0xc3, 0x7c, 0x86, 0x9c, 0x05, 0xa2, 0x42, 0xec, 0xcd, 0x8d, 0xad, 0xe2, 0x4a, 0x3e, 0x7b, 0xcd, - 0x85, 0x7c, 0xd2, 0x91, 0xa0, 0xe7, 0x38, 0x69, 0x6d, 0xad, 0xaf, 0xf3, 0x5e, 0x9f, 0x85, 0xc9, - 0x8d, 0xcd, 0x95, 0xb2, 0x25, 0x3c, 0xe8, 0xd1, 0x65, 0x7e, 0x6b, 0xbd, 0xb0, 0xb5, 0xb9, 0xb2, - 0x61, 0x55, 0xbe, 0xc2, 0xba, 0x9f, 0x2c, 0xc0, 0x7c, 0x6d, 0xb5, 0x50, 0xbc, 0x67, 0xaf, 0x6f, - 0x6c, 0xda, 0x95, 0x75, 0xbb, 0xb8, 0x52, 0x58, 0x5f, 0x2f, 0xaf, 0xe6, 0xe1, 0xda, 0xbf, 0x34, - 0xe0, 0xb9, 0x01, 0xba, 0x39, 0x79, 0x03, 0xae, 0xae, 0x94, 0x0b, 0xa5, 0xd5, 0x72, 0xad, 0x66, - 0x33, 0x96, 0xe5, 0xf5, 0x4d, 0x71, 0xb2, 0xb3, 0x6b, 0x9b, 0x85, 0xcd, 0xa4, 0x04, 0x5e, 0x85, - 0x57, 0x06, 0xa3, 0xc7, 0xc2, 0x72, 0x05, 0x5e, 0x1e, 0x8c, 0x2a, 0x84, 0x27, 0x43, 0xae, 0xc1, - 0xe5, 0xc1, 0x98, 0x91, 0xd0, 0x65, 0x97, 0xdf, 0xfd, 0xfd, 0x3f, 0x7c, 0xf1, 0xd4, 0xef, 0xff, - 0xd1, 0x8b, 0xc6, 0x1f, 0xfc, 0xd1, 0x8b, 0xc6, 0xbf, 0xf9, 0xa3, 0x17, 0x8d, 0xaf, 0xbc, 0x76, - 0x82, 0x1c, 0x87, 0xbb, 0x63, 0x68, 0x3a, 0xb8, 0xf5, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x6a, - 0x55, 0x0b, 0x55, 0x9f, 0x45, 0x01, 0x00, + 0x76, 0x18, 0x86, 0xa3, 0xba, 0xe7, 0xa3, 0xe7, 0xcd, 0x57, 0x4f, 0x62, 0x00, 0x0c, 0xb0, 0x58, + 0x0c, 0xb6, 0x76, 0x17, 0x0b, 0x60, 0x77, 0x81, 0xc3, 0xe0, 0x16, 0x77, 0xb8, 0xfd, 0xba, 0x9e, + 0xee, 0x01, 0xa6, 0x81, 0xf9, 0xe8, 0xab, 0x9e, 0x8f, 0xdb, 0xdb, 0x3b, 0xd6, 0xd5, 0x74, 0xe7, + 0xcc, 0xd4, 0xa2, 0xbb, 0xab, 0xaf, 0xaa, 0x1a, 0xc0, 0x1c, 0xc5, 0x1f, 0x3f, 0x24, 0xea, 0x7e, + 0x34, 0x3f, 0x8e, 0x27, 0x1f, 0xc9, 0x93, 0x25, 0x99, 0x0c, 0x86, 0x24, 0x93, 0x96, 0xc8, 0x90, + 0x25, 0x45, 0xc8, 0x0e, 0xd9, 0xb4, 0xa9, 0x50, 0x30, 0x28, 0x29, 0x64, 0xd1, 0x11, 0xfe, 0x08, + 0x9f, 0x15, 0x63, 0x91, 0xb4, 0x1c, 0x36, 0xc2, 0xa1, 0xb0, 0x83, 0x11, 0x8c, 0xf0, 0x39, 0x28, + 0x3b, 0xf2, 0x65, 0x66, 0x55, 0x66, 0x75, 0x75, 0x4f, 0xcf, 0x02, 0x1b, 0x24, 0xd6, 0xfe, 0x07, + 0x98, 0x7e, 0xf9, 0xde, 0xcb, 0xac, 0xcc, 0x97, 0x99, 0x2f, 0x5f, 0xbe, 0xf7, 0x12, 0x5e, 0x0a, + 0x69, 0x83, 0xb6, 0x3d, 0x3f, 0xbc, 0xde, 0xa0, 0x7b, 0x4e, 0xed, 0xe0, 0x7a, 0x78, 0xd0, 0xa6, + 0x01, 0xff, 0xf7, 0x5a, 0xdb, 0xf7, 0x42, 0x8f, 0x0c, 0xe3, 0x8f, 0x73, 0xb3, 0x7b, 0xde, 0x9e, + 0x87, 0x90, 0xeb, 0xec, 0x2f, 0x5e, 0x78, 0x6e, 0x7e, 0xcf, 0xf3, 0xf6, 0x1a, 0xf4, 0x3a, 0xfe, + 0xda, 0xe9, 0xec, 0x5e, 0x0f, 0xdd, 0x26, 0x0d, 0x42, 0xa7, 0xd9, 0x16, 0x08, 0x57, 0xa2, 0x0a, + 0x9c, 0x30, 0x64, 0x25, 0xa1, 0xeb, 0xb5, 0xae, 0x3f, 0xbc, 0xa1, 0xfe, 0x14, 0xa8, 0x6f, 0xa6, + 0xb7, 0xe5, 0x91, 0xef, 0xb4, 0xdb, 0xd4, 0x8f, 0xff, 0xe0, 0xe8, 0xe6, 0x3f, 0xc8, 0xc2, 0xd8, + 0x7d, 0x4a, 0xdb, 0x85, 0x86, 0xfb, 0x90, 0x92, 0x97, 0x61, 0x68, 0xcd, 0x69, 0xd2, 0x39, 0xe3, + 0xa2, 0x71, 0x79, 0x6c, 0x71, 0xfa, 0xc9, 0xe1, 0xfc, 0x78, 0x40, 0xfd, 0x87, 0xd4, 0xb7, 0x5b, + 0x4e, 0x93, 0x5a, 0x58, 0x48, 0x5e, 0x87, 0x31, 0xf6, 0x7f, 0xd0, 0x76, 0x6a, 0x74, 0x2e, 0x83, + 0x98, 0x93, 0x4f, 0x0e, 0xe7, 0xc7, 0x5a, 0x12, 0x68, 0xc5, 0xe5, 0xe4, 0x12, 0x8c, 0xae, 0x50, + 0x27, 0xa0, 0xe5, 0xd2, 0x5c, 0xf6, 0xa2, 0x71, 0x39, 0xbb, 0x38, 0xf1, 0xe4, 0x70, 0x3e, 0xd7, + 0x60, 0x20, 0xdb, 0xad, 0x5b, 0xb2, 0x90, 0x94, 0x61, 0x74, 0xe9, 0x71, 0xdb, 0xf5, 0x69, 0x30, + 0x37, 0x74, 0xd1, 0xb8, 0x3c, 0xbe, 0x70, 0xee, 0x1a, 0xef, 0x94, 0x6b, 0xb2, 0x53, 0xae, 0x6d, + 0xc8, 0x4e, 0x59, 0x3c, 0xf9, 0xbb, 0x87, 0xf3, 0x27, 0x9e, 0x1c, 0xce, 0x8f, 0x52, 0x4e, 0xf2, + 0xf3, 0xff, 0xe3, 0xbc, 0x61, 0x49, 0x7a, 0xf2, 0x0e, 0x0c, 0x6d, 0x1c, 0xb4, 0xe9, 0xdc, 0xd8, + 0x45, 0xe3, 0xf2, 0xd4, 0xc2, 0x85, 0x6b, 0x7c, 0x18, 0xa2, 0x8f, 0x8c, 0xff, 0x62, 0x58, 0x8b, + 0xb9, 0x27, 0x87, 0xf3, 0x43, 0x0c, 0xc5, 0x42, 0x2a, 0xf2, 0x26, 0x8c, 0x2c, 0x7b, 0x41, 0x58, + 0x2e, 0xcd, 0x01, 0x7e, 0xda, 0xa9, 0x27, 0x87, 0xf3, 0x33, 0xfb, 0x5e, 0x10, 0xda, 0x6e, 0xfd, + 0x0d, 0xaf, 0xe9, 0x86, 0xb4, 0xd9, 0x0e, 0x0f, 0x2c, 0x81, 0x64, 0x3e, 0x86, 0x49, 0x8d, 0x1f, + 0x19, 0x87, 0xd1, 0xcd, 0xb5, 0xfb, 0x6b, 0xeb, 0xdb, 0x6b, 0xf9, 0x13, 0x24, 0x07, 0x43, 0x6b, + 0xeb, 0xa5, 0xa5, 0xbc, 0x41, 0x46, 0x21, 0x5b, 0xa8, 0x54, 0xf2, 0x19, 0x32, 0x01, 0xb9, 0x52, + 0x61, 0xa3, 0xb0, 0x58, 0xa8, 0x2e, 0xe5, 0xb3, 0xe4, 0x24, 0x4c, 0x6f, 0x97, 0xd7, 0x4a, 0xeb, + 0xdb, 0x55, 0xbb, 0xb4, 0x54, 0xbd, 0xbf, 0xb1, 0x5e, 0xc9, 0x0f, 0x91, 0x29, 0x80, 0xfb, 0x9b, + 0x8b, 0x4b, 0xd6, 0xda, 0xd2, 0xc6, 0x52, 0x35, 0x3f, 0x4c, 0x66, 0x21, 0x2f, 0x49, 0xec, 0xea, + 0x92, 0xb5, 0x55, 0x2e, 0x2e, 0xe5, 0x47, 0xcc, 0x6f, 0x65, 0x21, 0xb7, 0x4a, 0x43, 0xa7, 0xee, + 0x84, 0x0e, 0x39, 0xaf, 0x0d, 0x1c, 0x7e, 0x93, 0x32, 0x62, 0x2f, 0x77, 0x8f, 0xd8, 0xf0, 0x93, + 0xc3, 0x79, 0xe3, 0x4d, 0x75, 0xa4, 0xde, 0x86, 0xf1, 0x12, 0x0d, 0x6a, 0xbe, 0xdb, 0x66, 0xd2, + 0x84, 0xa3, 0x35, 0xb6, 0x78, 0xf6, 0xc9, 0xe1, 0xfc, 0xa9, 0x7a, 0x0c, 0x56, 0x7a, 0x40, 0xc5, + 0x26, 0x65, 0x18, 0x59, 0x71, 0x76, 0x68, 0x23, 0x98, 0x1b, 0xbe, 0x98, 0xbd, 0x3c, 0xbe, 0xf0, + 0x82, 0xe8, 0x75, 0xd9, 0xc0, 0x6b, 0xbc, 0x74, 0xa9, 0x15, 0xfa, 0x07, 0x8b, 0xb3, 0x4f, 0x0e, + 0xe7, 0xf3, 0x0d, 0x04, 0xa8, 0x3d, 0xca, 0x51, 0x48, 0x35, 0x96, 0x84, 0x91, 0x23, 0x25, 0xe1, + 0xc5, 0xdf, 0x3d, 0x9c, 0x37, 0xd8, 0x08, 0x09, 0x49, 0x88, 0xf9, 0xe9, 0x32, 0x71, 0x11, 0x32, + 0xe5, 0xd2, 0xdc, 0x28, 0x4a, 0x60, 0xfe, 0xc9, 0xe1, 0xfc, 0x84, 0x36, 0x98, 0x99, 0x72, 0xe9, + 0xdc, 0x6d, 0x18, 0x57, 0xda, 0x48, 0xf2, 0x90, 0x7d, 0x40, 0x0f, 0x78, 0x7f, 0x5a, 0xec, 0x4f, + 0x32, 0x0b, 0xc3, 0x0f, 0x9d, 0x46, 0x47, 0x74, 0xa0, 0xc5, 0x7f, 0x7c, 0x21, 0xf3, 0x79, 0xc3, + 0xfc, 0x4b, 0x43, 0x90, 0xb3, 0x3c, 0x3e, 0x0b, 0xc9, 0x15, 0x18, 0xae, 0x86, 0x4e, 0x28, 0x87, + 0xe2, 0xe4, 0x93, 0xc3, 0xf9, 0x69, 0x36, 0x43, 0xa9, 0x52, 0x1f, 0xc7, 0x60, 0xa8, 0x95, 0x7d, + 0x27, 0x90, 0x43, 0x82, 0xa8, 0x6d, 0x06, 0x50, 0x51, 0x11, 0x83, 0x5c, 0x82, 0xa1, 0x55, 0xaf, + 0x4e, 0xc5, 0xa8, 0x90, 0x27, 0x87, 0xf3, 0x53, 0x4d, 0xaf, 0xae, 0x22, 0x62, 0x39, 0x79, 0x03, + 0xc6, 0x8a, 0x1d, 0xdf, 0xa7, 0x2d, 0x26, 0xc0, 0x43, 0x88, 0x3c, 0xf5, 0xe4, 0x70, 0x1e, 0x6a, + 0x1c, 0xc8, 0xa6, 0x5c, 0x8c, 0xc0, 0xba, 0xba, 0x1a, 0x3a, 0x7e, 0x48, 0xeb, 0x73, 0xc3, 0x03, + 0x75, 0x35, 0x9b, 0x74, 0x33, 0x01, 0x27, 0x49, 0x76, 0xb5, 0xe0, 0x44, 0x96, 0x61, 0xfc, 0xae, + 0xef, 0xd4, 0x68, 0x85, 0xfa, 0xae, 0x57, 0xc7, 0x31, 0xcc, 0x2e, 0x5e, 0x7a, 0x72, 0x38, 0x7f, + 0x7a, 0x8f, 0x81, 0xed, 0x36, 0xc2, 0x63, 0xea, 0x1f, 0x1c, 0xce, 0xe7, 0x4a, 0x1d, 0x1f, 0x7b, + 0xcf, 0x52, 0x49, 0xc9, 0xd7, 0xd9, 0x90, 0x04, 0x21, 0x76, 0x2d, 0xad, 0xe3, 0xe8, 0xf5, 0x6f, + 0xa2, 0x29, 0x9a, 0x78, 0xba, 0xe1, 0x04, 0xa1, 0xed, 0x73, 0xba, 0x44, 0x3b, 0x55, 0x96, 0x64, + 0x1d, 0x72, 0xd5, 0xda, 0x3e, 0xad, 0x77, 0x1a, 0x74, 0x2e, 0x87, 0xec, 0xcf, 0x08, 0xc1, 0x95, + 0xe3, 0x29, 0x8b, 0x17, 0xcf, 0x09, 0xde, 0x24, 0x10, 0x10, 0xa5, 0xef, 0x23, 0x26, 0x5f, 0xc8, + 0x7d, 0xef, 0x57, 0xe6, 0x4f, 0xfc, 0xd8, 0xbf, 0xbc, 0x78, 0xc2, 0xfc, 0x07, 0x19, 0xc8, 0x27, + 0x99, 0x90, 0x5d, 0x98, 0xdc, 0x6c, 0xd7, 0x9d, 0x90, 0x16, 0x1b, 0x2e, 0x6d, 0x85, 0x01, 0x0a, + 0x49, 0xff, 0x6f, 0x7a, 0x45, 0xd4, 0x3b, 0xd7, 0x41, 0x42, 0xbb, 0xc6, 0x29, 0x13, 0x5f, 0xa5, + 0xb3, 0x8d, 0xeb, 0xa9, 0xe2, 0xea, 0x1d, 0xa0, 0x84, 0x1d, 0xaf, 0x1e, 0xbe, 0xee, 0xf7, 0xa8, + 0x47, 0xb0, 0x15, 0x02, 0xd4, 0xaa, 0xef, 0x1c, 0xa0, 0x64, 0x0e, 0x2e, 0x40, 0x8c, 0x24, 0x45, + 0x80, 0x18, 0xd8, 0xfc, 0x9f, 0x0c, 0x98, 0xb2, 0x68, 0xe0, 0x75, 0xfc, 0x1a, 0x5d, 0xa6, 0x4e, + 0x9d, 0xfa, 0x4c, 0xfc, 0xef, 0xbb, 0xad, 0xba, 0x98, 0x53, 0x28, 0xfe, 0x0f, 0xdc, 0x96, 0x3a, + 0x85, 0xb1, 0x9c, 0x7c, 0x06, 0x46, 0xab, 0x9d, 0x1d, 0x44, 0xe5, 0x73, 0xea, 0x34, 0x8e, 0x58, + 0x67, 0xc7, 0x4e, 0xa0, 0x4b, 0x34, 0x72, 0x1d, 0x46, 0xb7, 0xa8, 0x1f, 0xc4, 0x2b, 0x1e, 0xae, + 0xf7, 0x0f, 0x39, 0x48, 0x25, 0x10, 0x58, 0xe4, 0x6e, 0xbc, 0xea, 0x8a, 0x9d, 0x6a, 0x3a, 0xb1, + 0xd6, 0xc5, 0xa2, 0xd2, 0x14, 0x10, 0x55, 0x54, 0x24, 0x96, 0xf9, 0x9d, 0x0c, 0xe4, 0x4b, 0x4e, + 0xe8, 0xec, 0x38, 0x81, 0xe8, 0xcf, 0xad, 0x9b, 0x6c, 0x1d, 0x57, 0x3e, 0x14, 0xd7, 0x71, 0xd6, + 0xf2, 0x8f, 0xfd, 0x79, 0xaf, 0x26, 0x3f, 0x6f, 0x9c, 0x6d, 0x9b, 0xe2, 0xf3, 0xe2, 0x8f, 0x7a, + 0xf7, 0xe8, 0x8f, 0xca, 0x8b, 0x8f, 0xca, 0xc9, 0x8f, 0x8a, 0x3f, 0x85, 0xbc, 0x0b, 0x43, 0xd5, + 0x36, 0xad, 0x89, 0x45, 0x44, 0xae, 0xfd, 0xfa, 0xc7, 0x31, 0x84, 0xad, 0x9b, 0x8b, 0x13, 0x82, + 0xcd, 0x50, 0xd0, 0xa6, 0x35, 0x0b, 0xc9, 0x94, 0x49, 0xf3, 0x4f, 0x46, 0x60, 0x36, 0x8d, 0x8c, + 0xbc, 0xab, 0x6f, 0x4e, 0xbc, 0x7b, 0x5e, 0xe8, 0xb9, 0x39, 0xcd, 0x19, 0xfa, 0xf6, 0x74, 0x15, + 0x72, 0x15, 0x26, 0x90, 0x35, 0xaf, 0x21, 0x7a, 0x8e, 0xad, 0x8a, 0xb9, 0xb6, 0x84, 0x19, 0x56, + 0x54, 0x4e, 0x5e, 0x80, 0xec, 0xa6, 0x55, 0x16, 0xdd, 0x35, 0xf6, 0xe4, 0x70, 0x3e, 0xdb, 0xf1, + 0xdd, 0x39, 0xc3, 0x62, 0x50, 0x72, 0x1d, 0x46, 0x8a, 0x85, 0x22, 0xf5, 0x43, 0xec, 0xa6, 0x89, + 0xc5, 0x33, 0x4c, 0x5a, 0x6a, 0x8e, 0x5d, 0xa3, 0x7e, 0xa8, 0x55, 0x2f, 0xd0, 0xc8, 0xeb, 0x90, + 0x2d, 0x6c, 0x57, 0x45, 0xcf, 0x80, 0xe8, 0x99, 0xc2, 0x76, 0x75, 0x71, 0x52, 0x74, 0x44, 0xd6, + 0x79, 0x14, 0x30, 0xee, 0x85, 0xed, 0xaa, 0x3a, 0x5a, 0x23, 0x7d, 0x46, 0xeb, 0x32, 0xe4, 0x98, + 0xf6, 0xc1, 0x36, 0x78, 0x5c, 0x14, 0xc7, 0xb8, 0x52, 0xb5, 0x2f, 0x60, 0x56, 0x54, 0x4a, 0x5e, + 0x8e, 0x94, 0x99, 0x5c, 0xcc, 0x4f, 0x28, 0x33, 0x52, 0x85, 0x21, 0x8f, 0x61, 0xb2, 0x74, 0xd0, + 0x72, 0x9a, 0x6e, 0x4d, 0x6c, 0xe1, 0x63, 0xb8, 0x85, 0x5f, 0xeb, 0x33, 0x8c, 0xd7, 0x34, 0x02, + 0xbe, 0xab, 0xcb, 0xc5, 0x77, 0xae, 0xce, 0xcb, 0xec, 0xe4, 0x0e, 0x3f, 0x67, 0x58, 0x7a, 0x45, + 0x6c, 0x2e, 0xc9, 0x25, 0x12, 0xb5, 0xad, 0x58, 0xec, 0x24, 0x38, 0x9e, 0x4b, 0xbe, 0x80, 0xa8, + 0x73, 0x29, 0xda, 0x74, 0xdf, 0x85, 0xec, 0xdd, 0x62, 0x65, 0x6e, 0x1c, 0x79, 0x10, 0xc1, 0xe3, + 0x6e, 0xb1, 0x52, 0x6c, 0x78, 0x9d, 0x7a, 0xf5, 0x4b, 0x2b, 0x8b, 0x67, 0x04, 0x9b, 0xc9, 0xbd, + 0x5a, 0x5b, 0x6b, 0x11, 0xa3, 0x23, 0x4b, 0x90, 0x93, 0x5f, 0x39, 0x37, 0x81, 0x3c, 0x66, 0x12, + 0x1f, 0xbf, 0x75, 0x93, 0xcf, 0xb5, 0xba, 0xf8, 0xad, 0xb6, 0x42, 0xe2, 0x90, 0x9b, 0x28, 0x65, + 0x8f, 0x0f, 0xca, 0xa5, 0x60, 0x6e, 0xf2, 0x62, 0xf6, 0xf2, 0x18, 0x8a, 0xc7, 0xc9, 0x36, 0x83, + 0xd9, 0x6e, 0x5d, 0x55, 0x76, 0x22, 0xc4, 0x73, 0xdb, 0x40, 0xba, 0x3b, 0x33, 0x45, 0xfd, 0x78, + 0x5d, 0x55, 0x3f, 0xc6, 0x17, 0x4e, 0x89, 0x06, 0x16, 0xbd, 0x66, 0xd3, 0x69, 0xd5, 0x91, 0x76, + 0x6b, 0x41, 0xd5, 0x4a, 0x0a, 0x30, 0x15, 0xb7, 0x7e, 0xc5, 0x0d, 0x42, 0x72, 0x1d, 0xc6, 0x24, + 0x84, 0xed, 0x3c, 0xd9, 0xd4, 0xef, 0xb4, 0x62, 0x1c, 0xf3, 0x77, 0x32, 0x00, 0x71, 0xc9, 0x73, + 0xba, 0x38, 0x7d, 0x4e, 0x5b, 0x9c, 0x4e, 0x25, 0xa5, 0xba, 0xe7, 0xb2, 0x44, 0xde, 0x87, 0x11, + 0xa6, 0xa7, 0x75, 0xa4, 0x1e, 0x7a, 0x26, 0x49, 0x8a, 0x85, 0x5b, 0x37, 0x17, 0xa7, 0x04, 0xf1, + 0x48, 0x80, 0x10, 0x4b, 0x90, 0x29, 0xeb, 0xda, 0x7f, 0x3b, 0x12, 0x0f, 0x86, 0x58, 0xd1, 0x2e, + 0x2b, 0x4b, 0x92, 0x11, 0x4f, 0x62, 0xb9, 0x24, 0x29, 0x0b, 0xd2, 0x59, 0xbe, 0x20, 0xf1, 0x4e, + 0x1d, 0x15, 0x0b, 0x52, 0x72, 0x39, 0xe2, 0x1d, 0x78, 0xe4, 0x72, 0xd4, 0x4e, 0xce, 0xf5, 0x21, + 0x14, 0x83, 0xcb, 0xa9, 0xbd, 0x92, 0x36, 0xcb, 0x2f, 0x1e, 0x35, 0xcb, 0x93, 0x73, 0xfc, 0x66, + 0xaf, 0x05, 0xf0, 0x94, 0x9c, 0x92, 0xce, 0x23, 0x95, 0x1c, 0x17, 0xc2, 0xb7, 0xf9, 0x7c, 0x1e, + 0xe9, 0x39, 0x9f, 0x4f, 0xa5, 0xce, 0x67, 0x3e, 0x9b, 0xdf, 0x86, 0xe1, 0xc2, 0x37, 0x3b, 0x3e, + 0x15, 0x0a, 0xe3, 0x84, 0xac, 0x93, 0xc1, 0xa2, 0x85, 0x60, 0xda, 0x61, 0x3f, 0x55, 0x45, 0x1b, + 0xcb, 0x59, 0xcd, 0x1b, 0x2b, 0x55, 0xa1, 0x0c, 0x92, 0x44, 0xb7, 0x6c, 0xac, 0x28, 0xcd, 0x0e, + 0xb5, 0xaf, 0x66, 0x54, 0xe4, 0x3a, 0x64, 0x0a, 0x25, 0x3c, 0x77, 0x8e, 0x2f, 0x8c, 0xc9, 0x6a, + 0x4b, 0x8b, 0xb3, 0x82, 0x64, 0xc2, 0xd1, 0x0e, 0x1d, 0x85, 0x12, 0x59, 0x84, 0xe1, 0xd5, 0x83, + 0xea, 0x97, 0x56, 0xc4, 0xea, 0x77, 0x52, 0xca, 0x35, 0x83, 0xad, 0xe3, 0xd6, 0x15, 0xc4, 0x2d, + 0x6e, 0x1e, 0x04, 0xdf, 0x68, 0xa8, 0x2d, 0x46, 0x34, 0x52, 0x81, 0xb1, 0x42, 0xbd, 0xe9, 0xb6, + 0x36, 0x03, 0xea, 0x8b, 0x15, 0x70, 0x2e, 0xd1, 0xee, 0xa8, 0x7c, 0x71, 0xee, 0xc9, 0xe1, 0xfc, + 0xac, 0xc3, 0x7e, 0xda, 0x9d, 0x80, 0xfa, 0x0a, 0xb7, 0x98, 0x09, 0xa9, 0x00, 0xac, 0x7a, 0xad, + 0x3d, 0xaf, 0x10, 0x36, 0x9c, 0x20, 0xb1, 0x20, 0xc6, 0x05, 0x91, 0x3e, 0x77, 0xaa, 0xc9, 0x60, + 0xb6, 0xc3, 0x80, 0x0a, 0x43, 0x85, 0xc7, 0x27, 0xb7, 0xc8, 0xdd, 0x80, 0x99, 0xae, 0x8f, 0xec, + 0x7f, 0x18, 0x36, 0xff, 0xba, 0xaa, 0x77, 0x89, 0x29, 0xcc, 0x4e, 0xfd, 0x62, 0x22, 0x19, 0xb1, + 0x16, 0xd8, 0x35, 0x91, 0xa2, 0x69, 0x74, 0x85, 0x0b, 0x75, 0xa6, 0x4b, 0xa8, 0xc7, 0x95, 0x5d, + 0x9d, 0x8b, 0x72, 0x34, 0xc4, 0xd9, 0x8f, 0x3f, 0xc4, 0xef, 0xc3, 0xc4, 0xaa, 0xd3, 0x72, 0xf6, + 0x68, 0x9d, 0x7d, 0x1f, 0x9f, 0xb4, 0x5c, 0xfd, 0x39, 0xd3, 0xe4, 0x70, 0x1c, 0x4d, 0xb5, 0xf7, + 0x35, 0x02, 0x72, 0x43, 0x4e, 0x89, 0xe1, 0x94, 0x29, 0x21, 0x35, 0x91, 0x61, 0x9c, 0x12, 0x62, + 0x22, 0x98, 0xff, 0xeb, 0x08, 0x7e, 0x23, 0x79, 0x03, 0x46, 0x2c, 0xba, 0x17, 0x2b, 0x5d, 0x78, + 0x78, 0xf7, 0x11, 0xa2, 0x76, 0x0c, 0xc7, 0xc1, 0x1d, 0x9d, 0xd6, 0x83, 0x7d, 0x77, 0x37, 0x14, + 0xbd, 0x13, 0xed, 0xe8, 0x02, 0xac, 0xec, 0xe8, 0x02, 0xa2, 0xed, 0xe8, 0x02, 0xc6, 0x96, 0x0d, + 0xab, 0x54, 0x15, 0x9d, 0x26, 0x7b, 0xd8, 0x2a, 0x29, 0xf3, 0xcf, 0xd7, 0x36, 0x54, 0x86, 0x4d, + 0x6e, 0xc1, 0x58, 0xa1, 0x56, 0xf3, 0x3a, 0xca, 0xe9, 0x97, 0x0b, 0x3c, 0x07, 0xea, 0x16, 0x9c, + 0x18, 0x95, 0x54, 0x61, 0x7c, 0x89, 0x1d, 0x19, 0xdd, 0xa2, 0x53, 0xdb, 0x97, 0x9d, 0x24, 0x27, + 0xbf, 0x52, 0x12, 0x8b, 0x3c, 0x45, 0x60, 0x8d, 0x01, 0x55, 0x93, 0x88, 0x82, 0x4b, 0x36, 0x60, + 0xbc, 0x4a, 0x6b, 0x3e, 0x0d, 0xab, 0xa1, 0xe7, 0xd3, 0xc4, 0x5a, 0xa6, 0x94, 0x2c, 0x5e, 0x90, + 0xa7, 0xd6, 0x00, 0x81, 0x76, 0xc0, 0xa0, 0x2a, 0x57, 0x05, 0x99, 0x1f, 0x3f, 0x9a, 0x9e, 0x7f, + 0x50, 0x5a, 0x14, 0xeb, 0x5b, 0xbc, 0x19, 0x72, 0xb0, 0x7a, 0xfc, 0x60, 0x90, 0xfa, 0x8e, 0x7e, + 0xfc, 0xe0, 0x58, 0x38, 0x52, 0xa5, 0x2a, 0xaa, 0x21, 0x62, 0xb5, 0x9b, 0x8e, 0x7b, 0x19, 0xc1, + 0xca, 0x48, 0xd5, 0x03, 0x54, 0x62, 0xb4, 0x91, 0x12, 0x58, 0xa4, 0x0d, 0x44, 0x8e, 0x1a, 0x57, + 0x11, 0x1b, 0x34, 0x08, 0xc4, 0x22, 0x78, 0x36, 0x31, 0xf8, 0x31, 0xc2, 0xe2, 0xab, 0x82, 0xf9, + 0x8b, 0x52, 0x0c, 0xc4, 0x89, 0x93, 0x15, 0x2a, 0xf5, 0xa4, 0xf0, 0x26, 0xb7, 0x01, 0x96, 0x1e, + 0x87, 0xd4, 0x6f, 0x39, 0x8d, 0xc8, 0x4c, 0x87, 0x86, 0x2a, 0x2a, 0xa0, 0xfa, 0x40, 0x2b, 0xc8, + 0xa4, 0x08, 0x93, 0x85, 0x20, 0xe8, 0x34, 0xa9, 0xe5, 0x35, 0x68, 0xc1, 0x5a, 0xc3, 0x05, 0x73, + 0x6c, 0xf1, 0xc5, 0x27, 0x87, 0xf3, 0x67, 0x1d, 0x2c, 0xb0, 0x7d, 0xaf, 0x41, 0x6d, 0xc7, 0x57, + 0xa5, 0x5b, 0xa7, 0x21, 0xeb, 0x00, 0xeb, 0x6d, 0xda, 0xaa, 0x52, 0xc7, 0xaf, 0xed, 0x27, 0xd6, + 0xc7, 0xb8, 0x60, 0xf1, 0xbc, 0xf8, 0xc2, 0x59, 0xaf, 0x4d, 0x5b, 0x01, 0xc2, 0xd4, 0x56, 0xc5, + 0x98, 0xe6, 0x0f, 0x6b, 0xa2, 0xc2, 0xc4, 0xf8, 0x3e, 0x3d, 0xa8, 0xf8, 0x74, 0xd7, 0x7d, 0x2c, + 0x66, 0x1d, 0x8a, 0xf1, 0x03, 0x7a, 0x60, 0xb7, 0x11, 0xaa, 0x8a, 0x71, 0x84, 0x4a, 0x3e, 0x0b, + 0xb9, 0xfb, 0xab, 0xd5, 0xfb, 0xf4, 0xa0, 0x5c, 0x12, 0xda, 0x02, 0x27, 0x6b, 0x06, 0x36, 0x23, + 0xd5, 0x3a, 0x25, 0xc2, 0x34, 0x17, 0xe3, 0x29, 0xcb, 0x6a, 0x2e, 0x36, 0x3a, 0x41, 0x48, 0xfd, + 0x72, 0x49, 0xad, 0xb9, 0xc6, 0x81, 0x89, 0x09, 0x14, 0xa1, 0x9a, 0x3f, 0x93, 0xc1, 0xe9, 0xca, + 0x46, 0xa6, 0xdc, 0x62, 0xc7, 0xfb, 0x1a, 0x8d, 0x18, 0xe0, 0xc8, 0xb8, 0x02, 0x9a, 0x18, 0x99, + 0x18, 0x59, 0xaf, 0x3a, 0x33, 0x70, 0xd5, 0xac, 0x4a, 0x69, 0x2c, 0x10, 0x36, 0x66, 0x51, 0xa5, + 0x2f, 0xa0, 0x89, 0x2a, 0x63, 0x64, 0x72, 0x09, 0x46, 0xcb, 0x85, 0xd5, 0x42, 0x27, 0xdc, 0xc7, + 0xc5, 0x22, 0xc7, 0x35, 0x30, 0xd7, 0x69, 0xda, 0x4e, 0x27, 0xdc, 0xb7, 0x64, 0x21, 0xb9, 0x8e, + 0x9a, 0x6d, 0x8b, 0x86, 0xdc, 0xba, 0x29, 0x76, 0x87, 0x80, 0x83, 0x12, 0x8a, 0x2d, 0x03, 0x99, + 0xbf, 0x6d, 0xc4, 0x93, 0x8b, 0x5c, 0xd2, 0x76, 0x23, 0xb4, 0x5d, 0xb0, 0xdd, 0x48, 0xb5, 0x5d, + 0xa0, 0x91, 0xd6, 0x02, 0x52, 0xec, 0x04, 0xa1, 0xd7, 0x5c, 0x6a, 0xd5, 0xdb, 0x9e, 0xdb, 0x0a, + 0x91, 0x8a, 0xf7, 0x84, 0xf9, 0xe4, 0x70, 0xfe, 0x42, 0x0d, 0x4b, 0x6d, 0x2a, 0x8a, 0xed, 0x04, + 0x97, 0x14, 0xea, 0xa7, 0xe8, 0x1c, 0xf3, 0x9f, 0x66, 0xb4, 0x45, 0x91, 0x35, 0xcf, 0xa2, 0xed, + 0x86, 0x5b, 0xc3, 0x13, 0xd7, 0x5d, 0xdf, 0xeb, 0xb4, 0xa3, 0x21, 0xc6, 0xe6, 0xf9, 0x71, 0xa9, + 0xbd, 0xc7, 0x8a, 0x75, 0xde, 0x29, 0xd4, 0xe4, 0x8b, 0x30, 0xc1, 0xf6, 0x27, 0xf1, 0x33, 0x98, + 0xcb, 0x60, 0xef, 0x9e, 0x47, 0x2b, 0x54, 0x40, 0xfd, 0x88, 0x8d, 0xb6, 0xb1, 0xa9, 0x14, 0xa4, + 0x0e, 0x73, 0x1b, 0xbe, 0xd3, 0x0a, 0xdc, 0x70, 0xa9, 0x55, 0xf3, 0x0f, 0x70, 0x3f, 0x5d, 0x6a, + 0x39, 0x3b, 0x0d, 0x5a, 0xc7, 0xcf, 0xcd, 0x2d, 0x5e, 0x7e, 0x72, 0x38, 0xff, 0x4a, 0xc8, 0x71, + 0x6c, 0x1a, 0x21, 0xd9, 0x94, 0x63, 0x29, 0x9c, 0x7b, 0x72, 0x62, 0xfb, 0xaf, 0xec, 0x56, 0xbc, + 0x59, 0x18, 0x8a, 0xcc, 0x0f, 0x67, 0xa2, 0xd1, 0x60, 0xd3, 0x5f, 0x6d, 0xa6, 0x4a, 0x60, 0xfe, + 0xb1, 0x11, 0x2f, 0xdb, 0xe4, 0x1d, 0x18, 0x17, 0xe2, 0xab, 0xc8, 0xc5, 0x39, 0xb6, 0x01, 0x48, + 0x59, 0x4f, 0x8c, 0xac, 0x8a, 0xce, 0x8e, 0x59, 0x85, 0xe2, 0x8a, 0x22, 0x1b, 0x78, 0xcc, 0x72, + 0x6a, 0x8d, 0x24, 0x95, 0x44, 0x63, 0x42, 0xb0, 0xb1, 0x52, 0xd5, 0x7b, 0x05, 0x85, 0x20, 0x6c, + 0x04, 0x29, 0xdd, 0xa0, 0x20, 0x3f, 0xfd, 0x87, 0xff, 0x77, 0x46, 0xda, 0xee, 0x40, 0x16, 0x61, + 0x72, 0xdb, 0xf3, 0x1f, 0xe0, 0xf8, 0x2a, 0x9d, 0x80, 0x23, 0xff, 0x48, 0x16, 0x24, 0x3f, 0x48, + 0x27, 0x51, 0xdb, 0xa6, 0xf4, 0x86, 0xde, 0xb6, 0x04, 0x07, 0x8d, 0x80, 0x8d, 0x43, 0xc4, 0x31, + 0x9a, 0x1d, 0x38, 0x0e, 0x71, 0x13, 0x34, 0x11, 0x56, 0xd1, 0xcd, 0xff, 0xcc, 0x50, 0x77, 0x01, + 0xd6, 0xc9, 0x25, 0xaf, 0xe9, 0xb8, 0x2d, 0xe5, 0x73, 0xf8, 0xe5, 0x09, 0x42, 0x93, 0x2d, 0x51, + 0x90, 0xc9, 0x4d, 0xc8, 0xf1, 0x5f, 0xd1, 0xc2, 0x87, 0x66, 0x03, 0x41, 0xa8, 0xaf, 0xda, 0x12, + 0xb1, 0x6b, 0x64, 0xb2, 0xc7, 0x1d, 0x99, 0x1f, 0x33, 0x60, 0x5c, 0x39, 0x51, 0xb1, 0xf5, 0xb7, + 0xe2, 0x7b, 0x1f, 0xd1, 0x5a, 0xa8, 0x2f, 0xfd, 0x6d, 0x0e, 0x4c, 0xac, 0xbf, 0x11, 0x6a, 0x62, + 0xc9, 0xcf, 0x1c, 0x63, 0xc9, 0x37, 0xff, 0x0f, 0x43, 0xa8, 0xa5, 0x03, 0xaf, 0x91, 0xfa, 0x7a, + 0x96, 0x39, 0xce, 0x62, 0xff, 0x45, 0x18, 0xb6, 0x68, 0xdd, 0x0d, 0x84, 0x4a, 0x39, 0xa3, 0xaa, + 0xc0, 0x58, 0x10, 0x6b, 0xe1, 0x3e, 0xfb, 0xa9, 0x6a, 0xe1, 0x58, 0xce, 0x74, 0x87, 0x72, 0x70, + 0xa7, 0x41, 0x1f, 0xbb, 0x5c, 0x92, 0xc5, 0xa6, 0x81, 0xba, 0x83, 0x1b, 0xd8, 0xbb, 0xac, 0x44, + 0x28, 0x31, 0xaa, 0xd4, 0x6a, 0x34, 0xe6, 0x07, 0x00, 0x71, 0x95, 0xe4, 0x3e, 0xe4, 0xc5, 0xdc, + 0x76, 0x5b, 0x7b, 0x15, 0xaf, 0xe1, 0xd6, 0xc4, 0x71, 0x68, 0x71, 0xfe, 0xc9, 0xe1, 0xfc, 0x0b, + 0xb5, 0xa8, 0xcc, 0x6e, 0x63, 0xa1, 0xc2, 0xb7, 0x8b, 0xd0, 0xfc, 0x0f, 0x32, 0xec, 0xf8, 0xc9, + 0xfa, 0xe8, 0x3e, 0x3d, 0x08, 0x9d, 0x9d, 0x3b, 0x6e, 0x43, 0x93, 0xc4, 0x07, 0x08, 0xb5, 0x77, + 0x5d, 0xed, 0xee, 0x42, 0x41, 0x66, 0x92, 0x78, 0xdf, 0xdf, 0x79, 0x0b, 0x09, 0x15, 0x49, 0x7c, + 0xe0, 0xef, 0xbc, 0x95, 0x24, 0x8b, 0x10, 0x89, 0x09, 0x23, 0x5c, 0x2a, 0x85, 0x0c, 0xc2, 0x93, + 0xc3, 0xf9, 0x11, 0x2e, 0xbc, 0x96, 0x28, 0x21, 0x67, 0x21, 0x5b, 0xad, 0xac, 0x89, 0xe5, 0x03, + 0x4d, 0x18, 0x41, 0xbb, 0x65, 0x31, 0x18, 0xab, 0x73, 0xa5, 0x54, 0xa8, 0xe0, 0xd9, 0x6b, 0x38, + 0xae, 0xb3, 0x51, 0x77, 0xda, 0xc9, 0xd3, 0x57, 0x84, 0x48, 0xde, 0x85, 0xf1, 0xfb, 0xa5, 0xe2, + 0xb2, 0x17, 0xf0, 0xa9, 0x3f, 0x12, 0x0b, 0xff, 0x83, 0x7a, 0xcd, 0x46, 0x03, 0x67, 0x72, 0x0d, + 0x55, 0xf0, 0xcd, 0xdf, 0x30, 0x60, 0x5c, 0x39, 0xd3, 0x93, 0xcf, 0x8a, 0xdb, 0x35, 0x03, 0x6f, + 0x8c, 0x4f, 0x77, 0x9f, 0xfa, 0x59, 0x29, 0x3f, 0x48, 0x36, 0xbd, 0x3a, 0x15, 0x77, 0x6d, 0xf1, + 0x99, 0x31, 0x33, 0xc8, 0x99, 0xf1, 0x36, 0x00, 0x97, 0x01, 0x6c, 0xb2, 0xb2, 0x17, 0x2b, 0x37, + 0xec, 0xea, 0xb8, 0xc4, 0xc8, 0xa6, 0x05, 0x13, 0xea, 0x79, 0x91, 0x2d, 0x9f, 0xe2, 0xc6, 0x40, + 0x98, 0xcf, 0x94, 0xe5, 0x53, 0x70, 0xeb, 0xbe, 0xc1, 0xd0, 0x49, 0xcc, 0xcf, 0xaa, 0x87, 0xfc, + 0x41, 0x27, 0xa0, 0xf9, 0x13, 0x46, 0x3c, 0xdd, 0xb7, 0x6e, 0x90, 0xb7, 0x61, 0x84, 0xdf, 0xd0, + 0x88, 0x8b, 0xac, 0x53, 0x91, 0xbe, 0xaf, 0x5e, 0xdf, 0x70, 0xeb, 0xda, 0xef, 0xf1, 0x9b, 0xda, + 0x13, 0x96, 0x20, 0x89, 0x0c, 0x73, 0xfa, 0x59, 0x5f, 0x72, 0x47, 0x13, 0xd4, 0x8d, 0x34, 0xc3, + 0x9c, 0xf9, 0xef, 0x67, 0x61, 0x4a, 0x47, 0x53, 0xaf, 0x71, 0x8c, 0x81, 0xae, 0x71, 0xbe, 0x08, + 0x39, 0xd6, 0x1f, 0x6e, 0x8d, 0x4a, 0xb5, 0xe3, 0x15, 0x34, 0x57, 0x0a, 0x98, 0x76, 0x3d, 0x09, + 0xd5, 0x83, 0x20, 0xa4, 0x4d, 0xa6, 0xfe, 0x5b, 0x11, 0x15, 0x59, 0x50, 0xac, 0xf0, 0xd9, 0x78, + 0x27, 0x96, 0x56, 0x78, 0x55, 0x6e, 0x23, 0x7b, 0xfc, 0x9b, 0x30, 0xc2, 0x34, 0xca, 0xe8, 0x74, + 0x8a, 0xad, 0x64, 0xca, 0x66, 0xc2, 0xb9, 0x80, 0x23, 0x91, 0x6d, 0xc8, 0xad, 0x38, 0x41, 0x58, + 0xa5, 0xb4, 0x35, 0xc0, 0x05, 0xed, 0xbc, 0xe8, 0xaa, 0x93, 0x78, 0xfb, 0x19, 0x50, 0xda, 0x4a, + 0xdc, 0xb0, 0x45, 0xcc, 0xc8, 0xd7, 0x00, 0x8a, 0x5e, 0x2b, 0xf4, 0xbd, 0xc6, 0x8a, 0xb7, 0x37, + 0x37, 0x82, 0x36, 0xc0, 0x0b, 0x89, 0x01, 0x88, 0x11, 0xb8, 0xe5, 0x2f, 0x3a, 0xfb, 0xd6, 0x78, + 0x81, 0xdd, 0xf0, 0xf6, 0x54, 0x79, 0x8d, 0xf1, 0xcd, 0x1f, 0x64, 0xe0, 0x4c, 0x0f, 0x36, 0x4c, + 0xd2, 0x70, 0xc3, 0x52, 0x24, 0x2d, 0xb1, 0x4f, 0x71, 0x3f, 0x0c, 0x7e, 0x63, 0xcf, 0x64, 0x63, + 0x28, 0xfd, 0xc6, 0x9e, 0xdc, 0x83, 0x21, 0xf6, 0xf1, 0x03, 0xdc, 0x3c, 0xca, 0x83, 0xec, 0x54, + 0xe8, 0xaa, 0x03, 0x83, 0x9d, 0x82, 0x3c, 0xc8, 0x67, 0x21, 0xbb, 0xb1, 0xb1, 0x82, 0xa3, 0x92, + 0x45, 0x75, 0x76, 0x32, 0x0c, 0x1b, 0x9a, 0x10, 0x4c, 0x32, 0xda, 0x6b, 0xd1, 0x45, 0x35, 0x43, + 0x27, 0x5f, 0x4e, 0x78, 0x3d, 0x5c, 0xed, 0xdf, 0x85, 0x83, 0x3b, 0x41, 0x3c, 0x8d, 0x37, 0x82, + 0x1f, 0x4f, 0x8e, 0x3b, 0x6e, 0x23, 0xa4, 0x3e, 0x39, 0xc7, 0x65, 0x3d, 0x3e, 0xd4, 0x59, 0xd1, + 0x6f, 0x32, 0x17, 0x4f, 0x1c, 0xce, 0x29, 0x9a, 0x21, 0x57, 0x95, 0x19, 0x92, 0xc5, 0x19, 0x32, + 0xd5, 0x6b, 0x2e, 0x98, 0x3f, 0x9e, 0x91, 0x55, 0x6c, 0x2d, 0x3c, 0xa7, 0xd7, 0x04, 0x6f, 0x69, + 0xd7, 0x04, 0x27, 0x23, 0x3b, 0x4d, 0x74, 0xe9, 0xb5, 0x70, 0xc4, 0xdd, 0xe5, 0x6d, 0x98, 0x90, + 0x5d, 0x80, 0xb7, 0x2d, 0x57, 0x60, 0x54, 0xde, 0xbe, 0xf3, 0xbb, 0x96, 0x69, 0x8d, 0xe7, 0xd6, + 0x82, 0x25, 0xcb, 0xcd, 0xff, 0x6a, 0x58, 0xd2, 0xf2, 0x9a, 0x58, 0x17, 0x16, 0xea, 0x75, 0x5f, + 0xed, 0x42, 0xa7, 0x5e, 0xf7, 0x2d, 0x84, 0xb2, 0x9d, 0xa4, 0xd2, 0xd9, 0x69, 0xb8, 0x35, 0xc4, + 0x51, 0xb4, 0xa0, 0x36, 0x42, 0x6d, 0x86, 0xaa, 0xce, 0xcc, 0x18, 0x59, 0xbb, 0x3a, 0xcc, 0xf6, + 0xbd, 0x3a, 0xfc, 0x21, 0x18, 0x2b, 0x36, 0xeb, 0xda, 0x2d, 0x81, 0x99, 0xd2, 0x29, 0xd7, 0x22, + 0x24, 0x2e, 0xd6, 0x91, 0xd1, 0xa3, 0xd6, 0xac, 0x77, 0xdf, 0x0d, 0xc4, 0x2c, 0xb5, 0xbb, 0xbf, + 0xe1, 0xa7, 0xb9, 0xfb, 0xbb, 0x05, 0x63, 0x9b, 0x01, 0xdd, 0xe8, 0xb4, 0x5a, 0xb4, 0x81, 0x9a, + 0x40, 0x8e, 0x2b, 0xae, 0x9d, 0x80, 0xda, 0x21, 0x42, 0xd5, 0x06, 0x44, 0xa8, 0xaa, 0x58, 0x8d, + 0xf6, 0x11, 0xab, 0xcf, 0xc2, 0x50, 0xa1, 0xdd, 0x96, 0x97, 0xa2, 0x91, 0xad, 0xb7, 0xdd, 0xc6, + 0x19, 0x3c, 0xe5, 0xb4, 0xdb, 0xfa, 0x15, 0x27, 0x62, 0xe3, 0x55, 0x20, 0xa5, 0x3e, 0x0e, 0xd0, + 0x78, 0xac, 0xd5, 0xb4, 0x29, 0xf5, 0x93, 0xc3, 0x13, 0x21, 0x6a, 0xf7, 0x87, 0x13, 0x03, 0xde, + 0x1f, 0x92, 0x97, 0x60, 0x42, 0x19, 0x76, 0x71, 0xf1, 0x68, 0x8d, 0xb7, 0xa3, 0x31, 0x0f, 0xce, + 0x55, 0x61, 0x4a, 0x1f, 0xa5, 0x67, 0x60, 0x79, 0xbf, 0x37, 0x94, 0xcb, 0xe5, 0xc7, 0xee, 0x0d, + 0xe5, 0x20, 0x3f, 0x6e, 0x91, 0xfb, 0x9d, 0x1d, 0xea, 0xb7, 0x68, 0x48, 0x03, 0xa1, 0x95, 0x06, + 0xe6, 0xb7, 0x32, 0x30, 0x5e, 0x68, 0xb7, 0x9f, 0x73, 0xcf, 0x86, 0xcf, 0x6b, 0xab, 0xc2, 0xe9, + 0x78, 0xf4, 0x8f, 0xe1, 0xd4, 0xf0, 0x9b, 0x19, 0x98, 0x4e, 0x50, 0xa8, 0xad, 0x37, 0x06, 0xbc, + 0xe9, 0xcf, 0x0c, 0x78, 0xd3, 0x9f, 0xed, 0x7d, 0xd3, 0xaf, 0xce, 0xb9, 0xa1, 0xa7, 0x99, 0x73, + 0xaf, 0x41, 0xb6, 0xd0, 0x6e, 0x27, 0x6f, 0x13, 0xda, 0xed, 0xad, 0x9b, 0x5c, 0xbb, 0x77, 0xda, + 0x6d, 0x8b, 0x61, 0x68, 0x22, 0x3d, 0x32, 0xa0, 0x48, 0x9b, 0x6f, 0xc2, 0x18, 0xf2, 0xc2, 0x65, + 0xf4, 0xa2, 0x98, 0x7f, 0x7c, 0x0d, 0xd5, 0xea, 0xe2, 0x73, 0xcd, 0xfc, 0xbf, 0xd8, 0x31, 0x92, + 0xfd, 0x7e, 0x4e, 0x65, 0x6c, 0x41, 0x93, 0xb1, 0xbc, 0x22, 0x63, 0x83, 0x48, 0xd7, 0x7f, 0x34, + 0x84, 0xbd, 0x25, 0xe4, 0x4a, 0xdc, 0x15, 0x1b, 0x29, 0x77, 0xc5, 0x4f, 0xb1, 0x6b, 0x3c, 0x48, + 0xde, 0x1a, 0x67, 0x71, 0x30, 0x5e, 0x4e, 0x36, 0xf5, 0x99, 0x5c, 0x18, 0x2f, 0x03, 0x29, 0xb7, + 0x02, 0x5a, 0xeb, 0xf8, 0xb4, 0xfa, 0xc0, 0x6d, 0x6f, 0x51, 0xdf, 0xdd, 0x3d, 0x10, 0x67, 0x6d, + 0x5c, 0xd8, 0x5d, 0x51, 0x6a, 0x07, 0x0f, 0xdc, 0x36, 0x3b, 0xe8, 0xb8, 0xbb, 0x07, 0x56, 0x0a, + 0x0d, 0x79, 0x1f, 0x46, 0x2d, 0xfa, 0xc8, 0x77, 0x43, 0x79, 0xa5, 0x33, 0x15, 0x1d, 0x4f, 0x10, + 0xca, 0xd5, 0x6f, 0x9f, 0xff, 0x50, 0xc7, 0x5f, 0x94, 0x93, 0x05, 0x7e, 0xcd, 0xc7, 0xaf, 0x6e, + 0x26, 0xe3, 0xaf, 0x2d, 0x6c, 0x57, 0x17, 0x67, 0x7a, 0x5c, 0x5d, 0x5f, 0x81, 0x61, 0xb4, 0xa9, + 0x88, 0x4d, 0x05, 0x9d, 0x3a, 0x6b, 0x0c, 0xa0, 0x1a, 0x14, 0x10, 0x83, 0x5c, 0x00, 0x88, 0x8c, + 0x99, 0xc1, 0x5c, 0x0e, 0x17, 0x6e, 0x05, 0xf2, 0xc9, 0xdd, 0x9a, 0x7e, 0x77, 0x18, 0xe7, 0xef, + 0x11, 0x5e, 0xc3, 0x7d, 0xfc, 0x0e, 0x74, 0x59, 0xca, 0x1e, 0x47, 0x96, 0xb6, 0x60, 0xa2, 0xca, + 0x56, 0x11, 0xdd, 0x01, 0xe1, 0x7c, 0xdc, 0xb9, 0xd7, 0xd4, 0xe2, 0x7e, 0xba, 0xb2, 0xc6, 0x87, + 0xd8, 0x49, 0x19, 0xe5, 0x2a, 0xf9, 0x8b, 0x0a, 0xe3, 0x14, 0xe9, 0x8c, 0x96, 0xbb, 0x1a, 0xef, + 0xac, 0x63, 0xcb, 0xe5, 0xc8, 0xd3, 0xc9, 0xe5, 0xe8, 0xc7, 0x92, 0xcb, 0x84, 0xab, 0x76, 0xee, + 0x38, 0xae, 0xda, 0xe7, 0xde, 0x87, 0x99, 0xae, 0x1e, 0x3e, 0xce, 0x01, 0xe3, 0x93, 0x13, 0xcb, + 0x1f, 0x01, 0x65, 0xe6, 0xe5, 0x2c, 0x5a, 0x77, 0x7d, 0x5a, 0x0b, 0x71, 0xe5, 0x17, 0x8b, 0xb5, + 0x2f, 0x60, 0x89, 0x2b, 0x63, 0x84, 0x91, 0xf7, 0x60, 0x94, 0x5b, 0x16, 0xf8, 0x89, 0x3e, 0x9e, + 0xb1, 0xc2, 0x0a, 0xc1, 0x3d, 0xf9, 0x39, 0x86, 0xda, 0xab, 0x82, 0xc8, 0xbc, 0x2b, 0x8d, 0x19, + 0x47, 0xcc, 0x8b, 0x79, 0x18, 0xde, 0x8a, 0x7b, 0x06, 0x5d, 0x04, 0xf9, 0x47, 0x58, 0x1c, 0x6e, + 0xfe, 0xb4, 0x01, 0x53, 0xfa, 0x57, 0x92, 0x6b, 0x30, 0x22, 0xfc, 0xa1, 0x0d, 0x3c, 0x62, 0xb2, + 0xaf, 0x19, 0xe1, 0x9e, 0xd0, 0x9a, 0xff, 0xb3, 0xc0, 0x62, 0x3b, 0x8f, 0xe0, 0x20, 0xac, 0x13, + 0xb8, 0xf3, 0x08, 0x21, 0xb5, 0x64, 0x19, 0x31, 0x61, 0xc4, 0xa2, 0x41, 0xa7, 0x11, 0xaa, 0xb6, + 0x37, 0x1f, 0x21, 0x96, 0x28, 0x31, 0x8b, 0x30, 0xc2, 0x97, 0xac, 0xc4, 0xbd, 0xa9, 0x71, 0x8c, + 0x7b, 0x53, 0xf3, 0xd0, 0x00, 0xa8, 0x56, 0x97, 0xef, 0xd3, 0x83, 0x8a, 0xe3, 0xfa, 0x68, 0x2c, + 0xc6, 0x29, 0x7d, 0x5f, 0x0c, 0xf9, 0x84, 0x30, 0x16, 0xf3, 0xe9, 0xff, 0x80, 0x1e, 0x68, 0xc6, + 0x62, 0x89, 0x8a, 0xeb, 0x86, 0xef, 0x3e, 0x74, 0x42, 0xca, 0x08, 0x33, 0x48, 0xc8, 0xd7, 0x0d, + 0x0e, 0x4d, 0x50, 0x2a, 0xc8, 0xe4, 0x6b, 0x30, 0x15, 0xff, 0x8a, 0x4c, 0xde, 0x53, 0x91, 0x58, + 0xe9, 0x85, 0x8b, 0x17, 0x9e, 0x1c, 0xce, 0x9f, 0x53, 0xb8, 0x26, 0x8d, 0xe1, 0x09, 0x66, 0xe6, + 0xaf, 0x1a, 0x78, 0x4b, 0x22, 0x3f, 0xf0, 0x12, 0x0c, 0x45, 0xde, 0x20, 0x13, 0xdc, 0x4a, 0x91, + 0x30, 0xeb, 0x61, 0x39, 0x79, 0x19, 0xb2, 0xf1, 0x97, 0xe0, 0x96, 0xa0, 0x7f, 0x01, 0x2b, 0x25, + 0x77, 0x61, 0x74, 0xa0, 0x36, 0xa3, 0x88, 0xa7, 0xb4, 0x55, 0x52, 0xe3, 0x28, 0xdc, 0xdb, 0xde, + 0xf8, 0xf4, 0x8e, 0xc2, 0xb7, 0x33, 0x30, 0xcd, 0xfa, 0xb5, 0xd0, 0x09, 0xf7, 0x3d, 0xdf, 0x0d, + 0x0f, 0x9e, 0x5b, 0x73, 0xc2, 0x3b, 0x9a, 0x52, 0x77, 0x4e, 0xae, 0x7d, 0xea, 0xb7, 0x0d, 0x64, + 0x55, 0xf8, 0x9d, 0x61, 0x38, 0x99, 0x42, 0x45, 0xde, 0xd0, 0xcc, 0x68, 0x73, 0x32, 0x88, 0xe9, + 0x07, 0x87, 0xf3, 0x13, 0x12, 0x7d, 0x23, 0x0e, 0x6a, 0x5a, 0xd0, 0xaf, 0x1c, 0x79, 0x4f, 0xa1, + 0x55, 0x4d, 0xbd, 0x72, 0xd4, 0x2f, 0x1a, 0xaf, 0xc0, 0xb0, 0xe5, 0x35, 0xa8, 0xbc, 0xf3, 0x46, + 0x45, 0xc6, 0x67, 0x00, 0xed, 0x66, 0x84, 0x01, 0xc8, 0x32, 0x8c, 0xb2, 0x3f, 0x56, 0x9d, 0xb6, + 0xb0, 0x25, 0x92, 0xe8, 0x58, 0x81, 0xd0, 0xb6, 0xdb, 0xda, 0x53, 0x4f, 0x16, 0x0d, 0x6a, 0x37, + 0x9d, 0xb6, 0xb6, 0xb3, 0x71, 0x44, 0xed, 0x84, 0x92, 0xeb, 0x7d, 0x42, 0x31, 0x8e, 0x3c, 0xa1, + 0xd4, 0x01, 0xaa, 0xee, 0x5e, 0xcb, 0x6d, 0xed, 0x15, 0x1a, 0x7b, 0x22, 0x14, 0xec, 0x4a, 0xef, + 0x51, 0xb8, 0x16, 0x23, 0xa3, 0xe0, 0x72, 0xc3, 0x3c, 0x87, 0xd9, 0x4e, 0x43, 0x33, 0x74, 0xc6, + 0xa8, 0x64, 0x0d, 0xa0, 0x50, 0x0b, 0xdd, 0x87, 0x4c, 0x80, 0x03, 0xe1, 0x7c, 0x27, 0x1b, 0x5c, + 0x2c, 0xdc, 0xa7, 0x07, 0x55, 0x1a, 0xc6, 0x86, 0x53, 0x07, 0x51, 0xd9, 0x3c, 0xd0, 0xfc, 0xe4, + 0x62, 0x0e, 0xa4, 0x0d, 0xa7, 0x0a, 0xf5, 0xba, 0xcb, 0xbe, 0xc0, 0x69, 0x6c, 0xf8, 0x6c, 0x30, + 0xea, 0xc8, 0x7a, 0x22, 0x9d, 0xf5, 0x15, 0xc1, 0xfa, 0x25, 0x27, 0xa2, 0xb2, 0x43, 0x4e, 0x96, + 0xac, 0x26, 0x9d, 0xb1, 0xb9, 0x0e, 0x53, 0xfa, 0xa7, 0xeb, 0x01, 0x6c, 0x13, 0x90, 0xb3, 0xaa, + 0x05, 0xbb, 0xba, 0x5c, 0xb8, 0x91, 0x37, 0x48, 0x1e, 0x26, 0xc4, 0xaf, 0x05, 0x7b, 0xe1, 0xad, + 0x5b, 0xf9, 0x8c, 0x06, 0x79, 0xeb, 0xc6, 0x42, 0x3e, 0x7b, 0x6f, 0x28, 0x97, 0xcd, 0x0f, 0xdd, + 0x1b, 0xca, 0x0d, 0xe5, 0x87, 0xef, 0x0d, 0xe5, 0x46, 0xf3, 0x39, 0x6e, 0x23, 0x30, 0xff, 0xae, + 0x01, 0x39, 0xd9, 0x6e, 0x72, 0x0b, 0xb2, 0xd5, 0xea, 0x72, 0xc2, 0x07, 0x39, 0xde, 0x5f, 0xf8, + 0x4a, 0x1a, 0x04, 0xaa, 0xbf, 0x0c, 0x23, 0x60, 0x74, 0x1b, 0x2b, 0x55, 0xb1, 0xbd, 0x4b, 0xba, + 0x78, 0xd9, 0xe6, 0x74, 0x29, 0x8e, 0x99, 0xb7, 0x20, 0x7b, 0x6f, 0x7b, 0x43, 0x1c, 0x5b, 0x24, + 0x5d, 0xbc, 0x92, 0x72, 0xba, 0x8f, 0x1e, 0xa9, 0xeb, 0x3b, 0x23, 0x30, 0x2d, 0x18, 0x57, 0x44, + 0x98, 0x6f, 0xb7, 0x4d, 0x2f, 0x0a, 0xee, 0x12, 0xdb, 0x2d, 0x83, 0x58, 0xa2, 0x84, 0x69, 0x07, + 0x2b, 0x5e, 0xcd, 0x69, 0x88, 0x7d, 0x1b, 0xb5, 0x83, 0x06, 0x03, 0x58, 0x1c, 0x6e, 0xfe, 0xb6, + 0x01, 0xf9, 0x8a, 0xef, 0x3d, 0x74, 0xd9, 0x32, 0xb3, 0xe1, 0x3d, 0xa0, 0xad, 0xad, 0x1b, 0xe4, + 0x4d, 0x39, 0xd9, 0x8c, 0xe8, 0x90, 0x3c, 0x8c, 0x93, 0x2d, 0x61, 0x72, 0x15, 0x13, 0x4e, 0x89, + 0x91, 0xcb, 0x0c, 0x1e, 0x77, 0x73, 0x44, 0x8c, 0xdc, 0x3c, 0x0c, 0x63, 0x73, 0x94, 0xd0, 0x87, + 0xe1, 0x90, 0x01, 0x2c, 0x0e, 0x57, 0x56, 0xa5, 0xef, 0x64, 0xba, 0xbe, 0x61, 0xe1, 0x53, 0x15, + 0xbb, 0xa2, 0x7f, 0xdc, 0x40, 0x2b, 0xf5, 0x07, 0x30, 0x9b, 0xec, 0x12, 0x34, 0x60, 0x14, 0x60, + 0x5a, 0x87, 0x4b, 0x5b, 0xc6, 0x99, 0xd4, 0xba, 0xb6, 0x16, 0xac, 0x24, 0xbe, 0xf9, 0x07, 0x06, + 0x8c, 0xe1, 0x9f, 0x56, 0xa7, 0x81, 0x97, 0xe0, 0x85, 0xed, 0xaa, 0xf0, 0x5e, 0x54, 0xd5, 0x38, + 0xe7, 0x51, 0x60, 0x0b, 0x57, 0x47, 0x6d, 0x7d, 0x89, 0x90, 0x05, 0x29, 0xf7, 0xd5, 0x94, 0xf7, + 0x5e, 0x11, 0x29, 0x77, 0xea, 0x0c, 0x12, 0xa4, 0x02, 0x19, 0xfd, 0x4e, 0xb6, 0xab, 0x4c, 0xfc, + 0xd4, 0xdb, 0x2e, 0xa4, 0xf3, 0x1a, 0xba, 0xdf, 0x09, 0x47, 0xc3, 0xcb, 0xae, 0xed, 0x6a, 0xc1, + 0x5a, 0xd3, 0x2e, 0xbb, 0x58, 0x1b, 0x35, 0xe7, 0x3a, 0x81, 0x64, 0xfe, 0xad, 0x5c, 0xb2, 0x03, + 0xc5, 0x56, 0x77, 0xcc, 0xb9, 0xf1, 0x36, 0x0c, 0x17, 0x1a, 0x0d, 0xef, 0x91, 0x58, 0x25, 0xa4, + 0x3d, 0x25, 0xea, 0x3f, 0xbe, 0x93, 0x39, 0x0c, 0x45, 0x73, 0xff, 0x66, 0x00, 0x52, 0x84, 0xb1, + 0xc2, 0x76, 0xb5, 0x5c, 0x2e, 0x6d, 0x6c, 0xac, 0x88, 0x80, 0xe5, 0x57, 0x65, 0xff, 0xb8, 0x6e, + 0xdd, 0x4e, 0xde, 0x0a, 0xc5, 0x9a, 0x7b, 0x4c, 0x47, 0xde, 0x05, 0xb8, 0xe7, 0xb9, 0xad, 0x55, + 0x1a, 0xee, 0x7b, 0x75, 0xf1, 0xf1, 0x2f, 0x3e, 0x39, 0x9c, 0x1f, 0xff, 0xc8, 0x73, 0x5b, 0x76, + 0x13, 0xc1, 0xac, 0xed, 0x31, 0x92, 0xa5, 0xfc, 0xcd, 0x7a, 0x7a, 0xd1, 0xe3, 0x17, 0xdb, 0xc3, + 0x71, 0x4f, 0xef, 0x78, 0x5d, 0x77, 0xda, 0x12, 0x8d, 0x34, 0x61, 0xba, 0xda, 0xd9, 0xdb, 0xa3, + 0x6c, 0x55, 0x17, 0xa7, 0xdf, 0x11, 0x71, 0xe6, 0x8a, 0xc2, 0xbd, 0xf9, 0x49, 0x84, 0x9d, 0x4f, + 0x82, 0xc5, 0x37, 0x98, 0x20, 0x7f, 0xff, 0x70, 0x5e, 0xdc, 0x36, 0x31, 0x25, 0x2d, 0x90, 0xf4, + 0xdd, 0xf6, 0x99, 0x24, 0x6f, 0xb2, 0x0e, 0x23, 0x77, 0xdd, 0x70, 0xb9, 0xb3, 0x23, 0x8e, 0xaf, + 0x2f, 0xf5, 0x99, 0x34, 0x1c, 0x91, 0x9f, 0xe0, 0xf7, 0xdc, 0x70, 0xbf, 0xa3, 0x7a, 0xa3, 0x0a, + 0x36, 0x64, 0x1b, 0x72, 0x45, 0xd7, 0xaf, 0x35, 0x68, 0xb1, 0x2c, 0x76, 0xfd, 0x97, 0xfb, 0xb0, + 0x94, 0xa8, 0xbc, 0x5f, 0x6a, 0xf8, 0xab, 0xe6, 0xaa, 0x5a, 0x80, 0xc4, 0x20, 0xff, 0xae, 0x01, + 0x2f, 0x44, 0xad, 0x2f, 0xec, 0xd1, 0x56, 0xb8, 0xea, 0x84, 0xb5, 0x7d, 0xea, 0x47, 0x91, 0x4e, + 0x7d, 0x7a, 0xe9, 0x0b, 0x5d, 0xbd, 0x74, 0x39, 0xee, 0x25, 0x87, 0x31, 0xb3, 0x9b, 0x9c, 0x5b, + 0x77, 0x9f, 0xf5, 0xab, 0x95, 0xd8, 0x00, 0xb1, 0xc1, 0x5c, 0xb8, 0xfe, 0xbf, 0xda, 0xe7, 0x83, + 0x63, 0x64, 0xe1, 0xd0, 0x19, 0xfd, 0xd6, 0xfc, 0x38, 0x22, 0x28, 0xb9, 0x2f, 0xdd, 0xbd, 0xb9, + 0x46, 0x72, 0xb1, 0x0f, 0x6f, 0xee, 0x02, 0x7e, 0xb2, 0x4f, 0x44, 0x04, 0x1f, 0xed, 0x15, 0x67, + 0x47, 0x28, 0x21, 0x47, 0x8c, 0xf6, 0x8a, 0x13, 0x8f, 0x76, 0xc3, 0x49, 0x8e, 0xf6, 0x8a, 0xb3, + 0x43, 0x8a, 0x3c, 0xb8, 0x63, 0x12, 0xb9, 0x5d, 0xe8, 0xc7, 0xad, 0x58, 0xe1, 0x3b, 0x73, 0x77, + 0x90, 0x87, 0xf9, 0x6f, 0x86, 0xe0, 0x5c, 0x6f, 0x79, 0x23, 0x5f, 0x92, 0x8b, 0x00, 0x5f, 0x6a, + 0x2f, 0x1d, 0x29, 0xa1, 0xd7, 0x8e, 0x5c, 0x1a, 0xbe, 0x0c, 0xb3, 0x4b, 0xad, 0x90, 0xfa, 0x6d, + 0xdf, 0x95, 0xc1, 0x70, 0xcb, 0x5e, 0x20, 0x9d, 0x3f, 0x5e, 0x79, 0x72, 0x38, 0x7f, 0x91, 0x46, + 0xe5, 0xc2, 0x0f, 0x08, 0x5d, 0x51, 0x14, 0x56, 0xa9, 0x1c, 0xce, 0xfd, 0x6a, 0x16, 0x86, 0x70, + 0x65, 0x7f, 0x19, 0xb2, 0xd5, 0xce, 0x8e, 0x58, 0xd2, 0xb9, 0x0e, 0xa4, 0xcd, 0x17, 0x56, 0x4a, + 0x3e, 0x0f, 0x60, 0xd1, 0xb6, 0x17, 0xb8, 0xa1, 0xe7, 0x1f, 0xa8, 0x9e, 0xb2, 0x7e, 0x04, 0xd5, + 0x5d, 0xa0, 0x24, 0x94, 0x2c, 0xc3, 0x74, 0xfc, 0x6b, 0xfd, 0x51, 0x8b, 0x4a, 0xd3, 0x1d, 0x1e, + 0xd3, 0x62, 0x72, 0xdb, 0x63, 0x65, 0xea, 0x0a, 0x90, 0x20, 0x23, 0x0b, 0x90, 0xdb, 0xf6, 0xfc, + 0x07, 0xbb, 0xac, 0x87, 0x87, 0xe2, 0x35, 0xea, 0x91, 0x80, 0xa9, 0x73, 0x51, 0xe2, 0x91, 0xb7, + 0x61, 0x7c, 0xa9, 0xf5, 0xd0, 0xf5, 0xbd, 0x56, 0x93, 0xb6, 0xa4, 0xaf, 0x0f, 0x37, 0x3f, 0xc4, + 0x60, 0xcd, 0x99, 0x3e, 0x06, 0xb3, 0xc3, 0x48, 0xa1, 0x16, 0x7a, 0xbe, 0x70, 0xf5, 0xe1, 0xe3, + 0xc4, 0x00, 0xda, 0x38, 0x31, 0x00, 0xeb, 0x44, 0x8b, 0xee, 0x0a, 0xf3, 0x2b, 0x76, 0xa2, 0x4f, + 0x77, 0xb5, 0x48, 0x01, 0xba, 0xcb, 0xd6, 0x58, 0x8b, 0xee, 0xe2, 0x09, 0x2a, 0x17, 0xb7, 0xdf, + 0xa7, 0xbb, 0x5d, 0x67, 0x6f, 0x81, 0x66, 0xfe, 0x5a, 0x6f, 0x81, 0x63, 0x42, 0x7d, 0x3c, 0x81, + 0x5b, 0x71, 0x06, 0x10, 0xb8, 0x37, 0x22, 0xc7, 0xaa, 0x4c, 0x1c, 0x79, 0xc1, 0x1d, 0xab, 0xd4, + 0x59, 0xc5, 0x71, 0xce, 0xfd, 0xff, 0x8f, 0x25, 0x44, 0xa2, 0x93, 0x32, 0x83, 0x76, 0x52, 0x76, + 0xa0, 0x4e, 0x22, 0x8b, 0x30, 0x19, 0x25, 0x94, 0xa8, 0x38, 0xc2, 0xaf, 0x5a, 0x38, 0x26, 0x45, + 0xe9, 0x41, 0xec, 0xb6, 0x13, 0xaa, 0x9a, 0xbd, 0x4e, 0x42, 0xde, 0x81, 0x71, 0xe1, 0x5d, 0x88, + 0x1c, 0x86, 0x63, 0xb7, 0x4c, 0xe9, 0x8a, 0x98, 0xa0, 0x57, 0xd1, 0xc9, 0x12, 0x4c, 0x55, 0xdc, + 0x36, 0x6d, 0xb8, 0x2d, 0x5a, 0x45, 0x17, 0x24, 0x21, 0x31, 0xe8, 0xa5, 0xd7, 0x16, 0x25, 0x36, + 0xf7, 0x4e, 0xd2, 0x0c, 0x11, 0x1a, 0x51, 0x52, 0x58, 0x47, 0x8f, 0x23, 0xac, 0xe6, 0xdf, 0xcd, + 0xc0, 0xf9, 0x7e, 0x1b, 0x17, 0xa9, 0xea, 0xc2, 0x72, 0x79, 0x80, 0xcd, 0xee, 0x68, 0x71, 0x59, + 0x82, 0xa9, 0x75, 0x7f, 0xcf, 0x69, 0xb9, 0xdf, 0x44, 0x85, 0x24, 0xf2, 0x8f, 0xc4, 0x2f, 0xf7, + 0x94, 0x12, 0xdd, 0xca, 0x97, 0x20, 0x3a, 0xf7, 0x50, 0x88, 0xd1, 0xc7, 0xf5, 0x07, 0xbd, 0x05, + 0x63, 0x45, 0xaf, 0x15, 0xd2, 0xc7, 0x61, 0xc2, 0x8f, 0x9f, 0x03, 0x93, 0x7e, 0xfc, 0x12, 0xd5, + 0xfc, 0x1d, 0x03, 0x2e, 0xf4, 0xdf, 0xfc, 0xc8, 0xa6, 0xde, 0x6d, 0x57, 0x07, 0xda, 0x32, 0x8f, + 0xec, 0xb8, 0x73, 0xab, 0xe2, 0x8b, 0x97, 0x60, 0x4a, 0x38, 0xb4, 0xe8, 0xba, 0x35, 0x76, 0xa0, + 0x70, 0x0c, 0x4b, 0xd1, 0xaf, 0x13, 0x44, 0xe6, 0x9f, 0x18, 0x70, 0xb6, 0xe7, 0x4e, 0x4b, 0x2a, + 0xfa, 0x37, 0xbc, 0x7a, 0xd4, 0xd6, 0x7c, 0x74, 0xf3, 0x7f, 0xd6, 0x10, 0xed, 0x7f, 0x0f, 0x26, + 0xaa, 0x9d, 0x9d, 0x64, 0x90, 0x3c, 0xce, 0x9c, 0x40, 0x81, 0x6b, 0x37, 0x28, 0x0a, 0x9c, 0x7d, + 0xbf, 0xf4, 0xdb, 0x13, 0x57, 0x52, 0xfc, 0x80, 0x80, 0xdf, 0x1f, 0x39, 0xd8, 0xa2, 0xff, 0xb3, + 0xaa, 0x78, 0x24, 0x88, 0xcc, 0xdf, 0xcc, 0xc0, 0x99, 0x1e, 0xbb, 0x39, 0x59, 0xd3, 0xbf, 0xfe, + 0xe5, 0xfe, 0x9b, 0xff, 0xd1, 0xdf, 0xfe, 0x8f, 0xe4, 0xb7, 0xa3, 0x49, 0x53, 0x88, 0xa0, 0x3c, + 0x28, 0x08, 0x93, 0xa6, 0x14, 0xd7, 0x40, 0x37, 0x69, 0x4a, 0x64, 0xf2, 0x16, 0x8c, 0xb1, 0x83, + 0x79, 0xa8, 0x1c, 0x89, 0xb8, 0x07, 0xaa, 0x04, 0xaa, 0xf2, 0x1a, 0x61, 0xb2, 0xcd, 0x54, 0x1f, + 0x78, 0xe9, 0x25, 0x85, 0x9b, 0x69, 0x42, 0x5c, 0x74, 0x75, 0x5a, 0x27, 0x33, 0x7f, 0x36, 0x03, + 0x53, 0xfc, 0x46, 0x86, 0x1f, 0xf7, 0x9e, 0xdb, 0xa3, 0xf4, 0xdb, 0xda, 0x51, 0x5a, 0xc6, 0x7e, + 0xa9, 0x9f, 0x36, 0xd0, 0x41, 0x7a, 0x1f, 0x48, 0x37, 0x0d, 0xb1, 0xe4, 0xbd, 0xe1, 0x20, 0x67, + 0xe8, 0x1b, 0x71, 0x98, 0x20, 0x66, 0xc7, 0xaa, 0xd9, 0x68, 0xc8, 0x08, 0x2c, 0x8d, 0x87, 0xf9, + 0xd3, 0x19, 0x98, 0x54, 0x4c, 0x9e, 0xcf, 0x6d, 0xc7, 0x7f, 0x41, 0xeb, 0x78, 0x19, 0xfd, 0xab, + 0x7c, 0xd9, 0x40, 0xfd, 0xde, 0x81, 0x99, 0x2e, 0x92, 0xa4, 0xe5, 0xd8, 0x18, 0xc4, 0x72, 0xfc, + 0x46, 0x77, 0x28, 0x17, 0x4f, 0x42, 0x14, 0x85, 0x72, 0xa9, 0xb1, 0x63, 0xdf, 0xce, 0xc0, 0xac, + 0xf8, 0x55, 0xe8, 0xd4, 0xdd, 0xb0, 0xe8, 0xb5, 0x76, 0xdd, 0xbd, 0xe7, 0x76, 0x2c, 0x0a, 0xda, + 0x58, 0xcc, 0xeb, 0x63, 0xa1, 0x7c, 0x60, 0xef, 0x21, 0x31, 0xff, 0x02, 0xc0, 0x5c, 0x2f, 0x82, + 0x81, 0xfd, 0x67, 0xe3, 0xb8, 0xdd, 0xcc, 0x00, 0x71, 0xbb, 0x2b, 0x90, 0xc7, 0xaa, 0xaa, 0x34, + 0x60, 0x9d, 0x10, 0xc4, 0x19, 0x50, 0x2e, 0x3e, 0x39, 0x9c, 0x3f, 0xef, 0xb0, 0x32, 0x3b, 0x10, + 0x85, 0x76, 0xc7, 0x57, 0x8f, 0xdb, 0x5d, 0x94, 0xe4, 0x57, 0x0d, 0x98, 0x42, 0xe0, 0xd2, 0x43, + 0xda, 0x0a, 0x91, 0xd9, 0x90, 0x70, 0xa0, 0x8a, 0x4e, 0xda, 0xd5, 0xd0, 0x77, 0x5b, 0x7b, 0xe2, + 0xa8, 0xbd, 0x23, 0x8e, 0xda, 0xef, 0x70, 0x13, 0xc1, 0xb5, 0x9a, 0xd7, 0xbc, 0xbe, 0xe7, 0x3b, + 0x0f, 0x5d, 0x6e, 0xcd, 0x77, 0x1a, 0xd7, 0xe3, 0x04, 0x78, 0x6d, 0x37, 0x91, 0xd2, 0x4e, 0xb0, + 0x42, 0x33, 0x06, 0x6f, 0x28, 0xc5, 0x6a, 0x13, 0xcd, 0x4c, 0xb4, 0x88, 0x7c, 0x05, 0xce, 0xf0, + 0x30, 0x27, 0xa6, 0x83, 0xb8, 0xad, 0x8e, 0xd7, 0x09, 0x16, 0x9d, 0xda, 0x03, 0xb6, 0xef, 0xf1, + 0x4b, 0x7d, 0xfc, 0xf2, 0x5a, 0x54, 0x68, 0xef, 0xf0, 0x52, 0x85, 0x65, 0x2f, 0x06, 0x64, 0x19, + 0x66, 0x78, 0x51, 0xa1, 0x13, 0x7a, 0xd5, 0x9a, 0xd3, 0x70, 0x5b, 0x7b, 0xa8, 0x44, 0xe6, 0xf8, + 0x7e, 0xec, 0x74, 0x42, 0xcf, 0x0e, 0x38, 0x5c, 0xe1, 0xd7, 0x4d, 0x44, 0xca, 0xec, 0xcc, 0xe6, + 0xd4, 0x57, 0x9d, 0xc7, 0x45, 0xa7, 0xed, 0xd4, 0xdc, 0x90, 0x47, 0xeb, 0x66, 0x79, 0x80, 0x88, + 0x4f, 0x9d, 0xba, 0xdd, 0x74, 0x1e, 0xdb, 0x35, 0x51, 0xa8, 0x1f, 0xda, 0x34, 0xba, 0x88, 0x95, + 0xdb, 0x8a, 0x58, 0x8d, 0x25, 0x59, 0xb9, 0xad, 0xde, 0xac, 0x62, 0x3a, 0xc9, 0x6a, 0xc3, 0xf1, + 0xf7, 0x68, 0xc8, 0x2f, 0xc3, 0xe1, 0xa2, 0x71, 0xd9, 0x50, 0x58, 0x85, 0x58, 0x66, 0xe3, 0xc5, + 0x78, 0x92, 0x95, 0x42, 0xc7, 0x24, 0x6f, 0xdb, 0x77, 0x43, 0xaa, 0x7e, 0xe1, 0x38, 0x36, 0x0b, + 0xfb, 0x1f, 0xdd, 0x01, 0x7a, 0x7d, 0x62, 0x17, 0x65, 0xcc, 0x4d, 0xf9, 0xc8, 0x89, 0x2e, 0x6e, + 0xe9, 0x5f, 0xd9, 0x45, 0x19, 0x71, 0x53, 0xbf, 0x73, 0x12, 0xbf, 0x53, 0xe1, 0xd6, 0xe3, 0x43, + 0xbb, 0x28, 0xc9, 0x1a, 0xeb, 0xb4, 0x90, 0xb6, 0x98, 0x44, 0x0b, 0x67, 0x80, 0x29, 0x6c, 0xda, + 0x2b, 0xe2, 0x46, 0x2b, 0xef, 0xcb, 0x62, 0x3b, 0xc5, 0x35, 0x20, 0x49, 0x4c, 0xfe, 0x1c, 0x4c, + 0x6f, 0x06, 0xf4, 0x4e, 0xb9, 0x52, 0x95, 0x81, 0x5d, 0x73, 0xd3, 0x78, 0xcf, 0x75, 0xe3, 0x88, + 0x45, 0xe7, 0x9a, 0x4a, 0x83, 0xa9, 0xe8, 0xf8, 0xb8, 0x75, 0x02, 0x6a, 0xef, 0xba, 0xed, 0x20, + 0x0a, 0x31, 0x55, 0xc7, 0x2d, 0x51, 0x95, 0xb9, 0x0c, 0x33, 0x5d, 0x6c, 0xc8, 0x14, 0x00, 0x03, + 0xda, 0x9b, 0x6b, 0xd5, 0xa5, 0x8d, 0xfc, 0x09, 0x92, 0x87, 0x09, 0xfc, 0xbd, 0xb4, 0x56, 0x58, + 0x5c, 0x59, 0x2a, 0xe5, 0x0d, 0x32, 0x03, 0x93, 0x08, 0x29, 0x95, 0xab, 0x1c, 0x94, 0xb9, 0x37, + 0x94, 0x1b, 0xce, 0x8f, 0x58, 0x79, 0x3e, 0x75, 0x43, 0x36, 0x01, 0x70, 0x4f, 0x31, 0xff, 0x72, + 0x06, 0xce, 0xca, 0x6d, 0x85, 0x86, 0x8f, 0x3c, 0xff, 0x81, 0xdb, 0xda, 0x7b, 0xce, 0x77, 0x87, + 0x3b, 0xda, 0xee, 0xf0, 0x4a, 0x62, 0xa7, 0x4e, 0x7c, 0x65, 0x9f, 0x2d, 0xe2, 0x17, 0x47, 0xe1, + 0xc5, 0xbe, 0x54, 0xe4, 0x4b, 0x6c, 0x37, 0x77, 0x69, 0x2b, 0x2c, 0xd7, 0x1b, 0x74, 0xc3, 0x6d, + 0x52, 0xaf, 0x13, 0x0a, 0xe7, 0x93, 0x97, 0x99, 0x7a, 0xcb, 0xf3, 0xc8, 0xd9, 0x6e, 0xbd, 0x41, + 0xed, 0x90, 0x17, 0x6b, 0xe2, 0xd6, 0x4d, 0xcd, 0x58, 0x46, 0xb9, 0x2e, 0xcb, 0xad, 0x90, 0xfa, + 0x0f, 0x1d, 0x9e, 0x4e, 0x4b, 0xb0, 0x7c, 0x40, 0x69, 0xdb, 0x76, 0x58, 0xa9, 0xed, 0x8a, 0x62, + 0x9d, 0x65, 0x17, 0x35, 0xb9, 0xa3, 0xb0, 0x2c, 0x32, 0x75, 0x78, 0xd5, 0x79, 0x2c, 0xec, 0xee, + 0x22, 0xe4, 0x3d, 0x62, 0xc9, 0x53, 0x38, 0x34, 0x9d, 0xc7, 0x56, 0x37, 0x09, 0xf9, 0x1a, 0x9c, + 0x12, 0x1b, 0x90, 0x88, 0xb9, 0x90, 0x5f, 0xcc, 0x23, 0x3a, 0x5e, 0x7b, 0x72, 0x38, 0x7f, 0x46, + 0x6c, 0x5f, 0xb6, 0x8c, 0x5f, 0x49, 0xfb, 0xea, 0x74, 0x2e, 0x64, 0x83, 0x6d, 0xc8, 0x89, 0xee, + 0x58, 0xa5, 0x41, 0xe0, 0xec, 0x49, 0x1b, 0x3d, 0xf7, 0x00, 0x53, 0x3a, 0xd3, 0x6e, 0xf2, 0x72, + 0xab, 0x27, 0x25, 0x59, 0x86, 0xa9, 0x6d, 0xba, 0xa3, 0x8e, 0xcf, 0x48, 0xb4, 0x54, 0xe5, 0x1f, + 0xd1, 0x9d, 0xde, 0x83, 0x93, 0xa0, 0x23, 0x2e, 0xcc, 0xa0, 0xf7, 0xec, 0x8a, 0x1b, 0x84, 0xb4, + 0x45, 0x7d, 0x8c, 0x66, 0x1b, 0xc5, 0xc5, 0x60, 0x2e, 0xd6, 0x90, 0xf5, 0xf2, 0xc5, 0x97, 0x9e, + 0x1c, 0xce, 0xbf, 0xc8, 0x3d, 0x71, 0x1b, 0x02, 0x6e, 0x27, 0x92, 0x4a, 0x76, 0x73, 0x25, 0x5f, + 0x87, 0x69, 0xcb, 0xeb, 0x84, 0x6e, 0x6b, 0xaf, 0x1a, 0xfa, 0x4e, 0x48, 0xf7, 0xf8, 0x86, 0x14, + 0x87, 0xcd, 0x25, 0x4a, 0x85, 0x71, 0x91, 0x03, 0xed, 0x40, 0x40, 0xb5, 0x1d, 0x41, 0x27, 0x20, + 0x3f, 0x04, 0x53, 0xdc, 0x45, 0x3f, 0xaa, 0x60, 0x4c, 0xcb, 0xbf, 0xa4, 0x17, 0x6e, 0xdd, 0xe0, + 0x07, 0x54, 0xee, 0xea, 0x9f, 0x56, 0x41, 0x82, 0x1b, 0xf9, 0x50, 0x74, 0x56, 0xc5, 0x6d, 0xed, + 0x45, 0x62, 0x0c, 0xd8, 0xf3, 0x6f, 0xc6, 0x5d, 0xd2, 0x66, 0xcd, 0x95, 0x62, 0xdc, 0xe3, 0xce, + 0xa7, 0x9b, 0x8f, 0x79, 0x68, 0x40, 0x3e, 0xd9, 0x40, 0xf2, 0x65, 0x18, 0xe3, 0xd7, 0x00, 0x34, + 0xd8, 0x17, 0x91, 0x72, 0xd2, 0xee, 0x1d, 0xc1, 0x75, 0x22, 0x91, 0xb7, 0x84, 0x5f, 0x32, 0x50, + 0xf5, 0x22, 0x7c, 0xf9, 0x84, 0x15, 0x33, 0x23, 0x75, 0x98, 0xe0, 0x6d, 0xa0, 0x18, 0x09, 0x2a, + 0x6e, 0x83, 0x5f, 0x52, 0xc7, 0x5c, 0x14, 0x25, 0xf8, 0x63, 0xb0, 0xa4, 0xf8, 0x52, 0x8e, 0xa0, + 0x55, 0xa1, 0x71, 0x5d, 0x04, 0xc8, 0x49, 0x42, 0xf3, 0x2c, 0x9c, 0xe9, 0xd1, 0x66, 0xf3, 0x21, + 0x5a, 0x48, 0x7b, 0xd4, 0x48, 0xbe, 0x0c, 0xb3, 0x48, 0x58, 0xf4, 0x5a, 0x2d, 0x5a, 0x0b, 0x71, + 0x92, 0x49, 0x23, 0x4b, 0x96, 0xdb, 0xcf, 0xf9, 0xf7, 0xd6, 0x22, 0x04, 0x3b, 0x69, 0x6b, 0x49, + 0xe5, 0x60, 0xfe, 0x52, 0x06, 0xe6, 0xc4, 0xbc, 0xb5, 0x68, 0xcd, 0xf3, 0xeb, 0xcf, 0xff, 0x3e, + 0xb1, 0xa4, 0xed, 0x13, 0x2f, 0x47, 0x81, 0x37, 0x69, 0x1f, 0xd9, 0x67, 0x9b, 0xf8, 0x4d, 0x03, + 0xce, 0xf7, 0x23, 0x62, 0xbd, 0x13, 0x45, 0xbe, 0x8e, 0x75, 0x45, 0xb8, 0xb6, 0xe1, 0x24, 0x0e, + 0x68, 0x71, 0x9f, 0xd6, 0x1e, 0x04, 0xcb, 0x5e, 0x10, 0xa2, 0x33, 0x4a, 0x46, 0x73, 0x54, 0x5f, + 0xf4, 0x3c, 0x7e, 0x63, 0x86, 0xd7, 0x8a, 0xc6, 0xf7, 0x0f, 0xe7, 0x81, 0x81, 0x78, 0xac, 0xaa, + 0x30, 0xdb, 0x3e, 0x3e, 0xb0, 0x6b, 0xc8, 0x83, 0xc7, 0xe6, 0x3e, 0xa0, 0x07, 0x81, 0x95, 0xc6, + 0x1a, 0x1d, 0x0b, 0x0a, 0x9d, 0x70, 0xbf, 0xe2, 0xd3, 0x5d, 0xea, 0xd3, 0x56, 0x8d, 0x7e, 0xca, + 0x1c, 0x0b, 0xf4, 0x8f, 0x1b, 0xe8, 0x5c, 0xfe, 0xbf, 0x01, 0xcc, 0xa6, 0x91, 0xb1, 0x7e, 0x51, + 0x8e, 0x82, 0xc9, 0x44, 0xd6, 0x7f, 0xde, 0x80, 0x89, 0x2a, 0xad, 0x79, 0xad, 0xfa, 0x1d, 0xbc, + 0x29, 0x11, 0xbd, 0x63, 0xf3, 0xad, 0x90, 0xc1, 0xed, 0xdd, 0xc4, 0x15, 0xca, 0x0f, 0x0e, 0xe7, + 0xbf, 0x38, 0xd8, 0x09, 0xac, 0xe6, 0x61, 0x88, 0x61, 0x88, 0x99, 0x8c, 0xa2, 0x2a, 0xd0, 0xe3, + 0x4c, 0xab, 0x94, 0x2c, 0xc2, 0xa4, 0x98, 0xae, 0x9e, 0x1a, 0xf8, 0x8c, 0x37, 0x02, 0x35, 0x59, + 0xd0, 0x95, 0xe9, 0x41, 0x23, 0x21, 0x37, 0x21, 0xbb, 0xb9, 0x70, 0x47, 0x8c, 0x81, 0x8c, 0xc0, + 0xda, 0x5c, 0xb8, 0x83, 0x46, 0x1e, 0xa6, 0x38, 0x4f, 0x76, 0x16, 0xb4, 0xcb, 0x8b, 0xcd, 0x85, + 0x3b, 0xe4, 0x47, 0xe1, 0x54, 0xc9, 0x0d, 0x44, 0x15, 0xdc, 0xc5, 0xa5, 0x8e, 0x2e, 0x9d, 0x23, + 0x3d, 0xa4, 0xf7, 0x73, 0xa9, 0xd2, 0xfb, 0x52, 0x3d, 0x62, 0x62, 0x73, 0xff, 0x99, 0x7a, 0x32, + 0xc0, 0x3b, 0xbd, 0x1e, 0xf2, 0x11, 0x4c, 0xa1, 0x91, 0x12, 0xbd, 0x7e, 0x30, 0xc9, 0xcc, 0x68, + 0x8f, 0x9a, 0x3f, 0x93, 0x5a, 0xf3, 0x39, 0xb4, 0x79, 0xda, 0xe8, 0x3b, 0x84, 0x09, 0x69, 0xb4, + 0xb3, 0xac, 0xc6, 0x99, 0xdc, 0x83, 0x69, 0xa1, 0x54, 0xac, 0xef, 0x6e, 0xec, 0xd3, 0x92, 0x73, + 0x20, 0xae, 0xb5, 0xf0, 0x9c, 0x22, 0x34, 0x11, 0xdb, 0xdb, 0xb5, 0xc3, 0x7d, 0x6a, 0xd7, 0x1d, + 0x6d, 0xfb, 0x4d, 0x10, 0x92, 0x1f, 0x86, 0xf1, 0x15, 0xaf, 0xc6, 0xf4, 0x49, 0x5c, 0x19, 0xc6, + 0x90, 0xcf, 0x07, 0x98, 0x55, 0x99, 0x83, 0x13, 0x4a, 0xc2, 0x0f, 0x0e, 0xe7, 0xdf, 0x3e, 0xae, + 0xd0, 0x28, 0x15, 0x58, 0x6a, 0x6d, 0xa4, 0x08, 0xb9, 0x6d, 0xba, 0xc3, 0xbe, 0x36, 0x99, 0x11, + 0x54, 0x82, 0xc5, 0x4d, 0xa3, 0xf8, 0xa5, 0xdd, 0x34, 0x0a, 0x18, 0xf1, 0x61, 0x06, 0xfb, 0xa7, + 0xe2, 0x04, 0xc1, 0x23, 0xcf, 0xaf, 0x63, 0x42, 0xaa, 0xf1, 0x1e, 0x9d, 0xbf, 0x90, 0xda, 0xf9, + 0xe7, 0x79, 0xe7, 0xb7, 0x15, 0x0e, 0xaa, 0x5a, 0xd4, 0xc5, 0x9e, 0x7c, 0x1d, 0xa6, 0x2c, 0xfa, + 0x8d, 0x8e, 0xeb, 0xd3, 0xd5, 0x3b, 0x05, 0x9c, 0x95, 0x13, 0x9a, 0x63, 0xac, 0x5e, 0xc8, 0x75, + 0x2f, 0x9f, 0xc3, 0xa4, 0x5d, 0xc5, 0x6e, 0xee, 0x3a, 0xba, 0x5d, 0x5d, 0x25, 0x21, 0x15, 0x18, + 0x2f, 0xd1, 0x87, 0x6e, 0x8d, 0xa2, 0xfb, 0x9e, 0xb8, 0x3e, 0x8f, 0x32, 0x14, 0xc6, 0x25, 0xdc, + 0xc2, 0x50, 0x47, 0x00, 0x77, 0x06, 0xd4, 0x23, 0x01, 0x22, 0x44, 0x72, 0x0b, 0xb2, 0xe5, 0x52, + 0x05, 0x0f, 0xa1, 0xb1, 0x57, 0x5c, 0xb9, 0x5e, 0x91, 0x69, 0xe9, 0xf0, 0x5e, 0xd0, 0xad, 0x6b, + 0x77, 0xef, 0xe5, 0x52, 0x85, 0xec, 0xc2, 0x24, 0x76, 0xc0, 0x32, 0x75, 0x78, 0xdf, 0x4e, 0xf7, + 0xe8, 0xdb, 0x6b, 0xa9, 0x7d, 0x3b, 0xc7, 0xfb, 0x76, 0x5f, 0x50, 0x6b, 0x79, 0xb6, 0x54, 0xb6, + 0x4c, 0x51, 0x2b, 0xd1, 0x5d, 0xa7, 0xd3, 0x90, 0xc6, 0xa5, 0x8d, 0x8d, 0x95, 0xb9, 0x7c, 0xac, + 0xa8, 0xd5, 0x79, 0x61, 0xd4, 0x7f, 0xbd, 0x9d, 0x73, 0xba, 0xf9, 0x88, 0x53, 0xe7, 0x8c, 0xe8, + 0x64, 0x51, 0xb0, 0x7a, 0xa7, 0x60, 0xfe, 0x27, 0x06, 0x2e, 0x37, 0xe4, 0x2a, 0x46, 0x95, 0x45, + 0x97, 0x5f, 0x68, 0x3f, 0x73, 0xda, 0x89, 0x94, 0x30, 0x1c, 0x85, 0xbc, 0x01, 0x23, 0x77, 0x9c, + 0x1a, 0x0d, 0xe5, 0x05, 0x02, 0x22, 0xef, 0x22, 0x44, 0x35, 0xb6, 0x71, 0x1c, 0xa6, 0x09, 0xf1, + 0x61, 0x28, 0xc4, 0xaf, 0x37, 0x14, 0x0b, 0xf2, 0xfe, 0x00, 0x35, 0x21, 0x31, 0x7c, 0xca, 0xf3, + 0x0e, 0x76, 0x4d, 0xcb, 0xae, 0x98, 0xca, 0xc1, 0xfc, 0xdf, 0x8d, 0x78, 0xfe, 0x90, 0xd7, 0x60, + 0xc8, 0xaa, 0x44, 0xed, 0xe7, 0xfe, 0xbb, 0x89, 0xe6, 0x23, 0x02, 0xf9, 0x10, 0x4e, 0x29, 0x7c, + 0x70, 0x0c, 0x68, 0x9d, 0x35, 0x88, 0x7f, 0xcc, 0xab, 0xe8, 0x60, 0xaa, 0xb4, 0xc4, 0xe1, 0x18, + 0x89, 0x16, 0xa5, 0xf3, 0x40, 0xb5, 0x2f, 0x2e, 0x28, 0xd1, 0x96, 0xcb, 0x79, 0x2b, 0x1f, 0xab, + 0xf2, 0xae, 0x23, 0x42, 0xf2, 0x63, 0xd3, 0x38, 0x70, 0x1f, 0x53, 0xf3, 0xb7, 0x0c, 0x6d, 0x5e, + 0x44, 0x99, 0xf2, 0x8d, 0x23, 0x32, 0xe5, 0xdf, 0x06, 0x28, 0x74, 0x42, 0x6f, 0xa9, 0xe5, 0x7b, + 0x0d, 0x7e, 0x8a, 0x15, 0x59, 0x91, 0xd0, 0x36, 0x47, 0x11, 0xac, 0xb9, 0xc2, 0x45, 0xc8, 0x64, + 0x05, 0xf2, 0x4b, 0xf7, 0xd1, 0x89, 0x38, 0xee, 0x2a, 0xfe, 0x39, 0xb8, 0xdc, 0xd2, 0x07, 0x6c, + 0x83, 0xe8, 0xd1, 0x4b, 0x5d, 0x94, 0xe6, 0xff, 0x69, 0x28, 0xaf, 0x33, 0x3c, 0xa7, 0xba, 0xce, + 0x2d, 0x4d, 0xd7, 0x99, 0x15, 0xa4, 0xd1, 0x57, 0xb1, 0xb2, 0x54, 0xfd, 0x74, 0x5a, 0xf1, 0x17, + 0x40, 0xc0, 0xb7, 0x32, 0x30, 0xbe, 0x19, 0x50, 0x9f, 0x5f, 0xe3, 0x7c, 0xba, 0xa2, 0x86, 0xa3, + 0xef, 0x1a, 0x28, 0xae, 0xf3, 0xf7, 0x0d, 0x34, 0xef, 0xa9, 0x14, 0xac, 0x37, 0x30, 0xcb, 0xab, + 0xd2, 0x1b, 0x9d, 0x80, 0xfa, 0x16, 0x42, 0x79, 0xbc, 0xde, 0x8a, 0x1e, 0xaf, 0xd7, 0xb0, 0x18, + 0x8c, 0x7c, 0x11, 0x86, 0x37, 0xd1, 0x58, 0xa1, 0x47, 0x6b, 0x44, 0xfc, 0xb1, 0x90, 0x2f, 0x11, + 0x1d, 0xf6, 0xa7, 0xba, 0xc2, 0x61, 0x19, 0xa9, 0xc2, 0x68, 0xd1, 0xa7, 0xf8, 0x0e, 0xc3, 0xd0, + 0xe0, 0x1e, 0xc7, 0x35, 0x4e, 0x92, 0xf4, 0x38, 0x16, 0x9c, 0xcc, 0x5f, 0xc8, 0x00, 0x89, 0xbf, + 0x11, 0x33, 0x20, 0x06, 0xcf, 0xed, 0xa0, 0xbf, 0xaf, 0x0d, 0xfa, 0x8b, 0x5d, 0x83, 0xce, 0x3f, + 0x6f, 0xa0, 0xb1, 0xff, 0x6d, 0x03, 0x4e, 0xa7, 0x13, 0x92, 0x97, 0x61, 0x64, 0x7d, 0xa3, 0x22, + 0x03, 0x7e, 0xc4, 0xa7, 0x78, 0x6d, 0x3c, 0x53, 0x59, 0xa2, 0x88, 0xbc, 0x09, 0x23, 0x5f, 0xb2, + 0x8a, 0x6c, 0x15, 0x54, 0x32, 0x13, 0x7d, 0xc3, 0xb7, 0x6b, 0xfa, 0x42, 0x28, 0x90, 0xd4, 0xb1, + 0xcd, 0x3e, 0xb3, 0xb1, 0xfd, 0x76, 0x06, 0xa6, 0x0b, 0xb5, 0x1a, 0x0d, 0x02, 0xb6, 0xc5, 0xd2, + 0x20, 0x7c, 0x6e, 0x07, 0x36, 0x3d, 0x94, 0x47, 0xfb, 0xb6, 0x81, 0x46, 0xf5, 0x77, 0x0c, 0x38, + 0x25, 0xa9, 0x1e, 0xba, 0xf4, 0xd1, 0xc6, 0xbe, 0x4f, 0x83, 0x7d, 0xaf, 0x51, 0x1f, 0x38, 0xfd, + 0x19, 0x53, 0x33, 0x30, 0xa5, 0x8b, 0x7a, 0xa7, 0xb7, 0x8b, 0x10, 0x4d, 0xcd, 0xe0, 0x69, 0x5f, + 0xae, 0xc3, 0x68, 0xa1, 0xdd, 0xf6, 0xbd, 0x87, 0x7c, 0xda, 0x4f, 0x0a, 0x07, 0x6c, 0x0e, 0xd2, + 0x1c, 0xb6, 0x39, 0x88, 0x35, 0xa3, 0x44, 0x5b, 0x3c, 0xd6, 0x7a, 0x92, 0x37, 0xa3, 0x4e, 0x5b, + 0xea, 0x61, 0x01, 0xcb, 0xcd, 0x9f, 0x1b, 0x82, 0x09, 0xf5, 0x43, 0x88, 0xc9, 0xd3, 0x1a, 0x79, + 0xbe, 0x1a, 0x17, 0xe1, 0x20, 0xc4, 0x12, 0x25, 0x71, 0x38, 0x51, 0xe6, 0xc8, 0x70, 0xa2, 0x6d, + 0x98, 0xac, 0xf8, 0x5e, 0xdb, 0x0b, 0x68, 0x9d, 0x3f, 0xa5, 0xc3, 0x57, 0xad, 0x93, 0x8a, 0x2a, + 0xcd, 0xfa, 0x1c, 0x2f, 0x2e, 0xf0, 0x20, 0xd9, 0x16, 0xd8, 0x76, 0xf2, 0xa1, 0x1d, 0x9d, 0x0f, + 0xbf, 0x13, 0x75, 0x02, 0x91, 0xfd, 0x20, 0xba, 0x13, 0x65, 0x10, 0xfd, 0x4e, 0x94, 0x41, 0xd4, + 0x69, 0x31, 0xfc, 0xac, 0xa6, 0x05, 0xf9, 0x05, 0x03, 0xc6, 0x0b, 0xad, 0x96, 0x08, 0x53, 0x3a, + 0xc2, 0x4f, 0xfb, 0xab, 0xe2, 0x5a, 0xf4, 0xed, 0x8f, 0x75, 0x2d, 0xba, 0xe1, 0x3b, 0x6e, 0x18, + 0xa0, 0x4a, 0x13, 0x57, 0xa8, 0x9e, 0x05, 0x94, 0x76, 0x90, 0xb7, 0x21, 0x1f, 0xc9, 0x63, 0xb9, + 0x55, 0xa7, 0x8f, 0x69, 0x30, 0x37, 0x7a, 0x31, 0x7b, 0x79, 0x92, 0xbf, 0x02, 0xa6, 0xdd, 0xf7, + 0x26, 0x11, 0xcd, 0x6f, 0x1b, 0x70, 0x5a, 0x15, 0x88, 0x6a, 0x67, 0xa7, 0xe9, 0xa2, 0x42, 0x4d, + 0xae, 0xc1, 0x98, 0x18, 0xaf, 0x48, 0x13, 0xed, 0xce, 0xe6, 0x14, 0xa3, 0x90, 0x25, 0x36, 0x44, + 0x8c, 0x87, 0xb0, 0x32, 0x9d, 0x4c, 0x4c, 0x37, 0x56, 0xb4, 0x38, 0x27, 0x3a, 0x3b, 0xef, 0xe3, + 0x6f, 0x7d, 0xec, 0x18, 0xc4, 0x7c, 0x0f, 0x66, 0xf4, 0x56, 0x56, 0x29, 0x66, 0xe4, 0x91, 0x9f, + 0x66, 0xa4, 0x7f, 0x9a, 0x2c, 0x37, 0xb7, 0x81, 0x74, 0xd1, 0x07, 0x78, 0xb7, 0x4f, 0x43, 0xe9, + 0x7b, 0x22, 0x2d, 0xeb, 0x5d, 0x88, 0xd1, 0xfb, 0x64, 0xe3, 0x6a, 0x77, 0x23, 0xa9, 0xf9, 0xcf, + 0xc6, 0xe1, 0x64, 0xca, 0xd2, 0x71, 0xc4, 0xd6, 0x3e, 0xaf, 0x4f, 0x9e, 0xb1, 0x28, 0x04, 0x42, + 0x4e, 0x99, 0xf7, 0xe4, 0xab, 0x53, 0x7d, 0xa6, 0x4a, 0xbf, 0xa7, 0xa8, 0x3e, 0x89, 0xed, 0x5d, + 0x8d, 0x52, 0x1a, 0x7e, 0x66, 0x51, 0x4a, 0x8b, 0x30, 0x29, 0xbe, 0x4a, 0x4c, 0xe5, 0x91, 0xd8, + 0xa0, 0xe4, 0xf3, 0x02, 0xbb, 0x6b, 0x4a, 0xeb, 0x24, 0x9c, 0x47, 0xe0, 0x35, 0x1e, 0x52, 0xc1, + 0x63, 0x54, 0xe5, 0x81, 0x05, 0xa9, 0x3c, 0x14, 0x12, 0xf2, 0xb7, 0x30, 0xb3, 0x29, 0x42, 0xd4, + 0xf9, 0x9c, 0xeb, 0x37, 0x9f, 0xeb, 0xcf, 0x66, 0x3e, 0xbf, 0x28, 0xdb, 0x98, 0x3e, 0xaf, 0x53, + 0x9a, 0x45, 0x7e, 0xcd, 0x80, 0x19, 0x1e, 0x2a, 0xa3, 0x36, 0xb6, 0x6f, 0xf8, 0x43, 0xed, 0xd9, + 0x34, 0xf6, 0x7c, 0x80, 0xd5, 0xf6, 0x68, 0x6b, 0x77, 0xa3, 0xc8, 0x57, 0x00, 0xa2, 0x19, 0x15, + 0xcc, 0x81, 0x9e, 0x1e, 0x22, 0x6d, 0xfb, 0x8c, 0x73, 0x4e, 0x85, 0x11, 0x9d, 0x96, 0xcf, 0x36, + 0x82, 0x92, 0x1f, 0x85, 0x59, 0x36, 0x5f, 0x22, 0x88, 0x08, 0xec, 0x9b, 0x1b, 0xc7, 0x5a, 0x3e, + 0xdb, 0x7b, 0x6b, 0xbf, 0x96, 0x46, 0xc6, 0x53, 0x48, 0xc4, 0x09, 0xe9, 0xc3, 0xa6, 0x7a, 0x66, + 0x4d, 0xa3, 0xc0, 0x48, 0x59, 0x6c, 0x3d, 0xcf, 0xf0, 0xd4, 0x63, 0x7d, 0x3b, 0x2b, 0xe7, 0x02, + 0x5f, 0xdf, 0x02, 0xdd, 0xd5, 0x1a, 0x41, 0xe4, 0x4b, 0x40, 0xa2, 0x18, 0x13, 0x0e, 0xa3, 0x32, + 0xfb, 0x13, 0xb7, 0x2e, 0xc5, 0xb1, 0x2a, 0xbe, 0x2c, 0x56, 0x85, 0xa4, 0x9b, 0x98, 0x50, 0x98, + 0x15, 0x1f, 0xcd, 0xa0, 0x32, 0x73, 0x6a, 0x30, 0x37, 0xa5, 0x85, 0x4d, 0xc6, 0x25, 0x71, 0xe6, + 0x7a, 0x25, 0xfd, 0xaa, 0x76, 0x6e, 0x4f, 0x63, 0x47, 0x6e, 0xc1, 0xd8, 0x8a, 0xb7, 0xe7, 0xb6, + 0x96, 0xa5, 0xc7, 0x82, 0xb8, 0x3d, 0x6d, 0x30, 0xa0, 0xbd, 0xaf, 0xfb, 0x1d, 0xc4, 0xa8, 0x4c, + 0xab, 0x2d, 0xf9, 0x07, 0x56, 0xa7, 0x85, 0x36, 0xa0, 0x1c, 0x57, 0x67, 0xea, 0xfe, 0x81, 0xed, + 0x77, 0x74, 0x87, 0x78, 0x44, 0x3a, 0xb7, 0x03, 0x67, 0x7b, 0x0e, 0x5a, 0x4a, 0xb6, 0x8a, 0xeb, + 0x7a, 0xb6, 0x8a, 0xb3, 0xbd, 0x16, 0xf7, 0x40, 0xcd, 0x58, 0xf1, 0xcb, 0x46, 0x62, 0x35, 0x17, + 0xaa, 0x17, 0x4f, 0x5e, 0xd8, 0x6b, 0xbb, 0xcb, 0x60, 0xee, 0x71, 0xbe, 0xde, 0x67, 0x62, 0x95, + 0x2f, 0xf1, 0x20, 0x07, 0x5f, 0xf9, 0x9f, 0x72, 0x61, 0x37, 0xff, 0x65, 0x16, 0x08, 0x6f, 0x61, + 0xd1, 0x69, 0x3b, 0x3b, 0x6e, 0xc3, 0x0d, 0x5d, 0x8c, 0x10, 0xca, 0x0b, 0x16, 0xce, 0x4e, 0x83, + 0xaa, 0xe1, 0x75, 0xc2, 0x83, 0x27, 0x2a, 0xb3, 0x93, 0x4a, 0x5a, 0x17, 0x61, 0x0f, 0x51, 0xcc, + 0x3c, 0x8d, 0x28, 0x7e, 0x1d, 0x5e, 0x28, 0xb4, 0x31, 0x5f, 0xb8, 0xac, 0xe5, 0x8e, 0xe7, 0x4b, + 0x21, 0xd2, 0x3c, 0x6d, 0x9d, 0x08, 0xad, 0xab, 0xa5, 0xfd, 0x58, 0x28, 0xfb, 0x48, 0xc5, 0xf7, + 0x9a, 0xed, 0x50, 0x0d, 0x55, 0x90, 0xfb, 0x48, 0x1b, 0x4b, 0x52, 0xf6, 0x11, 0x4e, 0x22, 0x79, + 0xb8, 0xbe, 0xdc, 0x47, 0x86, 0x51, 0x30, 0x23, 0x1e, 0xae, 0x4f, 0x7b, 0xec, 0x45, 0x11, 0x09, + 0x79, 0x07, 0xc6, 0x0b, 0x9d, 0xd0, 0x13, 0x8c, 0x85, 0xeb, 0x59, 0xec, 0x24, 0x26, 0x9a, 0xa2, + 0xa9, 0x6d, 0x31, 0xba, 0xf9, 0x1f, 0x67, 0xe0, 0x6c, 0xf7, 0xf0, 0x8a, 0xd2, 0x48, 0xc8, 0x8c, + 0x23, 0x84, 0x2c, 0x4d, 0x1a, 0xb8, 0x45, 0xec, 0x99, 0x49, 0x03, 0x4f, 0x3b, 0xfe, 0x31, 0xa5, + 0xa1, 0x0a, 0xe3, 0xea, 0x7a, 0x34, 0xf4, 0x71, 0xd7, 0x23, 0x95, 0x0b, 0x26, 0xf0, 0x56, 0xf2, + 0x43, 0xbf, 0x99, 0xe6, 0xe8, 0xca, 0xb3, 0xae, 0x70, 0xb0, 0xee, 0xe3, 0x2a, 0x8f, 0xb2, 0x99, + 0xd4, 0xa3, 0xac, 0x4c, 0x20, 0x93, 0x4d, 0x4d, 0x20, 0x53, 0x82, 0xe9, 0x6a, 0x67, 0x47, 0xd6, + 0x8d, 0x88, 0x43, 0x9a, 0xaf, 0xbe, 0x2d, 0xdb, 0xaf, 0x47, 0x61, 0x6a, 0x24, 0xe6, 0x4f, 0x65, + 0x60, 0xa2, 0xd2, 0xe8, 0xec, 0xb9, 0xad, 0x92, 0x13, 0x3a, 0xcf, 0xed, 0xe9, 0xfa, 0xb6, 0x76, + 0xba, 0x8e, 0xfc, 0xb9, 0xa3, 0x0f, 0x1b, 0xe8, 0x68, 0xfd, 0x5d, 0x03, 0xa6, 0x63, 0x12, 0xbe, + 0xc4, 0x2f, 0xc3, 0x10, 0xfb, 0x21, 0x94, 0xf5, 0x8b, 0x5d, 0x8c, 0x79, 0x4a, 0xd6, 0xe8, 0x2f, + 0x71, 0xde, 0xd5, 0x5f, 0x6b, 0x44, 0x0e, 0xe7, 0x3e, 0xc7, 0xdf, 0x4d, 0x3b, 0x7e, 0x2a, 0xd6, + 0xbf, 0x67, 0x40, 0x3e, 0xf9, 0x25, 0xe4, 0x3e, 0x8c, 0x32, 0x4e, 0x6e, 0xf4, 0x06, 0xdb, 0x2b, + 0x3d, 0xbe, 0xf9, 0x9a, 0x40, 0xe3, 0xcd, 0xc3, 0xce, 0xa7, 0x1c, 0x62, 0x49, 0x0e, 0xe7, 0x2c, + 0x98, 0x50, 0xb1, 0x52, 0x5a, 0xf7, 0x86, 0xbe, 0xaf, 0x9d, 0x4e, 0xef, 0x07, 0xb5, 0xd5, 0x7f, + 0x55, 0x6b, 0xb5, 0xd8, 0xd1, 0x06, 0x7d, 0x81, 0x13, 0x13, 0x37, 0x71, 0x29, 0x55, 0xe5, 0x2c, + 0x45, 0xa0, 0x23, 0x3c, 0x76, 0x2c, 0xe7, 0xf5, 0x09, 0x39, 0xc3, 0x63, 0x79, 0x1b, 0x21, 0xea, + 0xbe, 0xce, 0x71, 0xcc, 0xbf, 0x96, 0x85, 0xd3, 0x71, 0xf3, 0xf8, 0x7b, 0xa4, 0x15, 0xc7, 0x77, + 0x9a, 0xc1, 0x11, 0x33, 0xe0, 0x72, 0x57, 0xd3, 0x30, 0x99, 0xa2, 0x6c, 0x9a, 0xd2, 0x20, 0x33, + 0xd1, 0x20, 0xb4, 0x67, 0xf0, 0x06, 0xc9, 0x66, 0x90, 0xfb, 0x90, 0xad, 0xd2, 0x50, 0xac, 0x45, + 0x97, 0xba, 0x7a, 0x55, 0x6d, 0xd7, 0xb5, 0x2a, 0x0d, 0xf9, 0x20, 0xf2, 0x70, 0x3c, 0xaa, 0xe5, + 0x99, 0x60, 0x27, 0xd3, 0x6d, 0x18, 0x59, 0x7a, 0xdc, 0xa6, 0xb5, 0x50, 0x64, 0x2d, 0xbb, 0xd2, + 0x9f, 0x1f, 0xc7, 0x55, 0x72, 0xa3, 0x51, 0x04, 0xa8, 0x9d, 0xc5, 0x51, 0xce, 0xdd, 0x82, 0x9c, + 0xac, 0xfc, 0x58, 0x39, 0xbe, 0x6e, 0xc3, 0xb8, 0x52, 0xc9, 0xb1, 0x84, 0xfe, 0x4f, 0x0c, 0x18, + 0x61, 0x3b, 0xc1, 0xd6, 0xad, 0xe7, 0x74, 0x45, 0xba, 0xa9, 0xad, 0x48, 0x33, 0x4a, 0x2a, 0x1b, + 0x9c, 0x97, 0xb7, 0x8e, 0x58, 0x8b, 0x0e, 0xd9, 0xbe, 0x12, 0x21, 0x93, 0xbb, 0x30, 0x2a, 0xee, + 0x53, 0x85, 0xe7, 0x97, 0x9a, 0x1b, 0x47, 0xde, 0xb4, 0x46, 0x0a, 0xbf, 0xd7, 0x4e, 0x9e, 0x90, + 0x24, 0x35, 0x29, 0xc5, 0x79, 0x0d, 0xb4, 0x54, 0xeb, 0x1e, 0x3a, 0xa0, 0xf3, 0xdc, 0x2e, 0xca, + 0x23, 0x06, 0x3d, 0xa2, 0x04, 0x0b, 0xc2, 0xc6, 0x97, 0xed, 0xc7, 0xe4, 0xb4, 0xcc, 0x97, 0x9d, + 0x6a, 0xfe, 0xfb, 0xd7, 0x84, 0x67, 0x45, 0x91, 0x0d, 0x7b, 0x17, 0x26, 0xee, 0x78, 0xfe, 0x23, + 0xc7, 0xe7, 0xb1, 0xee, 0xf8, 0x99, 0xfc, 0x2e, 0x6d, 0x72, 0x97, 0xc3, 0x79, 0xb4, 0xfc, 0x0f, + 0x0e, 0xe7, 0x87, 0x16, 0x3d, 0xaf, 0x61, 0x69, 0xe8, 0x64, 0x1d, 0x26, 0x57, 0x9d, 0xc7, 0xca, + 0x0d, 0x2f, 0xf7, 0x28, 0xbd, 0xf2, 0xe4, 0x70, 0xfe, 0x6c, 0xd3, 0x79, 0x3c, 0xc0, 0xed, 0xae, + 0x4e, 0x4f, 0x5c, 0x98, 0xaa, 0x78, 0x7e, 0x28, 0x2a, 0x61, 0xc7, 0xbb, 0x6c, 0x8f, 0xfb, 0xe9, + 0xeb, 0xa9, 0xf7, 0xd3, 0x67, 0xd9, 0x99, 0xd6, 0xde, 0x8d, 0xc8, 0xb5, 0x30, 0x51, 0x8d, 0x31, + 0x79, 0x17, 0x66, 0x8a, 0xd4, 0x0f, 0xdd, 0x5d, 0xb7, 0xe6, 0x84, 0xf4, 0x8e, 0xe7, 0x37, 0x1d, + 0xa9, 0x48, 0xa2, 0x6d, 0x09, 0x2f, 0x02, 0x77, 0x11, 0x6c, 0x75, 0x63, 0x92, 0x0f, 0xd3, 0x7c, + 0x74, 0x87, 0xe3, 0x0b, 0xee, 0x14, 0x1f, 0xdd, 0x5e, 0x17, 0xdc, 0xdd, 0xde, 0xba, 0x7b, 0xfd, + 0x1c, 0x60, 0x72, 0x8b, 0x37, 0x84, 0xef, 0xcc, 0xd1, 0x0e, 0x2e, 0xd1, 0xb8, 0xf5, 0x70, 0x74, + 0x59, 0x80, 0xec, 0x62, 0xe5, 0x0e, 0x5a, 0x0b, 0xe5, 0x0d, 0x68, 0x6b, 0xdf, 0x69, 0xd5, 0x50, + 0xc1, 0x13, 0x4e, 0x67, 0xea, 0x82, 0xb7, 0x58, 0xb9, 0x43, 0x1c, 0x38, 0x59, 0xa1, 0x7e, 0xd3, + 0x0d, 0xbf, 0x7c, 0xe3, 0x86, 0x32, 0x50, 0x39, 0x6c, 0xda, 0x75, 0xd1, 0xb4, 0xf9, 0x36, 0xa2, + 0xd8, 0x8f, 0x6f, 0xdc, 0x48, 0x1d, 0x8e, 0xa8, 0x61, 0x69, 0xbc, 0xc8, 0x12, 0x4c, 0xad, 0x3a, + 0x8f, 0x63, 0x5f, 0xc1, 0x40, 0x44, 0x3b, 0xbc, 0x28, 0x05, 0x2b, 0xf6, 0x33, 0xd4, 0xc2, 0x19, + 0x75, 0x22, 0xa6, 0x9f, 0xc7, 0xe2, 0x15, 0x08, 0x3f, 0x51, 0x54, 0xd4, 0x14, 0xe1, 0xd4, 0x94, + 0x4c, 0x05, 0x9d, 0x6c, 0x46, 0xa7, 0x0c, 0xae, 0xa5, 0x8b, 0x64, 0xd0, 0xd7, 0xd5, 0x53, 0x86, + 0x83, 0x25, 0xda, 0x67, 0x4d, 0x47, 0xe7, 0x3b, 0xee, 0x3c, 0x69, 0xe9, 0x5c, 0xba, 0x0f, 0x2f, + 0x13, 0xc7, 0x3f, 0xbc, 0x50, 0x18, 0x5a, 0xf1, 0x6a, 0x0f, 0xd0, 0xfd, 0x63, 0x6c, 0xf1, 0x4b, + 0x6c, 0xba, 0x37, 0xbc, 0xda, 0x83, 0x67, 0xe7, 0xd8, 0x83, 0xec, 0xc9, 0x1a, 0x6b, 0x2a, 0x93, + 0x02, 0xd1, 0x27, 0xc2, 0x59, 0x64, 0x36, 0xd2, 0xde, 0x95, 0x32, 0xae, 0x57, 0x70, 0xa1, 0x91, + 0x5d, 0x6b, 0xe9, 0xe4, 0x84, 0x42, 0xbe, 0x44, 0x83, 0x07, 0xa1, 0xd7, 0x2e, 0x36, 0xdc, 0xf6, + 0x8e, 0xe7, 0xf8, 0x75, 0xb4, 0x07, 0xa4, 0xcd, 0xef, 0xd7, 0x52, 0xe7, 0xf7, 0x4c, 0x9d, 0xd3, + 0xdb, 0x35, 0xc9, 0xc0, 0xea, 0x62, 0x49, 0x3e, 0x84, 0x29, 0x26, 0xdc, 0x4b, 0x8f, 0x43, 0xda, + 0xe2, 0x23, 0x3f, 0x83, 0x3b, 0xf3, 0xac, 0x92, 0x43, 0x2c, 0x2a, 0xe4, 0x32, 0x85, 0x93, 0x9d, + 0x46, 0x04, 0xaa, 0x4c, 0xe9, 0xac, 0x48, 0x1d, 0xe6, 0x56, 0x9d, 0xc7, 0x4a, 0xd2, 0x6c, 0x45, + 0x48, 0x09, 0x0a, 0x18, 0xbe, 0x5a, 0xc5, 0x04, 0x2c, 0xce, 0xf5, 0xd1, 0x43, 0x5e, 0x7b, 0x72, + 0x22, 0x3f, 0x0c, 0x67, 0xc4, 0x67, 0x95, 0x30, 0x41, 0xa6, 0xe7, 0x1f, 0x54, 0xf7, 0x1d, 0x74, + 0x13, 0x3e, 0x79, 0xbc, 0x05, 0x51, 0x76, 0x58, 0x5d, 0xf2, 0xb1, 0x03, 0xce, 0xc8, 0xea, 0x55, + 0x03, 0xf9, 0x08, 0xa6, 0xb8, 0x19, 0x78, 0xd9, 0x0b, 0x42, 0x3c, 0x84, 0xce, 0x1e, 0xcf, 0xfb, + 0x8d, 0xdb, 0x96, 0xb9, 0xbf, 0x68, 0xe2, 0xd0, 0x9a, 0xe0, 0x4c, 0xde, 0x86, 0xf1, 0x8a, 0xdb, + 0xe2, 0x91, 0xfb, 0xe5, 0xca, 0xdc, 0xa9, 0x78, 0xff, 0x69, 0xbb, 0x2d, 0x5b, 0x9e, 0x04, 0xdb, + 0xd1, 0x72, 0xa1, 0x62, 0x93, 0x6d, 0x18, 0xaf, 0x56, 0x97, 0xef, 0xb8, 0x6c, 0x03, 0x6c, 0x1f, + 0xcc, 0x9d, 0xee, 0xd1, 0xca, 0x97, 0x53, 0x5b, 0x39, 0x19, 0x04, 0xfb, 0xf8, 0x32, 0x8e, 0x5d, + 0xf3, 0xda, 0x07, 0x96, 0xca, 0x29, 0xc5, 0x23, 0xec, 0xcc, 0x33, 0xf6, 0x08, 0x2b, 0xc3, 0xb4, + 0xe2, 0xf9, 0x82, 0x5e, 0x2f, 0x73, 0xf1, 0xe3, 0x41, 0xaa, 0x07, 0x58, 0xd2, 0xaf, 0x3f, 0x49, + 0x27, 0x5d, 0xc1, 0xce, 0x1e, 0xd7, 0x15, 0xcc, 0x85, 0x19, 0x3e, 0x18, 0x42, 0x0e, 0x70, 0xa4, + 0xcf, 0xf5, 0xe8, 0xc3, 0x2b, 0xa9, 0x7d, 0x78, 0x52, 0x8c, 0xb4, 0x14, 0x32, 0xbc, 0xf6, 0xe8, + 0xe6, 0x4a, 0x76, 0x81, 0x08, 0xa0, 0x78, 0x97, 0x07, 0xeb, 0x7a, 0xa1, 0x47, 0x5d, 0xaf, 0xa4, + 0xd6, 0x35, 0x25, 0xeb, 0xda, 0xe1, 0xd5, 0xa4, 0x70, 0x24, 0x2d, 0x59, 0x8f, 0x94, 0x2f, 0xec, + 0xd8, 0xf3, 0x38, 0x76, 0xd2, 0x2a, 0xd8, 0x8d, 0x80, 0x11, 0x30, 0xf3, 0x49, 0xa1, 0x4d, 0xf6, + 0x7b, 0x0a, 0xe7, 0x7b, 0x43, 0xb9, 0xc9, 0xfc, 0x54, 0x9a, 0x23, 0xda, 0x7f, 0x91, 0x49, 0x2c, + 0x9d, 0xa4, 0x0c, 0xa3, 0xa2, 0x47, 0x84, 0x2e, 0xd9, 0xfd, 0xdd, 0x2f, 0xa6, 0x7e, 0xf7, 0xa8, + 0xe8, 0x5c, 0x4b, 0xd2, 0x93, 0x47, 0x8c, 0x15, 0xfa, 0xc4, 0x09, 0xe5, 0xfb, 0x6b, 0x7c, 0x65, + 0x44, 0x90, 0xb6, 0x07, 0x94, 0x8e, 0xef, 0x11, 0xac, 0x3b, 0x9c, 0xe3, 0x66, 0x20, 0x6b, 0x23, + 0x0f, 0x78, 0xea, 0xbf, 0x6c, 0xe4, 0x56, 0xaa, 0xe7, 0xf9, 0x7b, 0x66, 0x15, 0xb2, 0x5a, 0xcc, + 0xdf, 0x32, 0x60, 0x52, 0x5b, 0x7b, 0xc9, 0x2d, 0xc5, 0x67, 0x3a, 0x0e, 0x8e, 0xd1, 0x70, 0x70, + 0x3a, 0x26, 0xbd, 0xa9, 0x6f, 0x09, 0xb7, 0xb2, 0x4c, 0x6f, 0xba, 0xd4, 0x47, 0xa2, 0xfa, 0x5b, + 0x82, 0xa2, 0x54, 0xc2, 0x43, 0x3d, 0x52, 0x09, 0xff, 0xfa, 0x59, 0x98, 0xd2, 0x95, 0x73, 0x76, + 0x5a, 0x46, 0x9b, 0xb8, 0x34, 0xd8, 0xf2, 0xe4, 0xd8, 0x08, 0xd1, 0x1e, 0x92, 0x41, 0x08, 0x79, + 0x15, 0x20, 0xf2, 0xb0, 0x92, 0x36, 0xd9, 0xe1, 0x27, 0x87, 0xf3, 0xc6, 0x9b, 0x96, 0x52, 0x40, + 0x7e, 0x08, 0x60, 0xcd, 0xab, 0xd3, 0x28, 0xbd, 0x7b, 0x9f, 0x7b, 0xa1, 0xd7, 0xba, 0xd2, 0x62, + 0x9d, 0x6a, 0x79, 0x75, 0xda, 0x9d, 0x03, 0x4b, 0xe1, 0x48, 0xbe, 0x00, 0xc3, 0x56, 0xa7, 0x41, + 0xa5, 0xed, 0x6e, 0x5c, 0xae, 0x81, 0x9d, 0x86, 0xf2, 0x24, 0xb7, 0xdf, 0x49, 0xba, 0x03, 0x30, + 0x00, 0x79, 0x9f, 0xa7, 0xcb, 0x12, 0x39, 0x29, 0x86, 0x63, 0x2b, 0xb5, 0xb2, 0x37, 0x76, 0x65, + 0xa5, 0x50, 0x48, 0xc8, 0x3a, 0x8c, 0xaa, 0xe6, 0x55, 0x25, 0xf8, 0x46, 0x35, 0xdd, 0x2b, 0xe7, + 0x1f, 0x91, 0x7f, 0x3b, 0x69, 0x79, 0x95, 0x5c, 0xc8, 0x3b, 0x30, 0xc6, 0xd8, 0xf3, 0xc7, 0x98, + 0x47, 0x63, 0x5b, 0xb4, 0xd2, 0xa0, 0xe4, 0x7b, 0xcc, 0x31, 0x01, 0xf9, 0x10, 0x13, 0xf6, 0x8b, + 0xae, 0xee, 0x7b, 0x5f, 0x78, 0xa9, 0xab, 0xab, 0x67, 0x9d, 0x76, 0x3b, 0xe5, 0x59, 0x95, 0x88, + 0x1f, 0xd9, 0x8b, 0x32, 0x1a, 0x0c, 0x92, 0xe2, 0xec, 0x6a, 0x57, 0x05, 0x73, 0x32, 0x48, 0xbf, + 0x3b, 0x4d, 0xbf, 0xc6, 0x97, 0xb4, 0x21, 0x1f, 0xab, 0x1d, 0xa2, 0x2e, 0xe8, 0x57, 0xd7, 0x9b, + 0x5d, 0x75, 0xa9, 0x03, 0xd8, 0x55, 0x5d, 0x17, 0x77, 0x52, 0x8f, 0xdf, 0xd0, 0x17, 0xf5, 0x8d, + 0xf7, 0xab, 0xef, 0xd5, 0xae, 0xfa, 0x4e, 0xd6, 0x77, 0xba, 0xeb, 0x49, 0xf0, 0x24, 0xef, 0xc0, + 0xa4, 0x84, 0xe0, 0xfc, 0x10, 0x2f, 0xb1, 0xa0, 0x6d, 0xa2, 0xbe, 0x83, 0x91, 0x0a, 0x7a, 0x92, + 0x78, 0x15, 0x59, 0xa5, 0xe6, 0xd2, 0x31, 0xa9, 0x51, 0x27, 0xa5, 0x42, 0x47, 0x26, 0x1f, 0xc0, + 0x78, 0xb9, 0xc9, 0x3e, 0xc4, 0x6b, 0x39, 0x21, 0x15, 0x8e, 0xd9, 0xf2, 0xee, 0x53, 0x29, 0x51, + 0x44, 0x95, 0x3f, 0xb5, 0x18, 0x17, 0xa9, 0x07, 0x11, 0x85, 0x82, 0x75, 0x1e, 0xb7, 0xa7, 0x0b, + 0x19, 0x96, 0x4e, 0xdb, 0x2f, 0xa6, 0xdc, 0x3f, 0x2a, 0xec, 0x45, 0xee, 0x17, 0x06, 0x95, 0x57, + 0x11, 0x89, 0xdc, 0x2f, 0x2a, 0x4f, 0xf2, 0x2e, 0x8c, 0x8b, 0xec, 0x8f, 0x05, 0x6b, 0x2d, 0x98, + 0xcb, 0xc7, 0xef, 0x94, 0xcb, 0x44, 0x91, 0xb6, 0xe3, 0x27, 0x9c, 0x50, 0x62, 0x7c, 0xf2, 0x65, + 0x98, 0xdd, 0x76, 0x5b, 0x75, 0xef, 0x51, 0x20, 0xb6, 0x29, 0xb1, 0xd0, 0xcd, 0xc4, 0xbe, 0xc2, + 0x8f, 0x78, 0x79, 0xa4, 0x2d, 0x74, 0x2d, 0x7c, 0xa9, 0x1c, 0xc8, 0x8f, 0x74, 0x71, 0xe6, 0x12, + 0x44, 0xfa, 0x49, 0xd0, 0x42, 0x97, 0x04, 0x75, 0x57, 0x9f, 0x14, 0xa7, 0xd4, 0x6a, 0x88, 0x07, + 0x44, 0xdf, 0xdf, 0xef, 0x79, 0x6e, 0x6b, 0xee, 0x24, 0xae, 0x85, 0x2f, 0x24, 0x83, 0xbb, 0x10, + 0x8f, 0xbf, 0xe9, 0x28, 0x5f, 0xd6, 0xd5, 0xb5, 0xc2, 0x8f, 0x3c, 0xcd, 0x30, 0x9a, 0xc2, 0x9a, + 0x7c, 0x00, 0x13, 0xec, 0xff, 0xe8, 0xd8, 0x3a, 0xab, 0x79, 0xac, 0x28, 0x98, 0xa2, 0x1e, 0x1c, + 0x23, 0x4c, 0x4f, 0x99, 0x72, 0xa2, 0xd5, 0x58, 0x91, 0xdb, 0x00, 0x4c, 0x7f, 0x11, 0xcb, 0xf1, + 0xa9, 0x38, 0xd5, 0x0e, 0x6a, 0x3d, 0xdd, 0x0b, 0x71, 0x8c, 0xcc, 0xce, 0xd2, 0xec, 0x57, 0xb5, + 0x53, 0xf7, 0xd8, 0xdc, 0x38, 0x8d, 0xb4, 0x78, 0x96, 0x46, 0xda, 0x80, 0xc3, 0x55, 0xe9, 0x50, + 0xd0, 0xc9, 0x32, 0x4c, 0x63, 0x4a, 0xa4, 0x72, 0x9d, 0xb6, 0x42, 0xbc, 0xe7, 0x9a, 0x3b, 0xa3, + 0xdc, 0x03, 0xb2, 0x22, 0xdb, 0x8d, 0xca, 0x54, 0x6d, 0x37, 0x41, 0x46, 0x02, 0x38, 0x19, 0xaf, + 0x2e, 0xf1, 0xad, 0xe2, 0x1c, 0x76, 0x92, 0xd4, 0xf1, 0xba, 0x31, 0xf8, 0x7a, 0xcc, 0x46, 0x44, + 0x59, 0xb8, 0xa4, 0xf9, 0x58, 0xad, 0x30, 0x8d, 0x3b, 0xb1, 0x80, 0xdc, 0x2d, 0x56, 0x92, 0x39, + 0x83, 0xce, 0xe2, 0x17, 0xe0, 0x30, 0xef, 0xd5, 0xda, 0x76, 0x9f, 0xbc, 0x41, 0x29, 0xd4, 0xe4, + 0x9b, 0x70, 0x4a, 0xae, 0x20, 0xa2, 0x48, 0xc8, 0xf5, 0xb9, 0x63, 0xae, 0xc4, 0xf5, 0x9d, 0xa8, + 0xea, 0x2e, 0x91, 0x4e, 0xaf, 0x82, 0x38, 0x30, 0x8e, 0xc3, 0x2a, 0x6a, 0x7c, 0xa1, 0x5f, 0x8d, + 0x97, 0xbb, 0x6a, 0x3c, 0xcd, 0xdf, 0xd7, 0xed, 0xaa, 0x4c, 0xe5, 0x49, 0x16, 0x61, 0x52, 0xcc, + 0x23, 0x21, 0x6d, 0xe7, 0xe3, 0x07, 0xa2, 0xe5, 0x0c, 0xec, 0x12, 0x38, 0x9d, 0x44, 0x5d, 0x91, + 0xf9, 0xc5, 0xe6, 0x8b, 0xda, 0x8a, 0x9c, 0xbc, 0xcf, 0xd4, 0x91, 0xd9, 0x8a, 0x14, 0x6b, 0x31, + 0x4b, 0x8f, 0xdb, 0xbe, 0x30, 0x62, 0x5c, 0x88, 0x93, 0x3e, 0x2a, 0xca, 0x8f, 0x4d, 0x23, 0x0c, + 0x75, 0x49, 0x48, 0xe3, 0x40, 0x36, 0xe1, 0x64, 0xb4, 0x6b, 0x2b, 0x8c, 0xe7, 0x91, 0x31, 0x1e, + 0x26, 0xe2, 0xad, 0x3e, 0x9d, 0x6f, 0x1a, 0x3d, 0x71, 0xe0, 0x8c, 0xb6, 0x4f, 0x2b, 0xac, 0x2f, + 0x22, 0xeb, 0xd7, 0x9e, 0x1c, 0xce, 0xbf, 0xac, 0x6f, 0xf2, 0xe9, 0xec, 0x7b, 0xf1, 0x21, 0x1f, + 0xc1, 0xb9, 0xe4, 0xde, 0xac, 0xd4, 0xf2, 0x12, 0xd6, 0x72, 0xf5, 0xc9, 0xe1, 0xfc, 0xa5, 0xae, + 0xed, 0x3d, 0xbd, 0xa2, 0x3e, 0xdc, 0xc8, 0x0f, 0xc1, 0x9c, 0xbe, 0x3f, 0x2b, 0x35, 0x99, 0xf1, + 0xdb, 0xe3, 0xd1, 0xc6, 0x9e, 0x5e, 0x43, 0x4f, 0x1e, 0x24, 0x84, 0xf9, 0x54, 0xe9, 0x56, 0xaa, + 0x79, 0x39, 0xfe, 0xa0, 0xae, 0x59, 0x92, 0x5e, 0xdd, 0x51, 0x2c, 0xc9, 0x23, 0xb8, 0x90, 0xb6, + 0x4d, 0x28, 0x95, 0xbe, 0x12, 0x99, 0x09, 0x5f, 0x4f, 0xdf, 0x72, 0xd2, 0x6b, 0x3e, 0x82, 0x2d, + 0xf9, 0x10, 0x4e, 0x29, 0xf3, 0x4b, 0xa9, 0xef, 0x55, 0xac, 0x0f, 0x23, 0x7d, 0xd4, 0x89, 0x99, + 0x5e, 0x4b, 0x3a, 0x0f, 0xf3, 0xaf, 0x18, 0x40, 0xba, 0x17, 0xbe, 0x81, 0x6f, 0x0e, 0xdf, 0x52, + 0xc2, 0x60, 0xd4, 0xd7, 0x87, 0xa3, 0xbc, 0x91, 0xaa, 0xc2, 0x1b, 0x07, 0xcc, 0x5c, 0xd2, 0x0e, + 0x58, 0xbd, 0x5f, 0xae, 0xfd, 0x43, 0x03, 0x66, 0xd3, 0xb6, 0xd8, 0x23, 0x1e, 0x7b, 0x31, 0x13, + 0x2e, 0xd7, 0x78, 0x15, 0xc8, 0x5d, 0xae, 0x23, 0x47, 0xeb, 0x79, 0x18, 0x66, 0x5f, 0x20, 0xdd, + 0x52, 0xf0, 0x14, 0xc7, 0x3e, 0x31, 0xb0, 0x38, 0x9c, 0x21, 0xf0, 0x58, 0x77, 0x76, 0xcc, 0x1b, + 0xe6, 0x08, 0xb8, 0x82, 0x5b, 0x1c, 0xce, 0x10, 0xd8, 0x69, 0x51, 0x9e, 0x6e, 0x10, 0x81, 0x1d, + 0x22, 0x03, 0x8b, 0xc3, 0xc9, 0x25, 0x18, 0x5d, 0x6f, 0xad, 0x50, 0xe7, 0xa1, 0xcc, 0x67, 0x89, + 0x57, 0x97, 0x5e, 0xcb, 0x6e, 0x30, 0x98, 0x25, 0x0b, 0xcd, 0xef, 0x1a, 0x30, 0xd3, 0xb5, 0xbb, + 0x1f, 0xfd, 0x9e, 0x4d, 0x7f, 0xe7, 0xd2, 0x41, 0xbe, 0x8f, 0x37, 0x7f, 0x28, 0xbd, 0xf9, 0xe6, + 0x6f, 0x0e, 0xc1, 0x99, 0x1e, 0x87, 0xad, 0xd8, 0x31, 0xdc, 0x38, 0xd2, 0x31, 0xfc, 0xab, 0xec, + 0x70, 0xe3, 0xb8, 0xcd, 0x60, 0xc3, 0x8b, 0x5b, 0x1c, 0xfb, 0xd0, 0x61, 0x99, 0x7c, 0x6e, 0xe2, + 0x25, 0xb1, 0x57, 0x9f, 0xad, 0x21, 0x85, 0x1d, 0x7a, 0xdd, 0x6b, 0xbd, 0xc6, 0xac, 0xcb, 0x35, + 0x3b, 0xfb, 0x67, 0xc4, 0x35, 0x5b, 0x77, 0x88, 0x1c, 0x7a, 0xa6, 0x0e, 0x91, 0xe9, 0xce, 0x3a, + 0xc3, 0x4f, 0xe3, 0xba, 0x55, 0x84, 0x49, 0xfe, 0x26, 0x7e, 0x21, 0xe0, 0x83, 0x34, 0x12, 0x67, + 0x91, 0x0c, 0xb0, 0xc0, 0x76, 0x82, 0xee, 0xb1, 0xd0, 0x68, 0xcc, 0xef, 0x66, 0x74, 0x8f, 0xf2, + 0x3f, 0x8b, 0xf2, 0x72, 0x05, 0x86, 0xb7, 0xf7, 0xa9, 0x2f, 0x97, 0x1e, 0x6c, 0xc8, 0x23, 0x06, + 0x50, 0x1b, 0x82, 0x18, 0xe4, 0x0e, 0x4c, 0x55, 0x78, 0xff, 0xc9, 0x4e, 0x19, 0x8a, 0x35, 0xd7, + 0xb6, 0x38, 0x5f, 0xa5, 0xf4, 0x4a, 0x82, 0xca, 0xfc, 0x61, 0x98, 0x50, 0x1b, 0x8d, 0x0b, 0x0b, + 0xfb, 0x2d, 0x66, 0x36, 0x5f, 0x58, 0x18, 0xc0, 0xe2, 0xf0, 0x23, 0xdf, 0xaa, 0x8a, 0x7b, 0x33, + 0x7b, 0x54, 0x6f, 0xb2, 0xca, 0x51, 0x6e, 0x95, 0xca, 0xf1, 0xb7, 0x5a, 0x79, 0xc8, 0x00, 0x16, + 0x87, 0x3f, 0xd3, 0xca, 0xff, 0xb1, 0xcc, 0xf4, 0xf9, 0x16, 0x8c, 0xc5, 0x1a, 0x7b, 0xfc, 0x22, + 0xc0, 0xc9, 0x34, 0x3d, 0x3c, 0xc6, 0x64, 0x55, 0x6d, 0x51, 0x7f, 0x47, 0x0b, 0x3f, 0x79, 0xc8, + 0x00, 0x6a, 0x55, 0x88, 0x71, 0x9c, 0x71, 0xbd, 0x0e, 0xa3, 0x05, 0x71, 0x6f, 0xc3, 0x07, 0x94, + 0x87, 0xd8, 0x74, 0x5d, 0xd2, 0x48, 0x2c, 0xf3, 0x7b, 0x06, 0x9c, 0x4a, 0x3d, 0xc8, 0xb3, 0x5a, + 0xb9, 0xc5, 0x40, 0x11, 0xeb, 0xa4, 0xb9, 0x80, 0x63, 0x1c, 0x27, 0x94, 0x66, 0xf0, 0x6f, 0x31, + 0x5f, 0x82, 0xb1, 0xc8, 0x8c, 0x4c, 0x66, 0xe5, 0xd0, 0xe1, 0x65, 0xbe, 0xb4, 0x46, 0xfe, 0x89, + 0x01, 0x23, 0xac, 0x09, 0xcf, 0x6d, 0x4e, 0x8e, 0x74, 0xd7, 0x0e, 0xf6, 0x49, 0x03, 0x65, 0xe2, + 0xf8, 0xd5, 0x11, 0xfe, 0x62, 0xa3, 0xc8, 0xbf, 0xb1, 0x03, 0x53, 0xeb, 0xe5, 0x52, 0x51, 0x39, + 0x8f, 0xea, 0x49, 0x49, 0xa3, 0xf7, 0xd3, 0x38, 0xc2, 0x41, 0xbc, 0xc6, 0x78, 0x6e, 0xbd, 0x96, + 0x7e, 0x56, 0x4d, 0x70, 0x64, 0x75, 0x54, 0x0b, 0xab, 0x2b, 0x4a, 0x1d, 0x99, 0x01, 0xeb, 0x08, + 0x9c, 0x66, 0xa3, 0x47, 0x1d, 0x3a, 0x47, 0xb2, 0x0f, 0xf9, 0xbb, 0xb8, 0x8b, 0x29, 0xb5, 0x64, + 0xfb, 0xd7, 0xf2, 0xb2, 0xa8, 0xe5, 0x05, 0xbe, 0xfd, 0xa5, 0xd7, 0xd3, 0xc5, 0x35, 0x96, 0xdc, + 0xa1, 0x23, 0x25, 0xf7, 0x2f, 0x1a, 0x30, 0xc2, 0xb7, 0x49, 0x31, 0x5a, 0x3d, 0x36, 0xe2, 0xed, + 0x67, 0xb3, 0x11, 0xe7, 0x71, 0xe5, 0xd2, 0x2c, 0xe8, 0xbc, 0x8c, 0x94, 0x60, 0xa4, 0x1a, 0x3a, + 0x61, 0x47, 0xc6, 0x6a, 0x49, 0xff, 0x1d, 0xb4, 0x2c, 0xf1, 0x92, 0x38, 0x20, 0x29, 0xc0, 0xdf, + 0x2a, 0x17, 0x8e, 0x41, 0xca, 0x71, 0x2c, 0xcc, 0xe8, 0x91, 0xb1, 0x30, 0x32, 0x7e, 0x68, 0x54, + 0xc4, 0xc2, 0xe8, 0x11, 0x30, 0x2b, 0x30, 0x26, 0x22, 0x6c, 0x16, 0x0f, 0x84, 0xfd, 0x38, 0xaf, + 0xdd, 0x4b, 0xd5, 0x17, 0xd5, 0x77, 0xb8, 0x39, 0xc8, 0xde, 0xd1, 0x1e, 0x83, 0x8b, 0x10, 0xc9, + 0x3a, 0x4f, 0x7f, 0xcc, 0x33, 0x94, 0xe8, 0x89, 0xb6, 0x22, 0xb8, 0x08, 0x41, 0x95, 0x6e, 0xfa, + 0x29, 0x09, 0x49, 0x62, 0x1e, 0xe6, 0xcf, 0x19, 0x90, 0x4f, 0xca, 0x0b, 0x79, 0x07, 0xc6, 0xa3, + 0x9c, 0x2e, 0x91, 0x67, 0x3c, 0x5a, 0x7e, 0xe2, 0x24, 0x30, 0x9a, 0x8f, 0xbc, 0x8a, 0x4e, 0x16, + 0x20, 0xc7, 0xa6, 0x9d, 0xf2, 0x0c, 0x32, 0xae, 0x27, 0x1d, 0x01, 0x53, 0x9d, 0x0a, 0x25, 0x9e, + 0x32, 0x6b, 0xff, 0x45, 0x16, 0xc6, 0x95, 0xc1, 0x22, 0x57, 0x20, 0x57, 0x0e, 0x56, 0xbc, 0xda, + 0x03, 0x5a, 0x17, 0xbe, 0x4a, 0x93, 0x4f, 0x0e, 0xe7, 0xc7, 0xdc, 0xc0, 0x6e, 0x20, 0xd0, 0x8a, + 0x8a, 0xc9, 0x22, 0x4c, 0xf2, 0xbf, 0x64, 0xb2, 0xb7, 0x4c, 0xec, 0x67, 0xc1, 0x91, 0x65, 0x9a, + 0x37, 0x55, 0x4d, 0xd0, 0x48, 0xc8, 0xd7, 0x00, 0x38, 0x80, 0x8d, 0xef, 0x00, 0x01, 0xb6, 0x72, + 0x02, 0x9f, 0x12, 0x15, 0x84, 0xae, 0xfa, 0x85, 0x28, 0x0a, 0x0a, 0x43, 0xf2, 0x75, 0x9e, 0xae, + 0x45, 0x0a, 0xd7, 0xd1, 0xd1, 0x5b, 0xa6, 0x74, 0x92, 0x66, 0xfc, 0xed, 0xf4, 0x68, 0x2b, 0x95, + 0x25, 0xf9, 0xb6, 0x01, 0xe7, 0x2c, 0x5a, 0xf3, 0x1e, 0x52, 0xff, 0xa0, 0x10, 0x22, 0x96, 0x5a, + 0xe3, 0xd1, 0xa1, 0x5d, 0x37, 0x45, 0x8d, 0xaf, 0xf9, 0x82, 0x0b, 0xe6, 0xb5, 0x68, 0xb6, 0x43, + 0xbb, 0x4f, 0x13, 0xfa, 0x54, 0x69, 0xfe, 0xf7, 0x86, 0x32, 0x05, 0xc8, 0x1a, 0x66, 0x9c, 0xe7, + 0xc2, 0x22, 0xee, 0x45, 0x23, 0x0d, 0x4f, 0xc2, 0x2d, 0xba, 0xbb, 0xf8, 0x82, 0x70, 0x2b, 0x3a, + 0x19, 0x89, 0x5c, 0x22, 0x13, 0x3d, 0x07, 0x92, 0x2f, 0xc2, 0x10, 0x0e, 0xd5, 0xd1, 0x2f, 0x6b, + 0xc9, 0xad, 0x66, 0x88, 0x8d, 0x11, 0xb6, 0x1a, 0x29, 0xc9, 0x67, 0x84, 0xdf, 0x7d, 0x56, 0x7b, + 0xdd, 0x95, 0x81, 0x58, 0x3b, 0xa2, 0x3d, 0x26, 0x0e, 0xf0, 0x53, 0xa4, 0xf5, 0x17, 0x33, 0x90, + 0x4f, 0x4e, 0x3c, 0xf2, 0x3e, 0x4c, 0xc8, 0x6c, 0x33, 0xcb, 0x8e, 0xc8, 0x21, 0x37, 0x21, 0x72, + 0xb8, 0x09, 0xb8, 0xbd, 0xef, 0x68, 0xef, 0xa5, 0x69, 0x04, 0x6c, 0x43, 0xde, 0x10, 0x71, 0xe3, + 0xca, 0x04, 0x0a, 0xbd, 0xb0, 0x9d, 0x78, 0xec, 0x51, 0xa2, 0x91, 0xb7, 0x20, 0xbb, 0x7a, 0xa7, + 0x20, 0xfc, 0x51, 0xe5, 0xfa, 0xb2, 0x7a, 0xa7, 0xc0, 0x3d, 0x07, 0xb8, 0x43, 0x80, 0xee, 0x9e, + 0xc0, 0xf0, 0xc9, 0x8a, 0x92, 0xc0, 0x67, 0x44, 0x4b, 0x47, 0x2d, 0xc1, 0xd1, 0xc7, 0x1d, 0x9d, + 0xc9, 0x47, 0x7d, 0x4c, 0xce, 0xfc, 0xf5, 0x2c, 0x8c, 0x45, 0xf5, 0x13, 0x02, 0xa8, 0x6f, 0x08, + 0x97, 0x54, 0xfc, 0x9b, 0x9c, 0x85, 0x9c, 0x54, 0x31, 0x84, 0x5b, 0xea, 0x68, 0x20, 0xd4, 0x8b, + 0x39, 0x90, 0xba, 0x04, 0x57, 0x2f, 0x2c, 0xf9, 0x93, 0xdc, 0x80, 0x48, 0x51, 0xe8, 0xa5, 0x51, + 0x0c, 0xb1, 0x01, 0xb3, 0x22, 0x34, 0x32, 0x05, 0x19, 0x97, 0xc7, 0x04, 0x8f, 0x59, 0x19, 0xb7, + 0x4e, 0xde, 0x87, 0x9c, 0x53, 0xaf, 0xd3, 0xba, 0xed, 0xc8, 0x0b, 0xc6, 0x7e, 0x42, 0x93, 0x63, + 0xdc, 0xf8, 0x8a, 0x8e, 0x54, 0x85, 0x90, 0x14, 0x60, 0xac, 0xe1, 0x70, 0x97, 0x81, 0xfa, 0x00, + 0xdb, 0x43, 0xcc, 0x21, 0xc7, 0xc8, 0x36, 0x03, 0x5a, 0x27, 0xaf, 0xc1, 0x10, 0x1b, 0x4d, 0xb1, + 0x1f, 0x44, 0x4f, 0xe3, 0xad, 0x6f, 0x54, 0x78, 0x87, 0x2d, 0x9f, 0xb0, 0x10, 0x81, 0xbc, 0x02, + 0xd9, 0xce, 0xc2, 0xae, 0x58, 0xe9, 0xf3, 0x71, 0x32, 0xad, 0x08, 0x8d, 0x15, 0x93, 0x9b, 0x90, + 0x7b, 0xa4, 0xe7, 0x61, 0x3a, 0x95, 0x18, 0xc6, 0x08, 0x3f, 0x42, 0x5c, 0xcc, 0xc1, 0x08, 0x77, + 0x3a, 0x31, 0x2f, 0x00, 0xc4, 0x55, 0x77, 0x7b, 0x0f, 0x9b, 0x5f, 0x83, 0xb1, 0xa8, 0x4a, 0xf2, + 0x22, 0xc0, 0x03, 0x7a, 0x60, 0xef, 0x3b, 0xad, 0x7a, 0x83, 0x2b, 0x9c, 0x13, 0xd6, 0xd8, 0x03, + 0x7a, 0xb0, 0x8c, 0x00, 0x72, 0x06, 0x46, 0xdb, 0x6c, 0x54, 0xe5, 0x53, 0xa5, 0xd6, 0x48, 0xbb, + 0xb3, 0xc3, 0x24, 0x74, 0x0e, 0x46, 0xd1, 0x88, 0x22, 0x26, 0xda, 0xa4, 0x25, 0x7f, 0x9a, 0xff, + 0x24, 0x83, 0x99, 0x35, 0x95, 0x76, 0x92, 0x97, 0x61, 0xb2, 0xe6, 0x53, 0xdc, 0x8e, 0xf0, 0x9d, + 0x5b, 0x51, 0xcf, 0x44, 0x0c, 0x2c, 0xd7, 0xc9, 0x25, 0x98, 0x8e, 0xdf, 0x4e, 0xb5, 0x6b, 0x3b, + 0x22, 0x69, 0xda, 0x84, 0x35, 0xd9, 0x96, 0x8f, 0xa7, 0x16, 0x77, 0x30, 0x96, 0x3d, 0xaf, 0xe6, + 0xac, 0x09, 0xa3, 0x17, 0x52, 0xac, 0x69, 0x05, 0x8e, 0x7e, 0x03, 0xa7, 0x61, 0xc4, 0x71, 0xf6, + 0x3a, 0x2e, 0x8f, 0xab, 0x9d, 0xb0, 0xc4, 0x2f, 0xf2, 0x3a, 0xcc, 0x04, 0xee, 0x5e, 0xcb, 0x09, + 0x3b, 0xbe, 0x48, 0x6d, 0x4a, 0x7d, 0x14, 0xa9, 0x49, 0x2b, 0x1f, 0x15, 0x14, 0x39, 0x9c, 0xbc, + 0x09, 0x44, 0xad, 0xcf, 0xdb, 0xf9, 0x88, 0xd6, 0xb8, 0xa8, 0x4d, 0x58, 0x33, 0x4a, 0xc9, 0x3a, + 0x16, 0x90, 0x97, 0x60, 0xc2, 0xa7, 0x01, 0xaa, 0x64, 0xd8, 0x6d, 0x98, 0x78, 0xda, 0x1a, 0x97, + 0x30, 0xd6, 0x77, 0x97, 0x21, 0xaf, 0x74, 0x07, 0xa6, 0x05, 0xe2, 0x19, 0xc3, 0xac, 0xa9, 0x18, + 0x6e, 0xb5, 0xcb, 0x75, 0x73, 0x11, 0x66, 0xba, 0x66, 0x2e, 0x79, 0x93, 0x9f, 0x03, 0xc4, 0x4e, + 0x3e, 0xc1, 0x8f, 0x3d, 0xe8, 0xf0, 0xa2, 0x6d, 0xe2, 0x02, 0xc9, 0x6c, 0xc1, 0x84, 0xba, 0x12, + 0x1f, 0x91, 0xb8, 0xee, 0x34, 0x06, 0xcf, 0xf1, 0x65, 0x6a, 0xe4, 0xc9, 0xe1, 0x7c, 0xc6, 0xad, + 0x63, 0xc8, 0xdc, 0x65, 0xc8, 0x49, 0x7d, 0x42, 0x9c, 0x11, 0xd0, 0x08, 0x26, 0x54, 0xcf, 0x03, + 0x2b, 0x2a, 0x35, 0x5f, 0x83, 0x51, 0xb1, 0xd8, 0xf6, 0x37, 0x7d, 0x99, 0x3f, 0x99, 0x81, 0x69, + 0x8b, 0xb2, 0xa5, 0x80, 0xf2, 0x6c, 0x95, 0x9f, 0xb2, 0xf7, 0x66, 0xb5, 0x6f, 0xeb, 0x93, 0x27, + 0xf2, 0x37, 0x0c, 0x38, 0x99, 0x82, 0xfb, 0xb1, 0xb2, 0xff, 0xdf, 0x82, 0xb1, 0x92, 0xeb, 0x34, + 0x0a, 0xf5, 0x7a, 0x14, 0x04, 0x88, 0x7a, 0x63, 0x9d, 0x49, 0x9a, 0xc3, 0xa0, 0xea, 0xb6, 0x1b, + 0xa1, 0x92, 0xab, 0x42, 0x28, 0xe2, 0xa7, 0x86, 0xe4, 0x8b, 0xb6, 0xc0, 0xdb, 0x14, 0xbf, 0x67, + 0x8b, 0x89, 0x63, 0x38, 0x30, 0x76, 0x78, 0x7c, 0x6e, 0x87, 0x2e, 0x3d, 0x71, 0x4c, 0xf2, 0xf3, + 0x06, 0x3a, 0xa0, 0xfe, 0x5c, 0x06, 0x4e, 0xa7, 0x13, 0x7e, 0xdc, 0x87, 0x1c, 0x30, 0x49, 0xa7, + 0xf2, 0x68, 0x30, 0x3e, 0xe4, 0xc0, 0x33, 0x7a, 0x22, 0x7e, 0x8c, 0x40, 0x76, 0x61, 0x72, 0xc5, + 0x09, 0xc2, 0x65, 0xea, 0xf8, 0xe1, 0x0e, 0x75, 0xc2, 0x01, 0x74, 0xdd, 0x57, 0xc4, 0xd7, 0xcc, + 0xe1, 0xf6, 0xb7, 0x2f, 0x29, 0x13, 0xaa, 0xa0, 0xce, 0x36, 0x12, 0x94, 0xa1, 0x01, 0x04, 0xe5, + 0x1b, 0x30, 0x5d, 0xa5, 0x4d, 0xa7, 0xbd, 0xef, 0xf9, 0x54, 0x58, 0xeb, 0xaf, 0xc1, 0x64, 0x04, + 0x4a, 0x95, 0x16, 0xbd, 0x58, 0xc3, 0x57, 0x3a, 0x22, 0x5e, 0x4a, 0xf4, 0x62, 0xf3, 0x2f, 0x67, + 0xe0, 0x4c, 0xa1, 0x26, 0x6e, 0xe4, 0x45, 0x81, 0x74, 0x1c, 0xfa, 0x84, 0xeb, 0x26, 0xd7, 0x61, + 0x6c, 0xd5, 0x79, 0xbc, 0x42, 0x9d, 0x80, 0x06, 0x22, 0x8d, 0x36, 0x57, 0xd4, 0x9c, 0xc7, 0xf1, + 0x45, 0xb5, 0x15, 0xe3, 0xa8, 0xc7, 0xd2, 0xa1, 0xa7, 0x3c, 0x96, 0x9a, 0x30, 0xb2, 0xec, 0x35, + 0xea, 0x62, 0x1b, 0x13, 0x37, 0x25, 0xfb, 0x08, 0xb1, 0x44, 0x89, 0xf9, 0x87, 0x06, 0x4c, 0x45, + 0x2d, 0xc6, 0x26, 0x7c, 0xe2, 0x5d, 0x72, 0x09, 0x46, 0xb1, 0xa2, 0x72, 0x49, 0xdd, 0x34, 0x1a, + 0x0c, 0x64, 0xbb, 0x75, 0x4b, 0x16, 0xaa, 0x3d, 0x31, 0xfc, 0x74, 0x3d, 0x61, 0xfe, 0x87, 0x78, + 0x09, 0xa3, 0x7e, 0x25, 0xdb, 0x89, 0x94, 0x86, 0x18, 0x03, 0x36, 0x24, 0xf3, 0xcc, 0x86, 0x24, + 0xdb, 0x73, 0x48, 0xbe, 0x95, 0x81, 0xf1, 0xa8, 0xb1, 0x9f, 0xb2, 0x8c, 0x6b, 0xd1, 0x77, 0x0d, + 0x14, 0x44, 0x5a, 0x55, 0xd6, 0x0a, 0x11, 0xab, 0xf9, 0x45, 0x18, 0x11, 0x93, 0xc9, 0x48, 0x38, + 0xd0, 0x24, 0x46, 0x77, 0x71, 0x4a, 0xb0, 0x1e, 0xc1, 0x01, 0x0d, 0x2c, 0x41, 0x87, 0x51, 0xba, + 0xdb, 0x74, 0x47, 0xdc, 0xc9, 0x3d, 0xb7, 0x7b, 0x54, 0x7a, 0x94, 0x6e, 0xfc, 0x61, 0x03, 0xed, + 0x4e, 0x87, 0xc3, 0x90, 0x4f, 0x92, 0x1c, 0x9d, 0xd3, 0xae, 0xd2, 0xd9, 0xe1, 0x5a, 0x38, 0xcf, + 0x69, 0xd7, 0xee, 0xec, 0x58, 0x0c, 0x46, 0x2e, 0xc1, 0x50, 0xc5, 0x77, 0x1f, 0xe2, 0x57, 0x4f, + 0xf0, 0x8b, 0xdf, 0xb6, 0xef, 0x3e, 0x54, 0x2f, 0x7e, 0x59, 0x39, 0x1e, 0x7d, 0x57, 0xaa, 0x18, + 0xf9, 0x84, 0x2a, 0xb8, 0x38, 0xfa, 0x36, 0x82, 0x64, 0x1e, 0x5f, 0x89, 0xc6, 0xb6, 0xca, 0x45, + 0xea, 0xf8, 0x22, 0xff, 0x9a, 0x58, 0xce, 0x70, 0xab, 0xdc, 0x41, 0x30, 0x7f, 0x4c, 0xca, 0x52, + 0x91, 0x48, 0x03, 0x88, 0xf2, 0x53, 0x4e, 0xe0, 0xa3, 0x4f, 0x83, 0x17, 0xa5, 0x9d, 0x4e, 0x65, + 0x6d, 0xab, 0xb3, 0x39, 0x85, 0xef, 0xb3, 0xb4, 0x26, 0x56, 0x44, 0x36, 0x0e, 0x34, 0x79, 0xe4, + 0x8e, 0x64, 0x26, 0x43, 0x03, 0x81, 0x67, 0xeb, 0x88, 0x0c, 0x1f, 0x31, 0x13, 0xf2, 0x1e, 0x8c, + 0xab, 0xf1, 0x6c, 0x3c, 0xea, 0xea, 0x3c, 0xcf, 0x82, 0xd1, 0xe3, 0x3d, 0x03, 0x95, 0x80, 0xec, + 0xc0, 0x99, 0xa2, 0xd7, 0x0a, 0x3a, 0x4d, 0x5a, 0xd7, 0xee, 0x8c, 0xcb, 0x25, 0x3c, 0x8a, 0x8e, + 0xf1, 0xe0, 0x98, 0x9a, 0x40, 0x11, 0xe1, 0x53, 0xd2, 0x3b, 0x51, 0x3f, 0x80, 0xf4, 0x62, 0x44, + 0x36, 0x60, 0xbc, 0x5a, 0x58, 0x5d, 0x91, 0x31, 0x49, 0xe3, 0xfa, 0xb2, 0x11, 0x97, 0x94, 0xd8, + 0xc4, 0xe0, 0x61, 0xf9, 0x4e, 0xb3, 0x21, 0x9d, 0xe3, 0x54, 0x3b, 0xa5, 0x82, 0x6c, 0x7e, 0x46, + 0x95, 0x6f, 0xa1, 0x6e, 0xf4, 0x95, 0x6f, 0xf3, 0xbf, 0x19, 0x81, 0xe9, 0x44, 0x75, 0xe2, 0xfc, + 0x63, 0x74, 0x9d, 0x7f, 0xaa, 0x00, 0xdc, 0xe8, 0x35, 0xa0, 0x75, 0x4a, 0xfa, 0x55, 0x8f, 0x8b, + 0xa8, 0x84, 0x68, 0xac, 0x14, 0x36, 0x8c, 0x29, 0x97, 0x84, 0x01, 0xad, 0x93, 0x11, 0x53, 0x2e, + 0x4c, 0x0a, 0xd3, 0x98, 0x0d, 0x99, 0x87, 0x61, 0x4c, 0x97, 0xa2, 0xba, 0xb5, 0xbb, 0x0c, 0x60, + 0x71, 0x38, 0x79, 0x19, 0x46, 0xd8, 0xe6, 0x5c, 0x2e, 0x89, 0xc9, 0x85, 0x6b, 0x16, 0xdb, 0xbd, + 0xd9, 0x4e, 0x28, 0x8a, 0xc8, 0x2d, 0x98, 0xe0, 0x7f, 0x89, 0xb8, 0xca, 0x11, 0xdd, 0xc3, 0xc3, + 0x76, 0xeb, 0x32, 0xb4, 0x52, 0xc3, 0x63, 0x5a, 0x6b, 0xb5, 0xb3, 0x23, 0x5e, 0xae, 0x1c, 0x8d, + 0xb5, 0xd6, 0x80, 0x03, 0xf1, 0xf9, 0xb1, 0x08, 0x81, 0xed, 0x91, 0xc2, 0xb9, 0x2c, 0x87, 0x67, + 0x15, 0xdc, 0x23, 0xb9, 0x53, 0x99, 0x25, 0x4a, 0xc8, 0x15, 0x6e, 0x7f, 0x46, 0x75, 0x83, 0xe7, + 0xc3, 0x46, 0x8b, 0x31, 0x1e, 0x78, 0x51, 0xe7, 0x88, 0x8a, 0x59, 0xe5, 0xec, 0xef, 0xa5, 0xa6, + 0xe3, 0x36, 0x84, 0xb8, 0x62, 0xe5, 0x88, 0x4b, 0x19, 0xd4, 0x8a, 0x11, 0xc8, 0x3b, 0x30, 0xc5, + 0x7e, 0x14, 0xbd, 0x66, 0xd3, 0x6b, 0x21, 0xfb, 0xf1, 0x38, 0x02, 0x1e, 0x49, 0x6a, 0x58, 0xc4, + 0x6b, 0x49, 0xe0, 0xb2, 0x75, 0x0a, 0x6f, 0xa3, 0x3a, 0xdc, 0x32, 0x3e, 0x11, 0xaf, 0x53, 0x48, + 0x1a, 0x70, 0xb8, 0xa5, 0x22, 0x91, 0xdb, 0x30, 0xc9, 0x7e, 0xde, 0x75, 0x1f, 0x52, 0x5e, 0xe1, + 0x64, 0x7c, 0x31, 0x88, 0x54, 0x7b, 0xac, 0x84, 0xd7, 0xa7, 0x63, 0x92, 0x2f, 0xc1, 0x29, 0xe4, + 0x54, 0xf3, 0xda, 0xb4, 0x5e, 0xd8, 0xdd, 0x75, 0x1b, 0x2e, 0xce, 0x5e, 0x11, 0x41, 0x88, 0xd6, + 0x48, 0x5e, 0x31, 0x62, 0xd8, 0x4e, 0x8c, 0x62, 0xa5, 0x53, 0x92, 0x6d, 0xc8, 0x17, 0x3b, 0x41, + 0xe8, 0x35, 0x0b, 0x61, 0xe8, 0xbb, 0x3b, 0x9d, 0x90, 0x06, 0x73, 0xd3, 0x5a, 0x9c, 0x1d, 0x9b, + 0x1c, 0x51, 0x21, 0xb7, 0x33, 0xd4, 0x90, 0xc2, 0x76, 0x22, 0x12, 0xab, 0x8b, 0x89, 0xf9, 0x5f, + 0x1b, 0x30, 0xa9, 0x91, 0x92, 0xb7, 0x60, 0xe2, 0x8e, 0xef, 0xd2, 0x56, 0xbd, 0x71, 0xa0, 0x1c, + 0x80, 0x50, 0x3b, 0xde, 0x15, 0x70, 0xfe, 0xd5, 0x1a, 0x5a, 0x64, 0x3f, 0xc8, 0xa4, 0xba, 0xce, + 0x5c, 0xe7, 0xd1, 0x15, 0x42, 0x40, 0xb3, 0x71, 0xe0, 0x2f, 0x0a, 0xa8, 0x90, 0x4e, 0x05, 0x85, + 0xbc, 0x0b, 0x23, 0xfc, 0xde, 0x4a, 0xf8, 0x71, 0x9c, 0x4d, 0xfb, 0x4c, 0x1e, 0xc9, 0x83, 0x82, + 0x88, 0xd7, 0xe5, 0x81, 0x25, 0x88, 0xcc, 0x5f, 0x30, 0x80, 0x74, 0xa3, 0x1e, 0x61, 0x4f, 0x39, + 0xf2, 0x1a, 0xfe, 0x8b, 0xd1, 0x6c, 0xcc, 0x6a, 0xd6, 0x43, 0x56, 0x13, 0x2f, 0xe0, 0x1d, 0x2f, + 0x66, 0x9d, 0x6a, 0xe0, 0xe1, 0xc5, 0xe6, 0x5f, 0xc8, 0x00, 0xc4, 0xd8, 0xe4, 0xf3, 0x3c, 0xad, + 0xef, 0x97, 0x3a, 0x4e, 0xc3, 0xdd, 0x75, 0xf5, 0x04, 0x34, 0xc8, 0xe4, 0x1b, 0xb2, 0xc4, 0xd2, + 0x11, 0xc9, 0xfb, 0x30, 0x5d, 0xad, 0xe8, 0xb4, 0x4a, 0x0a, 0xd3, 0xa0, 0x6d, 0x27, 0xc8, 0x93, + 0xd8, 0xe8, 0xaf, 0xa5, 0x8e, 0x06, 0xf7, 0xd7, 0xe2, 0x03, 0x21, 0x4a, 0xd8, 0xc2, 0x52, 0xad, + 0xe0, 0x8b, 0x91, 0x75, 0x5a, 0x2f, 0x97, 0xc4, 0x2a, 0x85, 0xad, 0x0b, 0xda, 0x76, 0x9b, 0x17, + 0xe0, 0x33, 0x85, 0x1a, 0x5e, 0xdc, 0x91, 0xc3, 0x3d, 0xa2, 0x75, 0x7e, 0x09, 0xcd, 0x49, 0x4d, + 0x2f, 0xa4, 0xe2, 0x14, 0xfd, 0xdc, 0xea, 0xd3, 0xf1, 0xa5, 0xe7, 0xb0, 0x16, 0x84, 0xa0, 0x7d, + 0x1d, 0xc7, 0xd8, 0xba, 0x19, 0x2b, 0xbf, 0xfc, 0xfa, 0x53, 0x5e, 0x7a, 0x2a, 0xaa, 0xdf, 0xdf, + 0x30, 0xe0, 0x54, 0x2a, 0x2d, 0xb9, 0x06, 0x10, 0xdb, 0x2a, 0x44, 0x2f, 0xf1, 0xd7, 0x22, 0x23, + 0xa8, 0xa5, 0x60, 0x90, 0xaf, 0x26, 0xad, 0x0c, 0x47, 0x6f, 0x84, 0xe7, 0x64, 0x3a, 0x03, 0xdd, + 0xca, 0x90, 0x62, 0x5b, 0x30, 0x7f, 0x23, 0x0b, 0x33, 0x4a, 0x34, 0x2d, 0x6f, 0xeb, 0x11, 0xfe, + 0x73, 0x0f, 0xe4, 0xcb, 0xa4, 0xc2, 0x13, 0x3a, 0xa3, 0xbd, 0x4e, 0xdc, 0xc5, 0xed, 0x9a, 0x8a, + 0xcc, 0x73, 0x78, 0xe0, 0xd2, 0x29, 0x1e, 0x2a, 0xed, 0xf2, 0x88, 0xd6, 0x98, 0x93, 0x00, 0x26, + 0x4b, 0x07, 0x2d, 0xa7, 0x19, 0xd5, 0xc6, 0x2f, 0xea, 0x5f, 0xef, 0x59, 0x9b, 0x86, 0xcd, 0xab, + 0x93, 0x3a, 0xe7, 0x5c, 0x9d, 0x97, 0xa5, 0xc4, 0xfa, 0x68, 0x54, 0xe7, 0xde, 0x87, 0x99, 0xae, + 0x46, 0x1f, 0x2b, 0x9d, 0xc8, 0x36, 0x90, 0xee, 0x76, 0xa4, 0x70, 0x78, 0x5d, 0x4f, 0x56, 0x73, + 0x2a, 0xba, 0xc6, 0x6b, 0x36, 0x9d, 0x56, 0x9d, 0x5f, 0xfb, 0x2f, 0xa8, 0xc9, 0x46, 0x7e, 0x29, + 0xa3, 0xba, 0xf2, 0x3f, 0xef, 0xb3, 0xee, 0x8b, 0xda, 0x29, 0xeb, 0x42, 0xaf, 0x31, 0x1d, 0xe8, + 0x34, 0xfb, 0xfd, 0x2c, 0x9c, 0xe9, 0x41, 0x49, 0x0e, 0x92, 0x42, 0xc4, 0x4f, 0xb7, 0x37, 0xfa, + 0x57, 0xf8, 0x2c, 0x44, 0x89, 0x7c, 0x9e, 0x07, 0xf3, 0xd5, 0xf0, 0x11, 0x22, 0x71, 0xae, 0xe3, + 0x2f, 0xbd, 0x45, 0xd0, 0x64, 0x14, 0x1f, 0x87, 0x92, 0xf7, 0x61, 0x18, 0xe3, 0x38, 0x12, 0xd9, + 0x3c, 0x18, 0x06, 0xc2, 0x95, 0xd4, 0x27, 0xec, 0xa7, 0x96, 0xfa, 0x04, 0x9f, 0xde, 0xfe, 0x1c, + 0x64, 0x0b, 0xdb, 0x55, 0x31, 0x2e, 0x53, 0x2a, 0xf9, 0x76, 0x35, 0xce, 0xe2, 0xe8, 0x68, 0xe9, + 0x16, 0x19, 0x05, 0x23, 0xbc, 0x5b, 0xac, 0x88, 0x51, 0x51, 0x09, 0xef, 0x16, 0x2b, 0x31, 0xe1, + 0x5e, 0x4d, 0x8b, 0x8e, 0xbe, 0x5b, 0xac, 0x7c, 0x72, 0x62, 0xff, 0x33, 0x19, 0x1e, 0x81, 0xc8, + 0x3f, 0xec, 0x7d, 0x98, 0xd0, 0x92, 0x89, 0x19, 0xb1, 0x3e, 0x16, 0x25, 0x42, 0x4b, 0xf8, 0x49, + 0x68, 0x04, 0x32, 0x1f, 0x6a, 0xf4, 0x88, 0xb7, 0xea, 0xe6, 0xa0, 0x3f, 0xfc, 0x9d, 0xcc, 0x87, + 0x1a, 0x91, 0x90, 0x9b, 0x90, 0xdb, 0xa0, 0x2d, 0xa7, 0x15, 0x46, 0x86, 0x36, 0x74, 0xcb, 0x0b, + 0x11, 0xa6, 0x6b, 0x0d, 0x11, 0x22, 0x3e, 0xb9, 0xae, 0x3c, 0x41, 0x1e, 0xed, 0xc5, 0xdc, 0x59, + 0x54, 0x29, 0x49, 0xbc, 0x59, 0xaf, 0x13, 0x99, 0xbf, 0x64, 0xc0, 0xa8, 0x18, 0x48, 0xe5, 0xdd, + 0x5b, 0x63, 0x80, 0x77, 0x6f, 0x6f, 0xc1, 0x98, 0x08, 0xa6, 0xd1, 0x5f, 0xab, 0x17, 0xf1, 0x37, + 0x89, 0xd7, 0xea, 0x23, 0xd4, 0x81, 0xbd, 0xce, 0xff, 0x9a, 0x68, 0xd9, 0xdd, 0x62, 0x85, 0x2c, + 0x40, 0x4e, 0x3e, 0x1f, 0x2e, 0xda, 0x86, 0xcb, 0x8e, 0x7c, 0x67, 0x5c, 0xed, 0x20, 0x89, 0xa7, + 0xbf, 0xc2, 0x9f, 0x19, 0xfc, 0x15, 0xfe, 0x41, 0xdb, 0x47, 0x53, 0x16, 0x89, 0xad, 0x9b, 0x2b, + 0x6e, 0x10, 0x92, 0x7b, 0xaa, 0x37, 0xbf, 0x28, 0x92, 0x2b, 0xc5, 0xb9, 0x5e, 0x2b, 0xc5, 0xd6, + 0x4d, 0x2b, 0x85, 0x0a, 0xef, 0x6b, 0x62, 0x70, 0x95, 0xfa, 0x0f, 0x9f, 0xe3, 0x55, 0x3a, 0xfd, + 0xbe, 0x26, 0xf9, 0x79, 0x03, 0x2d, 0xd2, 0xff, 0x22, 0x03, 0xa7, 0xd3, 0x09, 0xd5, 0x6f, 0x31, + 0xfa, 0x7c, 0xcb, 0x65, 0xc8, 0x2d, 0x7b, 0x41, 0xa8, 0xb8, 0x46, 0xa1, 0x59, 0x79, 0x5f, 0xc0, + 0xac, 0xa8, 0x94, 0x9d, 0xb9, 0xd9, 0xdf, 0xd1, 0xf4, 0x44, 0x7e, 0x18, 0x77, 0xc7, 0xce, 0xdc, + 0xbc, 0x88, 0xdc, 0x85, 0x9c, 0x25, 0x1c, 0xcf, 0x13, 0x5d, 0x23, 0xc1, 0x91, 0x36, 0x45, 0x7c, + 0x01, 0xd1, 0x72, 0xba, 0x09, 0x18, 0x29, 0xc0, 0xa8, 0x18, 0xfd, 0xc4, 0x95, 0x64, 0x8a, 0xc8, + 0xe8, 0x69, 0x16, 0x25, 0x1d, 0x5b, 0x51, 0xf0, 0x72, 0xa9, 0x5c, 0x92, 0x3e, 0xe4, 0xb8, 0xa2, + 0xf0, 0xcb, 0x27, 0x3d, 0xb1, 0x63, 0x84, 0x68, 0xfe, 0x64, 0x06, 0x60, 0x9b, 0xee, 0x3c, 0xdf, + 0xef, 0x87, 0x7c, 0x4e, 0x93, 0x30, 0xc5, 0xf3, 0x62, 0xf0, 0xe7, 0x43, 0xd6, 0xd1, 0x03, 0x62, + 0xf0, 0xc7, 0x43, 0xe6, 0x61, 0x98, 0x5b, 0x3b, 0x95, 0x43, 0x22, 0x37, 0x73, 0x72, 0xb8, 0xb9, + 0x03, 0xb3, 0x77, 0x69, 0x18, 0x9b, 0xb7, 0xe4, 0x95, 0x56, 0x7f, 0xb6, 0x6f, 0xc0, 0x98, 0xc0, + 0xd7, 0x9f, 0x82, 0x97, 0xa1, 0xac, 0x68, 0x8b, 0x91, 0x08, 0x6c, 0x35, 0x2a, 0xd1, 0x06, 0x0d, + 0xe9, 0x27, 0x5b, 0x4d, 0x15, 0x08, 0xff, 0x14, 0xfc, 0xb2, 0xc1, 0x6a, 0x38, 0xb2, 0x7f, 0xb6, + 0xe0, 0x54, 0xd4, 0xf6, 0x67, 0xc9, 0xf7, 0x3a, 0x3b, 0x52, 0x8a, 0x0c, 0x85, 0x31, 0xc7, 0x3e, + 0x3e, 0x0d, 0x8f, 0xe1, 0x9c, 0x24, 0xd8, 0x76, 0x23, 0x17, 0xb2, 0x81, 0x68, 0xc9, 0x3b, 0x30, + 0xae, 0xd0, 0x88, 0x1c, 0xb0, 0x68, 0xfe, 0x7c, 0xe4, 0x86, 0xfb, 0x76, 0xc0, 0xe1, 0xaa, 0xf9, + 0x53, 0x41, 0x37, 0x3f, 0x84, 0x17, 0x22, 0x87, 0xfb, 0x94, 0xaa, 0x13, 0xcc, 0x8d, 0xe3, 0x31, + 0x5f, 0x8b, 0x3f, 0xab, 0xdc, 0x8a, 0xc2, 0xbf, 0x24, 0x6f, 0xa2, 0x7e, 0x96, 0xf8, 0x98, 0xf3, + 0x5d, 0x01, 0x65, 0x4a, 0xdc, 0x98, 0xf9, 0xb6, 0xd2, 0xd8, 0x14, 0x86, 0x1a, 0xb1, 0x91, 0x24, + 0xfe, 0xc9, 0x0c, 0x4c, 0xaf, 0x97, 0x4b, 0xc5, 0xc8, 0xab, 0xe5, 0x53, 0xf6, 0xb8, 0x89, 0xf6, + 0x6d, 0xbd, 0xd7, 0x1b, 0x73, 0x13, 0x4e, 0x26, 0xba, 0x01, 0x55, 0x87, 0xf7, 0xb8, 0x63, 0x7c, + 0x04, 0x96, 0x6a, 0xc3, 0xe9, 0x34, 0xf6, 0x5b, 0x37, 0xad, 0x04, 0xb6, 0xf9, 0x77, 0x72, 0x09, + 0xbe, 0x62, 0x09, 0x7b, 0x03, 0xc6, 0xca, 0x41, 0xd0, 0xa1, 0xfe, 0xa6, 0xb5, 0xa2, 0x9a, 0x0a, + 0x5c, 0x04, 0xda, 0x1d, 0xbf, 0x61, 0xc5, 0x08, 0xe4, 0x0a, 0xe4, 0x44, 0x56, 0x3c, 0xb9, 0x26, + 0xa0, 0xd5, 0x36, 0x4a, 0xaa, 0x67, 0x45, 0xc5, 0xe4, 0x2d, 0x98, 0xe0, 0x7f, 0x73, 0x69, 0x13, + 0x1d, 0x8e, 0xc6, 0x41, 0x81, 0xce, 0xa5, 0xd3, 0xd2, 0xd0, 0xc8, 0x55, 0xc8, 0x16, 0x8a, 0x96, + 0xfa, 0x02, 0xb4, 0x53, 0xf3, 0xf9, 0x4b, 0xf0, 0xfa, 0x21, 0xa2, 0x68, 0x31, 0xed, 0x4f, 0x98, + 0x92, 0x7c, 0x61, 0xc9, 0x46, 0x09, 0x90, 0xd6, 0xa6, 0xc4, 0x66, 0x86, 0x30, 0x72, 0x1d, 0x46, + 0x4b, 0x6e, 0xd0, 0x6e, 0x38, 0x07, 0xc2, 0x8e, 0xcd, 0x53, 0x9e, 0x73, 0x90, 0x2a, 0x33, 0x02, + 0x8b, 0x5c, 0x81, 0x61, 0x34, 0xb2, 0x0a, 0x5b, 0x36, 0x4f, 0x0c, 0xce, 0x00, 0x5a, 0x62, 0x70, + 0x06, 0xc0, 0xa4, 0xab, 0x3c, 0x77, 0xdc, 0x98, 0x92, 0x74, 0x35, 0x99, 0x33, 0x4e, 0xe0, 0x74, + 0x47, 0x52, 0xc1, 0xb3, 0x8c, 0xa4, 0xda, 0x81, 0x33, 0x77, 0xd1, 0x7a, 0xa3, 0xc7, 0xb7, 0x6f, + 0x5a, 0x65, 0x61, 0x0f, 0xc7, 0x1b, 0x1f, 0x6e, 0xe0, 0x49, 0x86, 0xc8, 0xdb, 0x1d, 0x5f, 0x7d, + 0xc1, 0xa3, 0x17, 0x23, 0xf2, 0x65, 0x98, 0x4d, 0x2b, 0x12, 0x56, 0x73, 0x8c, 0xe4, 0x4e, 0xaf, + 0x40, 0x8d, 0xe4, 0x4e, 0xe3, 0x40, 0x56, 0x20, 0xcf, 0xe1, 0x85, 0x7a, 0xd3, 0x6d, 0x71, 0xcb, + 0xff, 0x64, 0xfc, 0xfa, 0xa6, 0xe0, 0xea, 0xb0, 0x42, 0x7e, 0x03, 0xa0, 0x85, 0x48, 0x24, 0x28, + 0xc9, 0xcf, 0x1b, 0xec, 0x34, 0xc7, 0x33, 0xad, 0x6d, 0x5a, 0x2b, 0x81, 0xc8, 0x02, 0x72, 0x3a, + 0x8e, 0x7e, 0xa8, 0x86, 0xbe, 0xdb, 0xda, 0x13, 0xe1, 0x0f, 0x1b, 0x22, 0xfc, 0xe1, 0x9d, 0x8f, + 0x15, 0xfe, 0xc0, 0x59, 0x05, 0x4f, 0x0e, 0xe7, 0x27, 0x7c, 0x51, 0x27, 0xce, 0x22, 0xad, 0x05, + 0xf8, 0x84, 0x5f, 0xa3, 0xe1, 0x3d, 0xda, 0x6c, 0x3d, 0xa4, 0xbe, 0xbb, 0xeb, 0xd2, 0x3a, 0xff, + 0xc8, 0x69, 0x5c, 0xc1, 0xf9, 0x13, 0x7e, 0xf8, 0xa4, 0x63, 0x27, 0x42, 0xe8, 0xfa, 0xd0, 0x54, + 0x0e, 0xec, 0xe0, 0x29, 0x1d, 0xf6, 0x79, 0x1c, 0x5b, 0x3e, 0x3e, 0x78, 0x4a, 0xef, 0x7e, 0x1b, + 0xc5, 0x48, 0x15, 0x1e, 0x8d, 0x44, 0x78, 0x07, 0xff, 0xe2, 0x18, 0x5f, 0x91, 0x0b, 0x9d, 0x70, + 0x5f, 0xae, 0xe1, 0x0b, 0x69, 0x41, 0x07, 0xdc, 0xe5, 0x49, 0x09, 0x3a, 0xd0, 0x43, 0x0d, 0xa4, + 0x29, 0x3d, 0x93, 0x6a, 0x4a, 0x7f, 0x03, 0xc6, 0xf0, 0xc1, 0xe2, 0xc8, 0xbb, 0x3b, 0x27, 0x6c, + 0x95, 0x0c, 0xc8, 0x53, 0x8a, 0xc5, 0x08, 0xe4, 0x3a, 0x00, 0x26, 0xe1, 0xe7, 0x1b, 0xbc, 0x92, + 0x16, 0x14, 0x73, 0xf5, 0x8b, 0x5b, 0x64, 0x05, 0x05, 0xd9, 0x57, 0xad, 0x3b, 0xea, 0xb5, 0x33, + 0x67, 0x1f, 0xf8, 0xbb, 0x02, 0x3d, 0x46, 0x60, 0x9f, 0xa7, 0x0c, 0x93, 0x58, 0x54, 0xf2, 0x5d, + 0x63, 0xa9, 0x22, 0xa1, 0x47, 0x97, 0x74, 0x65, 0xc5, 0x35, 0x65, 0x42, 0x78, 0x74, 0x45, 0x6e, + 0xaf, 0x56, 0x8c, 0x40, 0x3e, 0x07, 0xa3, 0x45, 0xea, 0x87, 0x1b, 0x1b, 0x2b, 0x78, 0x33, 0xcc, + 0x73, 0x67, 0xe6, 0x30, 0xcf, 0x61, 0x18, 0x36, 0x7e, 0x70, 0x38, 0x3f, 0x19, 0xba, 0x4d, 0x7a, + 0x2d, 0xba, 0xc6, 0x95, 0xd8, 0x64, 0x11, 0xf2, 0xfc, 0x8e, 0x31, 0x56, 0xe4, 0x70, 0x99, 0xc9, + 0xf1, 0x45, 0x4f, 0x5c, 0x48, 0x3e, 0xa2, 0x3b, 0x51, 0x96, 0xc7, 0x2e, 0x7c, 0xb2, 0x24, 0x93, + 0xa3, 0xaa, 0x1f, 0x09, 0xb1, 0x65, 0x41, 0x2c, 0xcc, 0xda, 0xb7, 0x76, 0x53, 0x90, 0x02, 0x4c, + 0x16, 0xbd, 0x66, 0xdb, 0x09, 0x5d, 0xcc, 0x8e, 0x7f, 0x20, 0x56, 0x14, 0xb4, 0x8e, 0xd4, 0xd4, + 0x02, 0xfd, 0xfd, 0x61, 0xa5, 0x80, 0xdc, 0x81, 0x29, 0xcb, 0xeb, 0xb0, 0x41, 0x92, 0x47, 0x1a, + 0xbe, 0x68, 0x44, 0x2f, 0xdb, 0xb3, 0xb1, 0xb4, 0xc5, 0xf9, 0x45, 0xcb, 0x8e, 0xa3, 0x51, 0x91, + 0xb5, 0x14, 0xdb, 0xb2, 0xba, 0x52, 0xa8, 0xb9, 0x1e, 0xbb, 0x98, 0xa5, 0x98, 0xa5, 0x6f, 0xc2, + 0x78, 0xb5, 0xba, 0xbe, 0x41, 0x83, 0xf0, 0x4e, 0xc3, 0x7b, 0x84, 0x0b, 0x45, 0x4e, 0xa4, 0x98, + 0x0e, 0x3c, 0x3b, 0xa4, 0x41, 0x68, 0xef, 0x36, 0xbc, 0x47, 0x96, 0x8a, 0x45, 0x7e, 0x48, 0x79, + 0x90, 0x19, 0x77, 0xfe, 0xe9, 0x23, 0x77, 0xfe, 0xc4, 0x63, 0xcd, 0x6c, 0xff, 0x4f, 0x7d, 0xac, + 0x99, 0xa1, 0x63, 0xa8, 0x02, 0x3b, 0x8c, 0x15, 0xea, 0x75, 0x9f, 0x06, 0x81, 0x98, 0xd1, 0xca, + 0x73, 0xf3, 0x0e, 0x2f, 0xd0, 0x42, 0x15, 0x14, 0x02, 0xf2, 0x2d, 0x03, 0x4e, 0xa9, 0xde, 0xce, + 0x38, 0x59, 0x9a, 0xb4, 0x15, 0xce, 0xcd, 0x60, 0x4b, 0xdf, 0xbc, 0x26, 0x57, 0xb4, 0x6b, 0x0a, + 0xda, 0xb5, 0x87, 0x37, 0xae, 0x29, 0xaf, 0x84, 0x56, 0x25, 0x91, 0x48, 0xa5, 0x91, 0xc6, 0x4f, + 0x5d, 0x9d, 0x9c, 0x14, 0x52, 0x52, 0x64, 0x9b, 0x1e, 0x93, 0x27, 0xf4, 0x6d, 0x28, 0x57, 0x30, + 0x5b, 0x90, 0x30, 0x4e, 0x09, 0xe9, 0xe3, 0x5e, 0x10, 0x6e, 0x5b, 0xdf, 0xdb, 0x14, 0x1a, 0x54, + 0x15, 0xab, 0x85, 0xd5, 0x95, 0x58, 0xdf, 0xf9, 0x74, 0xb9, 0x18, 0x6b, 0xdf, 0xd6, 0xc7, 0xc5, + 0x78, 0x13, 0x4e, 0x26, 0xba, 0x41, 0xaa, 0x8a, 0x1a, 0x38, 0xa9, 0x2a, 0x26, 0x68, 0xac, 0x04, + 0xb6, 0xf9, 0xb7, 0x47, 0x13, 0x7c, 0x85, 0x5b, 0x91, 0x09, 0x23, 0x5c, 0x13, 0x54, 0x9f, 0xa4, + 0xe3, 0x7a, 0xa2, 0x25, 0x4a, 0xc8, 0x59, 0xc8, 0x56, 0xab, 0xeb, 0xea, 0x83, 0x99, 0x41, 0xe0, + 0x59, 0x0c, 0xc6, 0x46, 0x08, 0x3d, 0x86, 0x94, 0xb4, 0x7d, 0x6c, 0xd9, 0xb3, 0x10, 0xca, 0xfa, + 0x5b, 0xea, 0x65, 0x43, 0x71, 0x7f, 0x0b, 0xbd, 0x2c, 0xd6, 0xc6, 0x8a, 0x30, 0x57, 0x08, 0x02, + 0xea, 0xe3, 0xeb, 0xbc, 0xdc, 0x11, 0xc5, 0x17, 0xba, 0x83, 0x58, 0xdd, 0xb1, 0x52, 0xa7, 0x16, + 0x58, 0x3d, 0x11, 0xc9, 0x65, 0xc8, 0x15, 0x3a, 0x75, 0x97, 0xb6, 0x6a, 0x5a, 0xea, 0x07, 0x47, + 0xc0, 0xac, 0xa8, 0x94, 0x7c, 0x09, 0x4e, 0x09, 0x22, 0xa9, 0x40, 0x8a, 0x1e, 0x18, 0x8d, 0xa7, + 0xa0, 0xd4, 0x6d, 0xe2, 0x4b, 0x4e, 0xde, 0x25, 0xe9, 0x94, 0xa4, 0x00, 0xf9, 0x25, 0x74, 0xa9, + 0x2f, 0x51, 0x6e, 0x6f, 0xf5, 0x7c, 0xf1, 0xb0, 0x38, 0x6a, 0xa2, 0xdc, 0xdd, 0xde, 0xae, 0x47, + 0x85, 0x56, 0x17, 0x3a, 0xb9, 0x0f, 0x27, 0x93, 0x30, 0xb6, 0x90, 0x73, 0xa5, 0x13, 0xf3, 0x46, + 0x75, 0x71, 0xc1, 0xa5, 0x3c, 0x8d, 0x8a, 0xec, 0xc0, 0x4c, 0x7c, 0xc9, 0xaf, 0xab, 0xa2, 0xd2, + 0x27, 0x2d, 0x2a, 0x97, 0xea, 0xe8, 0x0b, 0x42, 0x18, 0x4f, 0xc6, 0x0e, 0x03, 0x91, 0x4a, 0x6a, + 0x75, 0xb3, 0x23, 0x75, 0x98, 0xaa, 0xba, 0x7b, 0x2d, 0xb7, 0xb5, 0x77, 0x9f, 0x1e, 0x54, 0x1c, + 0xd7, 0x17, 0xde, 0x41, 0xd2, 0xf7, 0xaf, 0x10, 0x1c, 0x34, 0x9b, 0x34, 0xf4, 0x71, 0x8b, 0x64, + 0xe5, 0x18, 0x51, 0x67, 0xb0, 0xbd, 0x20, 0xe0, 0x74, 0x18, 0x3d, 0xd2, 0x76, 0x5c, 0x6d, 0x2f, + 0xd0, 0x79, 0x6a, 0xc7, 0x81, 0x89, 0x01, 0x8f, 0x03, 0x0d, 0x98, 0x59, 0x6a, 0xd5, 0xfc, 0x03, + 0x34, 0x7b, 0xcb, 0xc6, 0x4d, 0x1e, 0xd1, 0xb8, 0x57, 0x44, 0xe3, 0xce, 0x3b, 0x52, 0xc2, 0xd2, + 0x9a, 0xd7, 0xcd, 0x98, 0x54, 0xc5, 0x2b, 0xea, 0xe5, 0x52, 0xa5, 0xdc, 0x72, 0x43, 0x17, 0x1f, + 0x87, 0xe3, 0x7b, 0xcc, 0xab, 0x82, 0xe7, 0x8b, 0x5c, 0xed, 0x73, 0xeb, 0x6d, 0xdb, 0x95, 0x28, + 0x5d, 0xcf, 0xa4, 0xab, 0xf4, 0xe6, 0x7f, 0x9a, 0xe3, 0xab, 0xa1, 0xaa, 0xa6, 0xf5, 0xf2, 0x77, + 0x4a, 0xa8, 0x6f, 0x99, 0xe3, 0xa8, 0x6f, 0xd9, 0xa3, 0xd5, 0xb7, 0xa1, 0xa3, 0xd4, 0xb7, 0x84, + 0x7e, 0x35, 0x7c, 0x6c, 0xfd, 0x6a, 0xe4, 0x18, 0xfa, 0xd5, 0xe8, 0xb1, 0xf4, 0x2b, 0x4d, 0x51, + 0xcc, 0x1d, 0xa5, 0x28, 0xfe, 0x7f, 0xda, 0xd8, 0xf3, 0xaa, 0x8d, 0xa5, 0x6d, 0xae, 0xc7, 0xd2, + 0xc6, 0x7a, 0x2b, 0x53, 0xf9, 0x3f, 0x6d, 0x65, 0x6a, 0xe6, 0x63, 0x28, 0x53, 0x7f, 0x0e, 0xf2, + 0xc9, 0xf5, 0xfd, 0xe8, 0xe4, 0x46, 0xcf, 0x2c, 0x07, 0x09, 0xdb, 0x7d, 0x92, 0xeb, 0x2b, 0x3b, + 0xe4, 0x55, 0x7c, 0xf7, 0xa1, 0x13, 0xd2, 0xf8, 0x51, 0x66, 0x3c, 0xe4, 0xb5, 0x39, 0x14, 0xe7, + 0xbc, 0x82, 0x12, 0xa9, 0x16, 0x99, 0x34, 0xd5, 0xc2, 0xfc, 0xa9, 0x0c, 0xcc, 0xf0, 0xb4, 0x09, + 0xcf, 0xbf, 0x6d, 0xf1, 0x3d, 0x4d, 0x61, 0x94, 0x2e, 0x44, 0x89, 0xaf, 0xeb, 0x63, 0x5d, 0xfc, + 0x1a, 0x9c, 0xea, 0xea, 0x0a, 0x54, 0x1a, 0x4b, 0x32, 0x61, 0x45, 0x97, 0xda, 0x38, 0x97, 0x5e, + 0xc9, 0xd6, 0x4d, 0xab, 0x8b, 0xc2, 0xfc, 0x37, 0xd9, 0x2e, 0xfe, 0xc2, 0xce, 0xa8, 0x5a, 0x0e, + 0x8d, 0xe3, 0x59, 0x0e, 0x33, 0x83, 0x59, 0x0e, 0x13, 0x7b, 0x4b, 0x76, 0x90, 0xbd, 0xe5, 0x4b, + 0x30, 0xb9, 0x41, 0x9d, 0x66, 0xb0, 0xe1, 0x89, 0xb4, 0xa8, 0xdc, 0x85, 0x50, 0xe6, 0xa3, 0x60, + 0x65, 0x52, 0xe7, 0x89, 0x5c, 0x21, 0x42, 0x46, 0xc0, 0xd6, 0x43, 0x9e, 0x27, 0xd5, 0xd2, 0x39, + 0xa8, 0x8a, 0xec, 0x70, 0x1f, 0x45, 0xb6, 0x0a, 0x13, 0x82, 0x2e, 0xce, 0xe8, 0x14, 0x6b, 0x5c, + 0xac, 0x08, 0xe1, 0xb2, 0xf6, 0xe8, 0xf9, 0x98, 0xa8, 0x76, 0xae, 0x6c, 0x69, 0x4c, 0x58, 0x17, + 0x2c, 0xb5, 0xea, 0x6d, 0xcf, 0x6d, 0x61, 0x17, 0x8c, 0xc6, 0x5d, 0x40, 0x05, 0x98, 0x77, 0x81, + 0x82, 0x44, 0xde, 0x81, 0xa9, 0x42, 0xa5, 0xac, 0x92, 0xe5, 0x62, 0xe3, 0xa5, 0xd3, 0x76, 0x6d, + 0x8d, 0x34, 0x81, 0x6b, 0xfe, 0xd8, 0x98, 0x9c, 0x5b, 0x9f, 0xac, 0x95, 0x48, 0xb7, 0xfb, 0x64, + 0x8f, 0x69, 0xf7, 0x19, 0x3a, 0x6a, 0x3b, 0xd7, 0x74, 0x8c, 0xe1, 0x63, 0xe8, 0x18, 0x23, 0x4f, + 0x6d, 0xc3, 0x19, 0x3d, 0xa6, 0xd6, 0x90, 0x10, 0xf3, 0xdc, 0x20, 0x62, 0x9e, 0xaa, 0x69, 0x8c, + 0x3d, 0xbd, 0xa6, 0x01, 0xc7, 0xd6, 0x34, 0x94, 0xf7, 0x8b, 0xc7, 0x07, 0x7a, 0xbf, 0xd8, 0x18, + 0xe0, 0xfd, 0xe2, 0x4f, 0x95, 0xfa, 0xf2, 0xf5, 0x74, 0xf5, 0xa5, 0xff, 0x52, 0xff, 0xff, 0x66, + 0x05, 0xc6, 0xc7, 0x5e, 0xde, 0x76, 0x7c, 0x76, 0x16, 0x0c, 0xc8, 0x75, 0x18, 0x95, 0x99, 0x65, + 0x8c, 0xf8, 0x58, 0xdd, 0x9d, 0x52, 0x46, 0x62, 0xb1, 0x63, 0xa3, 0x24, 0x16, 0xb1, 0xd5, 0x3c, + 0x89, 0x86, 0x80, 0x69, 0x49, 0x34, 0x04, 0xcc, 0xfc, 0x9b, 0x43, 0x72, 0x26, 0xb3, 0x63, 0x8d, + 0x78, 0x2a, 0x6f, 0x51, 0x19, 0x39, 0x45, 0x7d, 0x4a, 0x8c, 0x4d, 0xc2, 0x67, 0x48, 0x27, 0xf9, + 0x38, 0x69, 0x79, 0x94, 0xd7, 0x0b, 0xb2, 0x03, 0xbc, 0x5e, 0x70, 0x5b, 0x4b, 0xfd, 0x3f, 0x14, + 0xe7, 0x9a, 0x66, 0xd2, 0xdd, 0x3f, 0xe9, 0xff, 0x2d, 0x35, 0x47, 0xff, 0x70, 0x1c, 0x86, 0x8e, + 0x94, 0x7d, 0xb2, 0xf3, 0x47, 0xfa, 0xe0, 0xc8, 0x71, 0x52, 0x54, 0x8d, 0xfe, 0xa9, 0xa6, 0xa8, + 0x5a, 0x02, 0x50, 0xde, 0x4f, 0xe3, 0xa6, 0xfa, 0x57, 0x59, 0x37, 0x1d, 0xfd, 0x76, 0x9a, 0x42, + 0x68, 0xfe, 0x53, 0x02, 0x33, 0xd5, 0xea, 0x7a, 0xc9, 0x75, 0xf6, 0x5a, 0x5e, 0x10, 0xba, 0xb5, + 0x72, 0x6b, 0xd7, 0x63, 0xca, 0x50, 0xb4, 0x2a, 0x28, 0xe9, 0x92, 0xe2, 0x15, 0x21, 0x2a, 0x66, + 0xca, 0xf6, 0x92, 0xef, 0x7b, 0xbe, 0xaa, 0x6c, 0x53, 0x06, 0xb0, 0x38, 0x9c, 0xe9, 0x1b, 0xd5, + 0x0e, 0x7f, 0x08, 0x8b, 0xdf, 0x9e, 0xa0, 0xbe, 0x11, 0x70, 0x90, 0x25, 0xcb, 0x08, 0xed, 0x16, + 0x58, 0xa1, 0x7f, 0x9e, 0xd1, 0x12, 0x5d, 0xc5, 0xc5, 0x7c, 0xcd, 0x13, 0x7b, 0x12, 0x06, 0xa1, + 0xb4, 0x11, 0xae, 0x5e, 0xb5, 0x75, 0xcd, 0x81, 0x03, 0x38, 0xa5, 0x05, 0x53, 0x0c, 0x6a, 0x51, + 0xba, 0x2a, 0xf4, 0x1b, 0x13, 0x63, 0xc2, 0x52, 0xcc, 0x4a, 0x6a, 0xae, 0xdc, 0xd4, 0x1a, 0xc8, + 0x4f, 0x19, 0xf0, 0x62, 0x6a, 0x49, 0x34, 0xbb, 0xc7, 0xb5, 0x64, 0x63, 0xca, 0xa2, 0xc1, 0xb3, + 0x02, 0xf7, 0xaa, 0xda, 0x4e, 0x59, 0x0a, 0xfa, 0xd7, 0x44, 0xfe, 0xa1, 0x01, 0x67, 0x34, 0x8c, + 0x68, 0xcd, 0x0b, 0x70, 0x6f, 0xea, 0x29, 0xd7, 0x1f, 0x3d, 0x1b, 0xb9, 0x7e, 0x59, 0xff, 0x96, + 0x78, 0x49, 0x56, 0xbf, 0xa1, 0x57, 0x0b, 0xc9, 0x43, 0x98, 0xc1, 0x22, 0x69, 0xdd, 0x62, 0x32, + 0x2b, 0x8c, 0x62, 0xb3, 0x71, 0xb3, 0x79, 0x80, 0x10, 0xbe, 0xec, 0xb2, 0xf0, 0xfd, 0xc3, 0xf9, + 0x49, 0x0d, 0x1d, 0xf3, 0x9c, 0x62, 0x1b, 0x22, 0x13, 0x99, 0xdb, 0xda, 0xf5, 0xb4, 0x67, 0xea, + 0x93, 0x55, 0x90, 0xff, 0xdc, 0x80, 0x39, 0x06, 0xe5, 0x9f, 0x71, 0xc7, 0xf7, 0x9a, 0x51, 0xb9, + 0xbc, 0xb3, 0xed, 0xd1, 0x6d, 0x8d, 0x67, 0xd3, 0x6d, 0xaf, 0x62, 0x93, 0xf9, 0x9a, 0x60, 0xef, + 0xfa, 0x5e, 0x33, 0x6e, 0xbe, 0xf6, 0x3e, 0x58, 0xaf, 0x46, 0x92, 0x1f, 0x37, 0xe0, 0xac, 0x66, + 0x60, 0x50, 0xb3, 0x7b, 0x8a, 0x30, 0x2c, 0x79, 0xc1, 0xaf, 0x16, 0x2d, 0x5e, 0x13, 0xf2, 0x7f, + 0x09, 0x5b, 0x10, 0xef, 0x16, 0xd8, 0x16, 0xbb, 0xc9, 0xb1, 0x94, 0x26, 0xf4, 0xae, 0x85, 0xb8, + 0x30, 0x83, 0x37, 0x4e, 0x9a, 0x6f, 0xc1, 0x6c, 0x6f, 0xdf, 0x82, 0x28, 0x03, 0x3f, 0x66, 0x50, + 0xec, 0xed, 0x60, 0xd0, 0xcd, 0x95, 0xfc, 0x08, 0x9c, 0xed, 0x02, 0x46, 0xb3, 0xed, 0x54, 0xcf, + 0xd9, 0xf6, 0xfa, 0x93, 0xc3, 0xf9, 0xd7, 0xd2, 0x6a, 0x4b, 0x9b, 0x69, 0xbd, 0x6b, 0x20, 0x0e, + 0x40, 0x5c, 0x28, 0x9e, 0x19, 0x4b, 0x17, 0xd0, 0xd7, 0x85, 0x7c, 0x28, 0xf8, 0x6c, 0x2d, 0x57, + 0xda, 0xa0, 0x6e, 0x79, 0x31, 0x12, 0xa1, 0x30, 0xa1, 0x64, 0x8f, 0x3c, 0xc0, 0xf7, 0xc6, 0x7a, + 0x56, 0xf2, 0xfd, 0xc3, 0x79, 0x0d, 0x9b, 0xe9, 0xc5, 0x6a, 0x5a, 0x4a, 0x55, 0x2f, 0xd6, 0x10, + 0xc9, 0xdf, 0x33, 0x60, 0x96, 0x01, 0x62, 0xa1, 0x12, 0x1f, 0x35, 0xd7, 0x4f, 0xea, 0xf7, 0x9f, + 0x8d, 0xd4, 0xbf, 0x84, 0x6d, 0x54, 0xa5, 0xbe, 0xab, 0x4b, 0x52, 0x1b, 0x87, 0xd2, 0xae, 0x5d, + 0x6e, 0x6a, 0xd2, 0x7e, 0x76, 0x00, 0x69, 0xe7, 0x03, 0x70, 0xb4, 0xb4, 0xf7, 0xac, 0x85, 0x6c, + 0xc0, 0x84, 0x50, 0x89, 0x79, 0x87, 0x5d, 0xd0, 0x92, 0xd5, 0xa9, 0x45, 0xfc, 0x9c, 0x22, 0x92, + 0x6b, 0x76, 0x7d, 0xa1, 0xc6, 0x85, 0xb4, 0xe0, 0x24, 0xff, 0xad, 0x5b, 0x07, 0xe6, 0x7b, 0x5a, + 0x07, 0x2e, 0x8b, 0x2f, 0xba, 0x28, 0xf8, 0x27, 0x8c, 0x04, 0xea, 0x13, 0x03, 0x29, 0x8c, 0x49, + 0x1b, 0x88, 0x06, 0xe6, 0x93, 0xf6, 0x62, 0x7f, 0x9b, 0xc0, 0x6b, 0xa2, 0xce, 0xf9, 0x64, 0x9d, + 0xc9, 0x99, 0x9b, 0xc2, 0x9b, 0x38, 0x30, 0x2d, 0xa0, 0xec, 0x00, 0x8c, 0x2b, 0xfc, 0x4b, 0x5a, + 0xc4, 0x76, 0xa2, 0x94, 0x3f, 0x0f, 0x25, 0x6b, 0xc2, 0x88, 0xfa, 0xc4, 0x82, 0x9e, 0xe4, 0x47, + 0xd6, 0x61, 0xa6, 0xd0, 0x6e, 0x37, 0x5c, 0x5a, 0xc7, 0xaf, 0xe4, 0x8f, 0x55, 0x99, 0x71, 0x1e, + 0x6c, 0x87, 0x17, 0x0a, 0x15, 0x3f, 0xf9, 0x52, 0x55, 0x37, 0xad, 0xf9, 0x2d, 0xa3, 0xab, 0xd1, + 0xec, 0xe4, 0x8e, 0x3f, 0x94, 0x60, 0x4d, 0x3c, 0xb9, 0xf3, 0x26, 0xa2, 0x05, 0x21, 0x46, 0x60, + 0xca, 0x92, 0x9a, 0x08, 0x24, 0x2b, 0x9e, 0x00, 0xe7, 0xa0, 0xf8, 0x40, 0x39, 0x2f, 0x7d, 0xbe, + 0xb2, 0xb1, 0xd2, 0x85, 0x3e, 0x5f, 0xc2, 0xd3, 0xcb, 0xfc, 0xf1, 0x8c, 0x2e, 0x76, 0xe4, 0xb2, + 0xa2, 0xb7, 0x2b, 0xa9, 0x48, 0xa4, 0xde, 0xae, 0x68, 0xeb, 0x7f, 0xc3, 0x80, 0x93, 0xeb, 0xfe, + 0x9e, 0xd3, 0x72, 0xbf, 0xc9, 0x53, 0x9a, 0x79, 0x38, 0x2e, 0x51, 0x9c, 0xca, 0x27, 0x9a, 0x1a, + 0xdd, 0x53, 0x2a, 0x66, 0x92, 0x82, 0x22, 0x63, 0xa5, 0xb5, 0x07, 0xbd, 0x68, 0xb1, 0x61, 0x4a, + 0x86, 0x7a, 0x8e, 0xce, 0xe1, 0xe6, 0xcf, 0x65, 0x60, 0x5c, 0x99, 0x02, 0xe4, 0xb3, 0x30, 0xa1, + 0xf2, 0x51, 0xad, 0x3e, 0x6a, 0xb5, 0x96, 0x86, 0x85, 0x66, 0x1f, 0xea, 0x34, 0x35, 0xb3, 0x0f, + 0x13, 0x74, 0x84, 0x1e, 0xf3, 0x68, 0xf3, 0x7e, 0xca, 0xd1, 0xe6, 0x58, 0xaf, 0x9a, 0xbd, 0xd3, + 0x7d, 0xc0, 0x19, 0xfc, 0x11, 0x32, 0xf3, 0x3b, 0x06, 0xe4, 0x93, 0x93, 0xf4, 0x13, 0xe9, 0x95, + 0x63, 0xd8, 0xd7, 0x7f, 0x36, 0x03, 0x79, 0x7c, 0x92, 0x92, 0xd6, 0x65, 0x6c, 0xc0, 0xf3, 0xea, + 0x2b, 0xf1, 0xae, 0x66, 0xfa, 0x7e, 0x21, 0xda, 0x57, 0xd4, 0x8f, 0xeb, 0x93, 0x33, 0x65, 0xe8, + 0x7b, 0xbf, 0x32, 0x7f, 0xc2, 0xfc, 0x00, 0x66, 0x93, 0xdd, 0x81, 0xe6, 0xef, 0x02, 0x4c, 0xeb, + 0xf0, 0x64, 0xe2, 0xe9, 0x24, 0x95, 0x95, 0xc4, 0x37, 0x7f, 0x2f, 0x93, 0xe4, 0x2d, 0xfc, 0x26, + 0xd8, 0xa2, 0xd3, 0x72, 0x76, 0x1a, 0x51, 0x6e, 0x5c, 0xbe, 0xe8, 0x70, 0x90, 0x25, 0xcb, 0x8e, + 0x93, 0x82, 0x3c, 0xf2, 0x70, 0xcf, 0xa6, 0x7b, 0xb8, 0x93, 0x5b, 0x09, 0x8f, 0x21, 0x25, 0x1c, + 0xfb, 0x11, 0xdd, 0xb1, 0x63, 0xaf, 0xa1, 0x84, 0xa3, 0x50, 0x11, 0x66, 0xb5, 0x9c, 0x75, 0x92, + 0x7e, 0x38, 0x36, 0xb8, 0x86, 0x58, 0xc0, 0x89, 0x53, 0x91, 0xc9, 0x32, 0x8c, 0xb2, 0x66, 0xae, + 0x3a, 0x6d, 0x61, 0xd5, 0x56, 0x9f, 0x67, 0x97, 0x9b, 0x97, 0x12, 0xf2, 0xd2, 0xa0, 0x6c, 0xcb, + 0xd7, 0x1e, 0x05, 0xe4, 0x88, 0xe6, 0x1f, 0x19, 0x6c, 0xfe, 0xd7, 0x1e, 0x7c, 0xca, 0x92, 0xa3, + 0xb3, 0x4f, 0xea, 0xe3, 0xd6, 0xf3, 0xfb, 0x19, 0x9e, 0xde, 0x58, 0x88, 0xcf, 0x6d, 0x18, 0xd9, + 0x70, 0xfc, 0x3d, 0x1a, 0x8a, 0x44, 0xbc, 0x2a, 0x17, 0x5e, 0x10, 0x07, 0x8b, 0x87, 0xf8, 0xdb, + 0x12, 0x04, 0xaa, 0x2d, 0x2c, 0x33, 0x90, 0x2d, 0x4c, 0x31, 0xcf, 0x66, 0x9f, 0x99, 0x79, 0xf6, + 0x2b, 0x51, 0x66, 0xe1, 0x42, 0x38, 0x40, 0x4a, 0xb4, 0x8b, 0xc9, 0x34, 0xdb, 0x5d, 0xc9, 0xeb, + 0x62, 0x76, 0xe4, 0x96, 0x9a, 0xb8, 0x5b, 0x71, 0x1a, 0x3f, 0x22, 0x45, 0xb7, 0xf9, 0xfb, 0x59, + 0xde, 0xc7, 0xa2, 0xa3, 0x2e, 0x69, 0x01, 0x25, 0x38, 0x4f, 0x12, 0x0f, 0x24, 0xf3, 0xd0, 0x92, + 0x4b, 0x30, 0xc4, 0x64, 0x53, 0xf4, 0x26, 0x7f, 0x5a, 0xdb, 0x6b, 0x68, 0x31, 0x80, 0xac, 0x9c, + 0xcd, 0x65, 0xdc, 0x93, 0xd4, 0x37, 0x02, 0x70, 0xdb, 0x52, 0xe7, 0x32, 0x62, 0x90, 0xcb, 0x30, + 0xb4, 0xe6, 0xd5, 0x65, 0xea, 0xbd, 0x59, 0x0c, 0x2b, 0xd4, 0x5e, 0xb8, 0x9d, 0x33, 0x2c, 0xc4, + 0x60, 0xdf, 0x1a, 0x25, 0xeb, 0x55, 0xbf, 0xb5, 0xb9, 0xeb, 0xd8, 0x3c, 0x49, 0xac, 0xfa, 0xad, + 0x71, 0x5e, 0xdf, 0x25, 0x98, 0xd2, 0xdf, 0x30, 0x12, 0x4e, 0x4f, 0x68, 0x66, 0x4d, 0x3c, 0x85, + 0xa4, 0x5a, 0xc7, 0x75, 0x22, 0xb2, 0x08, 0x93, 0x5a, 0xca, 0x1f, 0x71, 0xbd, 0x84, 0xe6, 0x4d, + 0x3d, 0x61, 0x90, 0x6a, 0xde, 0xd4, 0x48, 0xd8, 0x7e, 0x2e, 0xda, 0xaf, 0x5c, 0x32, 0x75, 0xb5, + 0x5d, 0xe0, 0x90, 0x9b, 0x90, 0xe3, 0xf1, 0x7b, 0xe5, 0x92, 0x7a, 0x5b, 0x11, 0x20, 0x2c, 0x11, + 0xff, 0x2a, 0x11, 0x95, 0x78, 0xad, 0xcf, 0x40, 0x5e, 0x2c, 0x49, 0xd1, 0x9b, 0x10, 0x78, 0x53, + 0x5c, 0x2e, 0x59, 0xea, 0x32, 0x52, 0x73, 0xeb, 0xbe, 0x85, 0x50, 0xf3, 0xbb, 0x06, 0x9c, 0x5d, + 0xa3, 0xe1, 0x23, 0xcf, 0x7f, 0x60, 0xd1, 0x20, 0xf4, 0x5d, 0xfe, 0xc4, 0x04, 0x4e, 0xc4, 0xcf, + 0x92, 0x77, 0x60, 0x18, 0xbd, 0x6f, 0x12, 0x3b, 0x43, 0xb2, 0x8e, 0xc5, 0x49, 0x21, 0xc0, 0xc3, + 0xe8, 0xca, 0x63, 0x71, 0x22, 0x72, 0x1b, 0x86, 0x4a, 0xb4, 0x75, 0x90, 0x78, 0x6b, 0xa0, 0x8b, + 0x38, 0x5a, 0x10, 0xea, 0xb4, 0x75, 0x60, 0x21, 0x89, 0xf9, 0x9d, 0x0c, 0x9c, 0x4a, 0x69, 0xd6, + 0xd6, 0x67, 0x9f, 0xd3, 0x55, 0x71, 0x51, 0x5b, 0x15, 0x2f, 0x0a, 0xd2, 0x9e, 0x1d, 0x9f, 0xba, + 0x48, 0xfe, 0x55, 0x03, 0xce, 0xe8, 0x02, 0x2a, 0xdc, 0xed, 0xb6, 0x6e, 0x92, 0xb7, 0x61, 0x64, + 0x99, 0x3a, 0x75, 0x2a, 0x53, 0x97, 0xc7, 0xcf, 0x83, 0xf3, 0xe0, 0x24, 0x5e, 0xc8, 0xd9, 0xfe, + 0x1e, 0x5f, 0xc3, 0x4e, 0x58, 0x82, 0x84, 0x94, 0x44, 0xe3, 0xb8, 0x3e, 0x6e, 0xca, 0x40, 0xc1, + 0xb4, 0xaa, 0xfa, 0xdc, 0xb3, 0x7f, 0xdf, 0x80, 0x17, 0xfa, 0xd0, 0xb0, 0x81, 0x63, 0x43, 0xaf, + 0x0e, 0x1c, 0xee, 0xa8, 0x08, 0x25, 0xef, 0xc1, 0xf4, 0x86, 0xd0, 0xe7, 0xe5, 0x70, 0x64, 0xe2, + 0xf9, 0x22, 0x55, 0x7d, 0x5b, 0x8e, 0x4b, 0x12, 0x59, 0x8b, 0x60, 0xcd, 0xf6, 0x8d, 0x60, 0x55, + 0x03, 0x42, 0x87, 0x06, 0x0d, 0x08, 0xfd, 0x20, 0xf9, 0xf2, 0xa7, 0xc8, 0xcb, 0x15, 0x87, 0xc3, + 0x1a, 0xbd, 0xc3, 0x61, 0xfb, 0x66, 0xff, 0xc1, 0x97, 0x0e, 0x74, 0xde, 0x4f, 0x3b, 0x9e, 0xef, + 0x6a, 0xe3, 0xf9, 0x42, 0xfa, 0x78, 0xf6, 0x1e, 0xc8, 0x5f, 0x36, 0x92, 0x1f, 0x3b, 0xd0, 0x08, + 0x9a, 0x30, 0x52, 0xf2, 0x9a, 0x8e, 0xdb, 0x52, 0xdf, 0x38, 0xab, 0x23, 0xc4, 0x12, 0x25, 0x83, + 0x45, 0x0f, 0x5f, 0x84, 0xe1, 0x35, 0xaf, 0x55, 0x28, 0x09, 0xdf, 0x3a, 0xe4, 0xd3, 0xf2, 0x5a, + 0xb6, 0x53, 0xb7, 0x78, 0x81, 0xf9, 0x53, 0xc3, 0x70, 0xd6, 0xa2, 0x7b, 0x2e, 0xd3, 0x38, 0x37, + 0x03, 0xb7, 0xb5, 0xa7, 0x85, 0x4a, 0x9a, 0x89, 0x31, 0x11, 0xf9, 0x2a, 0x19, 0x24, 0xaa, 0xe3, + 0x0a, 0xe4, 0xd8, 0x06, 0xa3, 0x0c, 0x0b, 0x5e, 0x47, 0xe0, 0x2b, 0x8c, 0x5c, 0x5e, 0x64, 0x31, + 0xb9, 0x2a, 0x36, 0x40, 0x25, 0xa3, 0x30, 0xdb, 0x00, 0x7f, 0x70, 0x38, 0x0f, 0xd5, 0x83, 0x20, + 0xa4, 0x78, 0xf8, 0x11, 0x9b, 0x60, 0xa4, 0xa5, 0x0e, 0xf5, 0xd0, 0x52, 0x57, 0x61, 0xb6, 0x50, + 0xe7, 0xeb, 0x9e, 0xd3, 0xa8, 0xf8, 0x6e, 0xab, 0xe6, 0xb6, 0x9d, 0x86, 0x3c, 0x79, 0xe1, 0xa5, + 0x94, 0x13, 0x95, 0xdb, 0xed, 0x08, 0xc1, 0x4a, 0x25, 0x63, 0x9f, 0x51, 0x5a, 0xab, 0xf2, 0x17, + 0x86, 0xf9, 0x4d, 0x13, 0x7e, 0x46, 0xbd, 0x15, 0xf0, 0x27, 0x86, 0xad, 0xa8, 0x18, 0xf5, 0x63, + 0xbc, 0xce, 0xdf, 0x58, 0xa9, 0xc6, 0x61, 0x1b, 0x3c, 0xe1, 0x21, 0xbf, 0xf2, 0x0f, 0x1b, 0x01, + 0x5e, 0xfb, 0x6b, 0x78, 0x31, 0x5d, 0xb5, 0xba, 0xcc, 0xe8, 0x72, 0x5d, 0x74, 0x41, 0xb0, 0xaf, + 0xd2, 0x71, 0x3c, 0x72, 0x1d, 0x80, 0xa7, 0xea, 0x41, 0x91, 0x19, 0x8b, 0xb5, 0x69, 0x1f, 0xa1, + 0x5c, 0x9b, 0x56, 0x50, 0xc8, 0x3b, 0x70, 0x72, 0xa9, 0xb8, 0x20, 0xed, 0x83, 0x25, 0xaf, 0xd6, + 0xc1, 0x0b, 0x5a, 0xc0, 0xfa, 0x70, 0x0c, 0x69, 0x6d, 0x81, 0xc9, 0x49, 0x1a, 0x1a, 0xb9, 0x04, + 0xa3, 0xe5, 0x12, 0xef, 0xfb, 0x71, 0x35, 0xab, 0xb7, 0x70, 0x7c, 0x90, 0x85, 0x64, 0x3d, 0x56, + 0xf7, 0x26, 0x8e, 0xd4, 0xcb, 0xce, 0x1e, 0xad, 0xea, 0x89, 0xe4, 0xdf, 0xfc, 0x91, 0x89, 0xa2, + 0x57, 0xa7, 0xc1, 0xd6, 0x8d, 0x4f, 0x59, 0xf2, 0x6f, 0xe5, 0xdb, 0x70, 0x21, 0xb8, 0x91, 0xba, + 0x6a, 0xfc, 0x7b, 0x98, 0xfc, 0xbb, 0x0b, 0x97, 0x7c, 0x1e, 0x86, 0xf1, 0xa7, 0x50, 0x21, 0x4e, + 0xa6, 0xb0, 0x8d, 0xd5, 0x87, 0x1a, 0x7f, 0xee, 0x0f, 0x09, 0x48, 0x19, 0x46, 0x85, 0xf6, 0x7a, + 0x9c, 0x14, 0xb6, 0x42, 0x0d, 0xe6, 0x83, 0x24, 0xe8, 0xcd, 0x3a, 0x4c, 0xa8, 0x15, 0x32, 0xe1, + 0x5c, 0x76, 0x82, 0x7d, 0x5a, 0x67, 0xbf, 0x44, 0xf6, 0x79, 0x14, 0xce, 0x7d, 0x84, 0xda, 0xac, + 0x1d, 0x96, 0x82, 0xc2, 0x16, 0xae, 0x72, 0xb0, 0x19, 0x88, 0xa6, 0x88, 0xf3, 0xac, 0x8b, 0xb6, + 0x91, 0xba, 0x25, 0x8a, 0xcc, 0xaf, 0xc0, 0xec, 0x5a, 0xa7, 0xd1, 0x60, 0x67, 0x5b, 0x99, 0x9d, + 0x34, 0x74, 0x42, 0x4a, 0x16, 0x61, 0x18, 0xff, 0xc0, 0x8a, 0xa6, 0xa2, 0x2e, 0x50, 0x71, 0xd0, + 0xd7, 0xca, 0xc0, 0x40, 0xcb, 0x50, 0x7f, 0x7f, 0x9b, 0x93, 0x9a, 0xbf, 0x1b, 0x3f, 0x3c, 0xb9, + 0xe1, 0x3b, 0xb5, 0x07, 0xd4, 0x17, 0x3b, 0xd0, 0xa0, 0x0f, 0x63, 0xde, 0x93, 0x8d, 0xd0, 0x77, + 0x85, 0xb4, 0x06, 0x1f, 0xd5, 0x18, 0xf2, 0x0e, 0x8c, 0x8b, 0x9d, 0x41, 0x49, 0x0f, 0x82, 0x31, + 0xd8, 0xf2, 0x79, 0xd1, 0xc4, 0xcd, 0xbd, 0x8a, 0x8e, 0x1b, 0x9e, 0xfe, 0x29, 0x5b, 0x37, 0x3e, + 0x89, 0x0d, 0x4f, 0xaf, 0xa3, 0x8f, 0xe8, 0xfe, 0x7d, 0x48, 0xf6, 0xad, 0x90, 0xdd, 0x5b, 0x6a, + 0x42, 0x00, 0x23, 0x3e, 0x7e, 0xc4, 0x09, 0x01, 0xd4, 0xe3, 0x47, 0x84, 0x1a, 0x8d, 0x49, 0xe6, + 0x88, 0x31, 0x79, 0x4f, 0x8e, 0x49, 0xb6, 0xb7, 0x60, 0x9c, 0xec, 0x33, 0x0e, 0xd5, 0x78, 0x86, + 0x0c, 0x0d, 0x74, 0x76, 0x3d, 0x81, 0x99, 0x0f, 0x39, 0x49, 0x72, 0x41, 0x13, 0x9c, 0xd4, 0x03, + 0xf1, 0xf0, 0xe0, 0x4c, 0x8f, 0x38, 0x10, 0x7f, 0x01, 0x26, 0x0a, 0x61, 0xe8, 0xd4, 0xf6, 0x69, + 0xbd, 0xc4, 0x96, 0x27, 0x25, 0x76, 0xd9, 0x11, 0x70, 0xf5, 0x66, 0x42, 0xc5, 0xe5, 0xb9, 0x78, + 0x9c, 0x40, 0x38, 0x8e, 0x45, 0xb9, 0x78, 0x18, 0x44, 0xcf, 0xc5, 0xc3, 0x20, 0xe4, 0x3a, 0x8c, + 0x96, 0x5b, 0x0f, 0x5d, 0xd6, 0x27, 0xb9, 0xf8, 0x31, 0x3d, 0x97, 0x83, 0xd4, 0xc5, 0x55, 0x60, + 0x91, 0xdb, 0x8a, 0xe6, 0x38, 0x16, 0x9f, 0x12, 0xb9, 0x5d, 0xc1, 0x96, 0x0a, 0xa4, 0xaa, 0x15, + 0x46, 0xaa, 0xe4, 0x2d, 0x18, 0x95, 0xe6, 0x22, 0x88, 0x4f, 0x86, 0x82, 0xb2, 0x3b, 0x42, 0x4d, + 0x22, 0xe3, 0x3b, 0x56, 0x4a, 0x16, 0xfd, 0x71, 0xe5, 0x1d, 0x2b, 0x25, 0x8b, 0xbe, 0xf6, 0x8e, + 0x95, 0x92, 0x4f, 0x3f, 0x3a, 0x69, 0x4f, 0x1c, 0x79, 0xd2, 0xde, 0x82, 0x89, 0x8a, 0xe3, 0x87, + 0x2e, 0x53, 0x17, 0x5a, 0x61, 0x30, 0x37, 0xa9, 0x19, 0xa7, 0x94, 0xa2, 0xc5, 0x0b, 0xf2, 0x3d, + 0xa7, 0xb6, 0x82, 0xaf, 0x3f, 0x04, 0x14, 0xc3, 0xd3, 0xdd, 0xc6, 0xa6, 0x9e, 0xc6, 0x6d, 0x0c, + 0x3b, 0x15, 0x0d, 0x12, 0xd3, 0xf1, 0xb1, 0x17, 0x35, 0xc3, 0x84, 0x55, 0x22, 0x42, 0x24, 0x5f, + 0x85, 0x09, 0xf6, 0x37, 0xbe, 0x4e, 0xeb, 0xd2, 0x60, 0x2e, 0x8f, 0x1f, 0x77, 0x21, 0x75, 0xf6, + 0xf3, 0x27, 0x6c, 0xab, 0x34, 0xe4, 0x13, 0x18, 0x19, 0x27, 0x2d, 0x8d, 0x1a, 0x37, 0xf2, 0x3e, + 0x4c, 0xc8, 0x07, 0x98, 0x71, 0x90, 0x66, 0x62, 0xc7, 0xbf, 0xba, 0x80, 0x77, 0xa5, 0xc3, 0x52, + 0x09, 0xd8, 0x36, 0x5f, 0x68, 0xf3, 0x05, 0x92, 0x28, 0xd2, 0xde, 0xee, 0x5a, 0x1c, 0x25, 0x1a, + 0xf9, 0x22, 0x4c, 0x14, 0xda, 0xed, 0x78, 0xc5, 0x39, 0xa9, 0x58, 0x1b, 0xda, 0x6d, 0x3b, 0x75, + 0xd5, 0xd1, 0x28, 0x92, 0x0b, 0xf3, 0xec, 0xb1, 0x16, 0x66, 0xf2, 0x66, 0xa4, 0x38, 0x9f, 0x8a, + 0x4d, 0x67, 0x42, 0x3b, 0x57, 0x67, 0x1a, 0x47, 0x32, 0xff, 0xd0, 0x80, 0x33, 0x3d, 0x7a, 0x39, + 0xca, 0x1c, 0x65, 0xf4, 0xcf, 0x1c, 0xc5, 0x66, 0xab, 0x7e, 0xdc, 0xc3, 0x3a, 0x85, 0x66, 0xa3, + 0xf6, 0x91, 0xd4, 0x71, 0x3c, 0x20, 0xe2, 0xe1, 0x65, 0xe5, 0x81, 0x62, 0x91, 0xbe, 0x30, 0xb1, + 0xf0, 0x6b, 0x0f, 0x34, 0xf3, 0x17, 0xbe, 0x7d, 0x0e, 0x8a, 0xba, 0xf2, 0x23, 0x4f, 0x9b, 0x35, + 0x29, 0xac, 0xcd, 0x43, 0x03, 0xc6, 0x15, 0xd9, 0x27, 0x17, 0x95, 0x38, 0xa3, 0x3c, 0x4f, 0x47, + 0xad, 0x70, 0xc8, 0xf0, 0xd5, 0x1f, 0x05, 0x39, 0x73, 0xb4, 0x65, 0x6d, 0x95, 0xa9, 0x1f, 0x4a, + 0x76, 0xad, 0xa6, 0x66, 0x06, 0xb3, 0xb0, 0x1c, 0x9f, 0x7e, 0x73, 0x82, 0xb0, 0x50, 0x0b, 0xdd, + 0x87, 0x74, 0x80, 0x85, 0x3e, 0x7e, 0xfa, 0xcd, 0x09, 0x42, 0xdb, 0x41, 0xb2, 0xae, 0xa7, 0xdf, + 0x22, 0x86, 0xe6, 0x4f, 0x18, 0x00, 0x9b, 0xe5, 0x22, 0xa6, 0xc7, 0x7b, 0xda, 0x8d, 0x38, 0x3d, + 0xe5, 0x90, 0xe4, 0xde, 0x67, 0x0b, 0xae, 0xc0, 0x94, 0x8e, 0x45, 0xde, 0x83, 0xe9, 0x6a, 0xcd, + 0xf7, 0x1a, 0x8d, 0x1d, 0xa7, 0xf6, 0x60, 0xc5, 0x6d, 0x51, 0x9e, 0xeb, 0x65, 0x98, 0x2f, 0xff, + 0x41, 0x54, 0x64, 0x37, 0x58, 0x99, 0x95, 0x44, 0x36, 0xff, 0xc4, 0x80, 0xf1, 0x72, 0x2b, 0x08, + 0x9d, 0x46, 0x03, 0x15, 0x8c, 0x4f, 0xd3, 0x8b, 0x04, 0xd1, 0x77, 0xf5, 0xe9, 0xd1, 0xb7, 0x60, + 0x3a, 0x81, 0xc6, 0x0e, 0xc6, 0x55, 0x0c, 0x83, 0x54, 0x0f, 0xc6, 0x3c, 0x30, 0xd2, 0x12, 0x25, + 0xe6, 0x92, 0x42, 0xb6, 0x75, 0x03, 0x2f, 0x8a, 0x16, 0x00, 0x5c, 0x09, 0x92, 0x6a, 0x3c, 0x49, + 0xb6, 0x64, 0xeb, 0x86, 0xa5, 0x60, 0x99, 0x6b, 0x30, 0x52, 0xf5, 0xfc, 0x70, 0xf1, 0x80, 0x6b, + 0xce, 0x25, 0x1a, 0xd4, 0xd4, 0x9b, 0x20, 0x17, 0xad, 0xaf, 0x35, 0x4b, 0x14, 0xb1, 0x73, 0xf3, + 0x1d, 0x97, 0x36, 0xea, 0xaa, 0xcb, 0xdf, 0x2e, 0x03, 0x58, 0x1c, 0xce, 0x4e, 0x17, 0xa7, 0xe3, + 0xf4, 0xad, 0xb1, 0x6f, 0xe1, 0xd3, 0x0a, 0x6c, 0x51, 0xeb, 0xdf, 0x97, 0xf4, 0x07, 0xff, 0xb4, + 0x9a, 0xfa, 0x74, 0xf5, 0xdf, 0x31, 0xe0, 0x5c, 0x6f, 0x12, 0xd5, 0x5d, 0xd1, 0xe8, 0xe3, 0xae, + 0xf8, 0x6a, 0xf2, 0xe6, 0x02, 0xd1, 0xc4, 0xcd, 0x45, 0x7c, 0x5f, 0x51, 0x42, 0x6f, 0xd1, 0x5a, + 0xf4, 0xb8, 0xea, 0xc5, 0x3e, 0x6d, 0x46, 0x44, 0x3e, 0xcc, 0x21, 0xd2, 0x58, 0x82, 0xd6, 0xfc, + 0xad, 0x21, 0x38, 0xdb, 0x93, 0x82, 0x2c, 0x2b, 0x99, 0xa0, 0xa7, 0xa2, 0x1c, 0xb4, 0x3d, 0xf1, + 0xaf, 0xe1, 0xbf, 0xe8, 0x10, 0x94, 0x0c, 0x62, 0x58, 0x8f, 0x32, 0x00, 0x67, 0x90, 0xd7, 0xeb, + 0x47, 0xf2, 0xe2, 0xe8, 0xc8, 0x0c, 0xba, 0x93, 0x01, 0x63, 0xac, 0x09, 0x0d, 0x1d, 0xb7, 0x11, + 0xa8, 0xd3, 0xae, 0xce, 0x41, 0x96, 0x2c, 0x8b, 0x7d, 0x48, 0x87, 0xd2, 0x7d, 0x48, 0xcd, 0x7f, + 0x6b, 0xc0, 0x58, 0xd4, 0x6c, 0x72, 0x0e, 0x4e, 0x6f, 0x58, 0x85, 0xe2, 0x92, 0xbd, 0xf1, 0x41, + 0x65, 0xc9, 0xde, 0x5c, 0xab, 0x56, 0x96, 0x8a, 0xe5, 0x3b, 0xe5, 0xa5, 0x52, 0xfe, 0x04, 0x99, + 0x81, 0xc9, 0xcd, 0xb5, 0xfb, 0x6b, 0xeb, 0xdb, 0x6b, 0xf6, 0x92, 0x65, 0xad, 0x5b, 0x79, 0x83, + 0x4c, 0xc2, 0x98, 0xb5, 0x58, 0x28, 0xda, 0x6b, 0xeb, 0xa5, 0xa5, 0x7c, 0x86, 0xe4, 0x61, 0xa2, + 0xb8, 0xbe, 0xb6, 0xb6, 0x54, 0xdc, 0x28, 0x6f, 0x95, 0x37, 0x3e, 0xc8, 0x67, 0x09, 0x81, 0x29, + 0x44, 0xa8, 0x58, 0xe5, 0xb5, 0x62, 0xb9, 0x52, 0x58, 0xc9, 0x0f, 0x31, 0x18, 0xc3, 0x57, 0x60, + 0xc3, 0x11, 0xa3, 0xfb, 0x9b, 0x8b, 0x4b, 0xf9, 0x11, 0x86, 0xc2, 0xfe, 0x52, 0x50, 0x46, 0x59, + 0xf5, 0x88, 0x52, 0x2a, 0x6c, 0x14, 0x16, 0x0b, 0xd5, 0xa5, 0x7c, 0x8e, 0x9c, 0x81, 0x93, 0x1a, + 0xc8, 0x5e, 0x59, 0xbf, 0x5b, 0x5e, 0xcb, 0x8f, 0x91, 0x59, 0xc8, 0x47, 0xb0, 0xd2, 0xa2, 0xbd, + 0x59, 0x5d, 0xb2, 0xf2, 0x90, 0x84, 0xae, 0x15, 0x56, 0x97, 0xf2, 0xe3, 0xe6, 0xbb, 0x3c, 0xbc, + 0x84, 0x77, 0x35, 0x39, 0x0d, 0xa4, 0xba, 0x51, 0xd8, 0xd8, 0xac, 0x26, 0x3e, 0x7e, 0x1c, 0x46, + 0xab, 0x9b, 0xc5, 0xe2, 0x52, 0xb5, 0x9a, 0x37, 0x08, 0xc0, 0xc8, 0x9d, 0x42, 0x79, 0x65, 0xa9, + 0x94, 0xcf, 0x98, 0x3f, 0x6f, 0xc0, 0x8c, 0x54, 0x77, 0xa4, 0x19, 0xfa, 0x29, 0xe7, 0xe2, 0x7b, + 0xda, 0x29, 0x4e, 0x7a, 0xff, 0x27, 0x2a, 0xe9, 0x33, 0x0d, 0x7d, 0x38, 0x95, 0x8a, 0x4c, 0x3e, + 0x80, 0xbc, 0x6c, 0xc0, 0xaa, 0x13, 0xd6, 0xf6, 0xe3, 0x65, 0xec, 0x42, 0xa2, 0x92, 0x04, 0x1a, + 0xb7, 0xa6, 0xc5, 0x4f, 0x1e, 0x75, 0xb1, 0x31, 0xbf, 0x67, 0xc0, 0x99, 0x1e, 0xc4, 0xa4, 0x08, + 0x23, 0x51, 0x62, 0xdc, 0x3e, 0x8e, 0x2e, 0xb3, 0xdf, 0x3f, 0x9c, 0x17, 0x88, 0xf8, 0xf2, 0x0b, + 0xfe, 0x65, 0x8d, 0x44, 0x99, 0x6e, 0x31, 0xdd, 0x2c, 0xef, 0x93, 0xb3, 0x89, 0xee, 0x14, 0x35, + 0x15, 0xb6, 0xab, 0x8b, 0xe3, 0xa2, 0x43, 0xb2, 0xce, 0xa3, 0x00, 0xf3, 0xcd, 0x9a, 0xdf, 0x35, + 0x98, 0xaa, 0x94, 0x44, 0x24, 0x45, 0x98, 0x2c, 0x04, 0x41, 0xa7, 0x49, 0x2d, 0xaf, 0x41, 0x0b, + 0xd6, 0x9a, 0xd8, 0x0b, 0xf0, 0xcc, 0xe3, 0x60, 0x01, 0x2a, 0xc6, 0xb6, 0xe3, 0xb7, 0xb4, 0x4b, + 0x2d, 0x95, 0x86, 0xdc, 0x06, 0x88, 0x1e, 0xe7, 0x95, 0x31, 0xd5, 0x3c, 0x0a, 0x5f, 0x40, 0x75, + 0x8d, 0x51, 0x41, 0x36, 0xff, 0xa2, 0x01, 0x13, 0x42, 0xed, 0x2f, 0x34, 0xa8, 0x1f, 0x3e, 0x9d, + 0xcc, 0xdc, 0xd6, 0x64, 0x26, 0xf2, 0xeb, 0x56, 0xf8, 0xb3, 0xe2, 0x54, 0x71, 0xf9, 0x2f, 0x0d, + 0xc8, 0x27, 0x11, 0xc9, 0x7b, 0x90, 0xab, 0xd2, 0x87, 0xd4, 0x77, 0xc3, 0x03, 0xb1, 0xfa, 0xc9, + 0x27, 0x04, 0x38, 0x8e, 0x28, 0xe3, 0xd6, 0xc5, 0x40, 0xfc, 0xb2, 0x22, 0x9a, 0x41, 0x17, 0x71, + 0xe5, 0xe0, 0x9e, 0x7d, 0x56, 0x07, 0x77, 0xf3, 0x5f, 0x65, 0xe0, 0xcc, 0x5d, 0x1a, 0xaa, 0xdf, + 0x14, 0xdd, 0x42, 0x7e, 0x66, 0xb0, 0xef, 0x52, 0xbe, 0x64, 0x0e, 0x46, 0xb1, 0x48, 0x8e, 0xaf, + 0x25, 0x7f, 0x92, 0xc5, 0x48, 0xae, 0xb3, 0x5a, 0x8e, 0xf2, 0x1e, 0x75, 0x5f, 0x53, 0xb2, 0x16, + 0x47, 0x62, 0x7d, 0x09, 0xa6, 0x30, 0x2d, 0x5f, 0x87, 0x4d, 0x07, 0x5a, 0x17, 0x06, 0x8c, 0x9c, + 0x95, 0x80, 0x92, 0xab, 0x90, 0x67, 0x90, 0x42, 0xed, 0x41, 0xcb, 0x7b, 0xd4, 0xa0, 0xf5, 0x3d, + 0xca, 0x9f, 0x4c, 0xcd, 0x59, 0x5d, 0x70, 0xc9, 0x73, 0xb3, 0xc5, 0x0f, 0xe0, 0xb4, 0x8e, 0x56, + 0x06, 0xc1, 0x33, 0x86, 0x9e, 0xbb, 0x0d, 0xe3, 0x1f, 0x33, 0x03, 0xb9, 0xf9, 0x3f, 0x18, 0x30, + 0x8b, 0x1f, 0xa7, 0x54, 0x8c, 0xe6, 0xe7, 0xcf, 0xc4, 0xbd, 0xa5, 0x24, 0xe5, 0x75, 0x18, 0x48, + 0x9f, 0x0a, 0x51, 0x2f, 0xc6, 0x56, 0x8d, 0xcc, 0x00, 0x56, 0x8d, 0xea, 0x71, 0x5e, 0x58, 0x1b, + 0xd0, 0x28, 0xc3, 0xdf, 0xc5, 0x8d, 0x87, 0xdc, 0xfc, 0xf3, 0x19, 0x18, 0xb5, 0x28, 0x3e, 0x3d, + 0x45, 0x2e, 0xc1, 0xe8, 0x9a, 0x17, 0xd2, 0x60, 0x55, 0x7b, 0x67, 0xac, 0xc5, 0x40, 0x76, 0xb3, + 0x6e, 0xc9, 0x42, 0x26, 0xf0, 0x15, 0xdf, 0xab, 0x77, 0x6a, 0xa1, 0x2a, 0xf0, 0x6d, 0x0e, 0xb2, + 0x64, 0x19, 0x79, 0x03, 0xc6, 0x04, 0xe7, 0xe8, 0xee, 0x07, 0x7d, 0x16, 0x7d, 0x1a, 0x3d, 0x5d, + 0x16, 0x23, 0xa0, 0xa2, 0xca, 0xb5, 0x86, 0x21, 0x45, 0x51, 0xed, 0x52, 0x04, 0xa4, 0xfe, 0x3d, + 0xdc, 0x47, 0xff, 0xfe, 0x0c, 0x8c, 0x14, 0x82, 0x80, 0x86, 0x32, 0xdc, 0x74, 0x22, 0x4a, 0x71, + 0x11, 0xd0, 0x90, 0x33, 0x76, 0xb0, 0xdc, 0x12, 0x78, 0xe6, 0x1f, 0x65, 0x60, 0x18, 0xff, 0xc4, + 0xfb, 0x2e, 0xbf, 0xb6, 0xaf, 0xdd, 0x77, 0xf9, 0xb5, 0x7d, 0x0b, 0xa1, 0xe4, 0x06, 0x9e, 0xb5, + 0x65, 0xfe, 0x68, 0xf1, 0xf5, 0x68, 0x44, 0xae, 0xc7, 0x60, 0x4b, 0xc5, 0x89, 0x2e, 0x02, 0xb3, + 0xa9, 0x41, 0xe6, 0xa7, 0x21, 0xb3, 0x5e, 0x15, 0x5f, 0x8c, 0x19, 0x2c, 0xbc, 0xc0, 0xca, 0xac, + 0x57, 0xb1, 0x37, 0x96, 0x0b, 0x0b, 0x6f, 0xdd, 0x52, 0x9f, 0xc4, 0x0b, 0xf6, 0x9d, 0x85, 0xb7, + 0x6e, 0x59, 0xa2, 0x84, 0xf5, 0x2f, 0xb6, 0xb9, 0xea, 0x7e, 0x93, 0x8a, 0x08, 0x4d, 0xec, 0x5f, + 0xfc, 0x36, 0x3b, 0x70, 0xbf, 0x49, 0xad, 0x18, 0x81, 0x2c, 0xc0, 0xb8, 0x08, 0xca, 0x45, 0x7c, + 0x25, 0x68, 0x56, 0x04, 0xed, 0x72, 0x0a, 0x15, 0x89, 0xdf, 0xe7, 0x88, 0x01, 0x92, 0xaf, 0xdc, + 0x88, 0xfb, 0x1c, 0x39, 0x84, 0x81, 0xa5, 0xa0, 0xc4, 0x01, 0xa6, 0x71, 0xe4, 0xa5, 0x1a, 0x60, + 0x8a, 0x69, 0x16, 0x23, 0x04, 0xf3, 0xd7, 0x32, 0x90, 0xab, 0x34, 0x3a, 0x7b, 0x6e, 0x6b, 0xeb, + 0xc6, 0x9f, 0xea, 0xb3, 0xcc, 0x6f, 0x02, 0x6e, 0x12, 0xe2, 0x44, 0x20, 0x4d, 0xb2, 0xbc, 0x69, + 0x42, 0xf9, 0xe0, 0x24, 0x88, 0x46, 0x6e, 0x82, 0x10, 0x4c, 0xf1, 0x4a, 0xd7, 0x29, 0x9d, 0x80, + 0xbf, 0x4f, 0x21, 0x49, 0x04, 0x2a, 0x79, 0x07, 0xc6, 0xe3, 0xf7, 0x71, 0xe3, 0xc7, 0xb7, 0x54, + 0xca, 0x62, 0x5c, 0xbe, 0x75, 0xc3, 0x52, 0xd1, 0xcd, 0xef, 0x64, 0x61, 0x42, 0x6d, 0x0f, 0xb1, + 0xe0, 0x64, 0xd0, 0x60, 0x47, 0x61, 0xe1, 0x93, 0xd2, 0xc6, 0x42, 0xb1, 0x9d, 0x5e, 0xd4, 0x1b, + 0xc4, 0xf0, 0xb8, 0x83, 0x4a, 0x95, 0x86, 0xa1, 0xdb, 0xda, 0x0b, 0x96, 0x4f, 0x58, 0x33, 0x41, + 0x0c, 0xe6, 0x78, 0xa4, 0x00, 0x39, 0xaf, 0x1d, 0xec, 0xd1, 0x96, 0x2b, 0x6f, 0x0c, 0x5e, 0xd6, + 0x18, 0xad, 0x8b, 0xc2, 0x2e, 0x5e, 0x11, 0x19, 0x79, 0x0b, 0x46, 0xbc, 0x36, 0x6d, 0x39, 0xae, + 0xd8, 0xe3, 0x5e, 0x48, 0x30, 0xa0, 0xad, 0x42, 0x59, 0x21, 0x14, 0xc8, 0xe4, 0x3a, 0x0c, 0x79, + 0x0f, 0xa2, 0xf1, 0x3a, 0xab, 0x13, 0x3d, 0x08, 0x1d, 0x85, 0x04, 0x11, 0x19, 0xc1, 0x47, 0x4e, + 0x73, 0x57, 0x8c, 0x98, 0x4e, 0x70, 0xcf, 0x69, 0xee, 0xaa, 0x04, 0x0c, 0x91, 0xbc, 0x0f, 0xd0, + 0x76, 0xf6, 0xa8, 0x6f, 0xd7, 0x3b, 0xe1, 0x81, 0x18, 0xb7, 0x0b, 0x1a, 0x59, 0x85, 0x15, 0x97, + 0x3a, 0xe1, 0x81, 0x42, 0x3b, 0xd6, 0x96, 0xc0, 0x2f, 0x0c, 0xfd, 0x2f, 0xbf, 0x32, 0x6f, 0x2c, + 0x02, 0xe4, 0x02, 0x51, 0x6c, 0xae, 0xc0, 0xd9, 0x9e, 0x1d, 0x4c, 0xae, 0x40, 0x7e, 0xd7, 0x11, + 0xd6, 0x8a, 0xda, 0xbe, 0xd3, 0x6a, 0xd1, 0x86, 0x10, 0xed, 0x69, 0x09, 0x2f, 0x72, 0x30, 0xe7, + 0x6c, 0xfe, 0x43, 0x03, 0xce, 0xf7, 0xeb, 0x66, 0x72, 0x0e, 0x72, 0x6d, 0xdf, 0xf5, 0x70, 0x3b, + 0xe7, 0x93, 0x21, 0xfa, 0x4d, 0x5e, 0x04, 0xe0, 0xfb, 0x4e, 0xe8, 0xec, 0x09, 0x7f, 0x59, 0x6b, + 0x0c, 0x21, 0x1b, 0xce, 0x5e, 0x40, 0x5e, 0x87, 0x99, 0x3a, 0xdd, 0x75, 0x3a, 0x8d, 0xd0, 0x0e, + 0x6a, 0xfb, 0xb4, 0x8e, 0x2e, 0xea, 0xe8, 0x07, 0x61, 0xe5, 0x45, 0x41, 0x55, 0xc2, 0xc9, 0x4b, + 0x30, 0xa1, 0xc6, 0xc3, 0x8b, 0xd7, 0xca, 0xc7, 0x9d, 0xb6, 0x2b, 0x23, 0xe2, 0x79, 0x8b, 0xef, + 0x0d, 0xe5, 0x8c, 0x7c, 0xc6, 0x42, 0x77, 0x00, 0xd3, 0x81, 0x33, 0x3d, 0x7a, 0x91, 0xb5, 0x2d, + 0x7e, 0xc2, 0x4a, 0x26, 0xc4, 0xed, 0x44, 0x0f, 0x59, 0x25, 0xab, 0xcb, 0xf4, 0xa8, 0xce, 0x3c, + 0x0f, 0xb3, 0x69, 0x52, 0x24, 0x4a, 0xef, 0x01, 0xe9, 0x1e, 0x7d, 0x72, 0x0d, 0xc6, 0xd8, 0xe8, + 0x63, 0xa4, 0x70, 0xc2, 0xaf, 0x10, 0xf1, 0x70, 0x2e, 0x59, 0xb9, 0x8f, 0xc4, 0xdf, 0x82, 0xd7, + 0x4d, 0xc9, 0x4b, 0x15, 0x3d, 0x72, 0x06, 0x46, 0x3d, 0x7f, 0x8f, 0xad, 0x61, 0xe2, 0x23, 0x46, + 0x3c, 0x7f, 0x6f, 0xd3, 0x97, 0xe3, 0xf7, 0x37, 0x33, 0x72, 0xfc, 0x16, 0x3d, 0x2f, 0x0c, 0x42, + 0xdf, 0x69, 0x6b, 0xf3, 0x99, 0x34, 0xe1, 0xac, 0xe7, 0x74, 0xc2, 0xfd, 0x05, 0x9b, 0xfd, 0xeb, + 0xf9, 0xd2, 0x3f, 0xbd, 0x26, 0xaf, 0x23, 0xc7, 0x17, 0xae, 0xeb, 0x82, 0x5f, 0x60, 0xd8, 0x05, + 0x15, 0xb9, 0xe8, 0xd5, 0xa9, 0xc2, 0x75, 0xf9, 0x84, 0x75, 0x86, 0xf3, 0xec, 0xc2, 0x22, 0xcb, + 0xa0, 0xbd, 0x39, 0x98, 0x3a, 0xa1, 0x95, 0xf7, 0x01, 0x75, 0xae, 0xe3, 0x3b, 0xca, 0x03, 0x85, + 0xef, 0xc1, 0x98, 0x5b, 0x17, 0xc9, 0x28, 0xc4, 0xb4, 0x9e, 0xd7, 0xd8, 0x94, 0xeb, 0x3c, 0x37, + 0x45, 0xcc, 0x83, 0xad, 0x09, 0xae, 0x80, 0x2e, 0x4e, 0x6a, 0x2b, 0x9f, 0xb9, 0x08, 0x73, 0xbd, + 0xc8, 0xc4, 0xfb, 0xf8, 0x46, 0xf4, 0x3e, 0xfe, 0x69, 0x18, 0x09, 0x94, 0xec, 0x18, 0x96, 0xf8, + 0x65, 0xfe, 0x39, 0xb8, 0x3c, 0x68, 0x1f, 0xe1, 0x13, 0xe8, 0xe9, 0x1d, 0x3e, 0x66, 0xcd, 0x38, + 0x5d, 0xfd, 0x86, 0x4f, 0xa0, 0x47, 0x09, 0x02, 0x5c, 0x29, 0x8f, 0x12, 0xb6, 0xe9, 0xbb, 0xe6, + 0xbb, 0x30, 0xa5, 0x2f, 0xf5, 0xe4, 0x75, 0x18, 0x8a, 0xb8, 0x4e, 0x45, 0x47, 0x12, 0x15, 0x89, + 0xf1, 0xb6, 0x10, 0xc9, 0xfc, 0x9f, 0x33, 0x70, 0x32, 0x65, 0xc1, 0x27, 0x1f, 0xc2, 0x49, 0x29, + 0x20, 0x7c, 0x4d, 0xe7, 0x03, 0xc7, 0x45, 0xe3, 0x4a, 0x9a, 0x68, 0x20, 0x5a, 0xca, 0xf0, 0xcd, + 0x08, 0xa1, 0x88, 0xcb, 0xff, 0xec, 0x88, 0x03, 0xf9, 0x00, 0x4e, 0x8b, 0x07, 0x8b, 0x14, 0xa9, + 0xb0, 0x7d, 0xba, 0x2b, 0x56, 0xff, 0x97, 0xba, 0x7a, 0xcf, 0xad, 0x29, 0xcd, 0xb1, 0xe8, 0xee, + 0xf2, 0x09, 0x6b, 0x36, 0x48, 0x81, 0x27, 0x25, 0xed, 0x6f, 0x1b, 0x60, 0x1e, 0xdd, 0x5f, 0xb8, + 0x02, 0x25, 0x3b, 0x9c, 0xad, 0x40, 0x4a, 0xef, 0xbd, 0x0c, 0x93, 0x3e, 0xdd, 0xf5, 0x69, 0xb0, + 0xaf, 0x74, 0xdf, 0x98, 0x35, 0x21, 0x80, 0xb2, 0x63, 0x64, 0x88, 0xcd, 0x00, 0x07, 0xbc, 0x1c, + 0x53, 0x0e, 0xb8, 0x6a, 0x2e, 0x88, 0xcc, 0x3b, 0xd1, 0x02, 0x92, 0x3a, 0x0e, 0xec, 0x88, 0xa2, + 0x36, 0x90, 0xff, 0xb8, 0x37, 0x94, 0xcb, 0xe4, 0xb3, 0x96, 0x08, 0x04, 0xda, 0x75, 0x1b, 0xd4, + 0xfc, 0xfb, 0x06, 0x9c, 0xeb, 0xdd, 0x79, 0xe4, 0x43, 0xc5, 0x44, 0x91, 0xe5, 0x79, 0x10, 0x8e, + 0xe8, 0x6f, 0xf5, 0x34, 0x27, 0x62, 0x53, 0x92, 0x6f, 0xf5, 0x08, 0x96, 0x4f, 0x73, 0xce, 0xba, + 0x2d, 0x35, 0x9c, 0x15, 0x37, 0x08, 0xb7, 0x6e, 0x90, 0x2b, 0x30, 0xca, 0x95, 0x1a, 0xd9, 0xd0, + 0x69, 0xad, 0xa1, 0x5b, 0x37, 0x2c, 0x59, 0x6e, 0x7e, 0xcf, 0x88, 0xb6, 0xe2, 0x64, 0xf3, 0xb7, + 0x6e, 0x90, 0xcf, 0x0d, 0x66, 0x6c, 0xc8, 0x49, 0x63, 0x43, 0x64, 0x68, 0xf8, 0xbc, 0x66, 0x68, + 0x78, 0xa5, 0x7f, 0x3f, 0x89, 0xbd, 0x24, 0xf9, 0x9a, 0xc2, 0x1f, 0x1b, 0xf0, 0x62, 0x5f, 0x0a, + 0x72, 0x1e, 0x72, 0x85, 0x4a, 0x79, 0x23, 0x1e, 0x59, 0x36, 0x5b, 0x24, 0x84, 0xdc, 0x85, 0xb1, + 0x45, 0x27, 0x70, 0x6b, 0x4c, 0x80, 0x45, 0x43, 0x5e, 0xeb, 0xdf, 0x90, 0x08, 0x9d, 0xe9, 0x2f, + 0xd1, 0x0f, 0x62, 0xc3, 0x0c, 0xce, 0x82, 0xae, 0x6c, 0xe5, 0xc9, 0x6d, 0xa7, 0x8b, 0x61, 0x17, + 0x19, 0x5b, 0x61, 0xba, 0x80, 0xc9, 0xc9, 0xf7, 0x10, 0x2e, 0x1e, 0xd5, 0xc0, 0x63, 0x84, 0x93, + 0x5d, 0x86, 0x5c, 0xc5, 0x09, 0x82, 0x47, 0x9e, 0x5f, 0x57, 0x1f, 0x2b, 0x69, 0x0b, 0x98, 0x15, + 0x95, 0x9a, 0x3f, 0x63, 0xc8, 0xbd, 0xe1, 0xe8, 0x0f, 0x51, 0xd2, 0x35, 0xd5, 0xfb, 0xa7, 0x6b, + 0xaa, 0x7f, 0xcc, 0x74, 0x4d, 0xe6, 0xaf, 0x89, 0x60, 0xef, 0x72, 0xbd, 0x92, 0x48, 0x94, 0xf9, + 0xb4, 0xa6, 0xd3, 0x25, 0x4d, 0x3a, 0x5f, 0x56, 0xf2, 0xbe, 0x75, 0xd7, 0xd5, 0xdb, 0x82, 0xaa, + 0x88, 0xea, 0xcf, 0x18, 0x70, 0xbe, 0x1f, 0x79, 0x6a, 0x4e, 0x4f, 0xe3, 0x78, 0x39, 0x3d, 0xaf, + 0x40, 0x8e, 0xc3, 0xf4, 0xcc, 0xfa, 0x82, 0x94, 0x75, 0xb8, 0x2c, 0x36, 0x0b, 0x00, 0xe5, 0x7a, + 0x65, 0xbd, 0xcd, 0x43, 0xce, 0x6f, 0xc2, 0x10, 0x6b, 0x5b, 0xa2, 0xa3, 0x58, 0x53, 0x0b, 0xab, + 0x2b, 0x02, 0x89, 0x9f, 0xae, 0x03, 0xa7, 0xd9, 0xb0, 0x10, 0xd9, 0xdc, 0x86, 0x29, 0x1d, 0x83, + 0x2c, 0xe9, 0x41, 0x4a, 0xf1, 0x63, 0x60, 0x8b, 0x9e, 0xc7, 0x8d, 0xb3, 0x8b, 0x67, 0xbf, 0x7f, + 0x38, 0x0f, 0xec, 0x27, 0xa7, 0x49, 0x0b, 0x62, 0x32, 0xbf, 0x9d, 0x81, 0xd9, 0xd8, 0xa3, 0x41, + 0x0e, 0xd7, 0x73, 0x7b, 0xe3, 0x58, 0xd0, 0x6e, 0xc4, 0xe6, 0xbb, 0xde, 0xdb, 0x91, 0x1f, 0xd8, + 0xc7, 0x10, 0x7f, 0x17, 0xe6, 0x7a, 0xe1, 0x93, 0xd7, 0xbb, 0x5e, 0xc4, 0x10, 0x9e, 0xb7, 0xd1, + 0xd3, 0x19, 0xca, 0x03, 0x19, 0xff, 0xdc, 0x80, 0x73, 0xc2, 0xa4, 0xb8, 0xea, 0xb8, 0x2d, 0x7c, + 0x05, 0xac, 0x46, 0x9f, 0xcd, 0x55, 0xf5, 0x5d, 0x6d, 0xca, 0xbc, 0xaa, 0x5b, 0x8e, 0xbb, 0x6a, + 0xeb, 0xfd, 0xb5, 0xe4, 0x0a, 0xba, 0x2b, 0xd7, 0xb8, 0x55, 0x67, 0x88, 0xbb, 0xe3, 0xb4, 0x18, + 0x40, 0x75, 0xc7, 0x41, 0x0c, 0xf3, 0x47, 0xe1, 0x42, 0xff, 0x0a, 0xc8, 0xd7, 0x60, 0xb2, 0xb0, + 0x47, 0x5b, 0xe1, 0x66, 0x7b, 0xcf, 0x77, 0xea, 0x54, 0x5e, 0x1d, 0xc8, 0x43, 0xad, 0x5a, 0xc6, + 0x5d, 0xb4, 0x85, 0x7b, 0x08, 0x83, 0xdb, 0x1d, 0x41, 0xa4, 0xd9, 0xed, 0x55, 0x6e, 0xe6, 0x8f, + 0x19, 0x40, 0xba, 0x79, 0x90, 0x5b, 0x30, 0xb1, 0xb9, 0x51, 0xac, 0x86, 0x8e, 0x1f, 0x2e, 0x7b, + 0x1d, 0xde, 0x9d, 0x93, 0xc2, 0x73, 0x21, 0xac, 0xd9, 0x01, 0x2b, 0xb0, 0xf7, 0xbd, 0x8e, 0x6f, + 0x69, 0x78, 0x98, 0x47, 0x88, 0xd2, 0x07, 0x75, 0xe7, 0x40, 0xcf, 0x23, 0x24, 0x60, 0x5a, 0x1e, + 0x21, 0x01, 0x33, 0xff, 0xba, 0x01, 0x2f, 0xc8, 0x03, 0x66, 0x3d, 0xa5, 0x2d, 0x45, 0xf4, 0x89, + 0xf3, 0x65, 0xe8, 0x57, 0x3f, 0xbd, 0x69, 0x46, 0xba, 0x8d, 0x62, 0x03, 0x51, 0x81, 0xe2, 0xb4, + 0xf8, 0x04, 0x62, 0xe8, 0xb5, 0x07, 0xf0, 0x1b, 0xcd, 0x47, 0x23, 0x1a, 0x7a, 0x6d, 0x64, 0x81, + 0x94, 0x26, 0x85, 0x59, 0xb5, 0x71, 0xb2, 0xc5, 0x64, 0x15, 0x46, 0x85, 0x6f, 0xbc, 0xd0, 0x44, + 0x64, 0xb8, 0x44, 0x9f, 0x6f, 0x5a, 0x9c, 0x96, 0xce, 0xa9, 0x22, 0xf4, 0xc8, 0x92, 0x3c, 0xcc, + 0x9f, 0x33, 0xf8, 0xeb, 0xcb, 0x18, 0x8d, 0xfb, 0xb4, 0x22, 0xad, 0xeb, 0x28, 0xd2, 0x59, 0x20, + 0x62, 0x3f, 0xd0, 0xc2, 0xff, 0x16, 0x4c, 0x27, 0x08, 0x88, 0x89, 0x6e, 0x49, 0x0d, 0x97, 0x3f, + 0x26, 0xc7, 0xbf, 0x7b, 0xcc, 0xd2, 0x60, 0xe6, 0xbf, 0x63, 0xc0, 0x2c, 0x3b, 0x21, 0x97, 0x9b, + 0x6d, 0xcf, 0x0f, 0xad, 0x4e, 0x43, 0xce, 0x77, 0xb6, 0x59, 0x4b, 0x4b, 0x05, 0xf7, 0xdf, 0xe0, + 0x9b, 0xb5, 0x80, 0x59, 0x51, 0x29, 0x59, 0x86, 0x9c, 0x88, 0x94, 0x94, 0x8f, 0x9f, 0x4a, 0x9b, + 0x8c, 0xce, 0x58, 0x20, 0xb1, 0x2f, 0xc1, 0x25, 0x4c, 0xd0, 0x58, 0x11, 0xb5, 0xf9, 0x47, 0x06, + 0x9c, 0xe9, 0x41, 0x43, 0xde, 0x85, 0x61, 0xbc, 0x0c, 0x13, 0xa3, 0x77, 0xbe, 0x47, 0x15, 0x61, + 0x6d, 0x7f, 0xeb, 0x06, 0xbf, 0x36, 0x6e, 0xb2, 0x1f, 0x16, 0xa7, 0x22, 0x1f, 0xc2, 0x58, 0xa1, + 0x5e, 0xd7, 0x9e, 0x68, 0x7d, 0xb3, 0x7f, 0x2b, 0xaf, 0x45, 0xf8, 0x5c, 0x67, 0xe6, 0x66, 0xd9, + 0x7a, 0x5d, 0xbc, 0x71, 0x69, 0xc5, 0xfc, 0xce, 0xbd, 0x03, 0x53, 0x3a, 0xf2, 0xb1, 0x74, 0xe6, + 0xef, 0x19, 0x90, 0xd7, 0xdb, 0xf0, 0xc9, 0xb8, 0xd5, 0xa6, 0x0d, 0xf3, 0x11, 0x42, 0xf5, 0x9d, + 0x0c, 0x9c, 0x4a, 0xed, 0x61, 0xf2, 0x26, 0x8c, 0x14, 0xda, 0xed, 0x72, 0x49, 0x48, 0x15, 0x57, + 0x1e, 0x9c, 0x76, 0x3b, 0x11, 0x88, 0x23, 0x90, 0xc8, 0x4d, 0xc8, 0xa1, 0x64, 0x32, 0x82, 0x4c, + 0x1c, 0xbb, 0x83, 0x11, 0xee, 0xc9, 0xd8, 0x1d, 0x89, 0x48, 0xee, 0xc0, 0x94, 0xf0, 0xb0, 0xb3, + 0xe8, 0x1e, 0x7d, 0x1c, 0x05, 0x91, 0x63, 0x9c, 0xbb, 0xf4, 0xc7, 0xb3, 0x7d, 0x5e, 0xa6, 0x46, + 0x03, 0xea, 0x54, 0xf8, 0x42, 0x0b, 0xe3, 0xa9, 0x72, 0xe2, 0x01, 0x44, 0xfc, 0x85, 0x16, 0x6c, + 0x44, 0x0f, 0x5e, 0x5d, 0x94, 0xd1, 0x70, 0x15, 0x82, 0xc0, 0xdd, 0x6b, 0x35, 0x69, 0x2b, 0xfc, + 0xe4, 0x86, 0x2b, 0xae, 0x63, 0xa0, 0xe1, 0xfa, 0xee, 0x10, 0x9f, 0xcc, 0x49, 0xb2, 0x23, 0x1e, + 0x21, 0x2b, 0xc1, 0x28, 0x8f, 0x2d, 0x95, 0x33, 0xe3, 0xc5, 0xd4, 0x26, 0x70, 0x9c, 0xad, 0x1b, + 0x5c, 0x7d, 0xe1, 0xb7, 0x72, 0x81, 0x25, 0x49, 0xc9, 0x16, 0x8c, 0x17, 0x1b, 0xd4, 0x69, 0x75, + 0xda, 0x6c, 0x91, 0x1e, 0xe0, 0xf4, 0x3c, 0x27, 0xbe, 0x65, 0xa2, 0xc6, 0xc9, 0xec, 0xd0, 0x6d, + 0x52, 0x5c, 0xc9, 0x55, 0x46, 0x64, 0x23, 0x32, 0xd4, 0x0f, 0xa1, 0x61, 0xe6, 0x33, 0x7d, 0xfa, + 0x27, 0x09, 0x44, 0x3a, 0xfd, 0x16, 0x4a, 0x58, 0xf2, 0x6d, 0x98, 0x5a, 0x71, 0x82, 0x70, 0xc3, + 0x77, 0x5a, 0x01, 0x86, 0xe7, 0x0c, 0xe0, 0x33, 0x2d, 0x53, 0xc9, 0x4f, 0xa3, 0x7f, 0x5e, 0x18, + 0x91, 0x62, 0x9b, 0x13, 0xec, 0x98, 0xbe, 0x74, 0xc7, 0x6d, 0x39, 0x0d, 0xf7, 0x9b, 0xf2, 0x3e, + 0x93, 0xeb, 0x4b, 0xbb, 0x12, 0x68, 0xc5, 0xe5, 0xe6, 0x57, 0xbb, 0xc6, 0x8d, 0xb7, 0x72, 0x1c, + 0x46, 0x85, 0x0b, 0x0b, 0x77, 0xe9, 0xa8, 0x2c, 0xad, 0x95, 0xca, 0x6b, 0x77, 0xf3, 0x06, 0x99, + 0x02, 0xa8, 0x58, 0xeb, 0xc5, 0xa5, 0x6a, 0x95, 0xfd, 0xce, 0xb0, 0xdf, 0xc2, 0xdf, 0xe3, 0xce, + 0xe6, 0x4a, 0x3e, 0xab, 0xb8, 0x7c, 0x0c, 0x99, 0xff, 0xcc, 0x80, 0xd3, 0xe9, 0x43, 0x49, 0x36, + 0x00, 0x9d, 0x7e, 0x84, 0xcd, 0xeb, 0x56, 0xdf, 0x71, 0x4f, 0x05, 0x27, 0x9d, 0x87, 0x42, 0xee, + 0x94, 0x92, 0x71, 0xa5, 0x76, 0x1c, 0xa5, 0x74, 0x77, 0xeb, 0x66, 0x11, 0xe6, 0x7a, 0xf1, 0xd0, + 0x3f, 0x75, 0x1a, 0xc6, 0x0b, 0x95, 0xca, 0x4a, 0xb9, 0x58, 0xd8, 0x28, 0xaf, 0xaf, 0xe5, 0x0d, + 0x32, 0x06, 0xc3, 0x77, 0xad, 0xf5, 0xcd, 0x4a, 0x3e, 0x63, 0xfe, 0x25, 0x03, 0x26, 0xcb, 0xad, + 0x90, 0xee, 0xf1, 0x14, 0x76, 0x4f, 0x3b, 0xf9, 0xbe, 0xa0, 0x4d, 0xbe, 0xb9, 0xc8, 0x3d, 0x2e, + 0xaa, 0x60, 0xa0, 0x99, 0xf7, 0x08, 0x66, 0xba, 0x48, 0x48, 0x15, 0x46, 0x0b, 0xdb, 0xd5, 0xf5, + 0x72, 0xa9, 0x28, 0x1a, 0x26, 0x95, 0x72, 0x01, 0xed, 0xae, 0x84, 0x5f, 0x3e, 0x3f, 0x0a, 0x6c, + 0xcf, 0xad, 0x2b, 0x59, 0x31, 0x97, 0x4f, 0x58, 0x92, 0x13, 0x3b, 0xa1, 0x8b, 0x73, 0x05, 0xaa, + 0xec, 0x2b, 0x30, 0xd7, 0x8b, 0x1b, 0x3b, 0xa9, 0xe8, 0xbe, 0x22, 0xa7, 0xa3, 0x24, 0x06, 0xba, + 0x93, 0x88, 0x44, 0x33, 0xff, 0x4a, 0x06, 0x4e, 0xb3, 0x7e, 0x69, 0xd0, 0x20, 0x60, 0xe7, 0x6c, + 0x76, 0xa4, 0x13, 0x4f, 0xd1, 0x7e, 0x0e, 0x46, 0xf6, 0x8f, 0x67, 0x80, 0xe1, 0xe8, 0x84, 0x00, + 0xae, 0x35, 0x62, 0xdf, 0xc3, 0xbf, 0xc9, 0x8b, 0xa0, 0xa4, 0xab, 0xc5, 0xa5, 0x62, 0xc2, 0x1a, + 0x6b, 0x47, 0x49, 0x6b, 0x3f, 0x0f, 0xc3, 0x18, 0x38, 0x21, 0x66, 0xbc, 0xd4, 0xd4, 0xd2, 0x5b, + 0x86, 0x11, 0x15, 0x16, 0x27, 0x20, 0xd7, 0x01, 0xe2, 0x10, 0x73, 0x31, 0xa5, 0xe5, 0xe9, 0x30, + 0x8a, 0x32, 0xb7, 0xc6, 0x9a, 0xbb, 0x8e, 0x88, 0xdb, 0xbe, 0x0a, 0x33, 0xd2, 0x50, 0xd0, 0x96, + 0x9e, 0xff, 0x3c, 0xc8, 0xc1, 0x9a, 0xe6, 0x05, 0xe5, 0xb6, 0xf0, 0xfe, 0x37, 0xff, 0x75, 0x06, + 0xc6, 0xb6, 0xd9, 0xfe, 0x87, 0xa7, 0xba, 0xfe, 0xa7, 0xc4, 0x05, 0x18, 0x5f, 0xf1, 0x9c, 0xba, + 0xfe, 0x94, 0x22, 0xde, 0xd4, 0x36, 0x3c, 0x47, 0x5a, 0x5e, 0x03, 0x4b, 0x45, 0x3a, 0xe2, 0x96, + 0xf9, 0x1e, 0x8c, 0xf0, 0xc8, 0x21, 0x91, 0xf8, 0x59, 0x6a, 0x40, 0x51, 0x8b, 0xae, 0xf1, 0x62, + 0xc5, 0xc2, 0xb7, 0x8b, 0x00, 0x75, 0x3b, 0x16, 0xb1, 0x47, 0xca, 0x19, 0x76, 0x78, 0xb0, 0x33, + 0xac, 0xe2, 0xef, 0x3d, 0x32, 0x88, 0xbf, 0xf7, 0xb9, 0xdb, 0x30, 0xae, 0xb4, 0xe7, 0x58, 0x0a, + 0xd1, 0x8f, 0x67, 0x60, 0x12, 0xbf, 0x2a, 0x32, 0xcd, 0x3f, 0x9f, 0x27, 0xf2, 0x2f, 0x68, 0x27, + 0xf2, 0x39, 0x75, 0xbc, 0xf8, 0x97, 0xf5, 0x39, 0x8a, 0xdf, 0x83, 0x99, 0x2e, 0x44, 0xf2, 0x16, + 0x0c, 0xb3, 0xe6, 0xcb, 0x13, 0x4c, 0x3e, 0x29, 0x01, 0x71, 0x3c, 0x1e, 0xfb, 0xf0, 0xc0, 0xe2, + 0xd8, 0xe6, 0xff, 0x6d, 0xc0, 0x84, 0xc8, 0x39, 0xd0, 0xda, 0xf5, 0x9e, 0xdb, 0xee, 0xbc, 0xad, + 0x75, 0xe7, 0x99, 0x28, 0x66, 0x40, 0x7e, 0x58, 0x9f, 0xde, 0xfc, 0x47, 0x18, 0xb9, 0xa6, 0x23, + 0x92, 0x12, 0xf7, 0xd0, 0xd3, 0x97, 0xe6, 0x24, 0x16, 0x5b, 0xab, 0x31, 0xa7, 0xd8, 0x4c, 0xfa, + 0xeb, 0xf0, 0xe7, 0xf6, 0x71, 0x91, 0x97, 0xf9, 0xbd, 0xe2, 0xd7, 0xc4, 0x95, 0xfc, 0x5e, 0xf1, + 0x6b, 0xe2, 0xea, 0x1b, 0xe2, 0xd7, 0x01, 0xd0, 0x09, 0xbb, 0x55, 0xa3, 0x91, 0x1d, 0x0d, 0xfd, + 0x32, 0x5c, 0x01, 0x65, 0xf8, 0x0a, 0x8a, 0xf9, 0xeb, 0x59, 0x80, 0xf8, 0xc2, 0x93, 0xcd, 0x48, + 0xaa, 0xa5, 0xea, 0x11, 0xf6, 0x3b, 0x04, 0xa9, 0xa3, 0x24, 0x40, 0xe4, 0x12, 0x0c, 0x29, 0xb9, + 0x7a, 0x53, 0x43, 0x3b, 0xd0, 0x4c, 0x5b, 0x04, 0x08, 0x0e, 0x5a, 0x35, 0xbb, 0x4e, 0x1b, 0x0e, + 0x5f, 0x9c, 0xb3, 0xf8, 0xca, 0xdf, 0x6c, 0x0c, 0xed, 0x91, 0x4d, 0x76, 0x8c, 0x61, 0x94, 0x18, + 0x02, 0x79, 0x37, 0x71, 0x23, 0x3c, 0x14, 0x47, 0xb4, 0xa8, 0x70, 0x35, 0xa2, 0x45, 0xb9, 0x2d, + 0x26, 0x0b, 0x10, 0x19, 0x90, 0xd5, 0x15, 0x2a, 0x2d, 0xb7, 0xb0, 0x84, 0x31, 0x1a, 0x69, 0x4a, + 0xd6, 0x9e, 0xd8, 0x14, 0x30, 0x95, 0x46, 0xc2, 0x48, 0x05, 0xc6, 0xdc, 0xd6, 0x43, 0xda, 0x0a, + 0x3d, 0xff, 0x60, 0x6e, 0x14, 0x67, 0xd5, 0x59, 0xe5, 0x6e, 0xb9, 0x2c, 0xcb, 0xf8, 0xa2, 0x8a, + 0x67, 0x96, 0x08, 0x5f, 0x0d, 0x21, 0x8c, 0x80, 0xe2, 0x22, 0xf9, 0x1f, 0x67, 0x80, 0x74, 0x33, + 0x20, 0x5f, 0x80, 0x71, 0xbe, 0x26, 0xdb, 0x7e, 0xf0, 0x0d, 0x71, 0x05, 0xcd, 0xfd, 0x2f, 0x15, + 0xb0, 0xea, 0x7f, 0xc9, 0xc1, 0x56, 0xf0, 0x8d, 0x06, 0xf9, 0x1a, 0x9c, 0xc4, 0x01, 0x68, 0x53, + 0xdf, 0xf5, 0xea, 0x36, 0x86, 0x7b, 0x39, 0x0d, 0x91, 0x1b, 0xee, 0x4d, 0x4c, 0x62, 0xda, 0x5d, + 0xdc, 0x63, 0xa0, 0x66, 0x18, 0x6a, 0x05, 0x31, 0x2b, 0x1c, 0x91, 0x6c, 0x40, 0x5e, 0xa5, 0xdf, + 0xed, 0x34, 0x1a, 0x62, 0xec, 0xaf, 0xe2, 0xdb, 0x46, 0x89, 0xb2, 0x1e, 0x8c, 0xa7, 0x62, 0xc6, + 0x77, 0x3a, 0x8d, 0x06, 0xf9, 0x1c, 0x80, 0xd7, 0xb2, 0x9b, 0x6e, 0x10, 0xb8, 0xad, 0x3d, 0x21, + 0x04, 0x18, 0xc8, 0x15, 0x43, 0xd5, 0x6e, 0xf4, 0x5a, 0xab, 0x1c, 0x28, 0xba, 0xf1, 0x2b, 0x30, + 0x23, 0x3c, 0x2f, 0xb7, 0xdd, 0x70, 0x5f, 0x68, 0x6c, 0x4f, 0xa3, 0xee, 0x29, 0x2a, 0xdb, 0xbf, + 0xcd, 0x00, 0x14, 0xb6, 0xab, 0xd2, 0xe9, 0xf7, 0x0a, 0x0c, 0x33, 0x3d, 0x54, 0x9e, 0x67, 0xd1, + 0x1a, 0x88, 0x7c, 0x55, 0x6b, 0x20, 0x62, 0xb0, 0x99, 0x67, 0xd1, 0x3d, 0x34, 0xa9, 0x64, 0xe2, + 0xc3, 0xaf, 0xcf, 0x41, 0x9a, 0x5a, 0xc5, 0x41, 0x64, 0x05, 0x20, 0x76, 0xc3, 0x15, 0x27, 0xa3, + 0x99, 0xd8, 0x9f, 0x4d, 0x14, 0x88, 0x2c, 0x02, 0xb1, 0x2b, 0xaf, 0x2a, 0x08, 0x31, 0x1a, 0xb9, + 0x0f, 0x43, 0x1b, 0xce, 0x9e, 0xf4, 0x27, 0xec, 0xe1, 0x9c, 0x7c, 0x51, 0x64, 0xe1, 0x8b, 0x1d, + 0x94, 0xa7, 0x42, 0x47, 0x4b, 0x56, 0x8a, 0x4c, 0xc8, 0x12, 0x8c, 0x88, 0x0c, 0xcb, 0x3d, 0x22, + 0x55, 0x44, 0x82, 0x65, 0x11, 0x8c, 0x89, 0x40, 0xed, 0x81, 0x58, 0x9e, 0x4b, 0x79, 0x01, 0xb2, + 0xd5, 0xea, 0xaa, 0x70, 0xc9, 0x99, 0x8c, 0xd5, 0xdc, 0x6a, 0x75, 0x55, 0x66, 0x91, 0x57, 0xdf, + 0xf0, 0x64, 0xc8, 0x26, 0x55, 0x7b, 0x85, 0x5c, 0x4a, 0x2a, 0xab, 0x68, 0x24, 0x92, 0xca, 0x6a, + 0xa4, 0xa2, 0xb2, 0x65, 0xb3, 0xcb, 0x83, 0x19, 0x97, 0x4d, 0xc5, 0x83, 0x59, 0xf3, 0x5b, 0xfe, + 0x89, 0xac, 0x12, 0x19, 0x23, 0x9a, 0xfb, 0x2e, 0xc0, 0x3d, 0xcf, 0x6d, 0xad, 0xd2, 0x70, 0xdf, + 0xab, 0x2b, 0x8e, 0xd4, 0xe3, 0x1f, 0x79, 0x6e, 0xcb, 0x6e, 0x22, 0xf8, 0x07, 0x87, 0xf3, 0x0a, + 0x92, 0xa5, 0xfc, 0xcd, 0x16, 0x7a, 0xf6, 0x4b, 0x7d, 0xb9, 0x1b, 0x17, 0x7a, 0xa4, 0x16, 0x0f, + 0x36, 0x44, 0x08, 0xe4, 0x36, 0x00, 0x8f, 0xd1, 0x51, 0x94, 0x3b, 0x1c, 0x6a, 0x7e, 0xa1, 0x92, + 0x8c, 0xec, 0x53, 0x90, 0xc9, 0x72, 0xd4, 0x74, 0x99, 0x36, 0x45, 0xe4, 0xd6, 0x40, 0x13, 0x88, + 0x18, 0x0e, 0x5b, 0x26, 0x59, 0x51, 0x13, 0x5c, 0x26, 0xc8, 0xb0, 0x11, 0xd5, 0xe5, 0x12, 0xb7, + 0x59, 0x8b, 0x25, 0x95, 0x37, 0x22, 0xd8, 0xaf, 0xdb, 0x35, 0x04, 0x6b, 0x8d, 0x88, 0x90, 0xc9, + 0x22, 0x4c, 0x73, 0x77, 0xbf, 0x28, 0xfd, 0x9a, 0x58, 0x5e, 0x71, 0x22, 0xc7, 0xf9, 0xd9, 0xd4, + 0xea, 0x13, 0x04, 0x66, 0x19, 0x46, 0xb8, 0x34, 0x60, 0x78, 0xa6, 0xc8, 0xfd, 0xa0, 0x04, 0x1a, + 0xf2, 0xf0, 0x4c, 0x01, 0xef, 0x0e, 0xcf, 0x54, 0x08, 0xcc, 0x5f, 0xce, 0xc2, 0x44, 0xe1, 0x9b, + 0x1d, 0x3f, 0x72, 0xd7, 0x2f, 0xc0, 0x64, 0xb5, 0xb3, 0x13, 0x39, 0x6b, 0xca, 0x19, 0xcc, 0x1f, + 0xbc, 0x53, 0x0b, 0x54, 0xf3, 0xba, 0x46, 0x41, 0x96, 0x60, 0x4a, 0xae, 0x1e, 0x22, 0x23, 0x23, + 0x9f, 0xd8, 0xe8, 0x5c, 0x2f, 0xc3, 0x08, 0xba, 0xf3, 0x31, 0x26, 0x88, 0xe2, 0x35, 0x24, 0x7b, + 0x9c, 0x35, 0x64, 0x68, 0xa0, 0x35, 0xe4, 0x43, 0x98, 0x90, 0xb5, 0xe1, 0xec, 0x1f, 0x7e, 0xba, + 0xd9, 0xaf, 0x31, 0x23, 0x2b, 0xd1, 0x2a, 0x30, 0xd2, 0x77, 0x15, 0xc0, 0x3b, 0x0b, 0x29, 0x76, + 0x5d, 0x29, 0xd6, 0x05, 0x0f, 0xf3, 0x8f, 0x0d, 0x80, 0xbb, 0xc5, 0xca, 0xc7, 0x58, 0x59, 0xdf, + 0x82, 0xb1, 0x15, 0x4f, 0x9a, 0xab, 0x15, 0x3b, 0x61, 0x43, 0x02, 0xd5, 0xcd, 0x22, 0xc2, 0x8c, + 0x56, 0xc4, 0xec, 0xb3, 0x58, 0x11, 0x6f, 0x03, 0x54, 0x7c, 0xef, 0x23, 0x5a, 0x0b, 0xe3, 0x44, + 0x43, 0x38, 0x53, 0xda, 0x1c, 0x9a, 0x30, 0x57, 0x2a, 0xc8, 0x57, 0xdf, 0x87, 0x69, 0x19, 0x53, + 0xb2, 0xb1, 0x52, 0xc5, 0x18, 0xd0, 0x69, 0x18, 0xdf, 0x5a, 0xb2, 0xca, 0x77, 0x3e, 0xb0, 0xef, + 0x6c, 0xae, 0xac, 0xe4, 0x4f, 0x90, 0x49, 0x18, 0x13, 0x80, 0x62, 0x21, 0x6f, 0x90, 0x09, 0xc8, + 0x95, 0xd7, 0xaa, 0x4b, 0xc5, 0x4d, 0x6b, 0x29, 0x9f, 0xb9, 0xba, 0x00, 0x53, 0xf1, 0x53, 0x51, + 0x68, 0x16, 0x19, 0x85, 0xac, 0x55, 0xd8, 0xce, 0x9f, 0x20, 0x00, 0x23, 0x95, 0xfb, 0xc5, 0xea, + 0x8d, 0x1b, 0x79, 0x83, 0x8c, 0xc3, 0xe8, 0xdd, 0x62, 0xc5, 0xbe, 0xbf, 0x5a, 0xcd, 0x67, 0xae, + 0x7e, 0x06, 0x66, 0x70, 0x9e, 0xad, 0xb8, 0x41, 0x48, 0x5b, 0xd4, 0xc7, 0x6a, 0x27, 0x20, 0x57, + 0xa5, 0x6c, 0x80, 0x42, 0xca, 0xeb, 0x5c, 0xed, 0x34, 0x42, 0xb7, 0xdd, 0xa0, 0x8f, 0xf3, 0xc6, + 0xd5, 0xdb, 0x30, 0x6d, 0x79, 0x9d, 0xd0, 0x6d, 0xed, 0x55, 0x43, 0x86, 0xb1, 0x77, 0x40, 0x4e, + 0xc1, 0xcc, 0xe6, 0x5a, 0x61, 0x75, 0xb1, 0x7c, 0x77, 0x73, 0x7d, 0xb3, 0x6a, 0xaf, 0x16, 0x36, + 0x8a, 0xcb, 0xdc, 0x0e, 0xb3, 0xba, 0x5e, 0xdd, 0xb0, 0xad, 0xa5, 0xe2, 0xd2, 0xda, 0x46, 0xde, + 0xb8, 0xfa, 0xd3, 0x06, 0x4c, 0x6d, 0x06, 0xc2, 0xaf, 0x65, 0x13, 0x43, 0x22, 0x2e, 0xc2, 0xf9, + 0xcd, 0xea, 0x92, 0x65, 0x6f, 0xac, 0xdf, 0x5f, 0x5a, 0xb3, 0x37, 0xab, 0x85, 0xbb, 0xc9, 0x40, + 0xac, 0x79, 0x78, 0x41, 0xc1, 0xb0, 0x96, 0x8a, 0xeb, 0x5b, 0x4b, 0x96, 0x5d, 0x29, 0x54, 0xab, + 0xdb, 0xeb, 0x56, 0x29, 0x6f, 0x90, 0x73, 0x70, 0x3a, 0x05, 0x61, 0xf5, 0x4e, 0x21, 0x9f, 0xe9, + 0x2a, 0x5b, 0x5b, 0xda, 0x2e, 0xac, 0xd8, 0x8b, 0xeb, 0x1b, 0xf9, 0xec, 0xd5, 0xf7, 0xd9, 0x9c, + 0xc0, 0x58, 0x05, 0x9e, 0x56, 0x21, 0x07, 0x43, 0x6b, 0xeb, 0x6b, 0x4b, 0x49, 0x5b, 0xd9, 0x04, + 0xe4, 0x0a, 0x95, 0x8a, 0xb5, 0xbe, 0xb5, 0x54, 0xca, 0x67, 0x58, 0x47, 0x96, 0x96, 0xd6, 0x58, + 0xcb, 0xb2, 0x57, 0xff, 0x7f, 0x40, 0x78, 0x10, 0x86, 0x8c, 0x4d, 0xc7, 0xce, 0xbb, 0x00, 0xe7, + 0x96, 0xd9, 0x57, 0x63, 0xbd, 0xab, 0xeb, 0xa5, 0xe4, 0xf7, 0x9c, 0x06, 0x92, 0x28, 0x5f, 0xbf, + 0x73, 0x27, 0x6f, 0x90, 0x33, 0x70, 0x32, 0x01, 0x2f, 0x59, 0xeb, 0x95, 0x7c, 0x26, 0xa5, 0xe0, + 0xfe, 0xd2, 0x52, 0x25, 0x9f, 0xbd, 0x6a, 0xc2, 0x4c, 0x91, 0xfa, 0x21, 0xdb, 0xad, 0x5a, 0xec, + 0x88, 0x84, 0xd5, 0x4f, 0xc2, 0xd8, 0xd2, 0x97, 0x37, 0x96, 0xd6, 0xaa, 0xe5, 0xf5, 0xb5, 0xfc, + 0x89, 0xab, 0xe7, 0x13, 0x38, 0x52, 0x2c, 0xaa, 0xd5, 0xe5, 0xfc, 0x89, 0xab, 0x5f, 0x65, 0x47, + 0x3b, 0x25, 0x65, 0xc9, 0x19, 0x38, 0xa9, 0xfe, 0xae, 0xd0, 0x56, 0xdd, 0x6d, 0xed, 0xe5, 0x4f, + 0x24, 0x0b, 0xac, 0x4e, 0xab, 0xc5, 0x0a, 0xb0, 0xf3, 0xd5, 0x82, 0x0d, 0xea, 0x37, 0xdd, 0x96, + 0x13, 0xd2, 0x7a, 0x3e, 0x73, 0xf5, 0x1a, 0x4c, 0x6a, 0x61, 0x26, 0xac, 0xde, 0x95, 0x75, 0x21, + 0x8e, 0xab, 0x4b, 0xa5, 0xf2, 0xe6, 0x6a, 0x7e, 0x98, 0x75, 0xfb, 0x72, 0xf9, 0xee, 0x72, 0x1e, + 0xae, 0x7e, 0x95, 0xad, 0xa3, 0x18, 0x89, 0xbd, 0x7a, 0xa7, 0x20, 0x1b, 0xca, 0x3a, 0x87, 0x07, + 0xa4, 0x2d, 0x55, 0xab, 0xdc, 0x9c, 0x77, 0x1e, 0xe6, 0xc4, 0x0f, 0xbb, 0xb0, 0x56, 0xb2, 0x97, + 0x0b, 0x56, 0x69, 0xbb, 0x60, 0xb1, 0x6e, 0xf9, 0x20, 0x9f, 0xc1, 0xfe, 0x55, 0x20, 0xf6, 0xc6, + 0xfa, 0x66, 0x71, 0x39, 0x9f, 0xbd, 0xea, 0x42, 0x3e, 0xe9, 0x8d, 0xd7, 0x65, 0x21, 0xb5, 0x36, + 0xd7, 0xd6, 0xf8, 0xa8, 0x4f, 0xc3, 0xf8, 0xfa, 0xc6, 0xf2, 0x92, 0x25, 0x82, 0xff, 0x30, 0xda, + 0x6f, 0x73, 0xad, 0xb0, 0xb9, 0xb1, 0xbc, 0x6e, 0x95, 0xbf, 0xc2, 0x86, 0x9f, 0xcc, 0xc1, 0x6c, + 0x75, 0xa5, 0x50, 0xbc, 0x6f, 0xaf, 0xad, 0x6f, 0xd8, 0xe5, 0x35, 0xbb, 0xb8, 0x5c, 0x58, 0x5b, + 0x5b, 0x5a, 0xc9, 0xc3, 0xd5, 0x7f, 0x6e, 0xc0, 0x0b, 0x7d, 0xcc, 0x4d, 0xe4, 0x4d, 0xb8, 0xb2, + 0xbc, 0x54, 0x28, 0xad, 0x2c, 0x55, 0xab, 0x36, 0x63, 0xb9, 0xb4, 0xb6, 0x21, 0x8c, 0x95, 0x76, + 0x75, 0xa3, 0xb0, 0x91, 0x94, 0x98, 0x2b, 0xf0, 0x6a, 0x7f, 0xf4, 0x58, 0x58, 0x2f, 0xc3, 0x2b, + 0xfd, 0x51, 0x85, 0xf0, 0x66, 0xc8, 0x55, 0xb8, 0xd4, 0x1f, 0x33, 0x12, 0xfa, 0xec, 0xe2, 0xbb, + 0xbf, 0xfb, 0xfb, 0x17, 0x4e, 0xfc, 0xee, 0x1f, 0x5c, 0x30, 0x7e, 0xef, 0x0f, 0x2e, 0x18, 0xff, + 0xea, 0x0f, 0x2e, 0x18, 0x5f, 0x79, 0xfd, 0x18, 0xe9, 0x99, 0x77, 0x46, 0xd0, 0x1a, 0x7e, 0xf3, + 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x3f, 0xee, 0x69, 0x2c, 0xea, 0x50, 0x01, 0x00, } func (this *PluginSpecV1) Equal(that interface{}) bool { @@ -17467,6 +18111,30 @@ func (this *PluginSpecV1_Jamf) Equal(that interface{}) bool { } return true } +func (this *PluginSpecV1_PagerDuty) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PluginSpecV1_PagerDuty) + if !ok { + that2, ok := that.(PluginSpecV1_PagerDuty) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.PagerDuty.Equal(that1.PagerDuty) { + return false + } + return true +} func (this *PluginSlackAccessSettings) Equal(that interface{}) bool { if that == nil { return this == nil @@ -17540,6 +18208,36 @@ func (this *PluginOpsgenieAccessSettings) Equal(that interface{}) bool { } return true } +func (this *PluginPagerDutySettings) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PluginPagerDutySettings) + if !ok { + that2, ok := that.(PluginPagerDutySettings) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.UserEmail != that1.UserEmail { + return false + } + if this.ApiEndpoint != that1.ApiEndpoint { + return false + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} func (this *PluginOpenAISettings) Equal(that interface{}) bool { if that == nil { return this == nil @@ -18409,6 +19107,16 @@ func (m *DatabaseSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.MongoAtlas.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 if m.AdminUser != nil { { size, err := m.AdminUser.MarshalToSizedBuffer(dAtA[:i]) @@ -18660,6 +19368,16 @@ func (m *AWS) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.OpenSearch.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 if len(m.AssumeRoleARN) > 0 { i -= len(m.AssumeRoleARN) copy(dAtA[i:], m.AssumeRoleARN) @@ -19117,6 +19835,54 @@ func (m *RedshiftServerless) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *OpenSearch) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *OpenSearch) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OpenSearch) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.EndpointType) > 0 { + i -= len(m.EndpointType) + copy(dAtA[i:], m.EndpointType) + i = encodeVarintTypes(dAtA, i, uint64(len(m.EndpointType))) + i-- + dAtA[i] = 0x1a + } + if len(m.DomainID) > 0 { + i -= len(m.DomainID) + copy(dAtA[i:], m.DomainID) + i = encodeVarintTypes(dAtA, i, uint64(len(m.DomainID))) + i-- + dAtA[i] = 0x12 + } + if len(m.DomainName) > 0 { + i -= len(m.DomainName) + copy(dAtA[i:], m.DomainName) + i = encodeVarintTypes(dAtA, i, uint64(len(m.DomainName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *GCPCloudSQL) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -19402,6 +20168,40 @@ func (m *MySQLOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *MongoAtlas) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MongoAtlas) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MongoAtlas) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *InstanceV1) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -19487,12 +20287,12 @@ func (m *InstanceSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x32 } } - n41, err41 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastSeen, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastSeen):]) - if err41 != nil { - return 0, err41 + n43, err43 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastSeen, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastSeen):]) + if err43 != nil { + return 0, err43 } - i -= n41 - i = encodeVarintTypes(dAtA, i, uint64(n41)) + i -= n43 + i = encodeVarintTypes(dAtA, i, uint64(n43)) i-- dAtA[i] = 0x2a if len(m.AuthID) > 0 { @@ -19576,12 +20376,12 @@ func (m *InstanceControlLogEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x20 } - n42, err42 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err42 != nil { - return 0, err42 + n44, err44 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err44 != nil { + return 0, err44 } - i -= n42 - i = encodeVarintTypes(dAtA, i, uint64(n42)) + i -= n44 + i = encodeVarintTypes(dAtA, i, uint64(n44)) i-- dAtA[i] = 0x1a if m.ID != 0 { @@ -20176,6 +20976,15 @@ func (m *AppSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.UserGroups) > 0 { + for iNdEx := len(m.UserGroups) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.UserGroups[iNdEx]) + copy(dAtA[i:], m.UserGroups[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.UserGroups[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } if len(m.Cloud) > 0 { i -= len(m.Cloud) copy(dAtA[i:], m.Cloud) @@ -21001,12 +21810,12 @@ func (m *ProvisionTokenV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - n63, err63 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err63 != nil { - return 0, err63 + n65, err65 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err65 != nil { + return 0, err65 } - i -= n63 - i = encodeVarintTypes(dAtA, i, uint64(n63)) + i -= n65 + i = encodeVarintTypes(dAtA, i, uint64(n65)) i-- dAtA[i] = 0x12 if len(m.Roles) > 0 { @@ -22849,6 +23658,13 @@ func (m *AuthPreferenceSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DefaultSessionTTL != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.DefaultSessionTTL)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 + } if m.AllowHeadless != nil { { size := m.AllowHeadless.Size() @@ -23332,12 +24148,12 @@ func (m *UserTokenSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n103, err103 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err103 != nil { - return 0, err103 + n105, err105 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err105 != nil { + return 0, err105 } - i -= n103 - i = encodeVarintTypes(dAtA, i, uint64(n103)) + i -= n105 + i = encodeVarintTypes(dAtA, i, uint64(n105)) i-- dAtA[i] = 0x22 if m.Usage != 0 { @@ -23454,12 +24270,12 @@ func (m *UserTokenSecretsSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n106, err106 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err106 != nil { - return 0, err106 + n108, err108 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err108 != nil { + return 0, err108 } - i -= n106 - i = encodeVarintTypes(dAtA, i, uint64(n106)) + i -= n108 + i = encodeVarintTypes(dAtA, i, uint64(n108)) i-- dAtA[i] = 0x1a if len(m.QRCode) > 0 { @@ -23623,20 +24439,20 @@ func (m *AccessReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if len(m.ThresholdIndexes) > 0 { - dAtA110 := make([]byte, len(m.ThresholdIndexes)*10) - var j109 int + dAtA112 := make([]byte, len(m.ThresholdIndexes)*10) + var j111 int for _, num := range m.ThresholdIndexes { for num >= 1<<7 { - dAtA110[j109] = uint8(uint64(num)&0x7f | 0x80) + dAtA112[j111] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j109++ + j111++ } - dAtA110[j109] = uint8(num) - j109++ + dAtA112[j111] = uint8(num) + j111++ } - i -= j109 - copy(dAtA[i:], dAtA110[:j109]) - i = encodeVarintTypes(dAtA, i, uint64(j109)) + i -= j111 + copy(dAtA[i:], dAtA112[:j111]) + i = encodeVarintTypes(dAtA, i, uint64(j111)) i-- dAtA[i] = 0x3a } @@ -23650,12 +24466,12 @@ func (m *AccessReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x32 - n112, err112 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err112 != nil { - return 0, err112 + n114, err114 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err114 != nil { + return 0, err114 } - i -= n112 - i = encodeVarintTypes(dAtA, i, uint64(n112)) + i -= n114 + i = encodeVarintTypes(dAtA, i, uint64(n114)) i-- dAtA[i] = 0x2a if len(m.Reason) > 0 { @@ -23758,20 +24574,20 @@ func (m *ThresholdIndexSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if len(m.Indexes) > 0 { - dAtA115 := make([]byte, len(m.Indexes)*10) - var j114 int + dAtA117 := make([]byte, len(m.Indexes)*10) + var j116 int for _, num := range m.Indexes { for num >= 1<<7 { - dAtA115[j114] = uint8(uint64(num)&0x7f | 0x80) + dAtA117[j116] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j114++ + j116++ } - dAtA115[j114] = uint8(num) - j114++ + dAtA117[j116] = uint8(num) + j116++ } - i -= j114 - copy(dAtA[i:], dAtA115[:j114]) - i = encodeVarintTypes(dAtA, i, uint64(j114)) + i -= j116 + copy(dAtA[i:], dAtA117[:j116]) + i = encodeVarintTypes(dAtA, i, uint64(j116)) i-- dAtA[i] = 0xa } @@ -23971,20 +24787,20 @@ func (m *AccessRequestSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n119, err119 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err119 != nil { - return 0, err119 + n121, err121 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err121 != nil { + return 0, err121 } - i -= n119 - i = encodeVarintTypes(dAtA, i, uint64(n119)) + i -= n121 + i = encodeVarintTypes(dAtA, i, uint64(n121)) i-- dAtA[i] = 0x2a - n120, err120 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err120 != nil { - return 0, err120 + n122, err122 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err122 != nil { + return 0, err122 } - i -= n120 - i = encodeVarintTypes(dAtA, i, uint64(n120)) + i -= n122 + i = encodeVarintTypes(dAtA, i, uint64(n122)) i-- dAtA[i] = 0x22 if m.State != 0 { @@ -24711,6 +25527,13 @@ func (m *RoleOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.CreateHostUserMode != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.CreateHostUserMode)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe0 + } if m.CreateDatabaseUser != nil { { size := m.CreateDatabaseUser.Size() @@ -26205,12 +27028,12 @@ func (m *UserSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x42 - n155, err155 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err155 != nil { - return 0, err155 + n157, err157 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err157 != nil { + return 0, err157 } - i -= n155 - i = encodeVarintTypes(dAtA, i, uint64(n155)) + i -= n157 + i = encodeVarintTypes(dAtA, i, uint64(n157)) i-- dAtA[i] = 0x3a { @@ -26352,28 +27175,28 @@ func (m *LoginStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n158, err158 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.RecoveryAttemptLockExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.RecoveryAttemptLockExpires):]) - if err158 != nil { - return 0, err158 + n160, err160 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.RecoveryAttemptLockExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.RecoveryAttemptLockExpires):]) + if err160 != nil { + return 0, err160 } - i -= n158 - i = encodeVarintTypes(dAtA, i, uint64(n158)) + i -= n160 + i = encodeVarintTypes(dAtA, i, uint64(n160)) i-- dAtA[i] = 0x2a - n159, err159 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockExpires):]) - if err159 != nil { - return 0, err159 + n161, err161 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockExpires):]) + if err161 != nil { + return 0, err161 } - i -= n159 - i = encodeVarintTypes(dAtA, i, uint64(n159)) + i -= n161 + i = encodeVarintTypes(dAtA, i, uint64(n161)) i-- dAtA[i] = 0x22 - n160, err160 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockedTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockedTime):]) - if err160 != nil { - return 0, err160 + n162, err162 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockedTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockedTime):]) + if err162 != nil { + return 0, err162 } - i -= n160 - i = encodeVarintTypes(dAtA, i, uint64(n160)) + i -= n162 + i = encodeVarintTypes(dAtA, i, uint64(n162)) i-- dAtA[i] = 0x1a if len(m.LockedMessage) > 0 { @@ -26430,12 +27253,12 @@ func (m *CreatedBy) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x1a - n162, err162 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err162 != nil { - return 0, err162 + n164, err164 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err164 != nil { + return 0, err164 } - i -= n162 - i = encodeVarintTypes(dAtA, i, uint64(n162)) + i -= n164 + i = encodeVarintTypes(dAtA, i, uint64(n164)) i-- dAtA[i] = 0x12 if m.Connector != nil { @@ -26553,20 +27376,20 @@ func (m *MFADevice) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } } - n165, err165 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUsed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUsed):]) - if err165 != nil { - return 0, err165 + n167, err167 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUsed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUsed):]) + if err167 != nil { + return 0, err167 } - i -= n165 - i = encodeVarintTypes(dAtA, i, uint64(n165)) + i -= n167 + i = encodeVarintTypes(dAtA, i, uint64(n167)) i-- dAtA[i] = 0x3a - n166, err166 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.AddedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.AddedAt):]) - if err166 != nil { - return 0, err166 + n168, err168 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.AddedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.AddedAt):]) + if err168 != nil { + return 0, err168 } - i -= n166 - i = encodeVarintTypes(dAtA, i, uint64(n166)) + i -= n168 + i = encodeVarintTypes(dAtA, i, uint64(n168)) i-- dAtA[i] = 0x32 if len(m.Id) > 0 { @@ -27170,12 +27993,12 @@ func (m *TunnelConnectionSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x22 } - n175, err175 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) - if err175 != nil { - return 0, err175 + n177, err177 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) + if err177 != nil { + return 0, err177 } - i -= n175 - i = encodeVarintTypes(dAtA, i, uint64(n175)) + i -= n177 + i = encodeVarintTypes(dAtA, i, uint64(n177)) i-- dAtA[i] = 0x1a if len(m.ProxyName) > 0 { @@ -27267,12 +28090,12 @@ func (m *AcquireSemaphoreRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x2a } - n176, err176 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err176 != nil { - return 0, err176 + n178, err178 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err178 != nil { + return 0, err178 } - i -= n176 - i = encodeVarintTypes(dAtA, i, uint64(n176)) + i -= n178 + i = encodeVarintTypes(dAtA, i, uint64(n178)) i-- dAtA[i] = 0x22 if m.MaxLeases != 0 { @@ -27321,12 +28144,12 @@ func (m *SemaphoreLease) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n177, err177 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err177 != nil { - return 0, err177 + n179, err179 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err179 != nil { + return 0, err179 } - i -= n177 - i = encodeVarintTypes(dAtA, i, uint64(n177)) + i -= n179 + i = encodeVarintTypes(dAtA, i, uint64(n179)) i-- dAtA[i] = 0x2a if len(m.LeaseID) > 0 { @@ -27384,12 +28207,12 @@ func (m *SemaphoreLeaseRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - n178, err178 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err178 != nil { - return 0, err178 + n180, err180 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err180 != nil { + return 0, err180 } - i -= n178 - i = encodeVarintTypes(dAtA, i, uint64(n178)) + i -= n180 + i = encodeVarintTypes(dAtA, i, uint64(n180)) i-- dAtA[i] = 0x12 if len(m.LeaseID) > 0 { @@ -27627,28 +28450,28 @@ func (m *WebSessionSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x48 } - n184, err184 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LoginTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LoginTime):]) - if err184 != nil { - return 0, err184 + n186, err186 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LoginTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LoginTime):]) + if err186 != nil { + return 0, err186 } - i -= n184 - i = encodeVarintTypes(dAtA, i, uint64(n184)) + i -= n186 + i = encodeVarintTypes(dAtA, i, uint64(n186)) i-- dAtA[i] = 0x42 - n185, err185 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err185 != nil { - return 0, err185 + n187, err187 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err187 != nil { + return 0, err187 } - i -= n185 - i = encodeVarintTypes(dAtA, i, uint64(n185)) + i -= n187 + i = encodeVarintTypes(dAtA, i, uint64(n187)) i-- dAtA[i] = 0x3a - n186, err186 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.BearerTokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.BearerTokenExpires):]) - if err186 != nil { - return 0, err186 + n188, err188 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.BearerTokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.BearerTokenExpires):]) + if err188 != nil { + return 0, err188 } - i -= n186 - i = encodeVarintTypes(dAtA, i, uint64(n186)) + i -= n188 + i = encodeVarintTypes(dAtA, i, uint64(n188)) i-- dAtA[i] = 0x32 if len(m.BearerToken) > 0 { @@ -27840,20 +28663,20 @@ func (m *SAMLSessionData) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - n187, err187 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExpireTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpireTime):]) - if err187 != nil { - return 0, err187 + n189, err189 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExpireTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpireTime):]) + if err189 != nil { + return 0, err189 } - i -= n187 - i = encodeVarintTypes(dAtA, i, uint64(n187)) + i -= n189 + i = encodeVarintTypes(dAtA, i, uint64(n189)) i-- dAtA[i] = 0x1a - n188, err188 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreateTime):]) - if err188 != nil { - return 0, err188 + n190, err190 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreateTime):]) + if err190 != nil { + return 0, err190 } - i -= n188 - i = encodeVarintTypes(dAtA, i, uint64(n188)) + i -= n190 + i = encodeVarintTypes(dAtA, i, uint64(n190)) i-- dAtA[i] = 0x12 if len(m.ID) > 0 { @@ -28135,12 +28958,12 @@ func (m *RemoteClusterStatusV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n192, err192 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) - if err192 != nil { - return 0, err192 + n194, err194 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) + if err194 != nil { + return 0, err194 } - i -= n192 - i = encodeVarintTypes(dAtA, i, uint64(n192)) + i -= n194 + i = encodeVarintTypes(dAtA, i, uint64(n194)) i-- dAtA[i] = 0x12 if len(m.Connection) > 0 { @@ -30424,12 +31247,12 @@ func (m *GithubAuthRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x62 } if m.Expires != nil { - n221, err221 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err221 != nil { - return 0, err221 + n223, err223 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err223 != nil { + return 0, err223 } - i -= n221 - i = encodeVarintTypes(dAtA, i, uint64(n221)) + i -= n223 + i = encodeVarintTypes(dAtA, i, uint64(n223)) i-- dAtA[i] = 0x5a } @@ -31441,21 +32264,21 @@ func (m *LockSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x2a } - n239, err239 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):]) - if err239 != nil { - return 0, err239 + n241, err241 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):]) + if err241 != nil { + return 0, err241 } - i -= n239 - i = encodeVarintTypes(dAtA, i, uint64(n239)) + i -= n241 + i = encodeVarintTypes(dAtA, i, uint64(n241)) i-- dAtA[i] = 0x22 if m.Expires != nil { - n240, err240 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err240 != nil { - return 0, err240 + n242, err242 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err242 != nil { + return 0, err242 } - i -= n240 - i = encodeVarintTypes(dAtA, i, uint64(n240)) + i -= n242 + i = encodeVarintTypes(dAtA, i, uint64(n242)) i-- dAtA[i] = 0x1a } @@ -32001,12 +32824,12 @@ func (m *RegisterUsingTokenRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro copy(dAtA[i:], m.XXX_unrecognized) } if m.Expires != nil { - n248, err248 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err248 != nil { - return 0, err248 + n250, err250 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err250 != nil { + return 0, err250 } - i -= n248 - i = encodeVarintTypes(dAtA, i, uint64(n248)) + i -= n250 + i = encodeVarintTypes(dAtA, i, uint64(n250)) i-- dAtA[i] = 0x62 } @@ -32186,12 +33009,12 @@ func (m *RecoveryCodesSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n251, err251 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err251 != nil { - return 0, err251 + n253, err253 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err253 != nil { + return 0, err253 } - i -= n251 - i = encodeVarintTypes(dAtA, i, uint64(n251)) + i -= n253 + i = encodeVarintTypes(dAtA, i, uint64(n253)) i-- dAtA[i] = 0x12 if len(m.Codes) > 0 { @@ -32551,20 +33374,20 @@ func (m *SessionTrackerSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n255, err255 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err255 != nil { - return 0, err255 + n257, err257 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err257 != nil { + return 0, err257 } - i -= n255 - i = encodeVarintTypes(dAtA, i, uint64(n255)) + i -= n257 + i = encodeVarintTypes(dAtA, i, uint64(n257)) i-- dAtA[i] = 0x2a - n256, err256 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err256 != nil { - return 0, err256 + n258, err258 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err258 != nil { + return 0, err258 } - i -= n256 - i = encodeVarintTypes(dAtA, i, uint64(n256)) + i -= n258 + i = encodeVarintTypes(dAtA, i, uint64(n258)) i-- dAtA[i] = 0x22 if m.State != 0 { @@ -32668,12 +33491,12 @@ func (m *Participant) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n257, err257 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastActive, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastActive):]) - if err257 != nil { - return 0, err257 + n259, err259 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastActive, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastActive):]) + if err259 != nil { + return 0, err259 } - i -= n257 - i = encodeVarintTypes(dAtA, i, uint64(n257)) + i -= n259 + i = encodeVarintTypes(dAtA, i, uint64(n259)) i-- dAtA[i] = 0x22 if len(m.Mode) > 0 { @@ -33234,6 +34057,16 @@ func (m *DatabaseResourceMatcher) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.AWS.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 if m.Labels != nil { { size := m.Labels.Size() @@ -33249,6 +34082,47 @@ func (m *DatabaseResourceMatcher) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *ResourceMatcherAWS) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceMatcherAWS) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceMatcherAWS) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.ExternalID) > 0 { + i -= len(m.ExternalID) + copy(dAtA[i:], m.ExternalID) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ExternalID))) + i-- + dAtA[i] = 0x12 + } + if len(m.AssumeRoleARN) > 0 { + i -= len(m.AssumeRoleARN) + copy(dAtA[i:], m.AssumeRoleARN) + i = encodeVarintTypes(dAtA, i, uint64(len(m.AssumeRoleARN))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *ClusterAlert) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -33320,12 +34194,12 @@ func (m *ClusterAlertSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n269, err269 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err269 != nil { - return 0, err269 + n272, err272 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err272 != nil { + return 0, err272 } - i -= n269 - i = encodeVarintTypes(dAtA, i, uint64(n269)) + i -= n272 + i = encodeVarintTypes(dAtA, i, uint64(n272)) i-- dAtA[i] = 0x1a if len(m.Message) > 0 { @@ -33455,12 +34329,12 @@ func (m *AlertAcknowledgement) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n270, err270 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err270 != nil { - return 0, err270 + n273, err273 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err273 != nil { + return 0, err273 } - i -= n270 - i = encodeVarintTypes(dAtA, i, uint64(n270)) + i -= n273 + i = encodeVarintTypes(dAtA, i, uint64(n273)) i-- dAtA[i] = 0x22 if len(m.Reason) > 0 { @@ -33877,6 +34751,27 @@ func (m *PluginSpecV1_Jamf) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } +func (m *PluginSpecV1_PagerDuty) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PluginSpecV1_PagerDuty) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.PagerDuty != nil { + { + size, err := m.PagerDuty.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + return len(dAtA) - i, nil +} func (m *PluginSlackAccessSettings) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -33970,6 +34865,47 @@ func (m *PluginOpsgenieAccessSettings) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *PluginPagerDutySettings) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PluginPagerDutySettings) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PluginPagerDutySettings) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.ApiEndpoint) > 0 { + i -= len(m.ApiEndpoint) + copy(dAtA[i:], m.ApiEndpoint) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ApiEndpoint))) + i-- + dAtA[i] = 0x12 + } + if len(m.UserEmail) > 0 { + i -= len(m.UserEmail) + copy(dAtA[i:], m.UserEmail) + i = encodeVarintTypes(dAtA, i, uint64(len(m.UserEmail))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *PluginOpenAISettings) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -34427,12 +35363,12 @@ func (m *PluginOAuth2AccessTokenCredentials) MarshalToSizedBuffer(dAtA []byte) ( i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n288, err288 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err288 != nil { - return 0, err288 + n292, err292 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err292 != nil { + return 0, err292 } - i -= n288 - i = encodeVarintTypes(dAtA, i, uint64(n288)) + i -= n292 + i = encodeVarintTypes(dAtA, i, uint64(n292)) i-- dAtA[i] = 0x1a if len(m.RefreshToken) > 0 { @@ -35220,20 +36156,20 @@ func (m *ScheduledAgentUpgradeWindow) MarshalToSizedBuffer(dAtA []byte) (int, er i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n302, err302 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Stop, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Stop):]) - if err302 != nil { - return 0, err302 + n306, err306 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Stop, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Stop):]) + if err306 != nil { + return 0, err306 } - i -= n302 - i = encodeVarintTypes(dAtA, i, uint64(n302)) + i -= n306 + i = encodeVarintTypes(dAtA, i, uint64(n306)) i-- dAtA[i] = 0x12 - n303, err303 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Start):]) - if err303 != nil { - return 0, err303 + n307, err307 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Start):]) + if err307 != nil { + return 0, err307 } - i -= n303 - i = encodeVarintTypes(dAtA, i, uint64(n303)) + i -= n307 + i = encodeVarintTypes(dAtA, i, uint64(n307)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -35304,6 +36240,16 @@ func (m *UserGroupV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 { size, err := m.ResourceHeader.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -35317,6 +36263,42 @@ func (m *UserGroupV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *UserGroupSpecV1) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UserGroupSpecV1) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UserGroupSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Applications) > 0 { + for iNdEx := len(m.Applications) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Applications[iNdEx]) + copy(dAtA[i:], m.Applications[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Applications[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *OktaImportRuleSpecV1) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -35614,12 +36596,12 @@ func (m *OktaAssignmentSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x30 } - n309, err309 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastTransition, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastTransition):]) - if err309 != nil { - return 0, err309 + n314, err314 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastTransition, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastTransition):]) + if err314 != nil { + return 0, err314 } - i -= n309 - i = encodeVarintTypes(dAtA, i, uint64(n309)) + i -= n314 + i = encodeVarintTypes(dAtA, i, uint64(n314)) i-- dAtA[i] = 0x2a if m.Status != 0 { @@ -35627,12 +36609,12 @@ func (m *OktaAssignmentSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x20 } - n310, err310 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CleanupTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CleanupTime):]) - if err310 != nil { - return 0, err310 + n315, err315 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CleanupTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CleanupTime):]) + if err315 != nil { + return 0, err315 } - i -= n310 - i = encodeVarintTypes(dAtA, i, uint64(n310)) + i -= n315 + i = encodeVarintTypes(dAtA, i, uint64(n315)) i-- dAtA[i] = 0x1a if len(m.Targets) > 0 { @@ -36424,6 +37406,393 @@ func (m *MessageWithHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *AWSMatcher) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AWSMatcher) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AWSMatcher) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.SSM != nil { + { + size, err := m.SSM.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if m.Params != nil { + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + { + size := m.Tags.Size() + i -= size + if _, err := m.Tags.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if m.AssumeRole != nil { + { + size, err := m.AssumeRole.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.Regions) > 0 { + for iNdEx := len(m.Regions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Regions[iNdEx]) + copy(dAtA[i:], m.Regions[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Regions[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Types) > 0 { + for iNdEx := len(m.Types) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Types[iNdEx]) + copy(dAtA[i:], m.Types[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Types[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *AssumeRole) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AssumeRole) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AssumeRole) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.ExternalID) > 0 { + i -= len(m.ExternalID) + copy(dAtA[i:], m.ExternalID) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ExternalID))) + i-- + dAtA[i] = 0x12 + } + if len(m.RoleARN) > 0 { + i -= len(m.RoleARN) + copy(dAtA[i:], m.RoleARN) + i = encodeVarintTypes(dAtA, i, uint64(len(m.RoleARN))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *InstallerParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InstallerParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *InstallerParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.PublicProxyAddr) > 0 { + i -= len(m.PublicProxyAddr) + copy(dAtA[i:], m.PublicProxyAddr) + i = encodeVarintTypes(dAtA, i, uint64(len(m.PublicProxyAddr))) + i-- + dAtA[i] = 0x32 + } + if len(m.SSHDConfig) > 0 { + i -= len(m.SSHDConfig) + copy(dAtA[i:], m.SSHDConfig) + i = encodeVarintTypes(dAtA, i, uint64(len(m.SSHDConfig))) + i-- + dAtA[i] = 0x2a + } + if m.InstallTeleport { + i-- + if m.InstallTeleport { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if len(m.ScriptName) > 0 { + i -= len(m.ScriptName) + copy(dAtA[i:], m.ScriptName) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ScriptName))) + i-- + dAtA[i] = 0x1a + } + if len(m.JoinToken) > 0 { + i -= len(m.JoinToken) + copy(dAtA[i:], m.JoinToken) + i = encodeVarintTypes(dAtA, i, uint64(len(m.JoinToken))) + i-- + dAtA[i] = 0x12 + } + if len(m.JoinMethod) > 0 { + i -= len(m.JoinMethod) + copy(dAtA[i:], m.JoinMethod) + i = encodeVarintTypes(dAtA, i, uint64(len(m.JoinMethod))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AWSSSM) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AWSSSM) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AWSSSM) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.DocumentName) > 0 { + i -= len(m.DocumentName) + copy(dAtA[i:], m.DocumentName) + i = encodeVarintTypes(dAtA, i, uint64(len(m.DocumentName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AzureMatcher) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AzureMatcher) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AzureMatcher) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Params != nil { + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + { + size := m.ResourceTags.Size() + i -= size + if _, err := m.ResourceTags.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if len(m.Regions) > 0 { + for iNdEx := len(m.Regions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Regions[iNdEx]) + copy(dAtA[i:], m.Regions[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Regions[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if len(m.Types) > 0 { + for iNdEx := len(m.Types) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Types[iNdEx]) + copy(dAtA[i:], m.Types[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Types[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.ResourceGroups) > 0 { + for iNdEx := len(m.ResourceGroups) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ResourceGroups[iNdEx]) + copy(dAtA[i:], m.ResourceGroups[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ResourceGroups[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Subscriptions) > 0 { + for iNdEx := len(m.Subscriptions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Subscriptions[iNdEx]) + copy(dAtA[i:], m.Subscriptions[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Subscriptions[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *GCPMatcher) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GCPMatcher) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GCPMatcher) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.ProjectIDs) > 0 { + for iNdEx := len(m.ProjectIDs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ProjectIDs[iNdEx]) + copy(dAtA[i:], m.ProjectIDs[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ProjectIDs[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + { + size := m.Tags.Size() + i -= size + if _, err := m.Tags.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.Locations) > 0 { + for iNdEx := len(m.Locations) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Locations[iNdEx]) + copy(dAtA[i:], m.Locations[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Locations[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Types) > 0 { + for iNdEx := len(m.Types) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Types[iNdEx]) + copy(dAtA[i:], m.Types[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Types[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { offset -= sovTypes(v) base := offset @@ -36771,6 +38140,8 @@ func (m *DatabaseSpecV3) Size() (n int) { l = m.AdminUser.Size() n += 1 + l + sovTypes(uint64(l)) } + l = m.MongoAtlas.Size() + n += 1 + l + sovTypes(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -36857,6 +38228,8 @@ func (m *AWS) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + l = m.OpenSearch.Size() + n += 1 + l + sovTypes(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -37036,6 +38409,30 @@ func (m *RedshiftServerless) Size() (n int) { return n } +func (m *OpenSearch) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DomainName) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.DomainID) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.EndpointType) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *GCPCloudSQL) Size() (n int) { if m == nil { return 0 @@ -37172,6 +38569,22 @@ func (m *MySQLOptions) Size() (n int) { return n } +func (m *MongoAtlas) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *InstanceV1) Size() (n int) { if m == nil { return 0 @@ -37542,6 +38955,12 @@ func (m *AppSpecV3) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + if len(m.UserGroups) > 0 { + for _, s := range m.UserGroups { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -38785,6 +40204,9 @@ func (m *AuthPreferenceSpecV2) Size() (n int) { l = m.AllowHeadless.Size() n += 1 + l + sovTypes(uint64(l)) } + if m.DefaultSessionTTL != 0 { + n += 2 + sovTypes(uint64(m.DefaultSessionTTL)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -39651,6 +41073,9 @@ func (m *RoleOptions) Size() (n int) { l = m.CreateDatabaseUser.Size() n += 2 + l + sovTypes(uint64(l)) } + if m.CreateHostUserMode != 0 { + n += 2 + sovTypes(uint64(m.CreateHostUserMode)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -43397,6 +44822,28 @@ func (m *DatabaseResourceMatcher) Size() (n int) { l = m.Labels.Size() n += 1 + l + sovTypes(uint64(l)) } + l = m.AWS.Size() + n += 1 + l + sovTypes(uint64(l)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ResourceMatcherAWS) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AssumeRoleARN) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.ExternalID) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -43694,6 +45141,18 @@ func (m *PluginSpecV1_Jamf) Size() (n int) { } return n } +func (m *PluginSpecV1_PagerDuty) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PagerDuty != nil { + l = m.PagerDuty.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} func (m *PluginSlackAccessSettings) Size() (n int) { if m == nil { return 0 @@ -43742,6 +45201,26 @@ func (m *PluginOpsgenieAccessSettings) Size() (n int) { return n } +func (m *PluginPagerDutySettings) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.UserEmail) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.ApiEndpoint) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *PluginOpenAISettings) Size() (n int) { if m == nil { return 0 @@ -44348,6 +45827,26 @@ func (m *UserGroupV1) Size() (n int) { _ = l l = m.ResourceHeader.Size() n += 1 + l + sovTypes(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovTypes(uint64(l)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *UserGroupSpecV1) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Applications) > 0 { + for _, s := range m.Applications { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -44841,6 +46340,189 @@ func (m *MessageWithHeader) Size() (n int) { return n } +func (m *AWSMatcher) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Types) > 0 { + for _, s := range m.Types { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Regions) > 0 { + for _, s := range m.Regions { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.AssumeRole != nil { + l = m.AssumeRole.Size() + n += 1 + l + sovTypes(uint64(l)) + } + l = m.Tags.Size() + n += 1 + l + sovTypes(uint64(l)) + if m.Params != nil { + l = m.Params.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if m.SSM != nil { + l = m.SSM.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *AssumeRole) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RoleARN) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.ExternalID) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *InstallerParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.JoinMethod) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.JoinToken) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.ScriptName) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.InstallTeleport { + n += 2 + } + l = len(m.SSHDConfig) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.PublicProxyAddr) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *AWSSSM) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DocumentName) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *AzureMatcher) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Subscriptions) > 0 { + for _, s := range m.Subscriptions { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.ResourceGroups) > 0 { + for _, s := range m.ResourceGroups { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Types) > 0 { + for _, s := range m.Types { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Regions) > 0 { + for _, s := range m.Regions { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + l = m.ResourceTags.Size() + n += 1 + l + sovTypes(uint64(l)) + if m.Params != nil { + l = m.Params.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *GCPMatcher) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Types) > 0 { + for _, s := range m.Types { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Locations) > 0 { + for _, s := range m.Locations { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + l = m.Tags.Size() + n += 1 + l + sovTypes(uint64(l)) + if len(m.ProjectIDs) > 0 { + for _, s := range m.ProjectIDs { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovTypes(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -47626,6 +49308,39 @@ func (m *DatabaseSpecV3) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MongoAtlas", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MongoAtlas.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -48333,6 +50048,39 @@ func (m *AWS) Unmarshal(dAtA []byte) error { } m.AssumeRoleARN = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OpenSearch", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.OpenSearch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -49380,7 +51128,7 @@ func (m *RedshiftServerless) Unmarshal(dAtA []byte) error { } return nil } -func (m *GCPCloudSQL) Unmarshal(dAtA []byte) error { +func (m *OpenSearch) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -49403,15 +51151,15 @@ func (m *GCPCloudSQL) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GCPCloudSQL: wiretype end group for non-group") + return fmt.Errorf("proto: OpenSearch: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GCPCloudSQL: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: OpenSearch: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProjectID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DomainName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -49439,11 +51187,11 @@ func (m *GCPCloudSQL) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProjectID = string(dAtA[iNdEx:postIndex]) + m.DomainName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InstanceID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DomainID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -49471,7 +51219,39 @@ func (m *GCPCloudSQL) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.InstanceID = string(dAtA[iNdEx:postIndex]) + m.DomainID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EndpointType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EndpointType = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -49495,7 +51275,7 @@ func (m *GCPCloudSQL) Unmarshal(dAtA []byte) error { } return nil } -func (m *Azure) Unmarshal(dAtA []byte) error { +func (m *GCPCloudSQL) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -49518,15 +51298,15 @@ func (m *Azure) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Azure: wiretype end group for non-group") + return fmt.Errorf("proto: GCPCloudSQL: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Azure: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GCPCloudSQL: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProjectID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -49554,147 +51334,11 @@ func (m *Azure) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.ProjectID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ResourceID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Redis", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Redis.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IsFlexiServer", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.IsFlexiServer = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AzureRedis) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AzureRedis: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AzureRedis: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClusteringPolicy", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field InstanceID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -49722,7 +51366,7 @@ func (m *AzureRedis) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ClusteringPolicy = string(dAtA[iNdEx:postIndex]) + m.InstanceID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -49746,7 +51390,7 @@ func (m *AzureRedis) Unmarshal(dAtA []byte) error { } return nil } -func (m *AD) Unmarshal(dAtA []byte) error { +func (m *Azure) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -49769,15 +51413,15 @@ func (m *AD) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AD: wiretype end group for non-group") + return fmt.Errorf("proto: Azure: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AD: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Azure: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field KeytabFile", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -49805,11 +51449,262 @@ func (m *AD) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.KeytabFile = string(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Krb5File", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResourceID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Redis", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Redis.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsFlexiServer", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsFlexiServer = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AzureRedis) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AzureRedis: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AzureRedis: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClusteringPolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClusteringPolicy = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AD) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AD: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AD: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeytabFile", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeytabFile = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Krb5File", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -50206,6 +52101,89 @@ func (m *MySQLOptions) Unmarshal(dAtA []byte) error { } return nil } +func (m *MongoAtlas) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MongoAtlas: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MongoAtlas: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *InstanceV1) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -52891,6 +54869,38 @@ func (m *AppSpecV3) Unmarshal(dAtA []byte) error { } m.Cloud = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserGroups", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UserGroups = append(m.UserGroups, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -60767,6 +62777,25 @@ func (m *AuthPreferenceSpecV2) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultSessionTTL", wireType) + } + m.DefaultSessionTTL = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DefaultSessionTTL |= Duration(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -66814,6 +68843,25 @@ func (m *RoleOptions) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 28: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CreateHostUserMode", wireType) + } + m.CreateHostUserMode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CreateHostUserMode |= CreateHostUserMode(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -91451,6 +93499,154 @@ func (m *DatabaseResourceMatcher) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AWS", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.AWS.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResourceMatcherAWS) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResourceMatcherAWS: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceMatcherAWS: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssumeRoleARN", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssumeRoleARN = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExternalID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExternalID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -93219,62 +95415,11 @@ func (m *PluginSpecV1) Unmarshal(dAtA []byte) error { } m.Settings = &PluginSpecV1_Jamf{v} iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PluginSlackAccessSettings) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PluginSlackAccessSettings: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PluginSlackAccessSettings: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FallbackChannel", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PagerDuty", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -93284,23 +95429,109 @@ func (m *PluginSlackAccessSettings) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - m.FallbackChannel = string(dAtA[iNdEx:postIndex]) + v := &PluginPagerDutySettings{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Settings = &PluginSpecV1_PagerDuty{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PluginSlackAccessSettings) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PluginSlackAccessSettings: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PluginSlackAccessSettings: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FallbackChannel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FallbackChannel = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -93503,6 +95734,121 @@ func (m *PluginOpsgenieAccessSettings) Unmarshal(dAtA []byte) error { } return nil } +func (m *PluginPagerDutySettings) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PluginPagerDutySettings: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PluginPagerDutySettings: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserEmail", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UserEmail = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApiEndpoint", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ApiEndpoint = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *PluginOpenAISettings) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -96659,6 +99005,39 @@ func (m *UserGroupV1) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -96681,7 +99060,7 @@ func (m *UserGroupV1) Unmarshal(dAtA []byte) error { } return nil } -func (m *OktaImportRuleSpecV1) Unmarshal(dAtA []byte) error { +func (m *UserGroupSpecV1) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -96704,36 +99083,17 @@ func (m *OktaImportRuleSpecV1) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: OktaImportRuleSpecV1: wiretype end group for non-group") + return fmt.Errorf("proto: UserGroupSpecV1: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: OktaImportRuleSpecV1: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: UserGroupSpecV1: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) - } - m.Priority = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Priority |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Mappings", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Applications", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -96743,25 +99103,127 @@ func (m *OktaImportRuleSpecV1) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - m.Mappings = append(m.Mappings, &OktaImportRuleMappingV1{}) - if err := m.Mappings[len(m.Mappings)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Applications = append(m.Applications, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OktaImportRuleSpecV1) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: OktaImportRuleSpecV1: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OktaImportRuleSpecV1: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) + } + m.Priority = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Priority |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Mappings", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Mappings = append(m.Mappings, &OktaImportRuleMappingV1{}) + if err := m.Mappings[len(m.Mappings)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -98881,7 +101343,1282 @@ func (m *WatchStatusSpecV1) Unmarshal(dAtA []byte) error { } return nil } -func (m *ServerInfoV1) Unmarshal(dAtA []byte) error { +func (m *ServerInfoV1) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ServerInfoV1: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ServerInfoV1: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubKind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SubKind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ServerInfoSpecV1) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ServerInfoSpecV1: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ServerInfoSpecV1: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AWS", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AWS == nil { + m.AWS = &ServerInfoSpecV1_AWSInfo{} + } + if err := m.AWS.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ServerInfoSpecV1_AWSInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AWSInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AWSInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccountID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InstanceID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.InstanceID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JamfSpecV1: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JamfSpecV1: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Enabled = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncDelay", wireType) + } + m.SyncDelay = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SyncDelay |= Duration(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApiEndpoint", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ApiEndpoint = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Username = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Password = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Inventory", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Inventory = append(m.Inventory, &JamfInventoryEntry{}) + if err := m.Inventory[len(m.Inventory)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JamfInventoryEntry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JamfInventoryEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JamfInventoryEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FilterRsql", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FilterRsql = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncPeriodPartial", wireType) + } + m.SyncPeriodPartial = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SyncPeriodPartial |= Duration(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncPeriodFull", wireType) + } + m.SyncPeriodFull = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SyncPeriodFull |= Duration(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OnMissing", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OnMissing = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MessageWithHeader) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MessageWithHeader: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MessageWithHeader: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceHeader", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ResourceHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AWSMatcher) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AWSMatcher: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AWSMatcher: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Types", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Types = append(m.Types, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Regions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Regions = append(m.Regions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssumeRole", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AssumeRole == nil { + m.AssumeRole = &AssumeRole{} + } + if err := m.AssumeRole.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Tags.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Params == nil { + m.Params = &InstallerParams{} + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SSM", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SSM == nil { + m.SSM = &AWSSSM{} + } + if err := m.SSM.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AssumeRole) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AssumeRole: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AssumeRole: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RoleARN", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RoleARN = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExternalID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExternalID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *InstallerParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -98904,15 +102641,15 @@ func (m *ServerInfoV1) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ServerInfoV1: wiretype end group for non-group") + return fmt.Errorf("proto: InstallerParams: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ServerInfoV1: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: InstallerParams: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JoinMethod", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -98940,11 +102677,11 @@ func (m *ServerInfoV1) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Kind = string(dAtA[iNdEx:postIndex]) + m.JoinMethod = JoinMethod(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SubKind", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JoinToken", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -98972,11 +102709,11 @@ func (m *ServerInfoV1) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SubKind = string(dAtA[iNdEx:postIndex]) + m.JoinToken = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ScriptName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99004,13 +102741,13 @@ func (m *ServerInfoV1) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Version = string(dAtA[iNdEx:postIndex]) + m.ScriptName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InstallTeleport", wireType) } - var msglen int + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -99020,30 +102757,17 @@ func (m *ServerInfoV1) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex + m.InstallTeleport = bool(v != 0) case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SSHDConfig", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -99053,81 +102777,29 @@ func (m *ServerInfoV1) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.SSHDConfig = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ServerInfoSpecV1) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ServerInfoSpecV1: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ServerInfoSpecV1: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AWS", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PublicProxyAddr", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -99137,27 +102809,23 @@ func (m *ServerInfoSpecV1) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - if m.AWS == nil { - m.AWS = &ServerInfoSpecV1_AWSInfo{} - } - if err := m.AWS.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.PublicProxyAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -99181,7 +102849,7 @@ func (m *ServerInfoSpecV1) Unmarshal(dAtA []byte) error { } return nil } -func (m *ServerInfoSpecV1_AWSInfo) Unmarshal(dAtA []byte) error { +func (m *AWSSSM) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -99204,47 +102872,15 @@ func (m *ServerInfoSpecV1_AWSInfo) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AWSInfo: wiretype end group for non-group") + return fmt.Errorf("proto: AWSSSM: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AWSInfo: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AWSSSM: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccountID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AccountID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InstanceID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DocumentName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99272,7 +102908,7 @@ func (m *ServerInfoSpecV1_AWSInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.InstanceID = string(dAtA[iNdEx:postIndex]) + m.DocumentName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -99296,7 +102932,7 @@ func (m *ServerInfoSpecV1_AWSInfo) Unmarshal(dAtA []byte) error { } return nil } -func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { +func (m *AzureMatcher) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -99319,17 +102955,17 @@ func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JamfSpecV1: wiretype end group for non-group") + return fmt.Errorf("proto: AzureMatcher: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JamfSpecV1: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AzureMatcher: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subscriptions", wireType) } - var v int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -99339,15 +102975,27 @@ func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.Enabled = bool(v != 0) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subscriptions = append(m.Subscriptions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceGroups", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99375,30 +103023,11 @@ func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.ResourceGroups = append(m.ResourceGroups, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncDelay", wireType) - } - m.SyncDelay = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.SyncDelay |= Duration(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ApiEndpoint", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Types", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99426,11 +103055,11 @@ func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ApiEndpoint = string(dAtA[iNdEx:postIndex]) + m.Types = append(m.Types, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 5: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Regions", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99458,13 +103087,13 @@ func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Username = string(dAtA[iNdEx:postIndex]) + m.Regions = append(m.Regions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 6: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceTags", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -99474,27 +103103,28 @@ func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - m.Password = string(dAtA[iNdEx:postIndex]) + if err := m.ResourceTags.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 7: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Inventory", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -99521,8 +103151,10 @@ func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Inventory = append(m.Inventory, &JamfInventoryEntry{}) - if err := m.Inventory[len(m.Inventory)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Params == nil { + m.Params = &InstallerParams{} + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -99548,7 +103180,7 @@ func (m *JamfSpecV1) Unmarshal(dAtA []byte) error { } return nil } -func (m *JamfInventoryEntry) Unmarshal(dAtA []byte) error { +func (m *GCPMatcher) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -99571,15 +103203,15 @@ func (m *JamfInventoryEntry) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JamfInventoryEntry: wiretype end group for non-group") + return fmt.Errorf("proto: GCPMatcher: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JamfInventoryEntry: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GCPMatcher: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FilterRsql", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Types", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -99607,13 +103239,13 @@ func (m *JamfInventoryEntry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.FilterRsql = string(dAtA[iNdEx:postIndex]) + m.Types = append(m.Types, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncPeriodPartial", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Locations", wireType) } - m.SyncPeriodPartial = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -99623,35 +103255,29 @@ func (m *JamfInventoryEntry) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.SyncPeriodPartial |= Duration(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncPeriodFull", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes } - m.SyncPeriodFull = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.SyncPeriodFull |= Duration(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes } - case 4: + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Locations = append(m.Locations, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OnMissing", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -99661,80 +103287,30 @@ func (m *JamfInventoryEntry) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - m.OnMissing = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { + if err := m.Tags.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MessageWithHeader) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MessageWithHeader: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MessageWithHeader: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + iNdEx = postIndex + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceHeader", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProjectIDs", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -99744,24 +103320,23 @@ func (m *MessageWithHeader) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ResourceHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ProjectIDs = append(m.ProjectIDs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex diff --git a/api/types/usergroup.go b/api/types/usergroup.go index d1ca3421d3d18..afaa415361823 100644 --- a/api/types/usergroup.go +++ b/api/types/usergroup.go @@ -28,16 +28,22 @@ import ( // UserGroup specifies an externally sourced group. type UserGroup interface { ResourceWithLabels + + // GetApplications will return a list of application IDs associated with the user group. + GetApplications() []string + // SetApplications will set the list of application IDs associated with the user group. + SetApplications([]string) } var _ ResourceWithLabels = (*UserGroupV1)(nil) // NewUserGroup returns a new UserGroup. -func NewUserGroup(metadata Metadata) (UserGroup, error) { +func NewUserGroup(metadata Metadata, spec UserGroupSpecV1) (UserGroup, error) { g := &UserGroupV1{ ResourceHeader: ResourceHeader{ Metadata: metadata, }, + Spec: spec, } if err := g.CheckAndSetDefaults(); err != nil { return nil, trace.Wrap(err) @@ -45,6 +51,16 @@ func NewUserGroup(metadata Metadata) (UserGroup, error) { return g, nil } +// GetApplications will return a list of application IDs associated with the user group. +func (g *UserGroupV1) GetApplications() []string { + return g.Spec.Applications +} + +// SetApplications will set the list of application IDs associated with the user group. +func (g *UserGroupV1) SetApplications(applications []string) { + g.Spec.Applications = applications +} + // String returns the user group string representation. func (g *UserGroupV1) String() string { return fmt.Sprintf("UserGroupV1(Name=%v, Labels=%v)", diff --git a/api/types/usergroup_test.go b/api/types/usergroup_test.go index 6ae61f2334717..69f95636bf48d 100644 --- a/api/types/usergroup_test.go +++ b/api/types/usergroup_test.go @@ -26,7 +26,7 @@ func TestUserGroupMatchSearch(t *testing.T) { ug, err := NewUserGroup(Metadata{ Name: "test", Description: "description", - }) + }, UserGroupSpecV1{}) require.NoError(t, err) // Match against the name diff --git a/api/utils/atlas/endpoints.go b/api/utils/atlas/endpoints.go new file mode 100644 index 0000000000000..1a3484ce401a1 --- /dev/null +++ b/api/utils/atlas/endpoints.go @@ -0,0 +1,53 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package atlas + +import ( + "net/url" + "strings" + + "github.com/gravitational/trace" +) + +// IsAtlasEndpoint returns true if the input URI is an MongoDB Atlas endpoint. +func IsAtlasEndpoint(endpoint string) bool { + return strings.Contains(endpoint, EndpointSuffix) +} + +// ParseAtlasEndpoint extracts the database name from the Atlas endpoint. +func ParseAtlasEndpoint(endpoint string) (string, error) { + // Add a temporary schema to make a valid URL for url.Parse if schema is + // not found. + if !strings.Contains(endpoint, "://") { + endpoint = "schema://" + endpoint + } + + parsed, err := url.Parse(endpoint) + if err != nil { + return "", trace.Wrap(err) + } + + parts := strings.Split(parsed.Hostname(), ".") + if !IsAtlasEndpoint(endpoint) || len(parts) < 3 { + return "", trace.BadParameter("failed to parse %q as Mongo Atlas endpoint", endpoint) + } + + return parts[0], nil +} + +const ( + // EndpointSuffix is the databases endpoint suffix. + EndpointSuffix = ".mongodb.net" +) diff --git a/api/utils/atlas/endpoints_test.go b/api/utils/atlas/endpoints_test.go new file mode 100644 index 0000000000000..76e07ca99ac91 --- /dev/null +++ b/api/utils/atlas/endpoints_test.go @@ -0,0 +1,82 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package atlas + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIsAtlasEndpoint(t *testing.T) { + for _, tc := range []struct { + desc string + endpoint string + result bool + }{ + // Valid + {"public endpoint host only", "test.xxxxxxx.mongodb.net", true}, + {"public endpoint", "mongodb://test.xxxxxxx.mongodb.net", true}, + {"public endpoint with srv", "mongodb+srv://test.xxxxxxx.mongodb.net", true}, + {"private link", "mongodb://pl-0-us-east-1-xxxxx.mongodb.net:1024,pl-0-us-east-1-xxxxx.mongodb.net:1025,pl-0-us-east-1-xxxxx.mongodb.net:1026/?ssl=true&authSource=admin&replicaSet=Cluster0-shard-0-shard-0", true}, + {"private link with srv", "mongodb+srv://cluster0-pl-0-xxxxx.mongodb.net", true}, + {"azure private link", "mongodb://cluster0-pl-0.xxxxx.azure.mongodb.net", true}, + {"azure private link with srv", "mongodb://pl-0-eastus2.xxxxx.azure.mongodb.net:1024,pl-0-eastus2.xxxxx.azure.mongodb.net:1025,pl-0-eastus2.xxxxx.azure.mongodb.net:1026/?ssl=truereplicaSet=atlas-xxxxxx-shard-0 ", true}, + // Invalid + {"internal name", "mongodb://mongodb", false}, + {"domain name with mongodb", "mongodb://mongodb.company.com", false}, + } { + t.Run(tc.desc, func(t *testing.T) { + require.Equal(t, tc.result, IsAtlasEndpoint(tc.endpoint)) + }) + } +} + +func TestParseAtlasEndpoint(t *testing.T) { + for _, tc := range []struct { + desc string + endpoint string + result string + errAssert require.ErrorAssertionFunc + }{ + // Valid + {"public endpoint host only", "test.xxxxxxx.mongodb.net", "test", require.NoError}, + {"public endpoint", "mongodb://test.xxxxxxx.mongodb.net", "test", require.NoError}, + {"public endpoint with srv", "mongodb+srv://test.xxxxxxx.mongodb.net", "test", require.NoError}, + { + "private link", + "mongodb://pl-0-us-east-1-xxxxx.mongodb.net:1024,pl-0-us-east-1-xxxxx.mongodb.net:1025,pl-0-us-east-1-xxxxx.mongodb.net:1026/?ssl=true&authSource=admin&replicaSet=Cluster0-shard-0-shard-0", + "pl-0-us-east-1-xxxxx", + require.NoError, + }, + {"private link with srv", "mongodb+srv://cluster0-pl-0-xxxxx.mongodb.net", "cluster0-pl-0-xxxxx", require.NoError}, + {"azure private link", "mongodb://cluster0-pl-0.xxxxx.azure.mongodb.net", "cluster0-pl-0", require.NoError}, + { + "azure private link with srv", + "mongodb://pl-0-eastus2.xxxxx.azure.mongodb.net:1024,pl-0-eastus2.xxxxx.azure.mongodb.net:1025,pl-0-eastus2.xxxxx.azure.mongodb.net:1026/?ssl=truereplicaSet=atlas-xxxxxx-shard-0 ", + "pl-0-eastus2", + require.NoError, + }, + // Invalid + {"internal name", "mongodb://mongodb", "", require.Error}, + {"domain name with mongodb", "mongodb://mongodb.company.com", "", require.Error}, + } { + t.Run(tc.desc, func(t *testing.T) { + res, err := ParseAtlasEndpoint(tc.endpoint) + tc.errAssert(t, err) + require.Equal(t, tc.result, res) + }) + } +} diff --git a/api/utils/aws/endpoint.go b/api/utils/aws/endpoint.go index 2b7814da04059..7fef2c2dffa56 100644 --- a/api/utils/aws/endpoint.go +++ b/api/utils/aws/endpoint.go @@ -352,6 +352,13 @@ const ( MemoryDBClusterEndpoint = "cluster" // MemoryDBNodeEndpoint is the endpoint of an individual MemoryDB node. MemoryDBNodeEndpoint = "node" + + // OpenSearchDefaultEndpoint is the default endpoint for domain. + OpenSearchDefaultEndpoint = "default" + // OpenSearchCustomEndpoint is the custom endpoint configured for domain. + OpenSearchCustomEndpoint = "custom" + // OpenSearchVPCEndpoint is the VPC endpoint for domain. + OpenSearchVPCEndpoint = "vpc" ) // ParseElastiCacheEndpoint extracts the details from the provided diff --git a/api/utils/aws/fuzz_test.go b/api/utils/aws/fuzz_test.go index 2623d4d7cadb9..c65d018119ec3 100644 --- a/api/utils/aws/fuzz_test.go +++ b/api/utils/aws/fuzz_test.go @@ -23,6 +23,21 @@ import ( ) func FuzzParseRDSEndpoint(f *testing.F) { + f.Add("") + f.Add(":123") + f.Add("foo:123") + f.Add("foo" + AWSCNEndpointSuffix) + f.Add("a.cluster-custom-b.c." + RDSServiceName + AWSEndpointSuffix) + f.Add("a.cluster-b.c." + RDSServiceName + AWSEndpointSuffix) + f.Add("a.proxy-b.c." + RDSServiceName + AWSEndpointSuffix) + f.Add("a.b.c." + RDSServiceName + AWSEndpointSuffix) + f.Add("a.endpoint.proxy-c.d." + RDSServiceName + AWSEndpointSuffix) + f.Add("a.cluster-custom-b." + RDSServiceName + ".c" + AWSCNEndpointSuffix) + f.Add("a.cluster-b." + RDSServiceName + ".c" + AWSCNEndpointSuffix) + f.Add("a.proxy-b." + RDSServiceName + ".c" + AWSCNEndpointSuffix) + f.Add("a.b." + RDSServiceName + ".c" + AWSCNEndpointSuffix) + f.Add("a.endpoint.proxy-c." + RDSServiceName + ".d" + AWSCNEndpointSuffix) + f.Fuzz(func(t *testing.T, endpoint string) { require.NotPanics(t, func() { _, _ = ParseRDSEndpoint(endpoint) @@ -31,6 +46,13 @@ func FuzzParseRDSEndpoint(f *testing.F) { } func FuzzParseRedshiftEndpoint(f *testing.F) { + f.Add("") + f.Add(":123") + f.Add("foo:123") + f.Add("foo" + AWSCNEndpointSuffix) + f.Add("redshift-cluster-1.abcdefghijklmnop.us-east-1.redshift.amazonaws.com") + f.Add("redshift-cluster-2.abcdefghijklmnop.redshift.cn-north-1.amazonaws.com.cn") + f.Fuzz(func(t *testing.T, endpoint string) { require.NotPanics(t, func() { _, _, _ = ParseRedshiftEndpoint(endpoint) @@ -39,6 +61,29 @@ func FuzzParseRedshiftEndpoint(f *testing.F) { } func FuzzParseElastiCacheEndpoint(f *testing.F) { + f.Add("") + f.Add(":123") + f.Add("foo:123") + f.Add("foo" + AWSEndpointSuffix) + f.Add("foo" + AWSCNEndpointSuffix) + f.Add("clustercfg.b.c.usnw1." + ElastiCacheServiceName + AWSEndpointSuffix) + f.Add("clustercfg.my-redis-shards.xxxxxx.use1.cache.foo:6379") + f.Add("a.b.clustercfg.usnw1." + ElastiCacheServiceName + AWSEndpointSuffix) + f.Add("my-redis-shards.xxxxxx.clustercfg.use1.cache.foo:6379") + f.Add("a.b.0001.usnw1." + ElastiCacheServiceName + AWSEndpointSuffix) + f.Add("my-redis-cluster-001.xxxxxx.0001.use0.cache.foo:6379") + f.Add("my-redis-shards-0001-001.xxxxxx.0001.use0.cache.foo:6379") + f.Add("master.b.c.usnw1." + ElastiCacheServiceName + AWSEndpointSuffix) + f.Add("master.my-redis-cluster.xxxxxx.use1.cache.foo:6379") + f.Add("replica.b.c.usnw1." + ElastiCacheServiceName + AWSEndpointSuffix) + f.Add("replica.my-redis-cluster.xxxxxx.use1.cache.foo:6379") + f.Add("a.b.c.usnw1." + ElastiCacheServiceName + AWSEndpointSuffix) + f.Add("a.b.c.usne1." + ElastiCacheServiceName + AWSEndpointSuffix) + f.Add("a.b.c.usse1." + ElastiCacheServiceName + AWSEndpointSuffix) + f.Add("a.b.c.ussw1." + ElastiCacheServiceName + AWSEndpointSuffix) + f.Add("my-redis-cluster.xxxxxx.ng.0001.use1.cache.foo:6379") + f.Add("my-redis-cluster-ro.xxxxxx.ng.0001.use1.cache.foo:6379") + f.Fuzz(func(t *testing.T, endpoint string) { require.NotPanics(t, func() { _, _ = ParseElastiCacheEndpoint(endpoint) @@ -47,6 +92,13 @@ func FuzzParseElastiCacheEndpoint(f *testing.F) { } func FuzzParseDynamoDBEndpoint(f *testing.F) { + f.Add("") + f.Add(":123") + f.Add("foo:123") + f.Add(DynamoDBServiceName + ".foo" + AWSEndpointSuffix) + f.Add(DynamoDBServiceName + ".foo" + AWSEndpointSuffix + ":1234") + f.Add(DynamoDBFipsServiceName + ".foo" + AWSCNEndpointSuffix) + f.Fuzz(func(t *testing.T, endpoint string) { require.NotPanics(t, func() { _, _ = ParseDynamoDBEndpoint(endpoint) @@ -55,6 +107,13 @@ func FuzzParseDynamoDBEndpoint(f *testing.F) { } func FuzzParseOpensearchEndpoint(f *testing.F) { + f.Add("") + f.Add(":123") + f.Add("foo:123") + f.Add("a.b." + OpenSearchServiceName + AWSEndpointSuffix) + f.Add("a.b." + OpenSearchServiceName + AWSEndpointSuffix + ":1234") + f.Add("a.b." + OpenSearchServiceName + AWSCNEndpointSuffix) + f.Fuzz(func(t *testing.T, endpoint string) { require.NotPanics(t, func() { _, _ = ParseOpensearchEndpoint(endpoint) diff --git a/api/utils/aws/identifiers.go b/api/utils/aws/identifiers.go index 2094b6e65e032..330fb8319478f 100644 --- a/api/utils/aws/identifiers.go +++ b/api/utils/aws/identifiers.go @@ -17,6 +17,10 @@ limitations under the License. package aws import ( + "regexp" + "strings" + "unicode" + "github.com/gravitational/trace" ) @@ -35,3 +39,38 @@ func IsValidAccountID(accountID string) error { return nil } + +// matchRoleName is a regex that matches against AWS IAM Role Names. +var matchRoleName = regexp.MustCompile(`^[\w+=,.@-]+$`).MatchString + +// IsValidIAMRoleName checks whether the role name is a valid AWS IAM Role identifier. +// +// > Length Constraints: Minimum length of 1. Maximum length of 64. +// > Pattern: [\w+=,.@-]+ +// https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html +func IsValidIAMRoleName(roleName string) error { + if len(roleName) == 0 || len(roleName) > 64 || !matchRoleName(roleName) { + return trace.BadParameter("role is invalid") + } + + return nil +} + +// IsValidRegion ensures the region looks to be valid. +// It does not do a full validation, because AWS doesn't provide documentation for that. +// However, they usually only have the following chars: [a-z0-9\-] +func IsValidRegion(region string) error { + indexNotFound := -1 + + if len(region) == 0 { + return trace.BadParameter("region is invalid") + } + + if strings.IndexFunc(region, func(r rune) bool { + return !(unicode.IsDigit(r) || unicode.IsLetter(r) || r == '-') + }) == indexNotFound { + return nil + } + + return trace.BadParameter("region is invalid") +} diff --git a/api/utils/aws/identifiers_test.go b/api/utils/aws/identifiers_test.go index 8d33fa9b9eae3..f5718beef88bd 100644 --- a/api/utils/aws/identifiers_test.go +++ b/api/utils/aws/identifiers_test.go @@ -17,6 +17,7 @@ limitations under the License. package aws import ( + "strings" "testing" "github.com/gravitational/trace" @@ -24,7 +25,7 @@ import ( ) func TestIsValidAccountID(t *testing.T) { - isBadParamErrFn := func(tt require.TestingT, err error, i ...interface{}) { + isBadParamErrFn := func(tt require.TestingT, err error, i ...any) { require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err) } @@ -74,3 +75,97 @@ func TestIsValidAccountID(t *testing.T) { }) } } + +func TestIsValidIAMRoleName(t *testing.T) { + isBadParamErrFn := func(tt require.TestingT, err error, i ...any) { + require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err) + } + + for _, tt := range []struct { + name string + role string + errCheck require.ErrorAssertionFunc + }{ + { + name: "valid", + role: "valid", + errCheck: require.NoError, + }, + { + name: "valid with numbers", + role: "00VALID11", + errCheck: require.NoError, + }, + { + name: "only one symbol", + role: "_", + errCheck: require.NoError, + }, + { + name: "all symbols", + role: "Test+1=2,3.4@5-6_7", + errCheck: require.NoError, + }, + { + name: "empty", + role: "", + errCheck: isBadParamErrFn, + }, + { + name: "too large", + role: strings.Repeat("r", 65), + errCheck: isBadParamErrFn, + }, + { + name: "invalid symbols", + role: "role/admin", + errCheck: isBadParamErrFn, + }, + } { + t.Run(tt.name, func(t *testing.T) { + tt.errCheck(t, IsValidIAMRoleName(tt.role)) + }) + } +} + +func TestIsValidRegion(t *testing.T) { + isBadParamErrFn := func(tt require.TestingT, err error, i ...any) { + require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err) + } + + for _, tt := range []struct { + name string + region string + errCheck require.ErrorAssertionFunc + }{ + { + name: "us region", + region: "us-east-1", + errCheck: require.NoError, + }, + { + name: "eu region", + region: "eu-west-1", + errCheck: require.NoError, + }, + { + name: "us gov", + region: "us-gov-east-1", + errCheck: require.NoError, + }, + { + name: "empty", + region: "", + errCheck: isBadParamErrFn, + }, + { + name: "symbols", + region: "us@east-1", + errCheck: isBadParamErrFn, + }, + } { + t.Run(tt.name, func(t *testing.T) { + tt.errCheck(t, IsValidRegion(tt.region)) + }) + } +} diff --git a/api/utils/azure/fuzz_test.go b/api/utils/azure/fuzz_test.go index fa31656acac10..5b2780164aa6b 100644 --- a/api/utils/azure/fuzz_test.go +++ b/api/utils/azure/fuzz_test.go @@ -23,6 +23,12 @@ import ( ) func FuzzParseDatabaseEndpoint(f *testing.F) { + f.Add("") + f.Add("foo") + f.Add(":1234") + f.Add("foo:1234") + f.Add("name.mysql.database.azure.com:1234") + f.Fuzz(func(t *testing.T, endpoint string) { require.NotPanics(t, func() { ParseDatabaseEndpoint(endpoint) @@ -31,6 +37,12 @@ func FuzzParseDatabaseEndpoint(f *testing.F) { } func FuzzParseCacheForRedisEndpoint(f *testing.F) { + f.Add("") + f.Add("foo") + f.Add("name.redis.cache.windows.net") + f.Add("name.redis.cache.windows.net:1234") + f.Add("name.region.redisenterprise.cache.azure.net") + f.Fuzz(func(t *testing.T, endpoint string) { require.NotPanics(t, func() { ParseCacheForRedisEndpoint(endpoint) @@ -39,6 +51,12 @@ func FuzzParseCacheForRedisEndpoint(f *testing.F) { } func FuzzNormalizeLocation(f *testing.F) { + f.Add("") + f.Add("foo") + f.Add("northcentralusstage") + f.Add("North Central US (Stage)") + f.Add("(US) North Central US (Stage)") + f.Fuzz(func(t *testing.T, location string) { require.NotPanics(t, func() { NormalizeLocation(location) @@ -47,6 +65,13 @@ func FuzzNormalizeLocation(f *testing.F) { } func FuzzParseMSSQLEndpoint(f *testing.F) { + f.Add("") + f.Add("foo") + f.Add(":1234") + f.Add("foo:1234") + f.Add("name.database.windows.net:1234") + f.Add(".database.windows.net:1234") + f.Fuzz(func(t *testing.T, endpoint string) { require.NotPanics(t, func() { ParseMSSQLEndpoint(endpoint) diff --git a/api/utils/sshutils/callback.go b/api/utils/sshutils/callback.go index f010324e5ba98..e10a38d6e5eca 100644 --- a/api/utils/sshutils/callback.go +++ b/api/utils/sshutils/callback.go @@ -35,7 +35,7 @@ type HostKeyCallbackConfig struct { // FIPS allows to set FIPS mode which will validate algorithms. FIPS bool // OnCheckCert is called on SSH certificate validation. - OnCheckCert func(*ssh.Certificate) + OnCheckCert func(*ssh.Certificate) error // Clock is used to set the Checker Time Clock clockwork.Clock } diff --git a/api/utils/sshutils/checker.go b/api/utils/sshutils/checker.go index 50bb38baf6b1d..68543405523c3 100644 --- a/api/utils/sshutils/checker.go +++ b/api/utils/sshutils/checker.go @@ -36,7 +36,7 @@ type CertChecker struct { FIPS bool // OnCheckCert is called when validating host certificate. - OnCheckCert func(*ssh.Certificate) + OnCheckCert func(*ssh.Certificate) error } // Authenticate checks the validity of a user certificate. @@ -67,7 +67,9 @@ func (c *CertChecker) CheckCert(principal string, cert *ssh.Certificate) error { } if c.OnCheckCert != nil { - c.OnCheckCert(cert) + if err := c.OnCheckCert(cert); err != nil { + return trace.Wrap(err) + } } return nil @@ -86,7 +88,9 @@ func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key ssh.PublicK } if cert, ok := key.(*ssh.Certificate); ok && c.OnCheckCert != nil { - c.OnCheckCert(cert) + if err := c.OnCheckCert(cert); err != nil { + return trace.Wrap(err) + } } return nil diff --git a/assets/aws/Makefile b/assets/aws/Makefile index 4f4b6101393cf..945ae8444ecc1 100644 --- a/assets/aws/Makefile +++ b/assets/aws/Makefile @@ -14,7 +14,7 @@ AWS_REGION ?= us-west-2 # This must be a _released_ version of Teleport, i.e. one which has binaries # available for download on https://gravitational.com/teleport/download # Unreleased versions will fail to build. -TELEPORT_VERSION ?= 13.0.4 +TELEPORT_VERSION ?= 13.1.5 # Teleport UID is the UID of a non-privileged 'teleport' user TELEPORT_UID ?= 1007 diff --git a/assets/aws/files/install-hardened.sh b/assets/aws/files/install-hardened.sh index 65c948cb67172..519147dafda4a 100644 --- a/assets/aws/files/install-hardened.sh +++ b/assets/aws/files/install-hardened.sh @@ -1,9 +1,5 @@ #!/bin/bash -# Set some curl options so that temporary failures get retried -# More info: https://ec.haxx.se/usingcurl-timeouts.html -CURL_OPTS=(-L --retry 100 --retry-delay 0 --connect-timeout 10 --max-time 300) - # Update packages dnf -y update @@ -28,32 +24,6 @@ usermod -a -G adm teleport install -d -m 0700 -o teleport -g adm /var/lib/teleport install -d -m 0755 -o teleport -g adm /run/teleport /etc/teleport.d - -# Pick the teleport tarball filename matching the requested teleport -# edition. -case "${TELEPORT_TYPE}-${TELEPORT_FIPS}" in - oss-0) TARBALL="teleport-v${TELEPORT_VERSION}-linux-amd64-bin.tar.gz" ;; - ent-0) TARBALL="teleport-ent-v${TELEPORT_VERSION}-linux-amd64-bin.tar.gz" ;; - ent-1) TARBALL="teleport-ent-v${TELEPORT_VERSION}-linux-amd64-fips-bin.tar.gz" ;; - oss-1) - echo "OSS FIPS not supported" >&2 - exit 1 - ;; - *) - echo "Invalid environment" >&2 - exit 1 - ;; -esac -TARBALL_FILENAME="/tmp/files/${TARBALL}" - -if [[ -f "${TARBALL_FILENAME}" ]]; then - echo "Found locally uploaded tarball: ${TARBALL_FILENAME}, moving to /tmp/teleport.tar.gz" - mv "${TARBALL_FILENAME}" /tmp/teleport.tar.gz -else - echo "Downloading teleport tarball ${TARBALL}" - curl "${CURL_OPTS[@]}" -o /tmp/teleport.tar.gz "https://get.gravitational.com/teleport/${TELEPORT_VERSION}/${TARBALL}" -fi - # Extract tarball to /tmp/teleport to get the binaries out mkdir /tmp/teleport tar -C /tmp/teleport -x -z -f /tmp/teleport.tar.gz --strip-components=1 diff --git a/assets/aws/go.mod b/assets/aws/go.mod index d61802ed1dcc5..fe30d07cd6dcc 100644 --- a/assets/aws/go.mod +++ b/assets/aws/go.mod @@ -4,22 +4,22 @@ go 1.19 require ( github.com/alecthomas/kingpin/v2 v2.3.2 // replaced - github.com/aws/aws-sdk-go-v2 v1.18.0 - github.com/aws/aws-sdk-go-v2/config v1.18.25 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.98.0 + github.com/aws/aws-sdk-go-v2 v1.18.1 + github.com/aws/aws-sdk-go-v2/config v1.18.27 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.102.0 ) require ( github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.13.24 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.13.26 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 // indirect github.com/aws/smithy-go v1.13.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect diff --git a/assets/aws/go.sum b/assets/aws/go.sum index 412e2811709b2..e3291d7f8f535 100644 --- a/assets/aws/go.sum +++ b/assets/aws/go.sum @@ -1,29 +1,29 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/aws/aws-sdk-go-v2 v1.18.0 h1:882kkTpSFhdgYRKVZ/VCgf7sd0ru57p2JCxz4/oN5RY= -github.com/aws/aws-sdk-go-v2 v1.18.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2/config v1.18.25 h1:JuYyZcnMPBiFqn87L2cRppo+rNwgah6YwD3VuyvaW6Q= -github.com/aws/aws-sdk-go-v2/config v1.18.25/go.mod h1:dZnYpD5wTW/dQF0rRNLVypB396zWCcPiBIvdvSWHEg4= -github.com/aws/aws-sdk-go-v2/credentials v1.13.24 h1:PjiYyls3QdCrzqUN35jMWtUK1vqVZ+zLfdOa/UPFDp0= -github.com/aws/aws-sdk-go-v2/credentials v1.13.24/go.mod h1:jYPYi99wUOPIFi0rhiOvXeSEReVOzBqFNOX5bXYoG2o= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 h1:jJPgroehGvjrde3XufFIJUZVK5A2L9a3KwSFgKy9n8w= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3/go.mod h1:4Q0UFP0YJf0NrsEuEYHpM9fTSEVnD16Z3uyEF7J9JGM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 h1:kG5eQilShqmJbv11XL1VpyDbaEJzWxd4zRiCG30GSn4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33/go.mod h1:7i0PF1ME/2eUPFcjkVIwq+DOygHEoK92t5cDqNgYbIw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 h1:vFQlirhuM8lLlpI7imKOMsjdQLuN9CPi+k44F/OFVsk= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27/go.mod h1:UrHnn3QV/d0pBZ6QBAEQcqFLf8FAzLmoUfPVIueOvoM= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 h1:gGLG7yKaXG02/jBlg210R7VgQIotiQntNhsCFejawx8= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34/go.mod h1:Etz2dj6UHYuw+Xw830KfzCfWGMzqvUTCjUj5b76GVDc= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.98.0 h1:WblDV33AG9dhv0zFEPEmGtD5UECSNpKMxtdENULfR8M= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.98.0/go.mod h1:L3ZT0N/vBsw77mOAawXmRnREpEjcHd2v5Hzf7AkIH8M= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 h1:0iKliEXAcCa2qVtRs7Ot5hItA2MsufrphbRFlz1Owxo= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27/go.mod h1:EOwBD4J4S5qYszS5/3DpkejfuK+Z5/1uzICfPaZLtqw= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 h1:UBQjaMTCKwyUYwiVnUt6toEJwGXsLBI6al083tpjJzY= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.10/go.mod h1:ouy2P4z6sJN70fR3ka3wD3Ro3KezSxU6eKGQI2+2fjI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 h1:PkHIIJs8qvq0e5QybnZoG1K/9QTrLr9OsqCIo59jOBA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10/go.mod h1:AFvkxc8xfBe8XA+5St5XIHHrQQtkxqrRincx4hmMHOk= -github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 h1:2DQLAKDteoEDI8zpCzqBMaZlJuoE9iTYD0gFmXVax9E= -github.com/aws/aws-sdk-go-v2/service/sts v1.19.0/go.mod h1:BgQOMsg8av8jset59jelyPW7NoZcZXLVpDsXunGDrk8= +github.com/aws/aws-sdk-go-v2 v1.18.1 h1:+tefE750oAb7ZQGzla6bLkOwfcQCEtC5y2RqoqCeqKo= +github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= +github.com/aws/aws-sdk-go-v2/config v1.18.27 h1:Az9uLwmssTE6OGTpsFqOnaGpLnKDqNYOJzWuC6UAYzA= +github.com/aws/aws-sdk-go-v2/config v1.18.27/go.mod h1:0My+YgmkGxeqjXZb5BYme5pc4drjTnM+x1GJ3zv42Nw= +github.com/aws/aws-sdk-go-v2/credentials v1.13.26 h1:qmU+yhKmOCyujmuPY7tf5MxR/RKyZrOPO3V4DobiTUk= +github.com/aws/aws-sdk-go-v2/credentials v1.13.26/go.mod h1:GoXt2YC8jHUBbA4jr+W3JiemnIbkXOfxSXcisUsZ3os= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4 h1:LxK/bitrAr4lnh9LnIS6i7zWbCOdMsfzKFBI6LUCS0I= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4/go.mod h1:E1hLXN/BL2e6YizK1zFlYd8vsfi2GTjbjBazinMmeaM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34 h1:A5UqQEmPaCFpedKouS4v+dHCTUo2sKqhoKO9U5kxyWo= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34/go.mod h1:wZpTEecJe0Btj3IYnDx/VlUzor9wm3fJHyvLpQF0VwY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28 h1:srIVS45eQuewqz6fKKu6ZGXaq6FuFg5NzgQBAM6g8Y4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28/go.mod h1:7VRpKQQedkfIEXb4k52I7swUnZP0wohVajJMRn3vsUw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35 h1:LWA+3kDM8ly001vJ1X1waCuLJdtTl48gwkPKWy9sosI= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35/go.mod h1:0Eg1YjxE0Bhn56lx+SHJwCzhW+2JGtizsrx+lCqrfm0= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.102.0 h1:P4dyjm49F2kKws0FpouBC6fjVImACXKt752+CWa01lM= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.102.0/go.mod h1:tIctCeX9IbzsUTKHt53SVEcgyfxV2ElxJeEB+QUbc4M= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28 h1:bkRyG4a929RCnpVSTvLM2j/T4ls015ZhhYApbmYs15s= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28/go.mod h1:jj7znCIg05jXlaGBlFMGP8+7UN3VtCkRBG2spnmRQkU= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.12 h1:nneMBM2p79PGWBQovYO/6Xnc2ryRMw3InnDJq1FHkSY= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.12/go.mod h1:HuCOxYsF21eKrerARYO6HapNeh9GBNq7fius2AcwodY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12 h1:2qTR7IFk7/0IN/adSFhYu9Xthr0zVFTgBrmPldILn80= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12/go.mod h1:E4VrHCPzmVB/KFXtqBGKb3c8zpbNBgKe3fisDNLAW5w= +github.com/aws/aws-sdk-go-v2/service/sts v1.19.2 h1:XFJ2Z6sNUUcAz9poj+245DMkrHE4h2j5I9/xD50RHfE= +github.com/aws/aws-sdk-go-v2/service/sts v1.19.2/go.mod h1:dp0yLPsLBOi++WTxzCjA/oZqi6NPIhoR+uF7GeMU9eg= github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/assets/aws/single-ami.pkr.hcl b/assets/aws/single-ami.pkr.hcl index ccb67ce093d5a..3272aca091cf3 100644 --- a/assets/aws/single-ami.pkr.hcl +++ b/assets/aws/single-ami.pkr.hcl @@ -67,6 +67,11 @@ variable "teleport_fips" { default = false } +variable "teleport_tarball" { + description = "Path to teleport tarball" + type = string +} + variable "teleport_uid" { type = string default = "1007" @@ -175,21 +180,16 @@ build { destination = "/tmp/files" } - provisioner "shell" { - remote_folder = local.remote_folder - inline = [ - "sudo cp /tmp/files/system/* /etc/systemd/system/", - "sudo cp /tmp/files/bin/* /usr/local/bin/" - ] + provisioner "file" { + source = var.teleport_tarball + destination = "/tmp/teleport.tar.gz" } provisioner "shell" { remote_folder = local.remote_folder - environment_vars = [ - "FIPS=${var.teleport_fips ? 1 : 0}" - ] inline = [ - "if [ \"$FIPS\" -eq 1 ]; then touch /tmp/teleport-fips; fi" + "sudo cp /tmp/files/system/* /etc/systemd/system/", + "sudo cp /tmp/files/bin/* /usr/local/bin/" ] } diff --git a/assets/backport/go.mod b/assets/backport/go.mod index 403e983b3a195..20bfa0d141fcf 100644 --- a/assets/backport/go.mod +++ b/assets/backport/go.mod @@ -5,23 +5,23 @@ go 1.18 require ( github.com/google/go-github/v41 v41.0.0 github.com/gravitational/trace v1.2.1 - github.com/stretchr/testify v1.8.3 - golang.org/x/oauth2 v0.8.0 + github.com/stretchr/testify v1.8.4 + golang.org/x/oauth2 v0.9.0 gopkg.in/yaml.v2 v2.4.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/jonboulle/clockwork v0.2.2 // indirect + github.com/jonboulle/clockwork v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/sirupsen/logrus v1.8.1 // indirect - golang.org/x/crypto v0.1.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/assets/backport/go.sum b/assets/backport/go.sum index 6fe2118da3d86..884add34bac16 100644 --- a/assets/backport/go.sum +++ b/assets/backport/go.sum @@ -36,8 +36,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -55,27 +55,29 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gravitational/trace v1.2.1 h1:Iaf43aqbKV5H8bdiRs1qByjEHgAfADJ0lt0JwRyu+q8= github.com/gravitational/trace v1.2.1/go.mod h1:n0ijrq6psJY0sOI/NzLp+xdd8xl79jjwzVOFHDY6+kQ= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -91,12 +93,12 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= +golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -111,12 +113,13 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -155,8 +158,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/assets/loadtest/.gitignore b/assets/loadtest/.gitignore index 7bf02cfaf4c25..7291a8fc7a146 100644 --- a/assets/loadtest/.gitignore +++ b/assets/loadtest/.gitignore @@ -15,4 +15,6 @@ k8s/secrets/** **/terraform.tfstate* **/terraform.tfvars -.secrets \ No newline at end of file +.secrets + +control-plane/vars.env \ No newline at end of file diff --git a/assets/loadtest/Makefile b/assets/loadtest/Makefile index 0cba13de646fb..2d1329630c1a4 100644 --- a/assets/loadtest/Makefile +++ b/assets/loadtest/Makefile @@ -1,75 +1,78 @@ -SOAK_TEST_DURATION ?= 30m -USE_CERT_MANAGER ?= yes -TELEPORT_IMAGE ?= public.ecr.aws/gravitational/teleport-ent:12.0.0 -NAMESPACE ?= loadtest - -.PHONY: reserve-ips -reserve-ips: - @make -C network apply - -# create gke cluster -.PHONY: create-cluster -create-cluster: - @make -C ./cluster apply - @make -C ./cluster get-creds - -# delete gke cluster -.PHONY: delete-cluster -delete-cluster: - @make -C cluster destroy USE_CERT_MANAGER=$(USE_CERT_MANAGER) - -# deploy teleport with etcd backend to loadtest namespace -.PHONY: deploy-etcd-cluster -deploy-etcd-cluster: - @make -C k8s apply BACKEND=etcd USE_CERT_MANAGER=$(USE_CERT_MANAGER) TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - -# deploy teleport with firestore backend to loadtest namespace -.PHONY: deploy-firestore-cluster -deploy-firestore-cluster: - @make -C k8s apply BACKEND=firestore USE_CERT_MANAGER=$(USE_CERT_MANAGER) TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - -# deploy teleport with dynamo backend to loadtest namespace -.PHONY: deploy-dynamo-cluster -deploy-dynamo-cluster: - @make -C k8s apply BACKEND=dynamo USE_CERT_MANAGER=$(USE_CERT_MANAGER) TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - -# delete the loadtest namespace -.PHONY: delete-deploy -delete-deploy: - @make -C k8s clean USE_CERT_MANAGER=$(USE_CERT_MANAGER) - -# run soak tests -.PHONY: run-soak-tests -run-soak-tests: - @make -C k8s run-soak-tests SOAK_TEST_DURATION=$(SOAK_TEST_DURATION) TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - -# run 500 node trusted cluster scaling test -# This installs 500 trusted clusters, waits for a period of time and then -# deletes all 500. When they are all removed from auth the process is repeated once more. -# The test helps identify any potential memory leaks caused by remote clusters -.PHONY: run-tc-scaling-test -run-tc-scaling-test: - @make -C k8s run-tc-scaling-test TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - -# run the 10k scaling test -# This tests installs 10,000 IoT nodes and then removes all 10,000 nodes after a fixed period of time. -# The process repeats once more and then the same is done for non-IoT nodes. The test helps identify any -# potential memory leaks caused by large clusters for both non-IoT and IoT nodes. -.PHONY: run-scaling-test -run-scaling-test: - @make -C k8s run-scaling-test TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - -# list pods in loadtest namespace -.PHONY: pods -pods: - @make -C k8s pods NAMESPACE=$(NAMESPACE) - -# get cluster credentials -.PHONY: get-creds -get-creds: - @make -C cluster get-creds - -# collect heap and goroutine profiles -.PHONY: collect-profiles -collect-profiles: - @make -C k8s collect-profiles PROFILE_LOCATION=$(shell pwd) NAMESPACE=$(NAMESPACE) \ No newline at end of file +# creates an eks cluster +.PHONY: create-aws-cluster +create-aws-cluster: + $(MAKE) -C cluster/aws create-cluster + +# creates an gks cluster +.PHONY: create-gcp-cluster +create-gcp-cluster: + $(MAKE) -C cluster/gcp create-cluster + +# deletes an eks cluster +.PHONY: delete-aws-cluster +delete-aws-cluster: + $(MAKE) -C cluster/aws destroy + +# deletes a gks cluster +.PHONY: delete-gcp-cluster +delete-gcp-cluster: + $(MAKE) -C cluster/gcp destroy + +# cleans up all deployed resources in the cluster and +# any resources created in the cloud provider +.PHONY: destroy-deploy +destroy-deploy: + $(MAKE) -C control-plane destroy + +# deploys teleport auth and proxy +.PHONY: deploy-control-plane +deploy-control-plane: + $(MAKE) -C control-plane deploy + +# deletes the teleport auth and proxy deployments +.PHONY: delete-teleport +delete-teleport: + $(MAKE) -C control-plane delete-teleport + +# deploys teleport auth and proxy to the cluster +.PHONY: deploy-teleport +deploy-teleport: + $(MAKE) -C control-plane deploy-teleport + +NODE_REPLICAS ?= 1000 +PROXY_SERVER ?= +NODE_TOKEN ?= + +# deploys nodes and adds them to the teleport cluster +.PHONY: deploy-nodes +deploy-nodes: + helm upgrade --install node-agents -n agents --create-namespace ./helm/node-agent/ --values ./helm/values/node-agents.yaml --set replicaCount=${NODE_REPLICAS} --set agentsPerPod=10 --set proxyServer=${PROXY_SERVER} --set joinParams.token_name=${NODE_TOKEN} + +# deletes all nodes +.PHONY: delete-nodes +delete-nodes: + helm delete -n agents node-agents + +TELEPORT_USER ?= test + +# creates a local teleport user +.PHONY: create-user +create-user: + kubectl --namespace teleport exec deploy/teleport-auth -- tctl users add ${TELEPORT_USER} --roles=access,editor,auditor + +# creates a token that can be used by nodes to join the +# teleport cluster +.PHONY: create-token +create-token: + kubectl --namespace teleport exec deploy/teleport-auth -- tctl tokens add --type=node --ttl=8h + +# forwards the grafana web app to localhost:6060 +.PHONY: forward-grafana +forward-grafana: + $(MAKE) -C control-plane forward-monitor + +# scales teleport auth pods up/down +.PHONY: scale-auth +scale-auth: + kubectl scale deployment/teleport-auth --replicas=$(REPLICAS) -n teleport + diff --git a/assets/loadtest/README.md b/assets/loadtest/README.md deleted file mode 100644 index b1fecb348a558..0000000000000 --- a/assets/loadtest/README.md +++ /dev/null @@ -1,119 +0,0 @@ -# loadtest - -Automation for the `loadtest` kuberentes cluster and performing Teleport load tests. - -## About - -This automation sets up a kubernetes cluster named `loadtest` in the configured GCP project. -This cluster is used for, among other things, the `1k`/`10k` scaling tests that are performed as part of -Teleports manual release test plan. - -## Setup - -### Prerequisites -- Make sure you have the following tools installed: - - `terraform` - - `gcloud` - - `kubectl` -- Make sure that you have a GCP service account key with `Compute Admin`, `Compute Network Admin`, - `Kubernetes Engine Admin`, `Kubernetes Engine Cluster Admin`, and `Service Account User` - - To authenticate as the service account follow these [instructions](https://cloud.google.com/docs/authentication/production) -- Make sure you have reserved static ip addresses for the proxy - - This only needs to be done once per GCP project, see the [network docs](./network/README.md) for details - -### Creating the Cluster - -First create a cluster, if you are running this automation for the first time, you may be asked to run -`terraform init` from the cluster directory before continuing. To resize the cluster, edit [`terraform.tfvars`](cluster/terraform.tfvars) as needed. - -```bash -$ make create-cluster -``` - -### DNS Entries -Before deploying anything to the cluster you first need to set `PROXY_HOST`. These variables should -be the DNS names to be used for the [`proxy`](./k8s/proxy.yaml). When everything is successfully deployed you should be able -to navigate to `https://PROXY_HOST:3080` in your browser. - -```bash -$ export PROXY_HOST=proxy.loadtest.com -``` - -### TLS Certificates - -Certificates can be provisioned automatically via [cert-manager](https://cert-manager.io/) or by hand. - -#### cert-manager -If you would like to use cert-manager to automatically retrieve TLS certificates for you, create -[`cetificate.yaml`](./k8s/certificate.yaml) with your `cert-manager.io/v1/ClusterIssuer`, `cert-manager.io/v1/Certificate` and any -secrets required for your solver. - -#### Kubernetes secret - -To manual supply TLS certificates create a tls secret, run the following: - -```bash -$ kubectl create secret tls teleport-tls -n loadtest \ - --cert=path/to/cert/file \ - --key=path/to/key/file -``` - -You **must** also provide `USE_CERT_MANAGER=no` to all make commands below. - -### Teleport Configuration -You must supply an [OIDC Connector](https://goteleport.com/docs/enterprise/sso/oidc/) that will be used for authentication. Create [`oidc.yaml`](./teleport/oidc.yaml) -before attempting to deploy Teleport to the cluster. - - -## Deploy Teleport - -### etcd Backend - -```bash -$ make deploy-etcd-cluster -``` - -### Firestore Backend - -To use the firestore backend you must have a GCP service account key with `Cloud Datastore User`, `Cloud Datastore Index Admin` -`Storage Object Admin` permissions. Set `GCP_CREDS_LOCATION` to the location that you saved the service account key. - -```bash -$ export GCP_CREDS_LOCATION=/path/to/service/account/key -$ make deploy-firestore-cluster -``` - -## Running Tests - -To run soak tests: - -```bash -$ make run-soak-tests -``` - - -**Note:** You must have enough nodes in the cluster to run the following tests. Ensure your `node_count` in [`terraform.tfvars`](cluster/terraform.tfvars) is correctly set. - -To run the 10k node scaling tests: - -```bash -$ make run-scaling-test -``` - -To run the trusted cluster scaling test: -```bash -$ make run-tc-scaling-test -``` - -## Cleanup - -To delete the loadtest deployment: -```bash -$ make delete-deploy -``` - - -To delete the entire cluster: -```bash -$ make delete-cluster -``` \ No newline at end of file diff --git a/assets/loadtest/cluster/aws/Makefile b/assets/loadtest/cluster/aws/Makefile new file mode 100644 index 0000000000000..46d1b826e11b5 --- /dev/null +++ b/assets/loadtest/cluster/aws/Makefile @@ -0,0 +1,14 @@ +# creates an eks cluster +.PHONY: create-cluster +create-cluster: + eksctl create cluster -f cluster.yaml + +# gets kubernetes credentials +.PHONY: get-creds +get-creds: + eksctl utils write-kubeconfig + +# deletes the eks cluster +.PHONY: destroy +destroy: + eksctl delete cluster -f cluster.yaml --wait --disable-nodegroup-eviction diff --git a/assets/loadtest/cluster/aws/cluster.yaml b/assets/loadtest/cluster/aws/cluster.yaml new file mode 100644 index 0000000000000..9b8d32a9f6eda --- /dev/null +++ b/assets/loadtest/cluster/aws/cluster.yaml @@ -0,0 +1,21 @@ +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig +metadata: + name: + region: + version: "1.23" + +iam: + withOIDC: true + +addons: + - name: aws-ebs-csi-driver + version: v1.11.4-eksbuild.1 + attachPolicyARNs: + - arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy + +managedNodeGroups: + - name: + instanceType: m5.4xlarge + minSize: 2 + maxSize: 10 \ No newline at end of file diff --git a/assets/loadtest/cluster/Makefile b/assets/loadtest/cluster/gcp/Makefile similarity index 93% rename from assets/loadtest/cluster/Makefile rename to assets/loadtest/cluster/gcp/Makefile index 6c97c3501f80b..e914b70fceebb 100644 --- a/assets/loadtest/cluster/Makefile +++ b/assets/loadtest/cluster/gcp/Makefile @@ -4,8 +4,8 @@ plan: terraform plan # apply cluster configuration -.PHONY: apply -apply: +.PHONY: create-cluster +create-cluster: terraform apply # authorize kubectl to manage the cluster diff --git a/assets/loadtest/cluster/README.md b/assets/loadtest/cluster/gcp/README.md similarity index 100% rename from assets/loadtest/cluster/README.md rename to assets/loadtest/cluster/gcp/README.md diff --git a/assets/loadtest/cluster/main.tf b/assets/loadtest/cluster/gcp/main.tf similarity index 100% rename from assets/loadtest/cluster/main.tf rename to assets/loadtest/cluster/gcp/main.tf diff --git a/assets/loadtest/cluster/outputs.tf b/assets/loadtest/cluster/gcp/outputs.tf similarity index 100% rename from assets/loadtest/cluster/outputs.tf rename to assets/loadtest/cluster/gcp/outputs.tf diff --git a/assets/loadtest/cluster/variables.tf b/assets/loadtest/cluster/gcp/variables.tf similarity index 100% rename from assets/loadtest/cluster/variables.tf rename to assets/loadtest/cluster/gcp/variables.tf diff --git a/assets/loadtest/control-plane/.gitignore b/assets/loadtest/control-plane/.gitignore new file mode 100644 index 0000000000000..8c22876fb3c99 --- /dev/null +++ b/assets/loadtest/control-plane/.gitignore @@ -0,0 +1,2 @@ +vars.env +state diff --git a/assets/loadtest/control-plane/Makefile b/assets/loadtest/control-plane/Makefile new file mode 100644 index 0000000000000..377b0b373f727 --- /dev/null +++ b/assets/loadtest/control-plane/Makefile @@ -0,0 +1,26 @@ +# initializes helm repos and install teleport +.PHONY: deploy +deploy: + ./init.sh + ./apply.sh + +# initializes helm repos and install teleport +.PHONY: destroy +destroy: + ./clean-non-kube.sh + +.PHONY: delete-teleport +delete-teleport: + ./teleport/uninstall-teleport.sh + +.PHONY: deploy-teleport +deploy-teleport: + ./teleport/install-teleport.sh + ./teleport/wait.sh auth + ./dns/update-record.sh UPSERT + ./teleport/wait.sh proxy + +# forwards the in cluster grafana to localhost:6060 +.PHONY: forward-monitor +forward-monitor: + ./monitoring/port-forward.sh \ No newline at end of file diff --git a/assets/loadtest/control-plane/README.md b/assets/loadtest/control-plane/README.md new file mode 100644 index 0000000000000..5a92bca9c1d94 --- /dev/null +++ b/assets/loadtest/control-plane/README.md @@ -0,0 +1,24 @@ +# control-plane + +A collection of scripts used to automate the process of setting up a teleport control plane using the +`teleport-cluster` helm chart in `aws`. + +*note:* This is an experimental tool used for internal testing and may be buggy/brittle. + +## Quickstart + +- Ensure aws cli is authenticated. + +- Set up eks cluster and load credentials into kubectl. + +- Create a `vars.env` in this directory (see `example-vars.env` for required contents and explanation). +Note that the name of the eks cluster must match the `CLUSTER_NAME` variable. + +- If needed, run `init.sh` to add/update all necessary helm repos. + +- Invoke `./apply.sh` to spin up the teleport control plane and monitoring stack. + +- Use `./monitoring/port-forward.sh` to forward the grafana ui. + +- When finished, first invoke `./clean-non-kube.sh`, then destroy the eks cluster (this ordering +is important, as some of the resources created by these scripts interfere with eks cluster teardown). diff --git a/assets/loadtest/control-plane/apply.sh b/assets/loadtest/control-plane/apply.sh new file mode 100755 index 0000000000000..aee99c9d73c23 --- /dev/null +++ b/assets/loadtest/control-plane/apply.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +set -euo pipefail + +# set up cluster resources (kube cluster must exist, aws and kubectl must be authenticated, +# and helm repos must be up to date). + +source vars.env + +log_info() { + echo "[i] $* [ $(caller | awk '{print $1}') ]" >&2 +} + + +case "$TELEPORT_BACKEND" in + dynamo) + ;; + etcd) + ;; + *) + echo "invalid teleport backend '$TELEPORT_BACKEND', expected one of 'dynamo' or 'etcd'" >&2 + exit 1 + ;; +esac + +log_info "generating iam policies..." + +./policies/gen-policies.sh + +log_info "creating iam policies..." + +./policies/create-policies.sh + +log_info "attaching iam policies..." + +./policies/attach-policies.sh attach + +log_info "installing monitoring stack..." + +./monitoring/install-monitoring.sh + +log_info "setting up cert-manager..." + +./dns/init-cert-manager.sh + +case "$TELEPORT_BACKEND" in + dynamo) + log_info "generating helm values for dynamo-backed control plane..." + ./teleport/gen-dynamo-teleport.sh + ;; + etcd) + log_info "installing etcd..." + make -C ../etcd deploy + + log_info "generating helm values for etcd-backed control plane..." + ./teleport/gen-etcd-teleport.sh + ;; + *) + echo "invalid teleport backend '$TELEPORT_BACKEND', expected one of 'dynamo' or 'etcd'" >&2 + exit 1 + ;; +esac + +log_info "installing control plane chart..." + +./teleport/install-teleport.sh + +log_info "waiting for auths to report ready..." + +./teleport/wait.sh auth + +log_info "setting up dns record..." + +./dns/update-record.sh UPSERT # CREATE|UPSERT|DELETE + +log_info "waiting for proxies to report ready..." + +./teleport/wait.sh proxy + + +if [[ "$TELEPORT_BACKEND" == "dynamo" ]]; then + log_info "switching dynamo to on-demand mode..." + + ./storage/set-on-demand.sh +fi + +log_info "setting grafana admin password..." + +./monitoring/set-password.sh diff --git a/assets/loadtest/control-plane/clean-non-kube.sh b/assets/loadtest/control-plane/clean-non-kube.sh new file mode 100755 index 0000000000000..6a754373ed9dc --- /dev/null +++ b/assets/loadtest/control-plane/clean-non-kube.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -euo pipefail + +# clean up the resources not automatically destroyed by bringing down the kube cluster. + +log_info() { + echo "[i] $* [ $(caller | awk '{print $1}') ]" >&2 +} + +log_info "detaching iam policies..." + +./policies/attach-policies.sh detach + +log_info "deleting iam policies..." + +./policies/delete-policies.sh + +log_info "destroying cluster storage..." + +./storage/delete-storage.sh + +log_info "deleting dns records..." + +./dns/update-record.sh DELETE diff --git a/assets/loadtest/control-plane/dns/init-cert-manager.sh b/assets/loadtest/control-plane/dns/init-cert-manager.sh new file mode 100755 index 0000000000000..ebf053bde8d2e --- /dev/null +++ b/assets/loadtest/control-plane/dns/init-cert-manager.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +set -euo pipefail + +source vars.env + +issuer_yaml="$STATE_DIR/aws-issuer.yaml" + +mkdir -p "$STATE_DIR" + +cat > "$issuer_yaml" <&2 + exit 1 +esac + +records_json="$STATE_DIR/records.json" + +NAMESPACE='teleport' +RELEASE_NAME='teleport' +MYZONE_DNS="${ROUTE53_ZONE}" +MYDNS="${CLUSTER_NAME}.${ROUTE53_ZONE}" +MY_CLUSTER_REGION="${AWS_REGION}" +MYZONE="$(aws route53 list-hosted-zones-by-name --dns-name="${MYZONE_DNS?}" | jq -r '.HostedZones[0].Id' | sed s_/hostedzone/__)" +MYELB="$(kubectl --namespace "${NAMESPACE?}" get "service/${RELEASE_NAME?}" -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')" +MYELB_NAME="${MYELB%%-*}" +MYELB_ZONE="$(aws elbv2 describe-load-balancers --region "${MY_CLUSTER_REGION?}" --names "${MYELB_NAME?}" | jq -r '.LoadBalancers[0].CanonicalHostedZoneId')" +jq -n --arg dns "${MYDNS?}" --arg elb "${MYELB?}" --arg elbz "${MYELB_ZONE?}" --arg act "$action" \ + '{ + "Comment": "Change records", + "Changes": [ + { + "Action": $act, + "ResourceRecordSet": { + "Name": $dns, + "Type": "A", + "AliasTarget": { + "HostedZoneId": $elbz, + "DNSName": ("dualstack." + $elb), + "EvaluateTargetHealth": false + } + } + }, + { + "Action": $act, + "ResourceRecordSet": { + "Name": ("*." + $dns), + "Type": "A", + "AliasTarget": { + "HostedZoneId": $elbz, + "DNSName": ("dualstack." + $elb), + "EvaluateTargetHealth": false + } + } + } + ] + }' > "$records_json" +jq < "$records_json" +CHANGEID="$(aws route53 change-resource-record-sets --hosted-zone-id "${MYZONE?}" --change-batch "file://${records_json}" | jq -r '.ChangeInfo.Id')" +aws route53 get-change --id "${CHANGEID?}" | jq '.ChangeInfo.Status' diff --git a/assets/loadtest/control-plane/example-vars.env b/assets/loadtest/control-plane/example-vars.env new file mode 100644 index 0000000000000..9ba0a511f2e63 --- /dev/null +++ b/assets/loadtest/control-plane/example-vars.env @@ -0,0 +1,32 @@ +# generated file output directory (relative) +STATE_DIR="state" + +# backend variant to use (must be one of "dynamo" or "etcd") +TELEPORT_BACKEND="dynamo" + +# the short name of the teleport cluster (full name will end up being .). +CLUSTER_NAME="my-cluster" + +# session recording bucket name +SESSION_BUCKET="${CLUSTER_NAME}-sess-deadbeefdeadbeef" + +# route53 zone name +ROUTE53_ZONE="my-route53.zone" + +# route53 zone id +ROUTE53_ZONE_ID="0123456789" + +# email for use with letsencrypt +EMAIL="alice@example.com" + +# aws account id +ACCOUNT_ID="0123456789" + +# grafana password +GRAFANA_PASS="insecure" + +# sets the version of teleport to install +TELEPORT_VERSION="13.0.0-alpha.2" + +# aws region to use for resources +AWS_REGION="$(aws configure get region)" diff --git a/assets/loadtest/control-plane/init.sh b/assets/loadtest/control-plane/init.sh new file mode 100755 index 0000000000000..b129d96963973 --- /dev/null +++ b/assets/loadtest/control-plane/init.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -euo pipefail + +# initialize dependencies + +helm repo add teleport https://charts.releases.teleport.dev +helm repo add jetstack https://charts.jetstack.io +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update diff --git a/assets/loadtest/control-plane/monitoring/install-monitoring.sh b/assets/loadtest/control-plane/monitoring/install-monitoring.sh new file mode 100755 index 0000000000000..7fce64fa6a7dc --- /dev/null +++ b/assets/loadtest/control-plane/monitoring/install-monitoring.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -euo pipefail + +source vars.env + +monitor_yaml="$STATE_DIR/monitoring.yaml" + +# source: examples/load-tests/values/kube-prometheus-stack.yaml +cat > "$monitor_yaml" <&2 + exit 1 +fi + +kubectl exec --stdin --namespace="monitoring" --tty --container grafana $GRAFANA_POD -- grafana-cli admin reset-admin-password $GRAFANA_PASS diff --git a/assets/loadtest/control-plane/policies/attach-policies.sh b/assets/loadtest/control-plane/policies/attach-policies.sh new file mode 100755 index 0000000000000..f11d2a0f56efb --- /dev/null +++ b/assets/loadtest/control-plane/policies/attach-policies.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +set -euo pipefail + +mode="${1:?'mode (one of attach or detach)'}" + +case "$mode" in + attach) + ;; + detach) + ;; + *) + echo "ERROR: unknown mode $mode, expected one of 'attach' or 'detach'." + ;; +esac + +source vars.env + +dynamo_policy_arn="arn:aws:iam::${ACCOUNT_ID}:policy/${CLUSTER_NAME}-dynamo" + +s3_policy_arn="arn:aws:iam::${ACCOUNT_ID}:policy/${CLUSTER_NAME}-s3" + +route53_policy_arn="arn:aws:iam::${ACCOUNT_ID}:policy/${CLUSTER_NAME}-route53" + + +# used for stripping out node role name +role_arn_prefix="arn:aws:iam::${ACCOUNT_ID}:role/" + + +log_info() { + echo "[i] $* [ $(caller | awk '{print $1}') ]" >&2 +} + +# discover the node groups associated with our eks cluster +nodegroups="$(aws eks list-nodegroups --cluster-name="$CLUSTER_NAME" | jq -r .nodegroups[])" + + +if test -z "$nodegroups"; then + log_info "failed to discover node group!" + exit 1 +fi + +while read -r ngroup; do + noderole_arn="$(aws eks describe-nodegroup \ + --cluster-name="$CLUSTER_NAME" \ + --nodegroup-name="$ngroup" \ + | jq -r .nodegroup.nodeRole)" + + if test -z "$noderole_arn"; then + log_info "failed to discover node role for group '$ngroup'!" + exit 1 + fi + + noderole_name="${noderole_arn#"$role_arn_prefix"}" + + log_info "${mode}ing policies to discovered node role '$noderole_name'..." + + if [[ "$TELEPORT_BACKEND" == "dynamo" ]]; then + aws iam "$mode-role-policy" \ + --policy-arn="$dynamo_policy_arn" \ + --role-name="$noderole_name" + fi + + aws iam "$mode-role-policy" \ + --policy-arn="$s3_policy_arn" \ + --role-name="$noderole_name" + + aws iam "$mode-role-policy" \ + --policy-arn="$route53_policy_arn" \ + --role-name="$noderole_name" + +done <<< "$nodegroups" diff --git a/assets/loadtest/control-plane/policies/create-policies.sh b/assets/loadtest/control-plane/policies/create-policies.sh new file mode 100755 index 0000000000000..dd71e923dd662 --- /dev/null +++ b/assets/loadtest/control-plane/policies/create-policies.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -euo pipefail + +source vars.env + +dynamo_policy="$STATE_DIR/dynamo-iam-policy" + +s3_policy="$STATE_DIR/s3-iam-policy" + +route53_policy="$STATE_DIR/route53-policy" + +if [[ "$TELEPORT_BACKEND" == "dynamo" ]]; then + aws iam create-policy \ + --policy-name "${CLUSTER_NAME}-dynamo" \ + --policy-document "$(cat "$dynamo_policy")" +fi + +aws iam create-policy \ + --policy-name "${CLUSTER_NAME}-s3" \ + --policy-document "$(cat "$s3_policy")" + +aws iam create-policy \ + --policy-name "${CLUSTER_NAME}-route53" \ + --policy-document "$(cat "$route53_policy")" + diff --git a/assets/loadtest/control-plane/policies/delete-policies.sh b/assets/loadtest/control-plane/policies/delete-policies.sh new file mode 100755 index 0000000000000..0389d3af6b7d7 --- /dev/null +++ b/assets/loadtest/control-plane/policies/delete-policies.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -euo pipefail + +source vars.env + +dynamo_policy_arn="arn:aws:iam::${ACCOUNT_ID}:policy/${CLUSTER_NAME}-dynamo" + +s3_policy_arn="arn:aws:iam::${ACCOUNT_ID}:policy/${CLUSTER_NAME}-s3" + +route53_policy_arn="arn:aws:iam::${ACCOUNT_ID}:policy/${CLUSTER_NAME}-route53" + +if [[ "$TELEPORT_BACKEND" == "dynamo" ]]; then + aws iam delete-policy \ + --policy-arn "$dynamo_policy_arn" +fi + +aws iam delete-policy \ + --policy-arn "$s3_policy_arn" + +aws iam delete-policy \ + --policy-arn "$route53_policy_arn" diff --git a/assets/loadtest/control-plane/policies/gen-policies.sh b/assets/loadtest/control-plane/policies/gen-policies.sh new file mode 100755 index 0000000000000..8fa0a717cbdf0 --- /dev/null +++ b/assets/loadtest/control-plane/policies/gen-policies.sh @@ -0,0 +1,128 @@ +#!/bin/bash + +set -euo pipefail + +source vars.env + +dynamo_policy="$STATE_DIR/dynamo-iam-policy" + +s3_policy="$STATE_DIR/s3-iam-policy" + +route53_policy="$STATE_DIR/route53-policy" + +mkdir -p "$STATE_DIR" + +cat > "$dynamo_policy" < "$s3_policy" < "$route53_policy" < /dev/null + +aws dynamodb update-table \ + --table-name "${CLUSTER_NAME}-events" \ + --billing-mode "PAY_PER_REQUEST" \ + > /dev/null diff --git a/assets/loadtest/control-plane/teleport/gen-dynamo-teleport.sh b/assets/loadtest/control-plane/teleport/gen-dynamo-teleport.sh new file mode 100755 index 0000000000000..081825f3acff3 --- /dev/null +++ b/assets/loadtest/control-plane/teleport/gen-dynamo-teleport.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -euo pipefail + +source vars.env + +values_yaml="$STATE_DIR/teleport-values.yaml" + +mkdir -p "$STATE_DIR" + +cat > "$values_yaml" < "$values_yaml" <&2 + exit 1 + ;; +esac + +kubectl wait pods \ + --namespace teleport \ + --timeout 10m \ + --selector "app.kubernetes.io/component=${component}" \ + --for "condition=Ready" diff --git a/assets/loadtest/etcd/Makefile b/assets/loadtest/etcd/Makefile index 58a53112a0ac7..9c788015ce42a 100644 --- a/assets/loadtest/etcd/Makefile +++ b/assets/loadtest/etcd/Makefile @@ -1,9 +1,33 @@ -# generates certificates -.PHONY: all -all: - make -C certs all - -# deletes generated certificates -.PHONY: destroy -destroy: - make -C certs clean +# deploys etcd into the cluster +.PHONY: deploy +deploy: + kubectl create namespace etcd --dry-run=client -o yaml | kubectl apply -f - + kubectl create secret tls client-certs -n etcd \ + --cert=./certs/client-cert.pem \ + --key=./certs/client-key.pem + + kubectl create secret tls server-certs -n etcd \ + --cert=./certs/server-cert.pem \ + --key=./certs/server-key.pem + + kubectl create secret tls client-certs -n etcd \ + --cert=./certs/client-cert.pem \ + --key=./certs/client-key.pem + + helm repo add bitnami https://charts.bitnami.com/bitnami + helm install etcd -n etcd --create-namespace bitnami/etcd \ + --set replicaCount=3 \ + --set metrics.enabled=true \ + --set metrics.podMonitor.enabled=true \ + --set auth.peer.secureTransport=true \ + --set auth.peer.useAutoTLS=true \ + --set auth.client.secureTransport=true \ + --set auth.client.existingSecret=client-certs \ + --set auth.client.enableAuthentication=true + + +# deletes etcd from the cluster +.PHONY: delete +delete: + helm delete -n etcd etcd + kubectl delete ns etcd \ No newline at end of file diff --git a/assets/loadtest/etcd/README.md b/assets/loadtest/etcd/README.md deleted file mode 100644 index dc127a63afb2e..0000000000000 --- a/assets/loadtest/etcd/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# etcd - -To generate self-signed certificates for secure connectivity to etcd run: - -```bash -$ make -``` - - -To delete the generated certificates run: - -```bash -$ make clean -``` \ No newline at end of file diff --git a/assets/loadtest/etcd/certs/Makefile b/assets/loadtest/etcd/certs/Makefile old mode 100755 new mode 100644 diff --git a/examples/load-tests/.gitignore b/assets/loadtest/helm/.gitignore similarity index 100% rename from examples/load-tests/.gitignore rename to assets/loadtest/helm/.gitignore diff --git a/examples/load-tests/README.md b/assets/loadtest/helm/README.md similarity index 100% rename from examples/load-tests/README.md rename to assets/loadtest/helm/README.md diff --git a/examples/load-tests/fixtures/user.yaml b/assets/loadtest/helm/fixtures/user.yaml similarity index 100% rename from examples/load-tests/fixtures/user.yaml rename to assets/loadtest/helm/fixtures/user.yaml diff --git a/examples/load-tests/node-agent/.helmignore b/assets/loadtest/helm/node-agent/.helmignore similarity index 100% rename from examples/load-tests/node-agent/.helmignore rename to assets/loadtest/helm/node-agent/.helmignore diff --git a/examples/load-tests/node-agent/Chart.yaml b/assets/loadtest/helm/node-agent/Chart.yaml similarity index 83% rename from examples/load-tests/node-agent/Chart.yaml rename to assets/loadtest/helm/node-agent/Chart.yaml index 345de8f837521..768446bb74150 100644 --- a/examples/load-tests/node-agent/Chart.yaml +++ b/assets/loadtest/helm/node-agent/Chart.yaml @@ -6,4 +6,4 @@ type: application version: 0.1.0 -appVersion: "12.0.0-dev" +appVersion: "13.0.0-alpha.1" diff --git a/examples/load-tests/node-agent/templates/config.yaml b/assets/loadtest/helm/node-agent/templates/config.yaml similarity index 90% rename from examples/load-tests/node-agent/templates/config.yaml rename to assets/loadtest/helm/node-agent/templates/config.yaml index 07958a06d654c..3d6b5e4457239 100644 --- a/examples/load-tests/node-agent/templates/config.yaml +++ b/assets/loadtest/helm/node-agent/templates/config.yaml @@ -24,6 +24,9 @@ data: enabled: false ssh_service: enabled: true + commands: + - name: fullname + command: ['bash', '-c', 'echo "$HOSTNAME-$REPLICA"'] # listen_addr set at runtime to avoid conflicts in the same pod # listen_addr: 0.0.0.0:3022 entrypoint.sh: |2 diff --git a/examples/load-tests/node-agent/templates/deployment.yaml b/assets/loadtest/helm/node-agent/templates/deployment.yaml similarity index 97% rename from examples/load-tests/node-agent/templates/deployment.yaml rename to assets/loadtest/helm/node-agent/templates/deployment.yaml index 8a8da4b2a8652..8e9b22e905e9e 100644 --- a/examples/load-tests/node-agent/templates/deployment.yaml +++ b/assets/loadtest/helm/node-agent/templates/deployment.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - namespace: agents + namespace: {{ .Release.Namespace }} name: {{ .Release.Name }} spec: replicas: {{ .Values.replicaCount }} diff --git a/examples/load-tests/node-agent/templates/serviceaccount.yaml b/assets/loadtest/helm/node-agent/templates/serviceaccount.yaml similarity index 100% rename from examples/load-tests/node-agent/templates/serviceaccount.yaml rename to assets/loadtest/helm/node-agent/templates/serviceaccount.yaml diff --git a/examples/load-tests/node-agent/values.yaml b/assets/loadtest/helm/node-agent/values.yaml similarity index 78% rename from examples/load-tests/node-agent/values.yaml rename to assets/loadtest/helm/node-agent/values.yaml index fd5820fc73589..a3b32c6cd2ce4 100644 --- a/examples/load-tests/node-agent/values.yaml +++ b/assets/loadtest/helm/node-agent/values.yaml @@ -19,14 +19,6 @@ joinParams: # DO NOT USE THIS IN PRODUCTION token_name: qwertyuiop -# Applied par agent (not per-pod) -resources: - limits: - memory: 150Mi - requests: - cpu: 20m - memory: 150Mi - tolerations: [] affinity: {} diff --git a/examples/load-tests/podmonitor.yaml b/assets/loadtest/helm/podmonitor.yaml similarity index 100% rename from examples/load-tests/podmonitor.yaml rename to assets/loadtest/helm/podmonitor.yaml diff --git a/examples/load-tests/tsh-bench-agent/.helmignore b/assets/loadtest/helm/tsh-bench-agent/.helmignore similarity index 100% rename from examples/load-tests/tsh-bench-agent/.helmignore rename to assets/loadtest/helm/tsh-bench-agent/.helmignore diff --git a/examples/load-tests/tsh-bench-agent/Chart.yaml b/assets/loadtest/helm/tsh-bench-agent/Chart.yaml similarity index 83% rename from examples/load-tests/tsh-bench-agent/Chart.yaml rename to assets/loadtest/helm/tsh-bench-agent/Chart.yaml index 69115468689d6..c3a0405f0c3ad 100644 --- a/examples/load-tests/tsh-bench-agent/Chart.yaml +++ b/assets/loadtest/helm/tsh-bench-agent/Chart.yaml @@ -6,4 +6,4 @@ type: application version: 0.1.0 -appVersion: "12.0.0-dev" +appVersion: "13.0.0-alpha.1" diff --git a/examples/load-tests/tsh-bench-agent/templates/deployment.yaml b/assets/loadtest/helm/tsh-bench-agent/templates/deployment.yaml similarity index 100% rename from examples/load-tests/tsh-bench-agent/templates/deployment.yaml rename to assets/loadtest/helm/tsh-bench-agent/templates/deployment.yaml diff --git a/examples/load-tests/tsh-bench-agent/values.yaml b/assets/loadtest/helm/tsh-bench-agent/values.yaml similarity index 100% rename from examples/load-tests/tsh-bench-agent/values.yaml rename to assets/loadtest/helm/tsh-bench-agent/values.yaml diff --git a/examples/load-tests/values/kube-prometheus-stack.yaml b/assets/loadtest/helm/values/kube-prometheus-stack.yaml similarity index 100% rename from examples/load-tests/values/kube-prometheus-stack.yaml rename to assets/loadtest/helm/values/kube-prometheus-stack.yaml diff --git a/assets/loadtest/helm/values/node-agents.yaml b/assets/loadtest/helm/values/node-agents.yaml new file mode 100644 index 0000000000000..c5ebd5e3d1e68 --- /dev/null +++ b/assets/loadtest/helm/values/node-agents.yaml @@ -0,0 +1,11 @@ +replicaCount: 30 +agentsPerPod: 15 + +minReadySeconds: 30 + +image: + tag: 13.0.0-alpha.2 + +joinParams: + method: token + token_name: "qwertyuiop" diff --git a/examples/load-tests/values/teleport.yaml b/assets/loadtest/helm/values/teleport.yaml similarity index 88% rename from examples/load-tests/values/teleport.yaml rename to assets/loadtest/helm/values/teleport.yaml index 67ed4b2982062..6ef242cc6e884 100644 --- a/examples/load-tests/values/teleport.yaml +++ b/assets/loadtest/helm/values/teleport.yaml @@ -26,8 +26,7 @@ podMonitor: enabled: true interval: "" -# TODO: change after v12 is released -teleportVersionOverride: 12.0.0-hugochartsplit.2 +teleportVersionOverride: 13.0.0-alpha.1 auth: teleportConfig: diff --git a/examples/load-tests/values/tsh-bench-agents.yaml b/assets/loadtest/helm/values/tsh-bench-agents.yaml similarity index 100% rename from examples/load-tests/values/tsh-bench-agents.yaml rename to assets/loadtest/helm/values/tsh-bench-agents.yaml diff --git a/assets/loadtest/k8s/Makefile b/assets/loadtest/k8s/Makefile deleted file mode 100644 index d63d8eff21984..0000000000000 --- a/assets/loadtest/k8s/Makefile +++ /dev/null @@ -1,499 +0,0 @@ -LICENSE_PATH ?= /var/lib/teleport/license.pem -CERT_MANAGER_VERSION ?= v1.7.1 -SOAK_TEST_DURATION ?= 30m -BACKEND ?= etcd -USE_CERT_MANAGER ?= yes -TELEPORT_IMAGE ?= public.ecr.aws/gravitational/teleport-ent:12.0.0 -NAMESPACE ?= loadtest -NODE ?= - -# performs initialization needed for cluster -# 1) generates etcd certs -# 2) creates namespace -# 3) installs cert-manager -# 4) creates and applies secrets -.PHONY: setup -setup: - @if [ -z ${TELEPORT_IMAGE} ]; then \ - echo "TELEPORT_IMAGE is not set, cannot apply cluster."; \ - exit 1; \ - fi - - - @echo "applying image: ${TELEPORT_IMAGE}" -ifeq ($(BACKEND), etcd) - $(MAKE) -C ../etcd/certs all -endif - kubectl create namespace $(NAMESPACE) --dry-run=client -o yaml | kubectl apply -f - - $(MAKE) -C ./secrets all -ifeq ($(USE_CERT_MANAGER), yes) - kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/$(CERT_MANAGER_VERSION)/cert-manager.yaml -endif - $(MAKE) generate-secrets - -# create kubernetes secrets -.PHONY: generate-secrets -generate-secrets: -ifeq ($(BACKEND), etcd) - kubectl create secret generic etcd-client-certs -n $(NAMESPACE) \ - --from-file=client-cert.pem=../etcd/certs/client-cert.pem \ - --from-file=client-key.pem=../etcd/certs/client-key.pem \ - --from-file=ca-cert.pem=../etcd/certs/ca-cert.pem \ - --dry-run=client -o yaml | kubectl apply -f - - - kubectl create secret generic etcd-server-certs -n $(NAMESPACE) \ - --from-file=server-cert.pem=../etcd/certs/server-cert.pem \ - --from-file=server-key.pem=../etcd/certs/server-key.pem \ - --from-file=ca-cert.pem=../etcd/certs/ca-cert.pem \ - --dry-run=client -o yaml | kubectl apply -f - -endif - -ifeq ($(BACKEND), firestore) - kubectl create secret generic gcp-creds -n $(NAMESPACE) \ - --from-file=gcp_creds.json=${GCP_CREDS_LOCATION} \ - --dry-run=client -o yaml | kubectl apply -f - -endif - - kubectl create secret generic license -n $(NAMESPACE) \ - --from-file=license.pem=$(LICENSE_PATH) \ - --dry-run=client -o yaml | kubectl apply -f - - -# deletes the loadtest and cert-manager namespaces -.PHONY: clean -clean: - $(MAKE) -C secrets clean - $(MAKE) -C ../etcd/certs clean - kubectl delete namespace $(NAMESPACE) --ignore-not-found - kubectl delete -f https://github.com/jetstack/cert-manager/releases/download/$(CERT_MANAGER_VERSION)/cert-manager.yaml --ignore-not-found - - -ifeq ($(BACKEND), etcd) -# deploys etcd and teleport to the loadtest namespace -.PHONY: apply -apply: setup install-etcd generate-certificates install-monitor install-teleport -else -# deploys and teleport to the loadtest namespace -.PHONY: apply -apply: setup generate-certificates install-monitor install-teleport -endif - -ifeq ($(USE_CERT_MANAGER), yes) -# generate-certificates applies a cert-manager.io/v1/ClusterIssuer and a cert-manager.io/v1/Certificate -# that will automatically fetch tls certificates -.PHONY: generate-certificates -generate-certificates: - kubectl wait --for=condition=available --timeout=600s deploy cert-manager -n cert-manager - kubectl wait --for=condition=available --timeout=600s deploy cert-manager-webhook -n cert-manager - kubectl wait --for=condition=available --timeout=600s deploy cert-manager-cainjector -n cert-manager -# we have to sleep here to due to issues with certmanager -# Error from server (InternalError): error when creating "certificate.yaml": Internal error occurred: failed calling webhook "webhook.cert-manager.io": Post "https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s": x509: certificate signed by unknown authority -# Error from server (InternalError): error when creating "certificate.yaml": Internal error occurred: failed calling webhook "webhook.cert-manager.io": Post "https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s": x509: certificate signed by unknown authority -# See https://github.com/jetstack/cert-manager/issues/2602 and https://github.com/jetstack/cert-manager/issues/2752 - @echo "waiting for cert-manager to be ready..." - @sleep 90 - kubectl apply -f certificate.yaml -else -.PHONY: generate-certificates -generate-certificates: - kubectl apply -f tls.yaml -endif - -# installs teleport auth, proxy, one IoT node and one non-IoT node -.PHONY: install-teleport -install-teleport: install-auth install-proxy install-node install-iot-node - -# deletes teleport deployments, services, and configmaps -.PHONY: delete-teleport -delete-teleport: delete-tc delete-nodes delete-proxy delete-auth - -# installs prometheus exporter -.PHONY: install-monitor -install-monitor: - $(MAKE) -s expand-yaml FILENAME=prometheus NAMESPACE=$(NAMESPACE) - kubectl apply -f prometheus-gen.yaml - -# deletes prometheus exporter -.PHONY: delete-monitor -delete-monitor: - kubectl delete -f prometheus-gen.yaml --ignore-not-found - -# installs an etcd cluster -.PHONY: install-etcd -install-etcd: - kubectl create configmap etcd-config -n $(NAMESPACE) \ - --from-file=etcd.sh=./etcd.sh \ - --dry-run=client -o yaml | kubectl apply -f - - - - $(MAKE) -s expand-yaml FILENAME=etcd NAMESPACE=$(NAMESPACE) - kubectl apply -f etcd-gen.yaml - -# deletes etcd deployment, services, and configmaps -.PHONY: delete-etcd -delete-etcd: - kubectl delete -f etcd-gen.yaml --ignore-not-found - kubectl delete configmap etcd-config -n $(NAMESPACE) --ignore-not-found - - -# install auth and applies required teleport resources for loadtests -.PHONY: install-auth -install-auth: setup-auth - kubectl wait --for=condition=ready pod -l teleport-role=auth -n $(NAMESPACE) --timeout=120s - - kubectl -n $(NAMESPACE) exec deploy/auth -c teleport -it \ - -- tctl --config /etc/teleport/teleport.yaml create -f /etc/teleport/admin.yaml - kubectl -n $(NAMESPACE) exec deploy/auth -c teleport -it \ - -- tctl --config /etc/teleport/teleport.yaml create -f /etc/teleport/oidc.yaml - kubectl -n $(NAMESPACE) exec deploy/auth -c teleport -it \ - -- tctl --config /etc/teleport/teleport.yaml create -f /etc/teleport/user.yaml - - -ifeq ($(BACKEND), etcd) -.PHONY: setup-auth -setup-auth: - $(MAKE) -s expand-yaml FILENAME=../teleport/teleport-auth-etcd - - kubectl create configmap auth-config -n $(NAMESPACE) \ - --from-file=teleport.yaml=../teleport/teleport-auth-etcd-gen.yaml \ - --from-file=oidc.yaml=../teleport/oidc.yaml \ - --from-file=admin.yaml=../teleport/admin.yaml \ - --from-file=user.yaml=../teleport/soaktest-user.yaml \ - --dry-run=client -o yaml | kubectl apply -f - - - $(MAKE) -s expand-yaml FILENAME=auth-etcd TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - kubectl apply -f auth-etcd-gen.yaml -else ifeq ($(BACKEND), firestore) -.PHONY: setup-auth -setup-auth: - $(MAKE) -s expand-yaml FILENAME=../teleport/teleport-auth-firestore - - kubectl create configmap auth-config -n $(NAMESPACE) \ - --from-file=teleport.yaml=../teleport/teleport-auth-firestore-gen.yaml \ - --from-file=oidc.yaml=../teleport/oidc.yaml \ - --from-file=admin.yaml=../teleport/admin.yaml \ - --from-file=user.yaml=../teleport/soaktest-user.yaml \ - --dry-run=client -o yaml | kubectl apply -f - - - $(MAKE) -s expand-yaml FILENAME=auth-firestore TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - kubectl apply -f auth-firestore-gen.yaml -else ifeq ($(BACKEND), dynamo) -.PHONY: setup-auth -setup-auth: - $(MAKE) -s expand-yaml DYNAMO_TABLE=${DYNAMO_TABLE} DYNAMO_REGION=${DYNAMO_REGION} FILENAME=../teleport/teleport-auth-dynamo - - kubectl create configmap auth-config -n $(NAMESPACE) \ - --from-file=teleport.yaml=../teleport/teleport-auth-dynamo-gen.yaml \ - --from-file=oidc.yaml=../teleport/oidc.yaml \ - --from-file=admin.yaml=../teleport/admin.yaml \ - --from-file=user.yaml=../teleport/soaktest-user.yaml \ - --dry-run=client -o yaml | kubectl apply -f - - - $(MAKE) -s expand-yaml FILENAME=auth-dynamo TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - kubectl apply -f auth-dynamo-gen.yaml -else -.PHONY: setup-auth -setup-auth: - @echo "unknown backend $(BACKEND)" - exit 1 -endif - -# deletes auth deployment, services and configmaps -.PHONY: delete-auth -delete-auth: - kubectl delete -f auth-etcd-gen.yaml --ignore-not-found - kubectl delete -f auth-dynamo-gen.yaml --ignore-not-found - kubectl delete -f auth-firestore-gen.yaml --ignore-not-found - kubectl delete configmap auth-config -n $(NAMESPACE) --ignore-not-found - -# install proxy -.PHONY: install-proxy -install-proxy: - $(MAKE) -s expand-yaml FILENAME=../teleport/teleport-proxy - kubectl create configmap proxy-config -n $(NAMESPACE) \ - --from-file=teleport.yaml=../teleport/teleport-proxy-gen.yaml \ - --dry-run=client -o yaml | kubectl apply -f - - - - $(MAKE) -s expand-yaml FILENAME=proxy TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - kubectl apply -f proxy-gen.yaml - -# deletes proxy deployment, services and configmaps -.PHONY: delete-proxy -delete-proxy: - kubectl delete -f proxy-gen.yaml --ignore-not-found - kubectl delete configmap proxy-config -n $(NAMESPACE) --ignore-not-found - -# deletes all node deployment and configmaps -.PHONY: delete-nodes -delete-nodes: delete-node delete-iot-node - -# deletes all non-IoT nodes -.PHONY: delete-node -delete-node: - kubectl delete -f node-gen.yaml --ignore-not-found - kubectl delete configmap node-config -n $(NAMESPACE) --ignore-not-found - -# deletes all IoT nodes -.PHONY: delete-iot-node -delete-iot-node: - kubectl delete -f iot-node-gen.yaml --ignore-not-found - kubectl delete configmap iot-node-config -n $(NAMESPACE) --ignore-not-found - -# install one IoT node and one non-IoT node -.PHONY: install-nodes -install-nodes: install-iot-node install-node - -# install an IoT mode node -.PHONY: install-iot-node -install-iot-node: - $(MAKE) -s expand-yaml FILENAME=../teleport/teleport-iot-node - kubectl create configmap iot-node-config -n $(NAMESPACE) \ - --from-file=teleport.yaml=../teleport/teleport-iot-node-gen.yaml \ - --dry-run=client -o yaml | kubectl apply -f - - - $(MAKE) -s expand-yaml FILENAME=iot-node TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - kubectl apply -f iot-node-gen.yaml - -# install a non-IoT mode node -.PHONY: install-node -install-node: - $(MAKE) -s expand-yaml FILENAME=../teleport/teleport-node - kubectl create configmap node-config -n $(NAMESPACE) \ - --from-file=teleport.yaml=../teleport/teleport-node-gen.yaml \ - --dry-run=client -o yaml | kubectl apply -f - - - $(MAKE) -s expand-yaml FILENAME=node TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - kubectl apply -f node-gen.yaml - -# installs a trusted cluster -.PHONY: install-tc -install-tc: - $(MAKE) -s expand-yaml FILENAME=../teleport/tc - kubectl create configmap tc-config -n $(NAMESPACE) \ - --from-file=teleport.yaml=../teleport/teleport-tc.yaml \ - --from-file=cluster.yaml=../teleport/tc-gen.yaml \ - --dry-run=client -o yaml | kubectl apply -f - - - $(MAKE) -s expand-yaml FILENAME=tc TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) NAMESPACE=$(NAMESPACE) - kubectl apply -f tc-gen.yaml - -# deletes all rc resources from teleport and deletes trusted cluster deployments and configmaps -.PHONY: delete-tc -delete-tc: - kubectl delete -f tc-gen.yaml --ignore-not-found - kubectl delete configmap tc-config -n $(NAMESPACE) --ignore-not-found - - kubectl -n $(NAMESPACE) exec deploy/auth -c teleport -it \ - -- /bin/bash -c "tctl --config /etc/teleport/teleport.yaml get rc | grep ' name:' | cut -d ':' -f2- | xargs -P 20 -n 1 -I {} tctl --config /etc/teleport/teleport.yaml rm rc/{}" - -# joins all trusted clusters to root cluster -.PHONY: setup-tc -setup-tc: - kubectl get pod -n $(NAMESPACE) -l app="tc" -o custom-columns=name:metadata.name --no-headers \ - | xargs -P 20 -n 1 -I {} kubectl -n $(NAMESPACE) exec {} -- tctl --config /etc/teleport/teleport.yaml create -f /etc/teleport/cluster.yaml - -# scales trusted clusters to 500 -.PHONY: scale-tc-500 -scale-tc-500: - kubectl scale --replicas=500 deploy tc -n $(NAMESPACE) - -# scales trusted clusters to 1 -.PHONY: scale-tc-1 -scale-tc-1: - kubectl scale --replicas=1 deploy tc -n $(NAMESPACE) - -# scales nodes to 1 -.PHONY: scale-1-non-iot -scale-1-non-iot: - kubectl scale --replicas=1 deploy node -n $(NAMESPACE) - -# scales nodes to 1000 -.PHONY: scale-1k-non-iot -scale-1k-non-iot: - kubectl scale --replicas=1000 deploy node -n $(NAMESPACE) - -# scales nodes to 10000 -.PHONY: scale-10k-non-iot -scale-10k-non-iot: - kubectl scale --replicas=10000 deploy node -n $(NAMESPACE) - -# scales nodes to 1 -.PHONY: scale-1-iot -scale-1-iot: - kubectl scale --replicas=1 deploy iot-node -n $(NAMESPACE) - -# scales nodes to 1000 -.PHONY: scale-1k-iot -scale-1k-iot: - kubectl scale --replicas=1000 deploy iot-node -n $(NAMESPACE) - -# scales nodes to 10000 -.PHONY: scale-10k-iot -scale-10k-iot: - kubectl scale --replicas=10000 deploy iot-node -n $(NAMESPACE) - -# gets pods in loadtest namespace -.PHONY: pods -pods: - kubectl get pods -n $(NAMESPACE) - -# removes all soak test jobs and configmaps -.PHONY: delete-soaktest -.PHONY: delete-soaktest -delete-soaktest: - kubectl delete job -l app=soaktest -n $(NAMESPACE) --ignore-not-found - - kubectl delete configmap soaktest-config -n $(NAMESPACE) --ignore-not-found - -# creates the soak test job -.PHONY: install-soaktest -install-soaktest: - kubectl create configmap soaktest-config -n $(NAMESPACE) \ - --from-file=soaktest.sh=../teleport/soaktest.sh \ - --from-literal=DURATION=$(SOAK_TEST_DURATION) \ - --dry-run=client -o yaml | kubectl apply -f - - - kubectl create secret generic soaktest -n $(NAMESPACE) \ - --from-file=auth=./secrets/soaktest-auth \ - --from-literal=PROXY_HOST=$$(cat ./secrets/secrets.env | grep PROXY_HOST | cut -d '=' -f2- ) \ - --dry-run=client -o yaml | kubectl apply -f - - - $(MAKE) -s expand-yaml FILENAME=soaktest TELEPORT_IMAGE=$(TELEPORT_IMAGE) NAMESPACE=$(NAMESPACE) - kubectl create -f soaktest-gen.yaml - -# deploys a job to run the soak tests -.PHONY: run-soak-tests -run-soak-tests: - kubectl -n $(NAMESPACE) exec $$(kubectl get pod -n $(NAMESPACE) -l teleport-role="auth" -o jsonpath="{.items[0].metadata.name}") -it \ - -- tctl auth sign --overwrite --user=soaktest-runner --out=/data/soaktest-auth --ttl=8760h --config /etc/teleport/teleport.yaml - - kubectl cp $(NAMESPACE)/$$(kubectl get pod -n $(NAMESPACE) -l teleport-role="auth" -o jsonpath="{.items[0].metadata.name}"):/data/soaktest-auth ./secrets/soaktest-auth - - kubectl wait --for=condition=available --timeout=600s deploy/node -n $(NAMESPACE) - kubectl wait --for=condition=available --timeout=600s deploy/iot-node -n $(NAMESPACE) - - $(MAKE) -s install-soaktest - - @sleep 1 - - kubectl wait --for=condition=ready pod $$(kubectl get pods --sort-by=.metadata.creationTimestamp -o jsonpath="{.items[-1:].metadata.name}" -l app=soaktest -n $(NAMESPACE)) -n $(NAMESPACE) --timeout=120s - kubectl logs $$(kubectl get pods --sort-by=.metadata.creationTimestamp -o jsonpath="{.items[-1:].metadata.name}" -l app=soaktest -n $(NAMESPACE)) -n $(NAMESPACE) --tail -1 -f - -# runs the node scaling tests -.PHONY: run-scaling-test -run-scaling-test: - $(MAKE) -s delete-nodes - $(MAKE) -s install-node - $(MAKE) -s scale-10k-non-iot - @kubectl wait --for=condition=available deploy/node -n $(NAMESPACE) --timeout=60m - @sleep 30 - $(MAKE) -s scale-1-non-iot - @sleep 15 - $(MAKE) -s scale-10k-non-iot - @kubectl wait --for=condition=available deploy/node -n $(NAMESPACE) --timeout=60m - @sleep 15 - $(MAKE) -s scale-1-non-iot - - @sleep 15 - - $(MAKE) -s delete-nodes - $(MAKE) -s install-iot-node - $(MAKE) -s scale-10k-iot - @kubectl wait --for=condition=available deploy/iot-node -n $(NAMESPACE) --timeout=60m - @sleep 30 - $(MAKE) -s scale-1-iot - @sleep 15 - $(MAKE) -s scale-10k-iot - @kubectl wait --for=condition=available deploy/iot-node -n $(NAMESPACE) --timeout=60m - @sleep 15 - $(MAKE) -s scale-1 - - $(MAKE) -s delete-nodes - $(MAKE) -s install-nodes - -# runs the trusted-cluster scaling tests -.PHONY: run-tc-scaling-test -run-tc-scaling-test: - $(MAKE) -s install-tc - $(MAKE) -s scale-tc-500 - kubectl wait --for=condition=available deploy/tc -n $(NAMESPACE) --timeout=60m - @sleep 120 - $(MAKE) -s setup-tc - - @sleep 300 - - $(MAKE) -s delete-tc - - @sleep 180 - - $(MAKE) -s install-tc - $(MAKE) -s scale-tc-500 - kubectl wait --for=condition=available deploy/tc -n $(NAMESPACE) --timeout=60m - @sleep 120 - $(MAKE) -s setup-tc - - @sleep 300 - - $(MAKE) -s delete-tc - -# collect goroutine and heap go profiles from the auth deployment -.PHONY: collect-profiles -collect-profiles: collect-auth collect-proxy collect-node - -# forwards the pods diagnostics address -.PHONY: forward-pod-diagnostics -forward-pod-diagnostics: - kubectl port-forward $(POD) 3434:3434 -n $(NAMESPACE) > /dev/null 2>&1 & - -# retrieves profiles from all pods matching the selector -.PHONY: collect-pods -collect-pods: - @for POD in $$(kubectl get pod -n $(NAMESPACE) -l $(SELECTOR) -o custom-columns=name:metadata.name --no-headers) ; do \ -$(MAKE) collect-pod POD=$$POD ; \ - done - -# retrieves profiles from all proxy pods -.PHONY: collect-proxy -collect-proxy: - $(MAKE) -s collect-pods SELECTOR=teleport-role="proxy" - -# retrieves profiles from all auth pods -.PHONY: collect-auth -collect-auth: - $(MAKE) -s collect-pods SELECTOR=teleport-role="auth" - -# retrieves profiles from a node -.PHONY: collect-node -collect-node: - $(MAKE) -s collect-pod POD=$(NODE) - -# retrieves profiles from a particular pod -ifeq ($(POD),) -.PHONY: collect-pod -collect-pod: - @echo "No pod provided; $(MAKE) collect-pod POD=" - exit 1 -else -.PHONY: collect-pod -collect-pod: - $(MAKE) -s forward-pod-diagnostics POD=$(POD) - @echo "waiting for $(POD) to be available..." - @timeout 30 sh -c 'until nc -z localhost 3434; do sleep 0.5; done' - @if [ $$? -ne 0 ]; then echo "unable to reach $$POD"; exit 1; fi - $(MAKE) -s fetch-profiles LOCATION=$(POD)-$(shell date +%s) - kill -s kill $$(pgrep -f 3434:3434) -endif - -# downloads the remote profiles -.PHONY: fetch-profiles -fetch-profiles: - mkdir -p $(PWD)/profiles/$(LOCATION)/ - curl -o $(PWD)/profiles/$(LOCATION)/goroutine.profile http://127.0.0.1:3434/debug/pprof/goroutine - curl -o $(PWD)/profiles/$(LOCATION)/heap.profile http://127.0.0.1:3434/debug/pprof/heap - curl -o $(PWD)/profiles/$(LOCATION)/trace.profile http://127.0.0.1:3434/debug/pprof/trace?seconds=10 - -# expands any placeholders in the provided yaml file with the value in the matching environment variable. the -# output file will be named the same with a -gen suffix, i.e input = test then output will be test-gen.yaml -.PHONY: expand-yaml -expand-yaml: - @bash -c "set -a && source ./secrets/secrets.env && set +a && envsubst < $(FILENAME).yaml > $(FILENAME)-gen.yaml" diff --git a/assets/loadtest/k8s/auth-dynamo.yaml b/assets/loadtest/k8s/auth-dynamo.yaml deleted file mode 100644 index 1d4fa0a54216f..0000000000000 --- a/assets/loadtest/k8s/auth-dynamo.yaml +++ /dev/null @@ -1,83 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: auth - namespace: ${NAMESPACE} - labels: - teleport-role: auth -spec: - replicas: 3 - selector: - matchLabels: - teleport-role: auth - template: - metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "3434" - labels: - backend: dynamo - teleport-role: auth - spec: - volumes: - - name: config - configMap: - name: auth-config - - name: license - secret: - secretName: license - - name: storage - emptyDir: {} - containers: - - name: teleport - image: ${TELEPORT_IMAGE} - args: ["-d", "--insecure", "--diag-addr=0.0.0.0:3434"] - ports: - - name: diag - containerPort: 3434 - protocol: TCP - readinessProbe: - failureThreshold: 3 - httpGet: - path: /healthz - port: 3434 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 30 - successThreshold: 1 - timeoutSeconds: 2 - livenessProbe: - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - tcpSocket: - port: 3434 - timeoutSeconds: 1 - volumeMounts: - - name: config - mountPath: /etc/teleport/ - readOnly: true - - name: license - mountPath: /var/lib/teleport/license.pem - subPath: license.pem - readOnly: true - - mountPath: /data - name: storage ---- -apiVersion: v1 -kind: Service -metadata: - name: auth - namespace: ${NAMESPACE} -spec: - ports: - - name: auth - port: 3025 - targetPort: 3025 - - name: diag - port: 3434 - targetPort: 3434 - selector: - teleport-role: auth - type: ClusterIP diff --git a/assets/loadtest/k8s/auth-etcd.yaml b/assets/loadtest/k8s/auth-etcd.yaml deleted file mode 100644 index 33cb2887ac64e..0000000000000 --- a/assets/loadtest/k8s/auth-etcd.yaml +++ /dev/null @@ -1,91 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: auth - namespace: ${NAMESPACE} - labels: - teleport-role: auth -spec: - replicas: 3 - selector: - matchLabels: - teleport-role: auth - template: - metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "3434" - labels: - teleport-role: auth - backend: etcd - prometheus.io/scrape: "true" - prometheus.io/port: "3434" - spec: - volumes: - - name: config - configMap: - name: auth-config - - name: certs - secret: - secretName: etcd-client-certs - - name: license - secret: - secretName: license - - name: storage - emptyDir: {} - containers: - - name: teleport - image: ${TELEPORT_IMAGE} - args: ["-d", "--insecure", "--diag-addr=0.0.0.0:3434"] - ports: - - name: diag - containerPort: 3434 - protocol: TCP - readinessProbe: - failureThreshold: 3 - httpGet: - path: /healthz - port: 3434 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 30 - successThreshold: 1 - timeoutSeconds: 2 - livenessProbe: - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - tcpSocket: - port: 3434 - timeoutSeconds: 1 - volumeMounts: - - name: config - mountPath: /etc/teleport/ - readOnly: true - - name: license - mountPath: /var/lib/teleport/license.pem - subPath: license.pem - readOnly: true - - name: certs - mountPath: /etc/etcd/certs/ - readOnly: true - - mountPath: /data - name: storage ---- -apiVersion: v1 -kind: Service -metadata: - name: auth - namespace: ${NAMESPACE} -spec: - ports: - - name: auth - port: 3025 - targetPort: 3025 - - name: diag - port: 3434 - targetPort: 3434 - selector: - teleport-role: auth - type: ClusterIP diff --git a/assets/loadtest/k8s/auth-firestore.yaml b/assets/loadtest/k8s/auth-firestore.yaml deleted file mode 100644 index e0a8afc7b8678..0000000000000 --- a/assets/loadtest/k8s/auth-firestore.yaml +++ /dev/null @@ -1,92 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: auth - namespace: ${NAMESPACE} - labels: - teleport-role: auth -spec: - replicas: 3 - selector: - matchLabels: - teleport-role: auth - template: - metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "3434" - labels: - teleport-role: auth - backend: firestore - prometheus.io/scrape: "true" - prometheus.io/port: "3434" - spec: - volumes: - - name: config - configMap: - name: auth-config - - name: creds - secret: - secretName: gcp-creds - - name: license - secret: - secretName: license - - name: storage - emptyDir: {} - containers: - - name: teleport - image: ${TELEPORT_IMAGE} - args: ["-d", "--insecure", "--diag-addr=0.0.0.0:3434"] - ports: - - name: diag - containerPort: 3434 - protocol: TCP - readinessProbe: - failureThreshold: 3 - httpGet: - path: /healthz - port: 3434 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 30 - successThreshold: 1 - timeoutSeconds: 2 - livenessProbe: - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - tcpSocket: - port: 3434 - timeoutSeconds: 1 - volumeMounts: - - name: config - mountPath: /etc/teleport/ - readOnly: true - - name: license - mountPath: /var/lib/teleport/license.pem - subPath: license.pem - readOnly: true - - name: creds - mountPath: /var/lib/teleport/gcp_creds.json - subPath: gcp_creds.json - readOnly: true - - mountPath: /data - name: storage ---- -apiVersion: v1 -kind: Service -metadata: - name: auth - namespace: ${NAMESPACE} -spec: - ports: - - name: auth - port: 3025 - targetPort: 3025 - - name: diag - port: 3434 - targetPort: 3434 - selector: - teleport-role: auth - type: ClusterIP diff --git a/assets/loadtest/k8s/etcd.sh b/assets/loadtest/k8s/etcd.sh deleted file mode 100644 index 9e7b9446f7667..0000000000000 --- a/assets/loadtest/k8s/etcd.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# This script runs etcd. -set -e -set -x - -PEERS="etcd-0=https://etcd-0.etcd:2380,etcd-1=https://etcd-1.etcd:2380,etcd-2=https://etcd-2.etcd:2380" -exec etcd \ - --name ${POD_NAME} \ - --advertise-client-urls https://${POD_NAME}.etcd:2379 \ - --listen-client-urls https://0.0.0.0:2379 \ - --initial-advertise-peer-urls https://${POD_NAME}.etcd:2380 \ - --listen-peer-urls https://0.0.0.0:2380 \ - --initial-cluster ${PEERS} \ - --trusted-ca-file=/etc/etcd/certs/ca-cert.pem \ - --cert-file=/etc/etcd/certs/server-cert.pem \ - --key-file=/etc/etcd/certs/server-key.pem \ - --peer-cert-file=/etc/etcd/certs/server-cert.pem \ - --peer-key-file=/etc/etcd/certs/server-key.pem \ - --peer-trusted-ca-file=/etc/etcd/certs/ca-cert.pem \ - --client-cert-auth \ - --peer-client-cert-auth \ - --auto-compaction-retention=1 \ No newline at end of file diff --git a/assets/loadtest/k8s/etcd.yaml b/assets/loadtest/k8s/etcd.yaml deleted file mode 100644 index 83c936bec4e7f..0000000000000 --- a/assets/loadtest/k8s/etcd.yaml +++ /dev/null @@ -1,74 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: etcd - namespace: ${NAMESPACE} - labels: - app: etcd -spec: - serviceName: etcd - replicas: 3 - selector: - matchLabels: - app: etcd - template: - metadata: - name: etcd - labels: - app: etcd - spec: - volumes: - - name: config - configMap: - name: etcd-config - defaultMode: 0777 - - name: server-certs - secret: - secretName: etcd-server-certs - - name: client-certs - secret: - secretName: etcd-client-certs - containers: - - name: etcd - image: quay.io/coreos/etcd:v3.3.25 - ports: - - containerPort: 2379 - name: client - - containerPort: 2380 - name: peer - volumeMounts: - - mountPath: /scripts - name: config - readOnly: true - - name: server-certs - mountPath: /etc/etcd/certs/ - readOnly: true - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - command: - - /bin/sh - - -c - - | - cp /scripts/etcd.sh /tmp - chmod +x /tmp/etcd.sh - /tmp/etcd.sh ---- -apiVersion: v1 -kind: Service -metadata: - name: etcd - namespace: ${NAMESPACE} - labels: - app: etcd -spec: - clusterIP: None - ports: - - port: 2379 - name: client - - port: 2380 - name: peer - selector: - app: etcd \ No newline at end of file diff --git a/assets/loadtest/k8s/iot-node.yaml b/assets/loadtest/k8s/iot-node.yaml deleted file mode 100644 index 0a65a092f8d2d..0000000000000 --- a/assets/loadtest/k8s/iot-node.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - teleport-role: node - name: iot-node - namespace: ${NAMESPACE} -spec: - replicas: 1 - selector: - matchLabels: - teleport-role: node - node: iot - template: - metadata: - labels: - teleport-role: node - node: iot - spec: - containers: - - image: ${TELEPORT_IMAGE} - name: teleport - args: ["-d", "--insecure", "--diag-addr=0.0.0.0:3434"] - ports: - - name: nodessh - containerPort: 3022 - protocol: TCP - - name: diag - containerPort: 3434 - protocol: TCP - readinessProbe: - failureThreshold: 3 - httpGet: - path: /healthz - port: 3434 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 30 - successThreshold: 1 - timeoutSeconds: 2 - livenessProbe: - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - tcpSocket: - port: 3434 - timeoutSeconds: 1 - volumeMounts: - - mountPath: /etc/teleport - name: config - readOnly: true - volumes: - - configMap: - name: iot-node-config - name: config diff --git a/assets/loadtest/k8s/node.yaml b/assets/loadtest/k8s/node.yaml deleted file mode 100644 index b1ecc77234d50..0000000000000 --- a/assets/loadtest/k8s/node.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - teleport-role: node - name: node - namespace: ${NAMESPACE} -spec: - replicas: 1 - selector: - matchLabels: - teleport-role: node - node: regular - template: - metadata: - labels: - teleport-role: node - node: regular - spec: - containers: - - image: ${TELEPORT_IMAGE} - name: teleport - args: ["-d", "--insecure", "--diag-addr=0.0.0.0:3434"] - ports: - - name: nodessh - containerPort: 3022 - protocol: TCP - - name: diag - containerPort: 3434 - protocol: TCP - readinessProbe: - failureThreshold: 3 - httpGet: - path: /healthz - port: 3434 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 30 - successThreshold: 1 - timeoutSeconds: 2 - livenessProbe: - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - tcpSocket: - port: 3434 - timeoutSeconds: 1 - volumeMounts: - - mountPath: /etc/teleport - name: config - readOnly: true - volumes: - - configMap: - name: node-config - name: config diff --git a/assets/loadtest/k8s/prometheus.yaml b/assets/loadtest/k8s/prometheus.yaml deleted file mode 100644 index 3649f3f7f92d0..0000000000000 --- a/assets/loadtest/k8s/prometheus.yaml +++ /dev/null @@ -1,291 +0,0 @@ ---- -apiVersion: v1 -kind: Namespace -metadata: - name: prometheus-loadtest ---- -# Source: prometheus/templates/server/serviceaccount.yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - component: "server" - app: prometheus - release: prometheus - chart: prometheus-15.4.0 - heritage: Helm - name: prometheus-server - namespace: prometheus-loadtest - annotations: - {} ---- -# Source: prometheus/templates/server/cm.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - component: "server" - app: prometheus - release: prometheus - chart: prometheus-15.4.0 - heritage: Helm - name: prometheus-server - namespace: prometheus-loadtest -data: - alerting_rules.yml: | - {} - alerts: | - {} - prometheus.yml: | - global: - evaluation_interval: 1m - scrape_interval: 1m - scrape_timeout: 10s - remote_write: - - url: ${PROM_REMOTE_URL} - basic_auth: - username: ${PROM_USER} - password: ${PROM_PASSWORD} - rule_files: - - /etc/config/recording_rules.yml - - /etc/config/alerting_rules.yml - - /etc/config/rules - - /etc/config/alerts - scrape_configs: - - job_name: kubernetes-pods - kubernetes_sd_configs: - - role: pod - relabel_configs: - - action: keep - regex: true - source_labels: - - __meta_kubernetes_pod_annotation_prometheus_io_scrape - - action: drop - regex: true - source_labels: - - __meta_kubernetes_pod_annotation_prometheus_io_scrape_slow - - action: replace - regex: (https?) - source_labels: - - __meta_kubernetes_pod_annotation_prometheus_io_scheme - target_label: __scheme__ - - action: replace - regex: (.+) - source_labels: - - __meta_kubernetes_pod_annotation_prometheus_io_path - target_label: __metrics_path__ - - action: replace - regex: ([^:]+)(?::\d+)?;(\d+) - replacement: $1:$2 - source_labels: - - __address__ - - __meta_kubernetes_pod_annotation_prometheus_io_port - target_label: __address__ - - action: labelmap - regex: __meta_kubernetes_pod_annotation_prometheus_io_param_(.+) - replacement: __param_$1 - - action: labelmap - regex: __meta_kubernetes_pod_label_(.+) - - action: replace - source_labels: - - __meta_kubernetes_namespace - target_label: namespace - - action: replace - source_labels: - - __meta_kubernetes_pod_name - target_label: pod - - action: drop - regex: Pending|Succeeded|Failed|Completed - source_labels: - - __meta_kubernetes_pod_phase - recording_rules.yml: | - {} - rules: | - {} ---- -# Source: prometheus/templates/server/clusterrole.yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - component: "server" - app: prometheus - release: prometheus - chart: prometheus-15.4.0 - heritage: Helm - name: prometheus-server -rules: - - apiGroups: - - "" - resources: - - nodes - - nodes/proxy - - nodes/metrics - - services - - endpoints - - pods - - ingresses - - configmaps - verbs: - - get - - list - - watch - - apiGroups: - - "extensions" - - "networking.k8s.io" - resources: - - ingresses/status - - ingresses - verbs: - - get - - list - - watch - - nonResourceURLs: - - "/metrics" - verbs: - - get ---- -# Source: prometheus/templates/server/clusterrolebinding.yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - component: "server" - app: prometheus - release: prometheus - chart: prometheus-15.4.0 - heritage: Helm - name: prometheus-server -subjects: - - kind: ServiceAccount - name: prometheus-server - namespace: prometheus-loadtest -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: prometheus-server ---- -# Source: prometheus/templates/server/service.yaml -apiVersion: v1 -kind: Service -metadata: - labels: - component: "server" - app: prometheus - release: prometheus - chart: prometheus-15.4.0 - heritage: Helm - name: prometheus-server - namespace: prometheus-loadtest -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: 9090 - selector: - component: "server" - app: prometheus - release: prometheus - sessionAffinity: None - type: "ClusterIP" ---- -# Source: prometheus/templates/server/deploy.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - component: "server" - app: prometheus - release: prometheus - chart: prometheus-15.4.0 - heritage: Helm - name: prometheus-server - namespace: prometheus-loadtest -spec: - selector: - matchLabels: - component: "server" - app: prometheus - release: prometheus - replicas: 1 - template: - metadata: - labels: - component: "server" - app: prometheus - release: prometheus - chart: prometheus-15.4.0 - heritage: Helm - spec: - enableServiceLinks: true - serviceAccountName: prometheus-server - containers: - - name: prometheus-server-configmap-reload - image: "jimmidyson/configmap-reload:v0.5.0" - imagePullPolicy: "IfNotPresent" - args: - - --volume-dir=/etc/config - - --webhook-url=http://127.0.0.1:9090/-/reload - resources: - {} - volumeMounts: - - name: config-volume - mountPath: /etc/config - readOnly: true - - - name: prometheus-server - image: "quay.io/prometheus/prometheus:v2.31.1" - imagePullPolicy: "IfNotPresent" - args: - - --storage.tsdb.retention.time=15d - - --config.file=/etc/config/prometheus.yml - - --storage.tsdb.path=/data - - --web.console.libraries=/etc/prometheus/console_libraries - - --web.console.templates=/etc/prometheus/consoles - - --web.enable-lifecycle - ports: - - containerPort: 9090 - readinessProbe: - httpGet: - path: /-/ready - port: 9090 - scheme: HTTP - initialDelaySeconds: 30 - periodSeconds: 5 - timeoutSeconds: 4 - failureThreshold: 3 - successThreshold: 1 - livenessProbe: - httpGet: - path: /-/healthy - port: 9090 - scheme: HTTP - initialDelaySeconds: 30 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 3 - successThreshold: 1 - resources: - {} - volumeMounts: - - name: config-volume - mountPath: /etc/config - - name: storage-volume - mountPath: /data - subPath: "" - hostNetwork: false - dnsPolicy: ClusterFirst - securityContext: - fsGroup: 65534 - runAsGroup: 65534 - runAsNonRoot: true - runAsUser: 65534 - terminationGracePeriodSeconds: 300 - volumes: - - name: config-volume - configMap: - name: prometheus-server - - name: storage-volume - emptyDir: - {} diff --git a/assets/loadtest/k8s/proxy.yaml b/assets/loadtest/k8s/proxy.yaml deleted file mode 100644 index c377949554d48..0000000000000 --- a/assets/loadtest/k8s/proxy.yaml +++ /dev/null @@ -1,102 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: proxy - namespace: ${NAMESPACE} - labels: - teleport-role: proxy -spec: - replicas: 2 - selector: - matchLabels: - teleport-role: proxy - template: - metadata: - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "3434" - labels: - teleport-role: proxy - prometheus.io/scrape: "true" - prometheus.io/port: "3434" - spec: - volumes: - - name: config - configMap: - name: proxy-config - - name: teleport-tls - secret: - secretName: teleport-tls - containers: - - name: teleport - image: ${TELEPORT_IMAGE} - args: ["-d", "--insecure", "--diag-addr=0.0.0.0:3434"] - ports: - - name: diag - containerPort: 3434 - protocol: TCP - - name: web - containerPort: 3080 - protocol: TCP - readinessProbe: - failureThreshold: 3 - httpGet: - path: /healthz - port: 3434 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 30 - successThreshold: 1 - timeoutSeconds: 2 - livenessProbe: - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - tcpSocket: - port: 3434 - timeoutSeconds: 1 - volumeMounts: - - name: config - mountPath: /etc/teleport/ - readOnly: true - - name: teleport-tls - mountPath: /etc/teleport-tls/ - readOnly: true ---- -apiVersion: v1 -kind: Service -metadata: - name: proxy - namespace: ${NAMESPACE} - labels: - teleport-role: proxy -spec: - type: LoadBalancer - loadBalancerIP: ${PROXY_IP} - ports: - - name: https - port: 3080 - targetPort: 3080 - protocol: TCP - - name: sshproxy - port: 3023 - targetPort: 3023 - protocol: TCP - - name: k8s - port: 3026 - targetPort: 3026 - protocol: TCP - - name: sshtun - port: 3024 - targetPort: 3024 - protocol: TCP - - name: mysql - port: 3036 - targetPort: 3036 - protocol: TCP - - name: diag - port: 3434 - targetPort: 3434 - selector: - teleport-role: proxy diff --git a/assets/loadtest/k8s/secrets/Makefile b/assets/loadtest/k8s/secrets/Makefile deleted file mode 100644 index 9e3ad14ff265d..0000000000000 --- a/assets/loadtest/k8s/secrets/Makefile +++ /dev/null @@ -1,58 +0,0 @@ - -# output: -# node-token : static join token for teleport nodes -# proxy-token : static join token for teleport proxies -# tc-token : static join token for teleport trusted clusters -# secrets.env : env file to be used to replace placeholder values in yaml files -.PHONY:all -all: join-tokens env - @rm -rf *csr - -.PHONY: env -env: - @if [ -z ${PROXY_HOST} ]; then \ - echo "PROXY_HOST is not set, cannot apply cluster."; \ - exit 1; \ - fi - - @if [ -z ${PROM_REMOTE_URL} ]; then \ - echo "PROM_REMOTE_URL is not set, cannot apply cluster."; \ - exit 1; \ - fi - - @if [ -z ${PROM_USER} ]; then \ - echo "PROM_USER is not set, cannot apply cluster."; \ - exit 1; \ - fi - - @if [ -z ${PROM_PASSWORD} ]; then \ - echo "PROM_PASSWORD is not set, cannot apply cluster."; \ - exit 1; \ - fi - - @echo PROXY_IP=$(shell make -C ../../network get-proxy-ip) > secrets.env - @echo PROXY_HOST=${PROXY_HOST} >> secrets.env - @echo NODE_TOKEN=$(shell cat node-token) >> secrets.env - @echo PROXY_TOKEN=$(shell cat proxy-token) >> secrets.env - @echo TC_TOKEN=$(shell cat tc-token) >> secrets.env - @echo GCP_PROJECT=$(shell make -C ../../cluster get-project) >> secrets.env - @echo PROM_REMOTE_URL=${PROM_REMOTE_URL} >> secrets.env - @echo PROM_USER=${PROM_USER} >> secrets.env - @echo PROM_PASSWORD=${PROM_PASSWORD} >> secrets.env - -node-token: - openssl rand -base64 32 | tr -d '\n' > node-token - -proxy-token: - openssl rand -base64 32 | tr -d '\n' > proxy-token - -tc-token: - openssl rand -base64 32 | tr -d '\n' > tc-token - -.PHONY: join-tokens -join-tokens: node-token proxy-token tc-token - -# removes everything -.PHONY:clean -clean: - rm -rf *-pass *-token *-auth *.env \ No newline at end of file diff --git a/assets/loadtest/k8s/soaktest.yaml b/assets/loadtest/k8s/soaktest.yaml deleted file mode 100644 index 98cc56f6f8cff..0000000000000 --- a/assets/loadtest/k8s/soaktest.yaml +++ /dev/null @@ -1,47 +0,0 @@ -apiVersion: batch/v1 -kind: Job -metadata: - generateName: soaktest- - namespace: ${NAMESPACE} - labels: - app: soaktest -spec: - completions: 1 - parallelism: 1 - backoffLimit: 2 - template: - metadata: - labels: - app: soaktest - spec: - restartPolicy: Never - volumes: - - name: config - configMap: - name: soaktest-config - defaultMode: 0777 - - name: soaktest-auth - secret: - secretName: soaktest - containers: - - image: ${TELEPORT_IMAGE} - name: teleport - envFrom: - - configMapRef: - name: soaktest-config - - secretRef: - name: soaktest - command: - - /bin/sh - - -c - - | - cp /scripts/soaktest.sh /tmp - chmod +x /tmp/soaktest.sh - /tmp/soaktest.sh - volumeMounts: - - mountPath: /scripts - name: config - readOnly: true - - mountPath: /etc/teleport - name: soaktest-auth - readOnly: true diff --git a/assets/loadtest/k8s/tc.yaml b/assets/loadtest/k8s/tc.yaml deleted file mode 100644 index 606ae8663146a..0000000000000 --- a/assets/loadtest/k8s/tc.yaml +++ /dev/null @@ -1,61 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: tc - name: tc - namespace: ${NAMESPACE} -spec: - replicas: 1 - selector: - matchLabels: - app: tc - template: - metadata: - labels: - app: tc - spec: - volumes: - - name: config - configMap: - name: tc-config - - name: license - secret: - secretName: license - containers: - - image: ${TELEPORT_IMAGE} - args: ["-d", "--insecure", "--diag-addr=0.0.0.0:3434"] - name: tc - ports: - - containerPort: 3022 - name: nodessh - protocol: TCP - - name: diag - containerPort: 3434 - protocol: TCP - readinessProbe: - failureThreshold: 3 - httpGet: - path: /healthz - port: 3434 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 30 - successThreshold: 1 - timeoutSeconds: 2 - livenessProbe: - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - tcpSocket: - port: 3434 - timeoutSeconds: 1 - volumeMounts: - - name: config - mountPath: /etc/teleport/ - readOnly: true - - name: license - mountPath: /var/lib/teleport/license.pem - subPath: license.pem - readOnly: true diff --git a/assets/loadtest/network/Makefile b/assets/loadtest/network/Makefile deleted file mode 100644 index aeaa90e8303e4..0000000000000 --- a/assets/loadtest/network/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# preview address configuration -.PHONY: plan -plan: - terraform plan - -# reserve static ips -.PHONY: apply -apply: - terraform apply - -# release static ips -.PHONY: destroy -destroy: - terraform destroy - -# print static ips -.PHONY: get-ips -get-ips: - @terraform output - -# print proxy static ip -.PHONY: get-proxy-ip -get-proxy-ip: - @terraform output -raw proxy_ip - -# print grafana static ip -.PHONY: get-grafana-ip -get-grafana-ip: - @terraform output -raw grafana_ip \ No newline at end of file diff --git a/assets/loadtest/network/README.md b/assets/loadtest/network/README.md deleted file mode 100644 index cdb525db6b0fc..0000000000000 --- a/assets/loadtest/network/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Network - -This reserves external static ip addresses to be used -for the [`k8s/proxy`](../k8s/proxy.yaml) and [`k8s/grafana`](../k8s/grafana.yaml) services. -Once you have the ips you **must** setup the DNS records accordingly. - -**NOTE**: This only needs to be run once for a GCP project. - -## Usage - -Confirm that everything is working correctly: - -```bash -$ make plan -``` - -If you are running this automation for the first time, you may be asked to run -`terraform init` before continuing. - -```bash -$ make apply -``` - ---- - -To release the static ip addresses run: - -```bash -$ make destroy -``` \ No newline at end of file diff --git a/assets/loadtest/network/main.tf b/assets/loadtest/network/main.tf deleted file mode 100644 index c12391b297034..0000000000000 --- a/assets/loadtest/network/main.tf +++ /dev/null @@ -1,19 +0,0 @@ -provider "google" { - project = var.project - region = var.region - zone = var.zone -} - -terraform { - required_version = ">= 0.12" - backend "gcs" { - bucket = "loadtest-tf-state" - prefix = "terraform/state" - } -} - -resource "google_compute_address" "proxy_ip" { - name = "proxy-ip" - address_type = "EXTERNAL" - network_tier = "PREMIUM" -} \ No newline at end of file diff --git a/assets/loadtest/network/outputs.tf b/assets/loadtest/network/outputs.tf deleted file mode 100644 index 1b4b436a62242..0000000000000 --- a/assets/loadtest/network/outputs.tf +++ /dev/null @@ -1,4 +0,0 @@ -output "proxy_ip" { - description = "The static proxy ip address" - value = google_compute_address.proxy_ip.address -} \ No newline at end of file diff --git a/assets/loadtest/network/variables.tf b/assets/loadtest/network/variables.tf deleted file mode 100644 index bf736c4aa81ed..0000000000000 --- a/assets/loadtest/network/variables.tf +++ /dev/null @@ -1,16 +0,0 @@ -variable "project" { - type = string - description = "The project to manage resources in." -} - -variable "region" { - type = string - description = "The region to manage resources in." - default = "us-central1" -} - -variable "zone" { - type = string - description = "The zone to manage resources in." - default = "us-central1-a" -} diff --git a/assets/loadtest/teleport/admin.yaml b/assets/loadtest/teleport/admin.yaml deleted file mode 100644 index efc5a507908c4..0000000000000 --- a/assets/loadtest/teleport/admin.yaml +++ /dev/null @@ -1,33 +0,0 @@ -kind: role -version: v3 -metadata: - name: clusteradmin -spec: - # SSH options used for user sessions - options: - # max_session_ttl defines the TTL (time to live) of SSH certificates - # issued to the users with this role. - max_session_ttl: 8h - - # forward_agent controls either users are allowed to use SSH agent forwarding - forward_agent: true - - # allow section declares a list of resource/verb combinations that are - # allowed for the users of this role. by default nothing is allowed. - allow: - # logins array defines the OS logins a user is allowed to use. - # A few special variables are supported here (see below) - logins: [root, ubuntu] - - # node labels that a user can connect to. The wildcard ('*') means "any node" - node_labels: - '*': '*' - - # see below. - rules: - - resources: ['*'] - verbs: ['*'] - - # the deny section uses the identical format as the 'allow' section. - # the deny rules always override allow rules. - deny: {} diff --git a/assets/loadtest/teleport/soaktest-user.yaml b/assets/loadtest/teleport/soaktest-user.yaml deleted file mode 100644 index 1c117f34426e2..0000000000000 --- a/assets/loadtest/teleport/soaktest-user.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: user -metadata: - name: soaktest-runner -spec: - roles: ['clusteradmin'] -version: v2 \ No newline at end of file diff --git a/assets/loadtest/teleport/soaktest.sh b/assets/loadtest/teleport/soaktest.sh deleted file mode 100755 index cb28bf6e7f614..0000000000000 --- a/assets/loadtest/teleport/soaktest.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# This script runs the teleport load test soak tests. -set -e -set -x - -direct_node=$(tsh --insecure --proxy="${PROXY_HOST}":3080 -i /etc/teleport/auth -l root ls -f names | grep -v iot) -tunnel_node=$(tsh --insecure --proxy="${PROXY_HOST}":3080 -i /etc/teleport/auth -l root ls -f names | grep iot) - -echo "${direct_node}" -echo "${tunnel_node}" - -if [ -z "${direct_node}" ]; then - echo "no direct dial nodes found to run soak test on."; - exit 1; -fi - -if [ -z "${tunnel_node}" ]; then - echo "no reverse tunnel nodes found to run soak test on."; - exit 1; -fi - -echo "----Direct Dial Node Test----" -tsh --insecure --proxy="${PROXY_HOST}":3080 -i /etc/teleport/auth bench --duration="${DURATION}" root@"${direct_node}" ls - -tsh --insecure --proxy="${PROXY_HOST}":3080 -i /etc/teleport/auth bench --duration="${DURATION}" --interactive root@"${direct_node}" ps aux - -echo "----Reverse Tunnel Node Test----" -tsh --insecure --proxy="${PROXY_HOST}":3080 -i /etc/teleport/auth bench --duration="${DURATION}" root@"${tunnel_node}" ls - -tsh --insecure --proxy="${PROXY_HOST}":3080 -i /etc/teleport/auth bench --duration="${DURATION}" --interactive root@"${tunnel_node}" ps aux \ No newline at end of file diff --git a/assets/loadtest/teleport/tc.yaml b/assets/loadtest/teleport/tc.yaml deleted file mode 100644 index 12e23cd2b52aa..0000000000000 --- a/assets/loadtest/teleport/tc.yaml +++ /dev/null @@ -1,12 +0,0 @@ -kind: trusted_cluster -version: v2 -metadata: - name: one -spec: - enabled: true - token: cluster-${TC_TOKEN} - tunnel_addr: "${PROXY_HOST}:3024" - web_proxy_addr: "${PROXY_HOST}:3080" - role_map: - - remote: '*' - local: ['access'] \ No newline at end of file diff --git a/assets/loadtest/teleport/teleport-auth-dynamo.yaml b/assets/loadtest/teleport/teleport-auth-dynamo.yaml deleted file mode 100644 index 3094c70a0bfee..0000000000000 --- a/assets/loadtest/teleport/teleport-auth-dynamo.yaml +++ /dev/null @@ -1,36 +0,0 @@ -teleport: - log: - severity: DEBUG - - data_dir: /var/lib/teleport - - advertise_ip: auth - - storage: - type: dynamodb - table_name: ${DYNAMO_TABLE} - region: ${DYNAMO_REGION} - - connection_limits: - max_connections: 65000 - max_users: 10000 - -auth_service: - enabled: yes - - listen_addr: 0.0.0.0:3025 - - authentication: - type: oidc - - cluster_name: one - tokens: - - "node:node-${NODE_TOKEN}" - - "proxy:proxy-${PROXY_TOKEN}" - - "trusted_cluster:cluster-${TC_TOKEN}" - -ssh_service: - enabled: no - -proxy_service: - enabled: no \ No newline at end of file diff --git a/assets/loadtest/teleport/teleport-auth-etcd.yaml b/assets/loadtest/teleport/teleport-auth-etcd.yaml deleted file mode 100644 index 4ddc5db51ea07..0000000000000 --- a/assets/loadtest/teleport/teleport-auth-etcd.yaml +++ /dev/null @@ -1,40 +0,0 @@ -teleport: - log: - severity: DEBUG - format: - output: json - - data_dir: /var/lib/teleport - - advertise_ip: auth - - storage: - type: etcd - peers: [https://etcd-0.etcd:2379, https://etcd-1.etcd:2379, https://etcd-2.etcd:2379] - tls_cert_file: /etc/etcd/certs/client-cert.pem - tls_key_file: /etc/etcd/certs/client-key.pem - tls_ca_file: /etc/etcd/certs/ca-cert.pem - prefix: teleport - connection_limits: - max_connections: 65000 - max_users: 10000 - -auth_service: - enabled: yes - - listen_addr: 0.0.0.0:3025 - - authentication: - type: oidc - - cluster_name: one - tokens: - - "node:node-${NODE_TOKEN}" - - "proxy:proxy-${PROXY_TOKEN}" - - "trusted_cluster:cluster-${TC_TOKEN}" - -ssh_service: - enabled: no - -proxy_service: - enabled: no \ No newline at end of file diff --git a/assets/loadtest/teleport/teleport-auth-firestore.yaml b/assets/loadtest/teleport/teleport-auth-firestore.yaml deleted file mode 100644 index da9265d9a1ee3..0000000000000 --- a/assets/loadtest/teleport/teleport-auth-firestore.yaml +++ /dev/null @@ -1,38 +0,0 @@ -teleport: - log: - severity: DEBUG - - data_dir: /var/lib/teleport - - advertise_ip: auth - - storage: - type: firestore - collection_name: cluster-data - credentials_path: /var/lib/teleport/gcp_creds.json - project_id: "${GCP_PROJECT}" - audit_events_uri: "firestore://events?projectID=${GCP_PROJECT}&credentialsPath=/var/lib/teleport/gcp_creds.json" - audit_sessions_uri: "gs://teleport-session-storage-2?projectID=${GCP_PROJECT}&credentialsPath=/var/lib/teleport/gcp_creds.json" - connection_limits: - max_connections: 65000 - max_users: 10000 - -auth_service: - enabled: yes - - listen_addr: 0.0.0.0:3025 - - authentication: - type: oidc - - cluster_name: one - tokens: - - "node:node-${NODE_TOKEN}" - - "proxy:proxy-${PROXY_TOKEN}" - - "trusted_cluster:cluster-${TC_TOKEN}" - -ssh_service: - enabled: no - -proxy_service: - enabled: no \ No newline at end of file diff --git a/assets/loadtest/teleport/teleport-iot-node.yaml b/assets/loadtest/teleport/teleport-iot-node.yaml deleted file mode 100644 index cbc1a01e3dda0..0000000000000 --- a/assets/loadtest/teleport/teleport-iot-node.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: v3 -teleport: - data_dir: /var/lib/teleport - log: - severity: DEBUG - format: - output: json - storage: - type: dir - auth_token: "node-${NODE_TOKEN}" - proxy_server: ${PROXY_HOST}:3080 -auth_service: - enabled: false -proxy_service: - enabled: false -ssh_service: - enabled: true diff --git a/assets/loadtest/teleport/teleport-node.yaml b/assets/loadtest/teleport/teleport-node.yaml deleted file mode 100644 index 0c09953a35601..0000000000000 --- a/assets/loadtest/teleport/teleport-node.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: v3 -teleport: - data_dir: /var/lib/teleport - log: - severity: DEBUG - format: - output: json - storage: - type: dir - auth_token: "node-${NODE_TOKEN}" - auth_server: auth:3025 -auth_service: - enabled: false -proxy_service: - enabled: false -ssh_service: - enabled: true diff --git a/assets/loadtest/teleport/teleport-proxy.yaml b/assets/loadtest/teleport/teleport-proxy.yaml deleted file mode 100644 index 88bc708c98c30..0000000000000 --- a/assets/loadtest/teleport/teleport-proxy.yaml +++ /dev/null @@ -1,30 +0,0 @@ -version: v3 -teleport: - log: - severity: DEBUG - format: - output: json - - data_dir: /var/lib/teleport - auth_server: auth:3025 - auth_token: "proxy-${PROXY_TOKEN}" - cache: - type: in-memory - connection_limits: - max_connections: 65000 - max_users: 10000 - -auth_service: - enabled: no - -ssh_service: - enabled: no - -proxy_service: - enabled: yes - https_cert_file: /etc/teleport-tls/tls.crt - https_key_file: /etc/teleport-tls/tls.key - public_addr: "${PROXY_HOST}:3080" - tunnel_public_addr: "${PROXY_HOST}:3024" - tunnel_listen_addr: 0.0.0.0:3024 - listen_addr: 0.0.0.0:3023 diff --git a/assets/loadtest/teleport/teleport-tc.yaml b/assets/loadtest/teleport/teleport-tc.yaml deleted file mode 100644 index 7bb83bf6906c4..0000000000000 --- a/assets/loadtest/teleport/teleport-tc.yaml +++ /dev/null @@ -1,13 +0,0 @@ -auth_service: - enabled: true -proxy_service: - enabled: true -ssh_service: - enabled: true -teleport: - data_dir: /var/lib/teleport - log: - output: stderr - severity: DEBUG - storage: - type: dir \ No newline at end of file diff --git a/build.assets/Dockerfile b/build.assets/Dockerfile index 44c23d07e37ca..aa4f1aaf78a83 100644 --- a/build.assets/Dockerfile +++ b/build.assets/Dockerfile @@ -1,20 +1,16 @@ # This Dockerfile makes the "build box" the container used to: -# * build Teleport Connect # * run test and linters in CI # * building other Docker images # # For Teleport releases we're using CentOS 7 box to keep the binaries compatible # with older Linux distributions (glibc 2.17+). # -# This image uses Ubuntu 20.04 as a base as Connect links against glibc and -# we want to keep the required version as low as possible. -# # Check the README to learn how to safely introduce changes to Dockerfiles. ## LIBFIDO2 ################################################################### # Build libfido2 separately for isolation, speed and flexibility. -FROM buildpack-deps:20.04 AS libfido2 +FROM buildpack-deps:22.04 AS libfido2 RUN apt-get update && \ apt-get install -y --no-install-recommends cmake && \ @@ -29,6 +25,7 @@ RUN git clone --depth=1 https://github.com/illiliti/libudev-zero.git -b 1.0.2 && make clean # Install libcbor. +# Keep the version below synced with devbox.json RUN git clone --depth=1 https://github.com/PJK/libcbor.git -b v0.10.2 && \ cd libcbor && \ [ "$(git rev-parse HEAD)" = 'efa6c0886bae46bdaef9b679f61f4b9d8bc296ae' ] && \ @@ -42,6 +39,7 @@ RUN git clone --depth=1 https://github.com/PJK/libcbor.git -b v0.10.2 && \ # Install openssl. # install_sw install only binaries, skips docs. +# Keep the version below synced with devbox.json RUN git clone --depth=1 https://github.com/openssl/openssl.git -b openssl-3.0.9 && \ cd openssl && \ [ "$(git rev-parse HEAD)" = 'de90e54bbe82e5be4fb9608b6f5c308bb837d355' ] && \ @@ -51,6 +49,7 @@ RUN git clone --depth=1 https://github.com/openssl/openssl.git -b openssl-3.0.9 # Install libfido2. # Depends on libcbor, libcrypto (OpenSSL 3.x), libudev and zlib1g-dev. +# Keep the version below synced with devbox.json RUN git clone --depth=1 https://github.com/Yubico/libfido2.git -b 1.13.0 && \ cd libfido2 && \ [ "$(git rev-parse HEAD)" = '486a8f8667e42f55cee2bba301b41433cacec830' ] && \ @@ -66,7 +65,7 @@ RUN git clone --depth=1 https://github.com/Yubico/libfido2.git -b 1.13.0 && \ ## LIBBPF ##################################################################### -FROM buildpack-deps:20.04 AS libbpf +FROM buildpack-deps:22.04 AS libbpf # Install required dependencies RUN apt-get update -y --fix-missing && \ @@ -98,7 +97,7 @@ RUN mkdir -p /opt && cd /opt && \ # 4. Fast, language-dependent dependencies # 5. Multi-stage layer copies -FROM ubuntu:20.04 AS buildbox +FROM ubuntu:22.04 AS buildbox COPY locale.gen /etc/locale.gen COPY profile /etc/profile @@ -115,7 +114,7 @@ ARG BUILDARCH # Install packages. # Java JRE is required by gcloud firestore emulator. -# Latest git 2.18+ is required for GitHub actions +# Latest git 2.18+ is required for GitHub actions. # NOTE: gcc-multilib is not available on ARM, so ony amd64 version includes it. RUN apt-get -y update && \ apt-get -y install software-properties-common && \ @@ -150,8 +149,8 @@ RUN apt-get -y update && \ python3-setuptools \ python3-wheel \ pkg-config \ - # Used during tag builds to build the RPM package of Connect. - rpm \ + # rsync is required for some integration tests + rsync \ softhsm2 \ sudo \ tree \ @@ -170,6 +169,7 @@ RUN apt-get -y update && \ tee /etc/apt/sources.list.d/docker.list > /dev/null && \ apt-get update && \ apt-get install -y docker-ce-cli && \ + if [ "$BUILDARCH" = "arm64" ]; then apt-get install -y binaryen; fi && \ pip3 --no-cache-dir install yamllint && \ dpkg-reconfigure locales && \ apt-get -y clean && \ @@ -212,6 +212,8 @@ RUN curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs | sh -s -- -y --p rustc --version && \ rustup component add rustfmt clippy && \ if [ "$BUILDARCH" = "amd64" ]; then rustup target add aarch64-unknown-linux-gnu; fi +# Install wasm-pack for targeting WebAssembly from Rust. +RUN cargo install wasm-pack # Switch back to root for the remaining instructions and keep it as the default # user. USER root @@ -244,11 +246,13 @@ RUN make -C /opt/pam_teleport install ENV SOFTHSM2_PATH "/usr/lib/softhsm/libsofthsm2.so" # Install bats. +# Keep the version below synced with devbox.json RUN curl -fsSL https://github.com/bats-core/bats-core/archive/v1.2.1.tar.gz | tar -xz && \ cd bats-core-1.2.1 && ./install.sh /usr/local && cd .. && \ rm -r bats-core-1.2.1 # Install shellcheck. +# Keep the version below synced with devbox.json RUN scversion='v0.9.0' && \ curl -fsSL "https://github.com/koalaman/shellcheck/releases/download/$scversion/shellcheck-$scversion.linux.$(if [ "$BUILDARCH" = "amd64" ]; then echo "x86_64"; else echo "aarch64"; fi).tar.xz" | \ tar -xJv && \ @@ -256,6 +260,7 @@ RUN scversion='v0.9.0' && \ shellcheck --version # Install helm. +# Keep the version below synced with devbox.json RUN mkdir -p helm-tarball && \ curl -fsSL https://get.helm.sh/helm-v3.5.2-$(go env GOOS)-$(go env GOARCH).tar.gz | tar -C helm-tarball -xz && \ cp helm-tarball/$(go env GOOS)-$(go env GOARCH)/helm /bin/ && \ @@ -292,13 +297,16 @@ ARG GOGO_PROTO_TAG # eg, "v1.3.2" RUN go install "github.com/gogo/protobuf/protoc-gen-gogofast@$GOGO_PROTO_TAG" # Install addlicense. +# Keep the version below synced with devbox.json RUN go install github.com/google/addlicense@v1.0.0 # Install GCI. +# Keep the version below synced with devbox.json RUN go install github.com/daixiang0/gci@v0.9.1 # Install golangci-lint. -RUN TAG='v1.53.1' && \ +# Keep the version below synced with devbox.json +RUN TAG='v1.53.3' && \ curl -fsSL "https://raw.githubusercontent.com/golangci/golangci-lint/$TAG/install.sh" | \ sh -s -- -b "$(go env GOPATH)/bin" "$TAG" diff --git a/build.assets/Dockerfile-arm-fips b/build.assets/Dockerfile-arm-fips deleted file mode 100644 index 3096fc5bf0634..0000000000000 --- a/build.assets/Dockerfile-arm-fips +++ /dev/null @@ -1,6 +0,0 @@ -ARG BUILDBOX_VERSION -FROM public.ecr.aws/gravitational/teleport-buildbox-fips:$BUILDBOX_VERSION - -RUN apt-get -y update && \ - apt-get -y install gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu && \ - apt-get -y autoclean && apt-get -y clean diff --git a/build.assets/Dockerfile-centos7 b/build.assets/Dockerfile-centos7 index 975ddc835f92b..536402c847d6d 100644 --- a/build.assets/Dockerfile-centos7 +++ b/build.assets/Dockerfile-centos7 @@ -253,6 +253,8 @@ RUN curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs | sh -s -- -y --p rustup --version && \ cargo --version && \ rustc --version +# Install wasm-pack for targeting WebAssembly from Rust. +RUN cargo install wasm-pack # Do a quick switch back to root and copy/setup libfido2 and libpcsclite binaries. # Do this last to take better advantage of the multi-stage build. diff --git a/build.assets/Dockerfile-centos7-fips b/build.assets/Dockerfile-centos7-fips index 733e3150bb6e0..50e9d27c86484 100644 --- a/build.assets/Dockerfile-centos7-fips +++ b/build.assets/Dockerfile-centos7-fips @@ -166,6 +166,8 @@ RUN curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs | sh -s -- -y --p rustc --version && \ rustup component add rustfmt clippy && \ rustup target add aarch64-unknown-linux-gnu +# Install wasm-pack for targeting WebAssembly from Rust. +RUN cargo install wasm-pack # Copy BoringSSL into the final image diff --git a/build.assets/Dockerfile-connect b/build.assets/Dockerfile-connect new file mode 100644 index 0000000000000..a6235025814f7 --- /dev/null +++ b/build.assets/Dockerfile-connect @@ -0,0 +1,46 @@ +# This Dockerfile makes the "build box connect" the container used +# to build the Teleport Connect. +# +# This image is base on the node image, which is based on Debian Buster. +# Using it as a image allows us to link agains the same version of +# glibc as Node.js. +# +# Check the README to learn how to safely introduce changes to Dockerfiles. + +## BUILDBOX-CONNECT ################################################################### + +# Pin the tag to Debian Buster to make sure the Glibc compatibility. +ARG NODE_VERSION +FROM node:${NODE_VERSION}-buster AS buildbox + +COPY locale.gen /etc/locale.gen +COPY profile /etc/profile +ENV LANGUAGE="en_US.UTF-8" \ + LANG="en_US.UTF-8" \ + LC_ALL="en_US.UTF-8" \ + LC_CTYPE="en_US.UTF-8" \ + DEBIAN_FRONTEND="noninteractive" + +# Install packages. +RUN apt-get -y update && \ + apt-get install -q -y --no-install-recommends \ + build-essential \ + ca-certificates \ + git \ + libc6-dev \ + libssl-dev \ + locales \ + openssh-client \ + pkg-config \ + python3-pip \ + python3-setuptools \ + python3-wheel \ + # Used during tag builds to build the RPM package of Connect. + rpm \ + && \ + dpkg-reconfigure locales && \ + apt-get -y clean && \ + rm -rf /var/lib/apt/lists/* + +# Do not create the ci user as we do on other images, as node image +# already has node user with UID:GID 1000:1000 user. diff --git a/build.assets/Dockerfile-fips b/build.assets/Dockerfile-fips deleted file mode 100644 index 181ec49d7e139..0000000000000 --- a/build.assets/Dockerfile-fips +++ /dev/null @@ -1,187 +0,0 @@ -# This Dockerfile makes the FIPS "build box": the container used to build official -# FIPS releases of Teleport and its documentation. - - -FROM ubuntu:18.04 as boringssl -# The below tools are required in order to build and compile the module: -# Clang compiler version 7.0.1 -# Go programming language version 1.12.7 -# Ninja build system version 1.9.0 -# -# We also need the FIPS 140-2 validated release of BoringSSL: ae223d6138807a13006342edfeef32e813246b39 -# For more information please refer to the section 12. Guidance and Secure Operation of: -# https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf - -RUN apt-get update -y --fix-missing && \ - apt-get -q -y upgrade && \ - apt-get install -y --no-install-recommends apt-utils ca-certificates curl && \ - apt-get install -q -y --no-install-recommends \ - build-essential \ - cmake \ - git \ - tar \ - xz-utils \ - unzip \ - zip \ - && \ - apt-get -y clean && \ - rm -rf /var/lib/apt/lists/* - - -RUN mkdir -p /opt && cd /opt && \ - curl -sLO https://releases.llvm.org/7.0.1/clang+llvm-7.0.1-x86_64-linux-gnu-ubuntu-18.04.tar.xz && \ - echo "e74ce06d99ed9ce42898e22d2a966f71ae785bdf4edbded93e628d696858921a" "clang+llvm-7.0.1-x86_64-linux-gnu-ubuntu-18.04.tar.xz" | sha256sum --check && \ - tar xJf clang+llvm-7.0.1-x86_64-linux-gnu-ubuntu-18.04.tar.xz && \ - rm -f clang+llvm-7.0.1-x86_64-linux-gnu-ubuntu-18.04.tar.xz -ENV PATH="/opt/clang+llvm-7.0.1-x86_64-linux-gnu-ubuntu-18.04/bin:$PATH" - - -RUN mkdir -p /opt && cd /opt && \ - curl -sLO https://go.dev/dl/go1.12.7.linux-amd64.tar.gz && \ - echo "66d83bfb5a9ede000e33c6579a91a29e6b101829ad41fffb5c5bb6c900e109d9" "go1.12.7.linux-amd64.tar.gz" | sha256sum --check && \ - tar xf go1.12.7.linux-amd64.tar.gz && \ - rm -f go1.12.7.linux-amd64.tar.gz && \ - chmod a+w /opt/go && \ - chmod a+w /var/lib && \ - chmod a-w / -ENV GOPATH="/go" \ - GOROOT="/opt/go" \ - PATH="$PATH:/opt/go/bin:/go/bin" - -RUN mkdir -p /opt && cd /opt && \ - curl -sLO https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip && \ - echo "1b1235f2b0b4df55ac6d80bbe681ea3639c9d2c505c7ff2159a3daf63d196305" "ninja-linux.zip" | sha256sum --check && \ - unzip ninja-linux.zip && \ - rm -f ninja-linux.zip && \ - mv /opt/ninja /usr/bin - -RUN mkdir -p /opt && cd /opt && \ - git clone https://github.com/google/boringssl.git && \ - cd boringssl && \ - git checkout ae223d6138807a13006342edfeef32e813246b39 && \ - mkdir build && \ - cd build && \ - cmake -DFIPS=1 -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja .. && \ - ninja - - -# Use Ubuntu 18.04 as base to get an older glibc version. -# Using a newer base image will build against a newer glibc, which creates a -# runtime requirement for the host to have newer glibc too. For example, -# teleport built on any newer Ubuntu version will not run on Centos 7 because -# of this. -FROM ubuntu:18.04 - -COPY locale.gen /etc/locale.gen -COPY profile /etc/profile - -ENV LANGUAGE="en_US.UTF-8" \ - LANG="en_US.UTF-8" \ - LC_ALL="en_US.UTF-8" \ - LC_CTYPE="en_US.UTF-8" \ - DEBIAN_FRONTEND="noninteractive" - -RUN apt-get update -y --fix-missing && \ - apt-get -q -y upgrade && \ - apt-get install -y --no-install-recommends apt-utils ca-certificates curl && \ - apt-get install -q -y --no-install-recommends \ - clang-10 \ - clang-format-10 \ - gcc \ - git \ - gzip \ - libc6-dev \ - libelf-dev \ - libpam-dev \ - libsqlite3-0 \ - llvm-10 \ - locales \ - make \ - net-tools \ - openssh-client \ - pkg-config \ - tar \ - tree \ - unzip \ - zip \ - zlib1g-dev \ - && \ - dpkg-reconfigure locales && \ - apt-get -y clean && \ - rm -rf /var/lib/apt/lists/* - -ARG UID -ARG GID -RUN (groupadd ci --gid=$GID -o && useradd ci --uid=$UID --gid=$GID --create-home --shell=/bin/sh && \ - mkdir -p -m0700 /var/lib/teleport && chown -R ci /var/lib/teleport) - -# Install etcd. -RUN (curl -L https://github.com/coreos/etcd/releases/download/v3.3.9/etcd-v3.3.9-linux-amd64.tar.gz | tar -xz && \ - cp etcd-v3.3.9-linux-amd64/etcd* /bin/) - -# Install Go. -ARG GOLANG_VERSION -RUN mkdir -p /opt && cd /opt && curl https://storage.googleapis.com/golang/$GOLANG_VERSION.linux-amd64.tar.gz | tar xz && \ - mkdir -p /go/src/github.com/gravitational/teleport && \ - chmod a+w /go && \ - chmod a+w /var/lib && \ - chmod a-w / -ENV GOEXPERIMENT=boringcrypto \ - GOPATH="/go" \ - GOROOT="/opt/go" \ - PATH="$PATH:/opt/go/bin:/go/bin:/go/src/github.com/gravitational/teleport/build" - -ARG BUILDARCH - -# Install Nodejs -ARG NODE_VERSION -ENV NODE_PATH="/usr/local/lib/nodejs-linux" -ENV PATH="$PATH:${NODE_PATH}/bin" -RUN export NODE_ARCH=$(if [ "$BUILDARCH" = "amd64" ]; then echo "x64"; else echo "arm64"; fi) && \ - export NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz" && \ - mkdir -p ${NODE_PATH} && \ - curl -o /tmp/nodejs.tar.xz -L ${NODE_URL} && \ - tar -xJf /tmp/nodejs.tar.xz -C /usr/local/lib/nodejs-linux --strip-components=1 -RUN corepack enable yarn - -# Install libbpf -ARG LIBBPF_VERSION -RUN mkdir -p /opt && cd /opt && \ - curl -fsSL https://github.com/libbpf/libbpf/archive/refs/tags/v${LIBBPF_VERSION}.tar.gz | tar xz && \ - cd /opt/libbpf-${LIBBPF_VERSION}/src && \ - make && \ - make install - -# Install PAM module and policies for testing. -COPY pam/ /opt/pam_teleport/ -RUN make -C /opt/pam_teleport install - -ARG RUST_VERSION -ENV RUSTUP_HOME=/usr/local/rustup \ - CARGO_HOME=/usr/local/cargo \ - PATH=/usr/local/cargo/bin:$PATH \ - RUST_VERSION=$RUST_VERSION - -RUN mkdir -p $RUSTUP_HOME && chmod a+w $RUSTUP_HOME && \ - mkdir -p $CARGO_HOME/registry && chmod -R a+w $CARGO_HOME - -# Install Rust using the ci user, as that is the user that -# will run builds using the Rust toolchains we install here. -USER ci -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain $RUST_VERSION && \ - rustup --version && \ - cargo --version && \ - rustc --version && \ - rustup component add rustfmt clippy && \ - rustup target add aarch64-unknown-linux-gnu - -# Copy BoringSSL into the final image -COPY --from=boringssl /opt/boringssl /opt/boringssl - -# set boring-rs crate env variables to point to pre-built binaries -# https://github.com/cloudflare/boring#support-for-pre-built-binaries -ENV BORING_BSSL_PATH=/opt/boringssl -ENV BORING_BSSL_INCLUDE_PATH=/opt/boringssl/include - -VOLUME ["/go/src/github.com/gravitational/teleport"] -EXPOSE 6600 2379 2380 diff --git a/build.assets/Dockerfile-multiarch b/build.assets/Dockerfile-multiarch index 8909273c97fd5..bebd0309ed2d6 100644 --- a/build.assets/Dockerfile-multiarch +++ b/build.assets/Dockerfile-multiarch @@ -130,6 +130,8 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --pr cargo --version && \ rustc --version && \ rustup target add ${RUST_ARCH} +# Install wasm-pack for targeting WebAssembly from Rust. +RUN cargo install wasm-pack USER root diff --git a/build.assets/Makefile b/build.assets/Makefile index 968d9e6f35b72..40ae773c1dca9 100644 --- a/build.assets/Makefile +++ b/build.assets/Makefile @@ -19,17 +19,21 @@ TEST_KUBE ?= OS ?= linux ARCH ?= amd64 -GOLANG_VERSION ?= go1.20.4 +# Sync with devbox.json. +GOLANG_VERSION ?= go1.20.5 +# Sync with devbox.json. NODE_VERSION ?= 16.18.1 +# Sync any version changes below with devbox.json. # run lint-rust check locally before merging code after you bump this RUST_VERSION ?= 1.68.0 LIBBPF_VERSION ?= 1.0.1 LIBPCSCLITE_VERSION ?= 1.9.9-teleport +# Sync any version changes below with devbox.json. # Protogen related versions. -BUF_VERSION ?= 1.20.0 +BUF_VERSION ?= 1.22.0 # Keep in sync with api/proto/buf.yaml (and buf.lock) GOGO_PROTO_TAG ?= v1.3.2 NODE_GRPC_TOOLS_VERSION ?= 1.12.4 @@ -54,7 +58,6 @@ include grpcbox.mk # target. The other solution was to remove the 'buildbox' dependency from the 'release' target, but this would # make it harder to run `make -C build.assets release` locally as the buildbox would not automatically be built. BUILDBOX_NAME=$(BUILDBOX) -BUILDBOX_FIPS_NAME=$(BUILDBOX_FIPS) DOCSBOX=ghcr.io/gravitational/docs @@ -67,9 +70,17 @@ ifeq ("$(DRONE)","true") CI := true endif ifeq ("$(CI)","true") +# The UID/GID of the runner user on ARC runners is 1001, not 1000 +# This var is currently only set for ARC runners via https://github.com/gravitational/cloud-terraform/pull/2473 +ifeq ("$(CI_SYSTEM)","ARC") +UID := 1001 +GID := 1001 +NOROOT := -u 1001:1001 +else UID := 1000 GID := 1000 NOROOT := -u 1000:1000 +endif # if running in CI and the GOCACHE environment variable is not set, set it to a sensible default ifeq ("$(GOCACHE)",) GOCACHE := /go/cache @@ -149,20 +160,7 @@ buildbox: # Builds a Docker buildbox for FIPS # .PHONY:buildbox-fips -buildbox-fips: - if [[ "$(BUILDBOX_FIPS_NAME)" == "$(BUILDBOX_FIPS)" ]]; then \ - if [[ $${DRONE} == "true" ]] && ! docker inspect --type=image $(BUILDBOX_FIPS) 2>&1 >/dev/null; then docker pull $(BUILDBOX_FIPS) || true; fi; \ - docker build \ - --build-arg UID=$(UID) \ - --build-arg GID=$(GID) \ - --build-arg BUILDARCH=$(RUNTIME_ARCH) \ - --build-arg GOLANG_VERSION=$(GOLANG_VERSION) \ - --build-arg NODE_VERSION=$(NODE_VERSION) \ - --build-arg RUST_VERSION=$(RUST_VERSION) \ - --build-arg LIBBPF_VERSION=$(LIBBPF_VERSION) \ - --cache-from $(BUILDBOX_FIPS) \ - --tag $(BUILDBOX_FIPS) -f Dockerfile-fips . ; \ - fi +buildbox-fips: buildbox-centos7-fips # # Builds a Docker buildbox for CentOS 7 builds @@ -214,31 +212,29 @@ buildbox-arm: buildbox --cache-from $(BUILDBOX_ARM) \ --tag $(BUILDBOX_ARM) -f Dockerfile-arm . -# -# Builds a Docker buildbox for ARMv7/ARM64 FIPS builds -# ARM buildboxes use a regular Teleport buildbox as a base which already has a user -# with the correct UID and GID created, so those arguments are not needed here. -# -.PHONY:buildbox-arm-fips -buildbox-arm-fips: buildbox-fips - @if [[ $${DRONE} == "true" ]] && ! docker inspect --type=image $(BUILDBOX_ARM_FIPS) 2>&1 >/dev/null; then docker pull $(BUILDBOX_ARM_FIPS) || true; fi; - docker build \ - --build-arg BUILDBOX_VERSION=$(BUILDBOX_VERSION) \ - --cache-from $(BUILDBOX_FIPS) \ - --cache-from $(BUILDBOX_ARM_FIPS) \ - --tag $(BUILDBOX_ARM_FIPS) -f Dockerfile-arm-fips . - CONNECT_VERSION ?= $(VERSION) ifeq ($(CONNECT_VERSION),) CONNECT_VERSION := $(BUILDBOX_VERSION)-dev endif +# +# Builds a Docker buildbox for Linux Connect builds +# +.PHONY:buildbox-connect +buildbox-connect: + if [[ $${DRONE} == "true" ]] && ! docker inspect --type=image $(BUILDBOX_CONNECT) 2>&1 >/dev/null; then docker pull $(BUILDBOX_CONNECT) || true; fi; \ + DOCKER_BUILDKIT=1 docker build \ + --build-arg NODE_VERSION=$(NODE_VERSION) \ + --cache-from $(BUILDBOX_CONNECT) \ + --tag $(BUILDBOX_CONNECT) -f Dockerfile-connect . ; + # # Builds Teleport Connect inside the buildbox container. # .PHONY:teleterm -teleterm: buildbox - docker run $(DOCKERFLAGS) $(NOROOT) $(BUILDBOX) \ +teleterm: buildbox-connect + # Always run this image as user 1000, as the Node base image assumes that. + docker run $(DOCKERFLAGS) -u 1000:1000 $(BUILDBOX_CONNECT) \ bash -c "cd $(SRCDIR) && export CONNECT_TSH_BIN_PATH=\$$PWD/../teleport/build/tsh && yarn install --frozen-lockfile && yarn build-term && yarn package-term -c.extraMetadata.version=$(CONNECT_VERSION)" # Builds webassets inside Docker. @@ -404,8 +400,7 @@ release-amd64: $(MAKE) release ARCH=amd64 FIDO2=yes .PHONY: release-amd64-fips -release-amd64-fips: - $(MAKE) release-fips ARCH=amd64 FIPS=yes BUILDBOX_FIPS_NAME=$(BUILDBOX_FIPS) +release-amd64-fips: release-amd64-centos7-fips .PHONY: release-386 release-386: @@ -439,9 +434,9 @@ release-arm64: buildbox-arm # CI should not use this target, it should use named Makefile targets like release-amd64-fips. # .PHONY:release-fips -release-fips: buildbox-fips +release-fips: buildbox-centos7-fips @if [ -z ${VERSION} ]; then echo "VERSION is not set"; exit 1; fi - docker run $(DOCKERFLAGS) -i $(NOROOT) $(BUILDBOX_FIPS_NAME) \ + docker run $(DOCKERFLAGS) -i $(NOROOT) $(BUILDBOX_CENTOS7_FIPS) \ /usr/bin/make -C e release -e ADDFLAGS="$(ADDFLAGS)" OS=$(OS) ARCH=$(ARCH) RUNTIME=$(GOLANG_VERSION) FIPS=yes VERSION=$(VERSION) GITTAG=v$(VERSION) REPRODUCIBLE=yes # diff --git a/build.assets/README.md b/build.assets/README.md index 73977bb579ecb..67f3ed0935a46 100644 --- a/build.assets/README.md +++ b/build.assets/README.md @@ -20,20 +20,23 @@ should be split into two stages: ECR. 3. Then you can open another PR which starts using the new build box image. -# DynamoDB static binary docker build +# DynamoDB static binary docker build The static binary will be built along with all nodejs assets inside the container. From the root directory of the source checkout run: + ``` docker build -f build.assets/Dockerfile.dynamodb -t teleportbuilder . ``` Then you can upload the result to an S3 bucket for release. + ``` docker run -it -e AWS_ACL=public-read -e S3_BUCKET=my-teleport-releases -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY teleportbuilder ``` -Or simply copy the binary out of the image using a volume (it will be copied to current directory/build/teleport. +Or simply copy the binary out of the image using a volume (it will be copied to current directory/build/teleport). + ``` docker run -v $(pwd)/build:/builds -it teleportbuilder cp /gopath/src/github.com/gravitational/teleport/teleport.tgz /builds ``` @@ -41,11 +44,13 @@ docker run -v $(pwd)/build:/builds -it teleportbuilder cp /gopath/src/github.com # OS package repo migrations An OS package repo migration is semi-manually publishing specific releases to the new APT and YUM repos. This is required in several situations: -* A customer requests that we add an older version to the repos -* We add another OS package repo (for example APK) -* A OS package promotion fails (for example https://drone.platform.teleport.sh/gravitational/teleport/14666/1/3), requires a PR to fix, and we don't want to cut another minor version + +- A customer requests that we add an older version to the repos +- We add another OS package repo (for example APK) +- A OS package promotion fails (for example https://drone.platform.teleport.sh/gravitational/teleport/14666/1/3), requires a PR to fix, and we don't want to cut another minor version Multiple migrations can be performed at once. To run a migration do the following: + 1. Clone https://github.com/gravitational/teleport.git. 2. Change to the directory the repo was cloned to. 3. Create a new branch from master. diff --git a/build.assets/flake/flake.lock b/build.assets/flake/flake.lock new file mode 100644 index 0000000000000..bf85aebea267d --- /dev/null +++ b/build.assets/flake/flake.lock @@ -0,0 +1,181 @@ +{ + "nodes": { + "batsPkgs": { + "locked": { + "lastModified": 1614022514, + "narHash": "sha256-htMUqRk3r5s3kuixCgojWZX9nwM++xeFfeZU+3xQLCA=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "5c1ffb7a9fc96f2d64ed3523c2bdd379bdb7b471", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "5c1ffb7a9fc96f2d64ed3523c2bdd379bdb7b471", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "helmPkgs": { + "locked": { + "lastModified": 1678571061, + "narHash": "sha256-0gI2FHID8XYD3504kLFRLH3C2GmMCzVMC50APV/kZp8=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8", + "type": "github" + } + }, + "libbpfPkgs": { + "locked": { + "lastModified": 1671056470, + "narHash": "sha256-rrcDHjRX9R8qXvkcGvKunsw3mf7zyPJzx1y8TPqjWdM=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1678571061, + "narHash": "sha256-0gI2FHID8XYD3504kLFRLH3C2GmMCzVMC50APV/kZp8=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1681358109, + "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "batsPkgs": "batsPkgs", + "flake-utils": "flake-utils", + "helmPkgs": "helmPkgs", + "libbpfPkgs": "libbpfPkgs", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1686537156, + "narHash": "sha256-mJD80brS6h6P4jzwdKID0S9RvfyiruxgJbXvPPIDqF0=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "e75da5cfc7da874401decaa88f4ccb3b4d64d20d", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/build.assets/flake/flake.nix b/build.assets/flake/flake.nix new file mode 100644 index 0000000000000..574c796039acf --- /dev/null +++ b/build.assets/flake/flake.nix @@ -0,0 +1,239 @@ +# Copyright 2023 Gravitational, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# This file contains the dependencies for the Teleport nix shell, which contains +# all of the utilities for building and linting Teleport. +# + +{ + description = "Teleport shell dependencies"; + + inputs = { + flake-utils.url = "github:numtide/flake-utils"; + nixpkgs.url = "github:nixos/nixpkgs/8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8"; # general packages + rust-overlay.url = "github:oxalica/rust-overlay"; + + + # Linting dependencies + helmPkgs.url = "github:nixos/nixpkgs/8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8"; # helm 3.11.1 + + # libbpf dependencies. + libbpfPkgs.url = "github:nixos/nixpkgs/79b3d4bcae8c7007c9fd51c279a8a67acfa73a2a"; # libbpf 1.0.1 + + # bats dependencies. + batsPkgs.url = "github:nixos/nixpkgs/5c1ffb7a9fc96f2d64ed3523c2bdd379bdb7b471"; # bats 1.2.1 + }; + + outputs = { self, + flake-utils, + nixpkgs, + rust-overlay, + + helmPkgs, + libbpfPkgs, + batsPkgs, + }: + flake-utils.lib.eachDefaultSystem + (system: + let + # These versions are not available from nixpkgs + gogoVersion = "v1.3.2"; + helmUnittestVersion = "v1.0.16"; + nodeProtocTsVersion = "v5.0.1"; + grpcToolsVersion = "1.12.4"; + libpcscliteVersion = "1.9.9-teleport"; + rustVersion = "1.68.0"; + yarnVersion = "1.22.19"; + + overlays = [ (import rust-overlay) ]; + + # Package aliases to make reusing these packages easier. + # The individual package names here have been determined by using + # https://lazamar.co.uk/nix-versions/ + libbpf = libbpfPkgs.legacyPackages.${system}.libbpf; + bats = batsPkgs.legacyPackages.${system}.bats; + + # pkgs is an alias for the nixpkgs at the system level. This will be used + # for general utilities. + pkgs = import nixpkgs { + inherit system overlays; + }; + + # The helm unittest plugin. + helm-unittest = pkgs.buildGoModule rec { + name = "helm-unittest"; + + src = pkgs.fetchFromGitHub { + owner = "vbehar"; + repo = "helm3-unittest"; + rev = helmUnittestVersion; + sha256 = "sha256-2UfQimIlA+hb1CpQrWfMh5iBEvgdnrkCGYaTJC3Bzpo="; + }; + + vendorSha256 = null; + + postInstall = '' + install -Dm644 plugin.yaml $out/helm-unittest/plugin.yaml + mkdir "$out/helm-unittest/bin" + mv $out/bin/helm3-unittest $out/helm-unittest/bin/unittest + ''; + + doCheck = false; + }; + + # Wrap helm with the unittest plugin. + helm = (pkgs.wrapHelm helmPkgs.legacyPackages.${system}.kubernetes-helm {plugins = [helm-unittest];}); + + libpcscliteAdditionalNativeBuildInputs = if pkgs.stdenv.isDarwin then + [pkgs.darwin.IOKit] else []; + libpcscliteAdditionalBuildInputs = if pkgs.stdenv.isLinux then + [pkgs.libusb1] else []; + + # Compile libpcsclite. + libpcsclite = pkgs.stdenv.mkDerivation { + name = "libpcsclite"; + src = pkgs.fetchFromGitHub { + owner = "gravitational"; + repo = "PCSC"; + rev = libpcscliteVersion; + sha256 = "sha256-Eig30fj7YlDHe6A/ceJ+KLhzT/ctxb9d4nFnsxk+WsA="; + }; + nativeBuildInputs = [ + pkgs.autoreconfHook + ] ++ libpcscliteAdditionalNativeBuildInputs; + buildInputs = [ + pkgs.autoconf-archive + pkgs.flex + pkgs.gcc + pkgs.pkg-config + ] ++ libpcscliteAdditionalBuildInputs; + configurePhase = '' + ./bootstrap + ./configure --enable-static --with-pic --disable-libsystemd --with-systemdsystemunitdir=$out --exec-prefix=$out --prefix=$out + ''; + makeFlags = [ + "CFLAGS=\"-std=gnu99\"" + ]; + }; + + # Compile protoc-gen-gogo for golang protobuf compilation. + protoc-gen-gogo = pkgs.buildGoModule { + name = "protoc-gen-gogo"; + version = gogoVersion; + + src = pkgs.fetchFromGitHub { + owner = "gogo"; + repo = "protobuf"; + rev = gogoVersion; + sha256 = "sha256-CoUqgLFnLNCS9OxKFS7XwjE17SlH6iL1Kgv+0uEK2zU="; + }; + + vendorSha256 = "sha256-nOL2Ulo9VlOHAqJgZuHl7fGjz/WFAaWPdemplbQWcak="; + + buildPhase = '' + export GOBIN="$out/bin" + export GOCACHE="$(mktemp -d)" + make install + cp -R protobuf "$out/protobuf" + ''; + }; + + node-protoc-ts = pkgs.buildNpmPackage { + name = "grpc_tools_node_protoc_ts"; + version = nodeProtocTsVersion; + + src = pkgs.fetchFromGitHub { + owner = "agreatfool"; + repo = "grpc_tools_node_protoc_ts"; + rev = nodeProtocTsVersion; + sha256 = "sha256-kDrflQVENjOY7ei3+D3Znx4eUDPoja8UGG2Phv1eptA="; + }; + + npmDepsHash = "sha256-fxOyItDkkv5OAmtScD9ykq26Meh6qyZSDmWegeh+GRY="; + }; + + grpc-tools = pkgs.stdenv.mkDerivation rec { + pname = "grpc-tools"; + version = grpcToolsVersion; + + src = pkgs.fetchFromGitHub { + owner = "grpc"; + repo = "grpc-node"; + rev = "grpc-tools@${grpcToolsVersion}"; + fetchSubmodules = true; + sha256 = "sha256-708lBIGW5+vvSTrZHl/kc+ck7JKNXElrghIGDrMSyx8="; + }; + + sourceRoot = "source/packages/grpc-tools"; + + nativeBuildInputs = [ pkgs.cmake ]; + + installPhase = '' + install -Dm755 -t $out/bin grpc_node_plugin + + cp grpc_node_plugin grpc_tools_node_protoc_plugin + install -Dm755 -t $out/bin grpc_tools_node_protoc_plugin + + install -Dm755 -t $out/bin deps/protobuf/protoc + ''; + }; + + rust = pkgs.rust-bin.stable.${rustVersion}.default; + + # Yarn binary. + yarn = pkgs.stdenv.mkDerivation { + name = "yarn"; + src = fetchTarball { + url = "https://yarnpkg.com/downloads/${yarnVersion}/yarn-v${yarnVersion}.tar.gz"; + sha256 = "sha256:0jl77rl2sidsj3ym637w7g35wnv190l96n050aqlm4pyc6wi8v6p"; + }; + buildInputs = [ + pkgs.nodejs-16_x + ]; + buildPhase = '' + mkdir "$out" + cp -R * "$out" + ''; + }; + + conditionalBuildInputs = if pkgs.stdenv.isLinux then [ + bats + libbpf + ] else if pkgs.stdenv.isDarwin then [ + pkgs.darwin.IOKit + ] else [ + pkgs.hello # The derivation below will not work with an empty array, so this is a dummy package to fill it in. + ]; + + conditional = pkgs.stdenv.mkDerivation { + name = "conditional"; + dontUnpack = true; + dontBuild = true; + propagatedBuildInputs = conditionalBuildInputs; + }; + in + { + packages = { + conditional = conditional; + node-protoc-ts = node-protoc-ts; + grpc-tools = grpc-tools; + helm = helm; + libpcsclite = libpcsclite; + protoc-gen-gogo = protoc-gen-gogo; + rust = rust; + yarn = yarn; + }; + }); +} diff --git a/build.assets/images.mk b/build.assets/images.mk index 6f165efde6440..5eb8a3b2aa9b9 100644 --- a/build.assets/images.mk +++ b/build.assets/images.mk @@ -6,12 +6,11 @@ BUILDBOX_VERSION ?= teleport14 BUILDBOX_BASE_NAME ?= public.ecr.aws/gravitational/teleport-buildbox BUILDBOX=$(BUILDBOX_BASE_NAME):$(BUILDBOX_VERSION) -BUILDBOX_FIPS=$(BUILDBOX_BASE_NAME)-fips:$(BUILDBOX_VERSION) BUILDBOX_CENTOS7=$(BUILDBOX_BASE_NAME)-centos7:$(BUILDBOX_VERSION) BUILDBOX_CENTOS7_FIPS=$(BUILDBOX_BASE_NAME)-centos7-fips:$(BUILDBOX_VERSION) BUILDBOX_ARM=$(BUILDBOX_BASE_NAME)-arm:$(BUILDBOX_VERSION) -BUILDBOX_ARM_FIPS=$(BUILDBOX_BASE_NAME)-arm-fips:$(BUILDBOX_VERSION) BUILDBOX_UI=$(BUILDBOX_BASE_NAME)-ui:$(BUILDBOX_VERSION) +BUILDBOX_CONNECT=$(BUILDBOX_BASE_NAME)-connect:$(BUILDBOX_VERSION) BUILDBOX_CENTOS7_ASSETS=$(BUILDBOX_BASE_NAME)-centos7-assets:$(BUILDBOX_VERSION) .PHONY:show-buildbox-base-image diff --git a/build.assets/tooling/cmd/difftest/main.go b/build.assets/tooling/cmd/difftest/main.go index 8183e29d64bd1..b343df0abd74a 100644 --- a/build.assets/tooling/cmd/difftest/main.go +++ b/build.assets/tooling/cmd/difftest/main.go @@ -60,6 +60,14 @@ var ( // TestProxySSH and TestList takes around 10-15s to run, largely due to the 7-10 seconds it takes to create a // tsh test suite. This prevents it from ever completing the 100 runs successfully. "TestProxySSH", "TestList", "TestForwardingTraces", "TestExportingTraces", + + // TestDiagnoseSSHConnection takes around 15s to run. + // When running 100x it exceeds the 600s defined to run the tests. + "TestDiagnoseSSHConnection", + + // TestServer_Authenticate_headless takes about 4-5 seconds to run, so if other tests are changed + // in the same PR that take >1 second total, it may cause the flaky test detector to time out. + "TestServer_Authenticate_headless", } ) @@ -169,7 +177,7 @@ func test(repoPath string, ref string, changedFiles []string) { } for _, n := range r.New { - if slices.Contains(testsToSkip, n.RefName) { + if slices.Contains(testsToSkip, n.RefName) || slices.Contains(testsToSkip, "*") { log.Printf("-skipping %q (%s)\n", n.RefName, dir) continue } @@ -182,7 +190,7 @@ func test(repoPath string, ref string, changedFiles []string) { } for _, n := range r.Changed { - if slices.Contains(testsToSkip, n.RefName) { + if slices.Contains(testsToSkip, n.RefName) || slices.Contains(testsToSkip, "*") { log.Printf("-skipping %q (%s)\n", n.RefName, dir) continue } diff --git a/build.assets/tooling/cmd/render-tests/_sample/README.md b/build.assets/tooling/cmd/render-tests/_sample/README.md new file mode 100644 index 0000000000000..566f256084672 --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/_sample/README.md @@ -0,0 +1,8 @@ +This is a dummy Go module for the purposes of generating test data for +render-test. Run: + + go test -cover -json ./... + +Modify some of the test files to make them fail or to skip tests to +vary the data. The output is stored in files in the `../testdata/` +directory. diff --git a/build.assets/tooling/cmd/render-tests/_sample/go.mod b/build.assets/tooling/cmd/render-tests/_sample/go.mod new file mode 100644 index 0000000000000..1dbc6becd677f --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/_sample/go.mod @@ -0,0 +1,3 @@ +module example.com + +go 1.20 diff --git a/web/packages/teleport/src/Assist/Chat/index.ts b/build.assets/tooling/cmd/render-tests/_sample/package1/foo.go similarity index 79% rename from web/packages/teleport/src/Assist/Chat/index.ts rename to build.assets/tooling/cmd/render-tests/_sample/package1/foo.go index c1c6b784089a7..5d8639df6613a 100644 --- a/web/packages/teleport/src/Assist/Chat/index.ts +++ b/build.assets/tooling/cmd/render-tests/_sample/package1/foo.go @@ -14,4 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ -export { Chat } from './Chat'; +package package1 + +import "fmt" + +func foo() { + fmt.Println("hello world: foo") +} + +func foo2() { + x := 1 + if x > 2 { + x++ + } + fmt.Println("x = ", x) +} diff --git a/build.assets/tooling/cmd/render-tests/_sample/package1/foo_test.go b/build.assets/tooling/cmd/render-tests/_sample/package1/foo_test.go new file mode 100644 index 0000000000000..9d946ad6ab107 --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/_sample/package1/foo_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2023 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package package1 + +import "testing" + +func Test1(t *testing.T) { + t.Log("doing stuff") + foo2() + // t.Fatal("fail") // uncomment for flaky result +} + +func Test2(t *testing.T) { + t.Log("stuff doing") +} diff --git a/web/packages/teleport/src/Assist/Sidebar/index.ts b/build.assets/tooling/cmd/render-tests/_sample/package2/bar.go similarity index 89% rename from web/packages/teleport/src/Assist/Sidebar/index.ts rename to build.assets/tooling/cmd/render-tests/_sample/package2/bar.go index 813fb0ef8bc9e..14db46ba46c4c 100644 --- a/web/packages/teleport/src/Assist/Sidebar/index.ts +++ b/build.assets/tooling/cmd/render-tests/_sample/package2/bar.go @@ -14,4 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -export { Sidebar } from './Sidebar'; +package package2 + +import "fmt" + +func bar() { + fmt.Println("bar") +} diff --git a/web/packages/teleport/src/services/ping/types.ts b/build.assets/tooling/cmd/render-tests/_sample/package2/bar_test.go similarity index 85% rename from web/packages/teleport/src/services/ping/types.ts rename to build.assets/tooling/cmd/render-tests/_sample/package2/bar_test.go index 480f59a6989ea..11714c70ed15a 100644 --- a/web/packages/teleport/src/services/ping/types.ts +++ b/build.assets/tooling/cmd/render-tests/_sample/package2/bar_test.go @@ -14,7 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -export interface PingResponse { - automaticUpgrades: boolean; - assistEnabled: boolean; +package package2 + +import "testing" + +func Test3(t *testing.T) { + // t.Fatal("not implemented") } diff --git a/build.assets/tooling/cmd/render-tests/_sample/package3/baz_test.go b/build.assets/tooling/cmd/render-tests/_sample/package3/baz_test.go new file mode 100644 index 0000000000000..3f42b3e11f57c --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/_sample/package3/baz_test.go @@ -0,0 +1,27 @@ +/* +Copyright 2023 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package package3 + +import "testing" + +func Test4(t *testing.T) { + // t.Fatal("sometimes I flake") // uncomment for flaky results +} + +func Test5(t *testing.T) { + // t.Fatal("nevermind") // uncomment for flaky result +} diff --git a/build.assets/tooling/cmd/render-tests/args.go b/build.assets/tooling/cmd/render-tests/args.go index 4debec4909e72..855eb7e6ca18c 100644 --- a/build.assets/tooling/cmd/render-tests/args.go +++ b/build.assets/tooling/cmd/render-tests/args.go @@ -27,13 +27,15 @@ import ( type reportMode int const ( - byPackage reportMode = 0 - byTest reportMode = iota + byPackage reportMode = iota + byTest + byFlakiness ) const ( - byPackageName = "package" - byTestName = "test" + byPackageName = "package" + byTestName = "test" + byFlakinessName = "flakiness" ) func (m *reportMode) String() string { @@ -44,6 +46,9 @@ func (m *reportMode) String() string { case byTest: return byTestName + case byFlakiness: + return byFlakinessName + default: return fmt.Sprintf("Unknown filter mode %d", *m) } @@ -57,6 +62,9 @@ func (m *reportMode) Set(text string) error { case byTestName: (*m) = byTest + case byFlakinessName: + (*m) = byFlakiness + default: return trace.Errorf("Invalid report mode %q", text) } @@ -65,14 +73,22 @@ func (m *reportMode) Set(text string) error { } type args struct { - report reportMode + report reportMode + top int + summaryFile string } -func parseCommandLine() args { - reportMode := byPackage - flag.Var(&reportMode, "report-by", - fmt.Sprintf("test reporting mode [%s, %s]", byPackageName, byTestName)) +func parseCommandLine() (args, error) { + var a args + flag.Var(&a.report, "report-by", + fmt.Sprintf("test reporting mode [%s, %s, %s]", byPackageName, byTestName, byFlakinessName)) + flag.IntVar(&a.top, "top", 0, "top number of flaky tests to report [default 0 - all]") + flag.StringVar(&a.summaryFile, "summary-file", "", "file to write summary to") flag.Parse() - return args{report: reportMode} + if a.top != 0 && a.report != byFlakiness { + return args{}, trace.Errorf("-top can only be used with -report-by flakiness") + } + + return a, nil } diff --git a/build.assets/tooling/cmd/render-tests/main.go b/build.assets/tooling/cmd/render-tests/main.go index 8f637c9e06264..6388786928395 100644 --- a/build.assets/tooling/cmd/render-tests/main.go +++ b/build.assets/tooling/cmd/render-tests/main.go @@ -27,16 +27,11 @@ import ( "io" "os" "os/signal" - "regexp" - "sort" - "strconv" "time" "github.com/gravitational/trace" ) -var covPattern = regexp.MustCompile(`^coverage: (\d+\.\d+)\% of statements`) - // matches `event` in src/cmd/internal/test2json/test2json.go type TestEvent struct { Time time.Time // encodes as an RFC3339-format string @@ -47,62 +42,37 @@ type TestEvent struct { Output string } -func (e *TestEvent) FullName() string { - if e.Test == "" { - return e.Package - } - return e.Package + "." + e.Test -} - -// action names used by the go test runner in its JSON output -const ( - actionPass = "pass" - actionFail = "fail" - actionSkip = "skip" - actionOutput = "output" -) - -// separator for console output -const separator = "===================================================" - func readInput(input io.Reader, ch chan<- TestEvent, errCh chan<- error) { defer close(ch) decoder := json.NewDecoder(input) - for { + var err error + for err == nil { event := TestEvent{} - - err := decoder.Decode(&event) - if errors.Is(err, io.EOF) { - return + if err = decoder.Decode(&event); err == nil { + ch <- event } + } - if err != nil { - fmt.Printf("Error parsing JSON test record: %v\n", err) - - scanner := bufio.NewScanner(decoder.Buffered()) - for scanner.Scan() { - line := scanner.Text() - if line != "" { - err = trace.Errorf(line) - break - } + if !errors.Is(err, io.EOF) { + fmt.Printf("Error parsing JSON test record: %v\n", err) + scanner := bufio.NewScanner(decoder.Buffered()) + for scanner.Scan() { + line := scanner.Text() + if line != "" { + err = trace.Errorf(line) + break } - - errCh <- err - - return } - - ch <- event + errCh <- err } } func main() { - args := parseCommandLine() - - testOutput := newOutputMap() - failedPackages := make(map[string]*packageOutput) - coverage := make(map[string]float64) + args, err := parseCommandLine() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } events := make(chan TestEvent) errors := make(chan error) @@ -111,124 +81,49 @@ func main() { signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt) -readloop: - for { + var summaryOut io.Writer = os.Stdout + if args.summaryFile != "" { + f, err := os.Create(args.summaryFile) + if err != nil { + // Don't fatally exit, because we should still summarize the + // results to stdout + fmt.Fprintf(os.Stderr, "Could not create summary file: %v\n", err) + } else { + summaryOut = io.MultiWriter(os.Stdout, f) + defer f.Close() + } + } + + rr := newRunResult(args.report, args.top) + ok := true + for ok { + var event TestEvent select { case <-signals: - break readloop + ok = false case err := <-errors: fmt.Printf("FATAL error: %q\n", err) + ok = false - case event, keepGoing := <-events: - if !keepGoing { - break readloop - } - - testName := event.FullName() - - testOutput.record(event) - - if args.report == byTest { - switch event.Action { - case actionPass, actionFail, actionSkip: - fmt.Printf("%s (in %6.2fs): %s\n", event.Action, event.ElapsedSeconds, event.FullName()) - } - } - - // if this is whole-package summary result - if event.Test == "" { - switch event.Action { - case actionOutput: - if matches := covPattern.FindStringSubmatch(event.Output); len(matches) != 0 { - value, err := strconv.ParseFloat(matches[1], 64) - if err != nil { - panic("Malformed coverage value: " + err.Error()) - } - coverage[testName] = value - } - - case actionFail: - // cache the failed test output - failedPackages[event.Package] = testOutput.getPkg(event.Package) - fallthrough - - case actionPass, actionSkip: - if args.report == byPackage { - // extract and format coverage value - covText := "------" - if covValue, ok := coverage[testName]; ok { - covText = fmt.Sprintf("%5.1f%%", covValue) - } - - // only display package results as progress messages - fmt.Printf("%s %s (in %6.2fs): %s\n", covText, event.Action, event.ElapsedSeconds, event.Package) - } - - // Don't need this no more - testOutput.deletePkg(event.Package) - } + case event, ok = <-events: + if ok { + rr.processTestEvent(event) + rr.printTestResult(os.Stdout, event) } } } - fmt.Println(separator) - - fmt.Printf("%d tests passed. %d failed, %d skipped\n", - testOutput.actionCounts[actionPass], testOutput.actionCounts[actionFail], testOutput.actionCounts[actionSkip]) - - fmt.Println(separator) - - if len(failedPackages) == 0 { - fmt.Println("All tests pass. Yay!") - os.Exit(0) - } - - // Generate a sorted list of package names, so that we present the - // packages that fail in a repeatable order. - names := make([]string, 0, len(failedPackages)) - for k := range failedPackages { - names = append(names, k) - } - sort.Strings(names) - - // Print a summary list of the failed tests and packages. - for _, pkgName := range names { - pkg := failedPackages[pkgName] - - fmt.Printf("FAIL: %s\n", pkgName) - - for testName := range pkg.failedSubtests { - fmt.Printf("FAIL: %s.%s\n", pkgName, testName) - } + if args.report == byFlakiness { + rr.printFlakinessSummary(summaryOut) + } else { + rr.printSummary(summaryOut) } + fmt.Fprintln(os.Stdout, separator) + rr.printFailedTestOutput(os.Stdout) - fmt.Println(separator) - - // Print the output of each failed package or test. Note that we only print - // the package output if there is no identifiable test that caused the - // failure, as it will probably swamp the individual test output. - for _, pkgName := range names { - pkg := failedPackages[pkgName] - - if len(pkg.failedSubtests) == 0 { - fmt.Printf("OUTPUT %s\n", pkgName) - fmt.Println(separator) - for _, l := range pkg.output { - fmt.Print(l) - } - fmt.Println(separator) - } else { - for _, testName := range pkg.FailedTests() { - fmt.Printf("OUTPUT %s.%s\n", pkgName, testName) - fmt.Println(separator) - for _, l := range pkg.failedSubtests[testName] { - fmt.Print(l) - } - fmt.Println(separator) - } - } + if rr.testCount.fail == 0 { + os.Exit(0) } - os.Exit(1) } diff --git a/build.assets/tooling/cmd/render-tests/main_test.go b/build.assets/tooling/cmd/render-tests/main_test.go new file mode 100644 index 0000000000000..c2f8117f1d35c --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/main_test.go @@ -0,0 +1,66 @@ +/* +Copyright 2023 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestReadInput(t *testing.T) { + // var passFailPass and func strToEvents in result_test.go + expected := strToEvents(t, passFailPass) + eventChan := make(chan TestEvent) + errChan := make(chan error) + + actual := []TestEvent{} + go readInput(strings.NewReader(passFailPass), eventChan, errChan) + ok := true + for ok { + var event TestEvent + select { + case err := <-errChan: + require.NoError(t, err) + case event, ok = <-eventChan: + if ok { + actual = append(actual, event) + } + } + } + + require.Equal(t, expected, actual) +} + +func TestReadInputFail(t *testing.T) { + // var passFailPass and func strToEvents in result_test.go + eventChan := make(chan TestEvent) + errChan := make(chan error) + + go readInput(strings.NewReader(passFailPass+"bad json data\noh no\n"), eventChan, errChan) + ok := true + var err error + for ok { + select { + case err = <-errChan: + case _, ok = <-eventChan: + } + } + + require.Error(t, err) +} diff --git a/build.assets/tooling/cmd/render-tests/outputMap.go b/build.assets/tooling/cmd/render-tests/outputMap.go deleted file mode 100644 index 48d51d680a747..0000000000000 --- a/build.assets/tooling/cmd/render-tests/outputMap.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2022 Gravitational, Inc -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import "sort" - -type packageOutput struct { - output []string - subtestOutput map[string][]string - failedSubtests map[string][]string -} - -func (pkg *packageOutput) FailedTests() []string { - result := []string{} - for testName := range pkg.failedSubtests { - result = append(result, testName) - } - sort.Strings(result) - return result -} - -type outputMap struct { - packages map[string]*packageOutput - actionCounts map[string]int -} - -func newOutputMap() *outputMap { - return &outputMap{ - packages: make(map[string]*packageOutput), - actionCounts: make(map[string]int), - } -} - -func (m *outputMap) record(event TestEvent) { - m.actionCounts[event.Action]++ - - var pkgOutput *packageOutput - var exists bool - if pkgOutput, exists = m.packages[event.Package]; !exists { - pkgOutput = &packageOutput{ - subtestOutput: make(map[string][]string), - failedSubtests: make(map[string][]string), - } - m.packages[event.Package] = pkgOutput - } - - switch event.Action { - case actionOutput: - pkgOutput.output = append(pkgOutput.output, event.Output) - if event.Test != "" { - pkgOutput.subtestOutput[event.Test] = append(pkgOutput.subtestOutput[event.Test], event.Output) - } - - case actionFail: - // If this is a single test result - if event.Test != "" { - pkgOutput.failedSubtests[event.Test] = pkgOutput.subtestOutput[event.Test] - } else { - // If this is a package result, we only want to preserve the package output if - // there are no failed subtests - if len(pkgOutput.failedSubtests) > 0 { - pkgOutput.output = nil - } - } - fallthrough - - case actionPass, actionSkip: - delete(pkgOutput.subtestOutput, event.Test) - } -} - -func (m *outputMap) getPkg(pkgName string) *packageOutput { - return m.packages[pkgName] -} - -func (m *outputMap) deletePkg(pkgName string) { - delete(m.packages, pkgName) -} diff --git a/build.assets/tooling/cmd/render-tests/result.go b/build.assets/tooling/cmd/render-tests/result.go new file mode 100644 index 0000000000000..4f9b91c8ebcfe --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/result.go @@ -0,0 +1,330 @@ +/* +Copyright 2023 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "fmt" + "io" + "regexp" + "sort" + "strconv" + + "golang.org/x/exp/maps" +) + +// separator for console output +const separator = "===================================================" + +// action names used by the go test runner in its JSON output +const ( + actionPass = "pass" + actionFail = "fail" + actionSkip = "skip" + actionOutput = "output" +) + +// covPattern matches output that contains package coverage values +var covPattern = regexp.MustCompile("\t" + `coverage: (\d+\.\d+)\% of statements`) + +type counts struct { + total int + pass int + fail int + skip int +} + +func (c *counts) record(action string) { + c.total++ + switch action { + case actionPass: + c.pass++ + case actionFail: + c.fail++ + case actionSkip: + c.skip++ + } +} + +func (c counts) String() string { + return fmt.Sprintf("%d passed, %d failed, %d skipped", c.pass, c.fail, c.skip) +} + +func (c counts) failureRate() float64 { + return float64(c.fail) / float64(c.total) +} + +// runResult records the results of an entire test run piped into render-tests. +type runResult struct { + pkgCount counts + testCount counts + packages map[string]*packageResult + reportBy reportMode + top int +} + +// packageResult records the test results of a single Go package including the +// individual tests within that package. +type packageResult struct { + name string + count counts + coverage *float64 + output []string + tests map[string]*testResult +} + +// testResult records the results of a single test. +type testResult struct { + name string + count counts + output []string +} + +func newRunResult(reportBy reportMode, top int) *runResult { + return &runResult{ + packages: map[string]*packageResult{}, + reportBy: reportBy, + top: top, + } +} + +func newPackageResult(name string) *packageResult { + return &packageResult{ + name: name, + tests: map[string]*testResult{}, + } +} + +func newTestResult(name string) *testResult { + return &testResult{ + name: name, + } +} + +func (rr *runResult) getPackage(name string) *packageResult { + if pkg, ok := rr.packages[name]; ok { + return pkg + } + pkg := newPackageResult(name) + rr.packages[name] = pkg + return pkg +} + +func (rr *runResult) processTestEvent(te TestEvent) { + pkg := rr.getPackage(te.Package) + pkg.processTestEvent(te) + + if te.Test == "" { + rr.pkgCount.record(te.Action) + } else { + rr.testCount.record(te.Action) + } +} + +func (rr *runResult) printTestResult(out io.Writer, te TestEvent) { + if !isTestResult(te.Action) { + return + } + + // Report each completion of packages and tests when reporting by test + if rr.reportBy == byTest { + testname := te.Package + if te.Test != "" { + testname += "." + te.Test + } + fmt.Fprintf(out, "%s (in %6.2fs): %s\n", te.Action, te.ElapsedSeconds, testname) + } else if rr.reportBy == byPackage && te.Test == "" { + pkg := rr.getPackage(te.Package) + covText := "------" + if pkg.coverage != nil { + covText = fmt.Sprintf("%5.1f%%", *pkg.coverage) + } + fmt.Fprintf(out, "%s %s (in %6.2fs): %s\n", te.Action, covText, te.ElapsedSeconds, pkg.name) + } +} + +func (rr *runResult) printSummary(out io.Writer) { + fmt.Fprintln(out, separator) + fmt.Fprintln(out, "Tests:", rr.testCount) + fmt.Fprintln(out, "Packages:", rr.pkgCount) + fmt.Fprintln(out, separator) + + if rr.testCount.fail == 0 { + fmt.Fprintln(out, "All tests pass. Yay!") + return + } + rr.printFailedTests(out) +} + +func (rr *runResult) printFlakinessSummary(out io.Writer) { + if rr.testCount.fail == 0 { + fmt.Fprintln(out, "No flaky tests!") + return + } + + // get all failed tests so we can get the top N flaky failures + var alltests []*testResult + for _, pkg := range rr.packages { + if pkg.count.fail == 0 { + continue + } + for _, test := range pkg.tests { + if test.count.fail > 0 { + alltests = append(alltests, test) + } + } + // Create a pseudo-test result for the package level output + // as it can contain relevant output not included in individual + // tests such as crash or data race output. + tr := &testResult{ + name: pkg.name, + count: pkg.count, + output: pkg.output, + } + alltests = append(alltests, tr) + } + // reverse sort by failure rate + sort.Slice(alltests, func(i, j int) bool { + return alltests[i].count.failureRate() > alltests[j].count.failureRate() + }) + for i, test := range alltests { + if rr.top != 0 && i >= rr.top { + break + } + fmt.Fprintf(out, "FAIL(%d/%d): %s\n", test.count.fail, test.count.total, test.name) + } +} + +// printFailedTests prints a summary list of the failed tests and packages in +// the given packages. +func (rr *runResult) printFailedTests(out io.Writer) { + // Order the packages by name for consistent output ordering. + pkgs := maps.Values(rr.packages) + sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].name < pkgs[j].name }) + + for _, pkg := range pkgs { + if pkg.count.fail == 0 { + continue + } + fmt.Fprintf(out, "FAIL: %s\n", pkg.name) + for _, test := range pkg.tests { + if test.count.fail == 0 { + continue + } + fmt.Fprintf(out, "FAIL: %s\n", test.name) + } + } +} + +// printFailedTestOutput prints the output of each failed package or test. Only +// print the package output if there is no test that failed (how can this +// happen?) so as to not swamp individual test output. +func (rr *runResult) printFailedTestOutput(out io.Writer) { + // Order the packages by name for consistent output ordering. + pkgs := maps.Values(rr.packages) + sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].name < pkgs[j].name }) + + for _, pkg := range pkgs { + if pkg.count.fail == 0 { + continue + } + printOutput(out, pkg.name, pkg.output) + for _, test := range pkg.tests { + if test.count.fail == 0 { + continue + } + printOutput(out, test.name, test.output) + } + } +} + +func printOutput(out io.Writer, test string, output []string) { + fmt.Fprintf(out, "OUTPUT %s\n", test) + fmt.Fprintln(out, separator) + for _, line := range output { + fmt.Fprint(out, line) + } + fmt.Fprintln(out, separator) +} + +func (pr *packageResult) processTestEvent(te TestEvent) { + if te.Test != "" { + tst := pr.getTest(pr.name + "." + te.Test) + tst.processTestEvent(te) + return + } + + if te.Action == actionOutput { + // Only append output if no failures. We only record the output + // of the first failure so we don't store too much redundant output. + if pr.count.fail == 0 { + pr.output = append(pr.output, te.Output) + } + if matches := covPattern.FindStringSubmatch(te.Output); len(matches) > 0 { + value, err := strconv.ParseFloat(matches[1], 64) + if err != nil { + panic("Malformed coverage value: " + err.Error()) + } + pr.coverage = &value + } + } + + if !isTestResult(te.Action) { + return + } + + pr.count.record(te.Action) + + // Delete test output of passed / skipped packages. Only save output of failures. + if pr.count.fail == 0 && (te.Action == actionPass || te.Action == actionSkip) { + pr.output = nil + } +} + +func (pr *packageResult) getTest(name string) *testResult { + if tst, ok := pr.tests[name]; ok { + return tst + } + tst := newTestResult(name) + pr.tests[name] = tst + return tst + +} + +func (tr *testResult) processTestEvent(te TestEvent) { + if te.Action == actionOutput { + // Only append output if no failures. We only record the output + // of the first failure so we don't store too much redundant output. + if tr.count.fail == 0 { + tr.output = append(tr.output, te.Output) + } + } + + if !isTestResult(te.Action) { + return + } + + tr.count.record(te.Action) + + // Delete test output of passed / skipped tests. Only save output of failures. + if tr.count.fail == 0 && (te.Action == actionPass || te.Action == actionSkip) { + tr.output = nil + } +} + +func isTestResult(action string) bool { + return action == actionPass || action == actionFail || action == actionSkip +} diff --git a/build.assets/tooling/cmd/render-tests/result_test.go b/build.assets/tooling/cmd/render-tests/result_test.go new file mode 100644 index 0000000000000..a3c643c6813a5 --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/result_test.go @@ -0,0 +1,267 @@ +/* +Copyright 2023 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "bytes" + _ "embed" + "encoding/json" + "errors" + "io" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +var ( + //go:embed testdata/pass-pass-pass.in + passPassPass string + + //go:embed testdata/pass-fail-pass.in + passFailPass string + + //go:embed testdata/pass-fail-skip.in + passFailSkip string + + //go:embed testdata/flaky-pass.in + flakyPass string + //go:embed testdata/flaky-fail-1.in + flakyFail1 string + //go:embed testdata/flaky-fail-4.in + flakyFail4 string + //go:embed testdata/flaky-fail-5.in + flakyFail5 string +) + +func TestHierarchy(t *testing.T) { + rr := newRunResult(byPackage, 0) + feedEvents(t, rr, passFailSkip) + + pkgname := "example.com/package" + require.Contains(t, rr.packages, pkgname) + pkg := rr.packages[pkgname] + require.Contains(t, pkg.tests, pkgname+".TestParse") + require.Contains(t, pkg.tests, pkgname+".TestEmpty") + require.Contains(t, pkg.tests, pkgname+".TestParseHostPort") +} + +func TestStatus(t *testing.T) { + rr := newRunResult(byPackage, 0) + feedEvents(t, rr, passFailSkip) + + require.Equal(t, 1, rr.testCount.pass) + require.Equal(t, 1, rr.testCount.fail) + require.Equal(t, 1, rr.testCount.skip) + require.Equal(t, 1, rr.pkgCount.fail) + pkgname := "example.com/package" + pkg := rr.packages[pkgname] + require.Equal(t, 1, pkg.count.fail) + require.Equal(t, 1, pkg.tests[pkgname+".TestEmpty"].count.pass) + require.Equal(t, 1, pkg.tests[pkgname+".TestParse"].count.fail) + require.Equal(t, 1, pkg.tests[pkgname+".TestParseHostPort"].count.skip) +} + +func TestSuccessOutput(t *testing.T) { + rr := newRunResult(byPackage, 0) + feedEvents(t, rr, passPassPass) + + pkgname := "example.com/package" + pkg := rr.packages[pkgname] + require.Empty(t, pkg.output) + require.Empty(t, pkg.tests[pkgname+".TestEmpty"].output) + require.Empty(t, pkg.tests[pkgname+".TestParseHostPort"].output) + require.Empty(t, pkg.tests[pkgname+".TestParse"].output) +} + +func TestFailureOutput(t *testing.T) { + rr := newRunResult(byPackage, 0) + feedEvents(t, rr, passFailSkip) + + pkgname := "example.com/package" + pkg := rr.packages[pkgname] + require.Empty(t, pkg.tests[pkgname+".TestEmpty"].output) + require.Empty(t, pkg.tests[pkgname+".TestParseHostPort"].output) + expectedTestOutput := []string{ + "=== RUN TestParse\n", + "=== PAUSE TestParse\n", + "=== CONT TestParse\n", + " addr_test.go:71: failed\n", + "--- FAIL: TestParse (0.00s)\n", + } + expectedPkgOutput := []string{ + "FAIL\n", + "\texample.com/package\tcoverage: 2.4% of statements\n", + "FAIL\texample.com/package\t0.007s\n", + } + require.Equal(t, expectedTestOutput, pkg.tests[pkgname+".TestParse"].output) + require.Equal(t, expectedPkgOutput, pkg.output) +} + +func TestPrintTestResultByPackage(t *testing.T) { + output := &bytes.Buffer{} + events := strToEvents(t, passFailSkip) + rr := newRunResult(byPackage, 0) + for _, event := range events { + rr.processTestEvent(event) + rr.printTestResult(output, event) + } + + expected := "fail 2.4% (in 0.01s): example.com/package\n" + require.Equal(t, expected, output.String()) +} + +func TestPrintTestResultByTest(t *testing.T) { + output := &bytes.Buffer{} + events := strToEvents(t, passFailSkip) + rr := newRunResult(byTest, 0) + for _, event := range events { + rr.processTestEvent(event) + rr.printTestResult(output, event) + } + + expected := ` +skip (in 0.00s): example.com/package.TestParseHostPort +pass (in 0.00s): example.com/package.TestEmpty +fail (in 0.00s): example.com/package.TestParse +fail (in 0.01s): example.com/package +`[1:] + require.Equal(t, expected, output.String()) +} + +func TestPrintSummaryNoFail(t *testing.T) { + rr := newRunResult(byTest, 0) + feedEvents(t, rr, passPassPass) + + output := &bytes.Buffer{} + rr.printSummary(output) + + expected := ` +=================================================== +Tests: 3 passed, 0 failed, 0 skipped +Packages: 1 passed, 0 failed, 0 skipped +=================================================== +All tests pass. Yay! +`[1:] + require.Equal(t, expected, output.String()) +} + +func TestPrintSummaryFail(t *testing.T) { + rr := newRunResult(byPackage, 0) + feedEvents(t, rr, passFailPass) + + output := &bytes.Buffer{} + rr.printSummary(output) + + expected := ` +=================================================== +Tests: 1 passed, 1 failed, 1 skipped +Packages: 1 passed, 1 failed, 0 skipped +=================================================== +FAIL: example.com/package +FAIL: example.com/package.TestParse +`[1:] + require.Equal(t, expected, output.String()) +} + +func TestPrintFailedTestOutput(t *testing.T) { + rr := newRunResult(byPackage, 0) + feedEvents(t, rr, passFailPass) + + output := &bytes.Buffer{} + rr.printFailedTestOutput(output) + + expected := ` +OUTPUT example.com/package +=================================================== +FAIL + example.com/package coverage: 2.4% of statements +FAIL example.com/package 0.007s +=================================================== +OUTPUT example.com/package.TestParse +=================================================== +=== RUN TestParse +=== PAUSE TestParse +=== CONT TestParse + addr_test.go:71: failed +--- FAIL: TestParse (0.00s) +=================================================== +`[1:] + require.Equal(t, expected, output.String()) +} + +func TestPrintFlakinessSummaryNoFail(t *testing.T) { + rr := newRunResult(byFlakiness, 2) // top 2 failures only + feedEvents(t, rr, flakyPass) + feedEvents(t, rr, flakyPass) + feedEvents(t, rr, flakyPass) + feedEvents(t, rr, flakyPass) + + output := &bytes.Buffer{} + rr.printFlakinessSummary(output) + + expected := "No flaky tests!\n" + require.Equal(t, expected, output.String()) +} + +func TestPrintFlakinessSummaryFail(t *testing.T) { + rr := newRunResult(byFlakiness, 3) // top 3 failures only (including packages) + feedEvents(t, rr, flakyPass) + feedEvents(t, rr, flakyFail1) + feedEvents(t, rr, flakyPass) + feedEvents(t, rr, flakyFail4) + feedEvents(t, rr, flakyFail5) + feedEvents(t, rr, flakyFail5) + feedEvents(t, rr, flakyFail5) + feedEvents(t, rr, flakyPass) + feedEvents(t, rr, flakyFail1) + feedEvents(t, rr, flakyPass) + + output := &bytes.Buffer{} + rr.printFlakinessSummary(output) + + expected := ` +FAIL(4/10): example.com/package3 +FAIL(3/10): example.com/package3.Test5 +FAIL(2/10): example.com/package1.Test1 +`[1:] + require.Equal(t, expected, output.String()) +} + +func strToEvents(t *testing.T, s string) []TestEvent { + t.Helper() + result := []TestEvent{} + decoder := json.NewDecoder(strings.NewReader(s)) + for { + event := TestEvent{} + err := decoder.Decode(&event) + if errors.Is(err, io.EOF) { + break + } + require.NoError(t, err) + result = append(result, event) + } + return result +} + +func feedEvents(t *testing.T, rr *runResult, s string) { + t.Helper() + events := strToEvents(t, s) + for _, event := range events { + rr.processTestEvent(event) + } +} diff --git a/build.assets/tooling/cmd/render-tests/testdata/flaky-fail-1.in b/build.assets/tooling/cmd/render-tests/testdata/flaky-fail-1.in new file mode 100644 index 0000000000000..0d777c5380466 --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/testdata/flaky-fail-1.in @@ -0,0 +1,39 @@ +{"Time":"2023-05-30T15:37:05.506456445+10:00","Action":"start","Package":"example.com/package1"} +{"Time":"2023-05-30T15:37:05.506570915+10:00","Action":"start","Package":"example.com/package2"} +{"Time":"2023-05-30T15:37:05.506620642+10:00","Action":"run","Package":"example.com/package2","Test":"Test3"} +{"Time":"2023-05-30T15:37:05.50663482+10:00","Action":"output","Package":"example.com/package2","Test":"Test3","Output":"=== RUN Test3\n"} +{"Time":"2023-05-30T15:37:05.506647252+10:00","Action":"output","Package":"example.com/package2","Test":"Test3","Output":"--- PASS: Test3 (0.00s)\n"} +{"Time":"2023-05-30T15:37:05.506654935+10:00","Action":"pass","Package":"example.com/package2","Test":"Test3","Elapsed":0} +{"Time":"2023-05-30T15:37:05.506661569+10:00","Action":"output","Package":"example.com/package2","Output":"PASS\n"} +{"Time":"2023-05-30T15:37:05.506668204+10:00","Action":"output","Package":"example.com/package2","Output":"\texample.com/package2\tcoverage: 0.0% of statements\n"} +{"Time":"2023-05-30T15:37:05.506673862+10:00","Action":"output","Package":"example.com/package2","Output":"ok \texample.com/package2\t(cached)\tcoverage: 0.0% of statements\n"} +{"Time":"2023-05-30T15:37:05.506681125+10:00","Action":"pass","Package":"example.com/package2","Elapsed":0} +{"Time":"2023-05-30T15:37:05.506722611+10:00","Action":"start","Package":"example.com/package3"} +{"Time":"2023-05-30T15:37:05.506746497+10:00","Action":"run","Package":"example.com/package3","Test":"Test4"} +{"Time":"2023-05-30T15:37:05.506754598+10:00","Action":"output","Package":"example.com/package3","Test":"Test4","Output":"=== RUN Test4\n"} +{"Time":"2023-05-30T15:37:05.506769265+10:00","Action":"output","Package":"example.com/package3","Test":"Test4","Output":"--- PASS: Test4 (0.00s)\n"} +{"Time":"2023-05-30T15:37:05.506779462+10:00","Action":"pass","Package":"example.com/package3","Test":"Test4","Elapsed":0} +{"Time":"2023-05-30T15:37:05.506785119+10:00","Action":"run","Package":"example.com/package3","Test":"Test5"} +{"Time":"2023-05-30T15:37:05.506790287+10:00","Action":"output","Package":"example.com/package3","Test":"Test5","Output":"=== RUN Test5\n"} +{"Time":"2023-05-30T15:37:05.506795874+10:00","Action":"output","Package":"example.com/package3","Test":"Test5","Output":"--- PASS: Test5 (0.00s)\n"} +{"Time":"2023-05-30T15:37:05.506801113+10:00","Action":"pass","Package":"example.com/package3","Test":"Test5","Elapsed":0} +{"Time":"2023-05-30T15:37:05.506805862+10:00","Action":"output","Package":"example.com/package3","Output":"PASS\n"} +{"Time":"2023-05-30T15:37:05.506810681+10:00","Action":"output","Package":"example.com/package3","Output":"coverage: [no statements]\n"} +{"Time":"2023-05-30T15:37:05.50681543+10:00","Action":"output","Package":"example.com/package3","Output":"ok \texample.com/package3\t(cached)\tcoverage: [no statements]\n"} +{"Time":"2023-05-30T15:37:05.506822903+10:00","Action":"pass","Package":"example.com/package3","Elapsed":0} +{"Time":"2023-05-30T15:37:05.507702765+10:00","Action":"run","Package":"example.com/package1","Test":"Test1"} +{"Time":"2023-05-30T15:37:05.507715685+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"=== RUN Test1\n"} +{"Time":"2023-05-30T15:37:05.507723717+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":" foo_test.go:6: doing stuff\n"} +{"Time":"2023-05-30T15:37:05.507729374+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"x = 1\n"} +{"Time":"2023-05-30T15:37:05.507734193+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":" foo_test.go:8: fail\n"} +{"Time":"2023-05-30T15:37:05.507743831+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"--- FAIL: Test1 (0.00s)\n"} +{"Time":"2023-05-30T15:37:05.507750885+10:00","Action":"fail","Package":"example.com/package1","Test":"Test1","Elapsed":0} +{"Time":"2023-05-30T15:37:05.507758498+10:00","Action":"run","Package":"example.com/package1","Test":"Test2"} +{"Time":"2023-05-30T15:37:05.507763806+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":"=== RUN Test2\n"} +{"Time":"2023-05-30T15:37:05.507777216+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":" foo_test.go:12: stuff doing\n"} +{"Time":"2023-05-30T15:37:05.507782873+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":"--- PASS: Test2 (0.00s)\n"} +{"Time":"2023-05-30T15:37:05.5077886+10:00","Action":"pass","Package":"example.com/package1","Test":"Test2","Elapsed":0} +{"Time":"2023-05-30T15:37:05.507793838+10:00","Action":"output","Package":"example.com/package1","Output":"FAIL\n"} +{"Time":"2023-05-30T15:37:05.508093038+10:00","Action":"output","Package":"example.com/package1","Output":"\texample.com/package1\tcoverage: 60.0% of statements\n"} +{"Time":"2023-05-30T15:37:05.508278118+10:00","Action":"output","Package":"example.com/package1","Output":"FAIL\texample.com/package1\t0.002s\n"} +{"Time":"2023-05-30T15:37:05.50829474+10:00","Action":"fail","Package":"example.com/package1","Elapsed":0.002} diff --git a/build.assets/tooling/cmd/render-tests/testdata/flaky-fail-4.in b/build.assets/tooling/cmd/render-tests/testdata/flaky-fail-4.in new file mode 100644 index 0000000000000..4c7100a2dd2d5 --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/testdata/flaky-fail-4.in @@ -0,0 +1,39 @@ +{"Time":"2023-05-30T15:38:53.265810939+10:00","Action":"start","Package":"example.com/package1"} +{"Time":"2023-05-30T15:38:53.265919752+10:00","Action":"run","Package":"example.com/package1","Test":"Test1"} +{"Time":"2023-05-30T15:38:53.265931136+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"=== RUN Test1\n"} +{"Time":"2023-05-30T15:38:53.265940146+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":" foo_test.go:6: doing stuff\n"} +{"Time":"2023-05-30T15:38:53.265949295+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"x = 1\n"} +{"Time":"2023-05-30T15:38:53.265961238+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"--- PASS: Test1 (0.00s)\n"} +{"Time":"2023-05-30T15:38:53.265966825+10:00","Action":"pass","Package":"example.com/package1","Test":"Test1","Elapsed":0} +{"Time":"2023-05-30T15:38:53.265974368+10:00","Action":"run","Package":"example.com/package1","Test":"Test2"} +{"Time":"2023-05-30T15:38:53.265980095+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":"=== RUN Test2\n"} +{"Time":"2023-05-30T15:38:53.265986311+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":" foo_test.go:12: stuff doing\n"} +{"Time":"2023-05-30T15:38:53.265970596+10:00","Action":"start","Package":"example.com/package2"} +{"Time":"2023-05-30T15:38:53.265993085+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":"--- PASS: Test2 (0.00s)\n"} +{"Time":"2023-05-30T15:38:53.266004469+10:00","Action":"pass","Package":"example.com/package1","Test":"Test2","Elapsed":0} +{"Time":"2023-05-30T15:38:53.266004469+10:00","Action":"run","Package":"example.com/package2","Test":"Test3"} +{"Time":"2023-05-30T15:38:53.266010616+10:00","Action":"output","Package":"example.com/package1","Output":"PASS\n"} +{"Time":"2023-05-30T15:38:53.26601299+10:00","Action":"output","Package":"example.com/package2","Test":"Test3","Output":"=== RUN Test3\n"} +{"Time":"2023-05-30T15:38:53.266016831+10:00","Action":"output","Package":"example.com/package1","Output":"\texample.com/package1\tcoverage: 60.0% of statements\n"} +{"Time":"2023-05-30T15:38:53.26602165+10:00","Action":"output","Package":"example.com/package2","Test":"Test3","Output":"--- PASS: Test3 (0.00s)\n"} +{"Time":"2023-05-30T15:38:53.266023117+10:00","Action":"output","Package":"example.com/package1","Output":"ok \texample.com/package1\t(cached)\tcoverage: 60.0% of statements\n"} +{"Time":"2023-05-30T15:38:53.266028285+10:00","Action":"pass","Package":"example.com/package2","Test":"Test3","Elapsed":0} +{"Time":"2023-05-30T15:38:53.26603499+10:00","Action":"output","Package":"example.com/package2","Output":"PASS\n"} +{"Time":"2023-05-30T15:38:53.26603499+10:00","Action":"pass","Package":"example.com/package1","Elapsed":0} +{"Time":"2023-05-30T15:38:53.266041555+10:00","Action":"output","Package":"example.com/package2","Output":"\texample.com/package2\tcoverage: 0.0% of statements\n"} +{"Time":"2023-05-30T15:38:53.26604833+10:00","Action":"output","Package":"example.com/package2","Output":"ok \texample.com/package2\t(cached)\tcoverage: 0.0% of statements\n"} +{"Time":"2023-05-30T15:38:53.266056012+10:00","Action":"pass","Package":"example.com/package2","Elapsed":0} +{"Time":"2023-05-30T15:38:53.332950364+10:00","Action":"start","Package":"example.com/package3"} +{"Time":"2023-05-30T15:38:53.334705198+10:00","Action":"run","Package":"example.com/package3","Test":"Test4"} +{"Time":"2023-05-30T15:38:53.33485871+10:00","Action":"output","Package":"example.com/package3","Test":"Test4","Output":"=== RUN Test4\n"} +{"Time":"2023-05-30T15:38:53.334871421+10:00","Action":"output","Package":"example.com/package3","Test":"Test4","Output":" baz_test.go:6: sometimes I flake\n"} +{"Time":"2023-05-30T15:38:53.334885738+10:00","Action":"output","Package":"example.com/package3","Test":"Test4","Output":"--- FAIL: Test4 (0.00s)\n"} +{"Time":"2023-05-30T15:38:53.334894189+10:00","Action":"fail","Package":"example.com/package3","Test":"Test4","Elapsed":0} +{"Time":"2023-05-30T15:38:53.334915561+10:00","Action":"run","Package":"example.com/package3","Test":"Test5"} +{"Time":"2023-05-30T15:38:53.334923243+10:00","Action":"output","Package":"example.com/package3","Test":"Test5","Output":"=== RUN Test5\n"} +{"Time":"2023-05-30T15:38:53.334931764+10:00","Action":"output","Package":"example.com/package3","Test":"Test5","Output":"--- PASS: Test5 (0.00s)\n"} +{"Time":"2023-05-30T15:38:53.334939307+10:00","Action":"pass","Package":"example.com/package3","Test":"Test5","Elapsed":0} +{"Time":"2023-05-30T15:38:53.334947059+10:00","Action":"output","Package":"example.com/package3","Output":"FAIL\n"} +{"Time":"2023-05-30T15:38:53.334956069+10:00","Action":"output","Package":"example.com/package3","Output":"coverage: [no statements]\n"} +{"Time":"2023-05-30T15:38:53.335260368+10:00","Action":"output","Package":"example.com/package3","Output":"FAIL\texample.com/package3\t0.002s\n"} +{"Time":"2023-05-30T15:38:53.335292355+10:00","Action":"fail","Package":"example.com/package3","Elapsed":0.002} diff --git a/build.assets/tooling/cmd/render-tests/testdata/flaky-fail-5.in b/build.assets/tooling/cmd/render-tests/testdata/flaky-fail-5.in new file mode 100644 index 0000000000000..c05655412afa7 --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/testdata/flaky-fail-5.in @@ -0,0 +1,39 @@ +{"Time":"2023-05-30T15:39:01.411862493+10:00","Action":"start","Package":"example.com/package1"} +{"Time":"2023-05-30T15:39:01.411959782+10:00","Action":"run","Package":"example.com/package1","Test":"Test1"} +{"Time":"2023-05-30T15:39:01.411966767+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"=== RUN Test1\n"} +{"Time":"2023-05-30T15:39:01.411974798+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":" foo_test.go:6: doing stuff\n"} +{"Time":"2023-05-30T15:39:01.411981573+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"x = 1\n"} +{"Time":"2023-05-30T15:39:01.411989256+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"--- PASS: Test1 (0.00s)\n"} +{"Time":"2023-05-30T15:39:01.411994075+10:00","Action":"pass","Package":"example.com/package1","Test":"Test1","Elapsed":0} +{"Time":"2023-05-30T15:39:01.412001129+10:00","Action":"run","Package":"example.com/package1","Test":"Test2"} +{"Time":"2023-05-30T15:39:01.412006786+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":"=== RUN Test2\n"} +{"Time":"2023-05-30T15:39:01.412014468+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":" foo_test.go:12: stuff doing\n"} +{"Time":"2023-05-30T15:39:01.412023548+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":"--- PASS: Test2 (0.00s)\n"} +{"Time":"2023-05-30T15:39:01.412028856+10:00","Action":"pass","Package":"example.com/package1","Test":"Test2","Elapsed":0} +{"Time":"2023-05-30T15:39:01.412033046+10:00","Action":"output","Package":"example.com/package1","Output":"PASS\n"} +{"Time":"2023-05-30T15:39:01.412038214+10:00","Action":"output","Package":"example.com/package1","Output":"\texample.com/package1\tcoverage: 60.0% of statements\n"} +{"Time":"2023-05-30T15:39:01.412043522+10:00","Action":"output","Package":"example.com/package1","Output":"ok \texample.com/package1\t(cached)\tcoverage: 60.0% of statements\n"} +{"Time":"2023-05-30T15:39:01.412032068+10:00","Action":"start","Package":"example.com/package2"} +{"Time":"2023-05-30T15:39:01.412051275+10:00","Action":"pass","Package":"example.com/package1","Elapsed":0} +{"Time":"2023-05-30T15:39:01.412060284+10:00","Action":"run","Package":"example.com/package2","Test":"Test3"} +{"Time":"2023-05-30T15:39:01.41206636+10:00","Action":"output","Package":"example.com/package2","Test":"Test3","Output":"=== RUN Test3\n"} +{"Time":"2023-05-30T15:39:01.412074532+10:00","Action":"output","Package":"example.com/package2","Test":"Test3","Output":"--- PASS: Test3 (0.00s)\n"} +{"Time":"2023-05-30T15:39:01.412080818+10:00","Action":"pass","Package":"example.com/package2","Test":"Test3","Elapsed":0} +{"Time":"2023-05-30T15:39:01.41208836+10:00","Action":"output","Package":"example.com/package2","Output":"PASS\n"} +{"Time":"2023-05-30T15:39:01.412092621+10:00","Action":"output","Package":"example.com/package2","Output":"\texample.com/package2\tcoverage: 0.0% of statements\n"} +{"Time":"2023-05-30T15:39:01.412098837+10:00","Action":"output","Package":"example.com/package2","Output":"ok \texample.com/package2\t(cached)\tcoverage: 0.0% of statements\n"} +{"Time":"2023-05-30T15:39:01.412106449+10:00","Action":"pass","Package":"example.com/package2","Elapsed":0} +{"Time":"2023-05-30T15:39:01.480442467+10:00","Action":"start","Package":"example.com/package3"} +{"Time":"2023-05-30T15:39:01.481862621+10:00","Action":"run","Package":"example.com/package3","Test":"Test4"} +{"Time":"2023-05-30T15:39:01.481938399+10:00","Action":"output","Package":"example.com/package3","Test":"Test4","Output":"=== RUN Test4\n"} +{"Time":"2023-05-30T15:39:01.481953904+10:00","Action":"output","Package":"example.com/package3","Test":"Test4","Output":"--- PASS: Test4 (0.00s)\n"} +{"Time":"2023-05-30T15:39:01.48196005+10:00","Action":"pass","Package":"example.com/package3","Test":"Test4","Elapsed":0} +{"Time":"2023-05-30T15:39:01.481966266+10:00","Action":"run","Package":"example.com/package3","Test":"Test5"} +{"Time":"2023-05-30T15:39:01.481970596+10:00","Action":"output","Package":"example.com/package3","Test":"Test5","Output":"=== RUN Test5\n"} +{"Time":"2023-05-30T15:39:01.481979187+10:00","Action":"output","Package":"example.com/package3","Test":"Test5","Output":" baz_test.go:10: nevermind\n"} +{"Time":"2023-05-30T15:39:01.481984425+10:00","Action":"output","Package":"example.com/package3","Test":"Test5","Output":"--- FAIL: Test5 (0.00s)\n"} +{"Time":"2023-05-30T15:39:01.481989104+10:00","Action":"fail","Package":"example.com/package3","Test":"Test5","Elapsed":0} +{"Time":"2023-05-30T15:39:01.482003561+10:00","Action":"output","Package":"example.com/package3","Output":"FAIL\n"} +{"Time":"2023-05-30T15:39:01.482009218+10:00","Action":"output","Package":"example.com/package3","Output":"coverage: [no statements]\n"} +{"Time":"2023-05-30T15:39:01.482341663+10:00","Action":"output","Package":"example.com/package3","Output":"FAIL\texample.com/package3\t0.001s\n"} +{"Time":"2023-05-30T15:39:01.48242233+10:00","Action":"fail","Package":"example.com/package3","Elapsed":0.002} diff --git a/build.assets/tooling/cmd/render-tests/testdata/flaky-pass.in b/build.assets/tooling/cmd/render-tests/testdata/flaky-pass.in new file mode 100644 index 0000000000000..9b5347e4da9dc --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/testdata/flaky-pass.in @@ -0,0 +1,38 @@ +{"Time":"2023-05-30T15:35:36.877912355+10:00","Action":"start","Package":"example.com/package1"} +{"Time":"2023-05-30T15:35:36.877982756+10:00","Action":"run","Package":"example.com/package1","Test":"Test1"} +{"Time":"2023-05-30T15:35:36.877987994+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"=== RUN Test1\n"} +{"Time":"2023-05-30T15:35:36.877994279+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":" foo_test.go:6: doing stuff\n"} +{"Time":"2023-05-30T15:35:36.877999587+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"x = 1\n"} +{"Time":"2023-05-30T15:35:36.878006711+10:00","Action":"output","Package":"example.com/package1","Test":"Test1","Output":"--- PASS: Test1 (0.00s)\n"} +{"Time":"2023-05-30T15:35:36.878011879+10:00","Action":"pass","Package":"example.com/package1","Test":"Test1","Elapsed":0} +{"Time":"2023-05-30T15:35:36.878017606+10:00","Action":"run","Package":"example.com/package1","Test":"Test2"} +{"Time":"2023-05-30T15:35:36.878021867+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":"=== RUN Test2\n"} +{"Time":"2023-05-30T15:35:36.878026756+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":" foo_test.go:12: stuff doing\n"} +{"Time":"2023-05-30T15:35:36.878031505+10:00","Action":"output","Package":"example.com/package1","Test":"Test2","Output":"--- PASS: Test2 (0.00s)\n"} +{"Time":"2023-05-30T15:35:36.878036254+10:00","Action":"pass","Package":"example.com/package1","Test":"Test2","Elapsed":0} +{"Time":"2023-05-30T15:35:36.878041003+10:00","Action":"output","Package":"example.com/package1","Output":"PASS\n"} +{"Time":"2023-05-30T15:35:36.878045264+10:00","Action":"output","Package":"example.com/package1","Output":"\texample.com/package1\tcoverage: 60.0% of statements\n"} +{"Time":"2023-05-30T15:35:36.878050013+10:00","Action":"output","Package":"example.com/package1","Output":"ok \texample.com/package1\t(cached)\tcoverage: 60.0% of statements\n"} +{"Time":"2023-05-30T15:35:36.87806014+10:00","Action":"pass","Package":"example.com/package1","Elapsed":0} +{"Time":"2023-05-30T15:35:36.878058673+10:00","Action":"start","Package":"example.com/package2"} +{"Time":"2023-05-30T15:35:36.878085772+10:00","Action":"run","Package":"example.com/package2","Test":"Test3"} +{"Time":"2023-05-30T15:35:36.878091149+10:00","Action":"output","Package":"example.com/package2","Test":"Test3","Output":"=== RUN Test3\n"} +{"Time":"2023-05-30T15:35:36.878097854+10:00","Action":"output","Package":"example.com/package2","Test":"Test3","Output":"--- PASS: Test3 (0.00s)\n"} +{"Time":"2023-05-30T15:35:36.878103441+10:00","Action":"pass","Package":"example.com/package2","Test":"Test3","Elapsed":0} +{"Time":"2023-05-30T15:35:36.87810868+10:00","Action":"output","Package":"example.com/package2","Output":"PASS\n"} +{"Time":"2023-05-30T15:35:36.878113918+10:00","Action":"output","Package":"example.com/package2","Output":"\texample.com/package2\tcoverage: 0.0% of statements\n"} +{"Time":"2023-05-30T15:35:36.878118737+10:00","Action":"output","Package":"example.com/package2","Output":"ok \texample.com/package2\t(cached)\tcoverage: 0.0% of statements\n"} +{"Time":"2023-05-30T15:35:36.878125022+10:00","Action":"pass","Package":"example.com/package2","Elapsed":0} +{"Time":"2023-05-30T15:35:36.878156521+10:00","Action":"start","Package":"example.com/package3"} +{"Time":"2023-05-30T15:35:36.878174889+10:00","Action":"run","Package":"example.com/package3","Test":"Test4"} +{"Time":"2023-05-30T15:35:36.878180057+10:00","Action":"output","Package":"example.com/package3","Test":"Test4","Output":"=== RUN Test4\n"} +{"Time":"2023-05-30T15:35:36.878185854+10:00","Action":"output","Package":"example.com/package3","Test":"Test4","Output":"--- PASS: Test4 (0.00s)\n"} +{"Time":"2023-05-30T15:35:36.878191092+10:00","Action":"pass","Package":"example.com/package3","Test":"Test4","Elapsed":0} +{"Time":"2023-05-30T15:35:36.878195004+10:00","Action":"run","Package":"example.com/package3","Test":"Test5"} +{"Time":"2023-05-30T15:35:36.878199753+10:00","Action":"output","Package":"example.com/package3","Test":"Test5","Output":"=== RUN Test5\n"} +{"Time":"2023-05-30T15:35:36.878212953+10:00","Action":"output","Package":"example.com/package3","Test":"Test5","Output":"--- PASS: Test5 (0.00s)\n"} +{"Time":"2023-05-30T15:35:36.87821875+10:00","Action":"pass","Package":"example.com/package3","Test":"Test5","Elapsed":0} +{"Time":"2023-05-30T15:35:36.87822308+10:00","Action":"output","Package":"example.com/package3","Output":"PASS\n"} +{"Time":"2023-05-30T15:35:36.878227899+10:00","Action":"output","Package":"example.com/package3","Output":"coverage: [no statements]\n"} +{"Time":"2023-05-30T15:35:36.878232159+10:00","Action":"output","Package":"example.com/package3","Output":"ok \texample.com/package3\t(cached)\tcoverage: [no statements]\n"} +{"Time":"2023-05-30T15:35:36.878239213+10:00","Action":"pass","Package":"example.com/package3","Elapsed":0} diff --git a/build.assets/tooling/cmd/render-tests/testdata/pass-fail-pass.in b/build.assets/tooling/cmd/render-tests/testdata/pass-fail-pass.in new file mode 100644 index 0000000000000..853df905233b9 --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/testdata/pass-fail-pass.in @@ -0,0 +1,37 @@ +{"Time":"2023-05-24T17:29:16.929248048+10:00","Action":"start","Package":"example.com/package"} +{"Time":"2023-05-24T17:29:16.929248048+10:00","Action":"start","Package":"example.com/package2"} +{"Time":"2023-05-24T17:29:16.934340321+10:00","Action":"run","Package":"example.com/package","Test":"TestParseHostPort"} +{"Time":"2023-05-24T17:29:16.934457584+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"=== RUN TestParseHostPort\n"} +{"Time":"2023-05-24T17:29:16.934493832+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"=== PAUSE TestParseHostPort\n"} +{"Time":"2023-05-24T17:29:16.934500118+10:00","Action":"pause","Package":"example.com/package","Test":"TestParseHostPort"} +{"Time":"2023-05-24T17:29:16.934502037+10:00","Action":"start","Package":"example.com/package2"} +{"Time":"2023-05-24T17:29:16.934506823+10:00","Action":"run","Package":"example.com/package2","Test":"TestEmpty"} +{"Time":"2023-05-24T17:29:16.934511572+10:00","Action":"output","Package":"example.com/package2","Test":"TestEmpty","Output":"=== RUN TestEmpty\n"} +{"Time":"2023-05-24T17:29:16.934518556+10:00","Action":"output","Package":"example.com/package2","Test":"TestEmpty","Output":"=== PAUSE TestEmpty\n"} +{"Time":"2023-05-24T17:29:16.934523794+10:00","Action":"pause","Package":"example.com/package","Test":"TestEmpty"} +{"Time":"2023-05-24T17:29:16.934528962+10:00","Action":"run","Package":"example.com/package","Test":"TestParse"} +{"Time":"2023-05-24T17:29:16.934533781+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"=== RUN TestParse\n"} +{"Time":"2023-05-24T17:29:16.934539508+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"=== PAUSE TestParse\n"} +{"Time":"2023-05-24T17:29:16.934544188+10:00","Action":"pause","Package":"example.com/package","Test":"TestParse"} +{"Time":"2023-05-24T17:29:16.934549286+10:00","Action":"cont","Package":"example.com/package","Test":"TestParseHostPort"} +{"Time":"2023-05-24T17:29:16.934555921+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"=== CONT TestParseHostPort\n"} +{"Time":"2023-05-24T17:29:16.93456067+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":" addr_test.go:32: \n"} +{"Time":"2023-05-24T17:29:16.934565978+10:00","Action":"cont","Package":"example.com/package","Test":"TestParse"} +{"Time":"2023-05-24T17:29:16.934570797+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"=== CONT TestParse\n"} +{"Time":"2023-05-24T17:29:16.934579877+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"--- PASS: TestParseHostPort (0.00s)\n"} +{"Time":"2023-05-24T17:29:16.934586442+10:00","Action":"skip","Package":"example.com/package","Test":"TestParseHostPort","Elapsed":0} +{"Time":"2023-05-24T17:29:16.934592169+10:00","Action":"cont","Package":"example.com/package2","Test":"TestEmpty"} +{"Time":"2023-05-24T17:29:16.934596988+10:00","Action":"output","Package":"example.com/package2","Test":"TestEmpty","Output":"=== CONT TestEmpty\n"} +{"Time":"2023-05-24T17:29:16.934602785+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":" addr_test.go:71: failed\n"} +{"Time":"2023-05-24T17:29:16.934608442+10:00","Action":"output","Package":"example.com/package2","Test":"TestEmpty","Output":"--- PASS: TestEmpty (0.00s)\n"} +{"Time":"2023-05-24T17:29:16.93461368+10:00","Action":"pass","Package":"example.com/package2","Test":"TestEmpty","Elapsed":0} +{"Time":"2023-05-24T17:29:16.934618429+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"--- FAIL: TestParse (0.00s)\n"} +{"Time":"2023-05-24T17:29:16.934629464+10:00","Action":"fail","Package":"example.com/package","Test":"TestParse","Elapsed":0} +{"Time":"2023-05-24T17:29:16.934634283+10:00","Action":"output","Package":"example.com/package","Output":"FAIL\n"} +{"Time":"2023-05-24T17:29:16.935972653+10:00","Action":"output","Package":"example.com/package","Output":"\texample.com/package\tcoverage: 2.4% of statements\n"} +{"Time":"2023-05-24T17:29:16.936504774+10:00","Action":"output","Package":"example.com/package","Output":"FAIL\texample.com/package\t0.007s\n"} +{"Time":"2023-05-24T17:29:16.936553034+10:00","Action":"fail","Package":"example.com/package","Elapsed":0.007} +{"Time":"2023-05-24T17:58:42.948894851+10:00","Action":"output","Package":"example.com/package2","Output":"PASS\n"} +{"Time":"2023-05-24T17:58:42.948904+10:00","Action":"output","Package":"example.com/package2","Output":"\texample.com/package\tcoverage: 3.3% of statements\n"} +{"Time":"2023-05-24T17:58:42.948909797+10:00","Action":"output","Package":"example.com/package2","Output":"ok \texample.com/package\t\tcoverage: 3.3% of statements\n"} +{"Time":"2023-05-24T17:29:16.936583274+10:00","Action":"pass","Package":"example.com/package2","Elapsed":0.007} diff --git a/build.assets/tooling/cmd/render-tests/testdata/pass-fail-skip.in b/build.assets/tooling/cmd/render-tests/testdata/pass-fail-skip.in new file mode 100644 index 0000000000000..72f9b0b25c7ab --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/testdata/pass-fail-skip.in @@ -0,0 +1,31 @@ +{"Time":"2023-05-24T17:29:16.929248048+10:00","Action":"start","Package":"example.com/package"} +{"Time":"2023-05-24T17:29:16.934340321+10:00","Action":"run","Package":"example.com/package","Test":"TestParseHostPort"} +{"Time":"2023-05-24T17:29:16.934457584+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"=== RUN TestParseHostPort\n"} +{"Time":"2023-05-24T17:29:16.934493832+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"=== PAUSE TestParseHostPort\n"} +{"Time":"2023-05-24T17:29:16.934500118+10:00","Action":"pause","Package":"example.com/package","Test":"TestParseHostPort"} +{"Time":"2023-05-24T17:29:16.934506823+10:00","Action":"run","Package":"example.com/package","Test":"TestEmpty"} +{"Time":"2023-05-24T17:29:16.934511572+10:00","Action":"output","Package":"example.com/package","Test":"TestEmpty","Output":"=== RUN TestEmpty\n"} +{"Time":"2023-05-24T17:29:16.934518556+10:00","Action":"output","Package":"example.com/package","Test":"TestEmpty","Output":"=== PAUSE TestEmpty\n"} +{"Time":"2023-05-24T17:29:16.934523794+10:00","Action":"pause","Package":"example.com/package","Test":"TestEmpty"} +{"Time":"2023-05-24T17:29:16.934528962+10:00","Action":"run","Package":"example.com/package","Test":"TestParse"} +{"Time":"2023-05-24T17:29:16.934533781+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"=== RUN TestParse\n"} +{"Time":"2023-05-24T17:29:16.934539508+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"=== PAUSE TestParse\n"} +{"Time":"2023-05-24T17:29:16.934544188+10:00","Action":"pause","Package":"example.com/package","Test":"TestParse"} +{"Time":"2023-05-24T17:29:16.934549286+10:00","Action":"cont","Package":"example.com/package","Test":"TestParseHostPort"} +{"Time":"2023-05-24T17:29:16.934555921+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"=== CONT TestParseHostPort\n"} +{"Time":"2023-05-24T17:29:16.93456067+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":" addr_test.go:32: \n"} +{"Time":"2023-05-24T17:29:16.934565978+10:00","Action":"cont","Package":"example.com/package","Test":"TestParse"} +{"Time":"2023-05-24T17:29:16.934570797+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"=== CONT TestParse\n"} +{"Time":"2023-05-24T17:29:16.934579877+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"--- SKIP: TestParseHostPort (0.00s)\n"} +{"Time":"2023-05-24T17:29:16.934586442+10:00","Action":"skip","Package":"example.com/package","Test":"TestParseHostPort","Elapsed":0} +{"Time":"2023-05-24T17:29:16.934592169+10:00","Action":"cont","Package":"example.com/package","Test":"TestEmpty"} +{"Time":"2023-05-24T17:29:16.934596988+10:00","Action":"output","Package":"example.com/package","Test":"TestEmpty","Output":"=== CONT TestEmpty\n"} +{"Time":"2023-05-24T17:29:16.934602785+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":" addr_test.go:71: failed\n"} +{"Time":"2023-05-24T17:29:16.934608442+10:00","Action":"output","Package":"example.com/package","Test":"TestEmpty","Output":"--- PASS: TestEmpty (0.00s)\n"} +{"Time":"2023-05-24T17:29:16.93461368+10:00","Action":"pass","Package":"example.com/package","Test":"TestEmpty","Elapsed":0} +{"Time":"2023-05-24T17:29:16.934618429+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"--- FAIL: TestParse (0.00s)\n"} +{"Time":"2023-05-24T17:29:16.934629464+10:00","Action":"fail","Package":"example.com/package","Test":"TestParse","Elapsed":0} +{"Time":"2023-05-24T17:29:16.934634283+10:00","Action":"output","Package":"example.com/package","Output":"FAIL\n"} +{"Time":"2023-05-24T17:29:16.935972653+10:00","Action":"output","Package":"example.com/package","Output":"\texample.com/package\tcoverage: 2.4% of statements\n"} +{"Time":"2023-05-24T17:29:16.936504774+10:00","Action":"output","Package":"example.com/package","Output":"FAIL\texample.com/package\t0.007s\n"} +{"Time":"2023-05-24T17:29:16.936553034+10:00","Action":"fail","Package":"example.com/package","Elapsed":0.007} diff --git a/build.assets/tooling/cmd/render-tests/testdata/pass-pass-pass.in b/build.assets/tooling/cmd/render-tests/testdata/pass-pass-pass.in new file mode 100644 index 0000000000000..48fe32cdd8e16 --- /dev/null +++ b/build.assets/tooling/cmd/render-tests/testdata/pass-pass-pass.in @@ -0,0 +1,29 @@ +{"Time":"2023-05-24T17:58:42.948659276+10:00","Action":"start","Package":"example.com/package"} +{"Time":"2023-05-24T17:58:42.948757054+10:00","Action":"run","Package":"example.com/package","Test":"TestParseHostPort"} +{"Time":"2023-05-24T17:58:42.948764178+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"=== RUN TestParseHostPort\n"} +{"Time":"2023-05-24T17:58:42.948771791+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"=== PAUSE TestParseHostPort\n"} +{"Time":"2023-05-24T17:58:42.948778565+10:00","Action":"pause","Package":"example.com/package","Test":"TestParseHostPort"} +{"Time":"2023-05-24T17:58:42.9487852+10:00","Action":"run","Package":"example.com/package","Test":"TestEmpty"} +{"Time":"2023-05-24T17:58:42.948791416+10:00","Action":"output","Package":"example.com/package","Test":"TestEmpty","Output":"=== RUN TestEmpty\n"} +{"Time":"2023-05-24T17:58:42.948796654+10:00","Action":"output","Package":"example.com/package","Test":"TestEmpty","Output":"=== PAUSE TestEmpty\n"} +{"Time":"2023-05-24T17:58:42.948801334+10:00","Action":"pause","Package":"example.com/package","Test":"TestEmpty"} +{"Time":"2023-05-24T17:58:42.948806641+10:00","Action":"run","Package":"example.com/package","Test":"TestParse"} +{"Time":"2023-05-24T17:58:42.94881153+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"=== RUN TestParse\n"} +{"Time":"2023-05-24T17:58:42.948816699+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"=== PAUSE TestParse\n"} +{"Time":"2023-05-24T17:58:42.948821448+10:00","Action":"pause","Package":"example.com/package","Test":"TestParse"} +{"Time":"2023-05-24T17:58:42.948826197+10:00","Action":"cont","Package":"example.com/package","Test":"TestParseHostPort"} +{"Time":"2023-05-24T17:58:42.948831365+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"=== CONT TestParseHostPort\n"} +{"Time":"2023-05-24T17:58:42.948836184+10:00","Action":"cont","Package":"example.com/package","Test":"TestParse"} +{"Time":"2023-05-24T17:58:42.948841003+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"=== CONT TestParse\n"} +{"Time":"2023-05-24T17:58:42.948845822+10:00","Action":"cont","Package":"example.com/package","Test":"TestEmpty"} +{"Time":"2023-05-24T17:58:42.948850083+10:00","Action":"output","Package":"example.com/package","Test":"TestEmpty","Output":"=== CONT TestEmpty\n"} +{"Time":"2023-05-24T17:58:42.948857695+10:00","Action":"output","Package":"example.com/package","Test":"TestParseHostPort","Output":"--- PASS: TestParseHostPort (0.00s)\n"} +{"Time":"2023-05-24T17:58:42.948866705+10:00","Action":"pass","Package":"example.com/package","Test":"TestParseHostPort","Elapsed":0} +{"Time":"2023-05-24T17:58:42.948874457+10:00","Action":"output","Package":"example.com/package","Test":"TestParse","Output":"--- PASS: TestParse (0.00s)\n"} +{"Time":"2023-05-24T17:58:42.948880184+10:00","Action":"pass","Package":"example.com/package","Test":"TestParse","Elapsed":0} +{"Time":"2023-05-24T17:58:42.948885283+10:00","Action":"output","Package":"example.com/package","Test":"TestEmpty","Output":"--- PASS: TestEmpty (0.00s)\n"} +{"Time":"2023-05-24T17:58:42.948890032+10:00","Action":"pass","Package":"example.com/package","Test":"TestEmpty","Elapsed":0} +{"Time":"2023-05-24T17:58:42.948894851+10:00","Action":"output","Package":"example.com/package","Output":"PASS\n"} +{"Time":"2023-05-24T17:58:42.948904+10:00","Action":"output","Package":"example.com/package","Output":"\texample.com/package\tcoverage: 3.3% of statements\n"} +{"Time":"2023-05-24T17:58:42.948909797+10:00","Action":"output","Package":"example.com/package","Output":"ok \texample.com/package\t\tcoverage: 3.3% of statements\n"} +{"Time":"2023-05-24T17:58:42.948917759+10:00","Action":"pass","Package":"example.com/package","Elapsed":0} diff --git a/build.assets/tooling/cmd/rerun/main.go b/build.assets/tooling/cmd/rerun/main.go new file mode 100644 index 0000000000000..a1f5960b5bd00 --- /dev/null +++ b/build.assets/tooling/cmd/rerun/main.go @@ -0,0 +1,159 @@ +/* +Copyright 2023 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Command rerun runs a command repeatedly until a timeout or number of runs completes. +// +// Usage: rerun [-t timeout] [-n count] [args...] +// +// Rerun runs with [args...] number of times or until +// elapses since starting, whichever comes first. The command will be allowed +// to complete if elapses, after which no more runs will be made. +// +// The exit code of command is the 's exit code from the last run. +// If the could not be run, then the exit code will be 1 and no +// more runs will be made. +// +// is parsed as a [time.Duration string]. +// +// If is 0 (the default), then only the will apply. +// If is 0 (the default), then only the will apply. +// If neither or , then the will not be run. +// +// is executed directly with [args...] as provided. If +// does not contain any path separators, the search path is used to locate +// it. No shell is used to run . +// +// [time.Duration string]: https://golang.org/pkg/time/#ParseDuration +package main + +import ( + "errors" + "flag" + "fmt" + "os" + "os/exec" + "os/signal" + "sync" + "syscall" + "time" +) + +var ( + count = flag.Int("n", 0, "Maximum number of runs") + timeout = flag.Duration("t", 0, "Rerun until timeout passes") +) + +func usage() { + fmt.Fprintln(flag.CommandLine.Output(), "usage: rerun [-t timeout] [-n count] [args...]") + flag.PrintDefaults() +} + +type UsageError string + +func (u UsageError) Error() string { + return string(u) +} + +func main() { + flag.Usage = usage + flag.Parse() + code, err := rerun(flag.Args()) + if err != nil { + fmt.Fprintln(os.Stderr, err) + var uerr UsageError + if errors.As(err, &uerr) { + usage() + } + } + os.Exit(code) +} + +func rerun(args []string) (int, error) { + if len(args) < 1 { + return 1, UsageError("no command supplied") + } + if *count < 0 { + return 1, UsageError("run count must be a non-negative number") + } + if *timeout < 0 { + return 1, UsageError("timeout must be a non-negative duration") + } + if *count == 0 && *timeout == 0 { + return 0, nil + } + + var ( + cmd *exec.Cmd + proc *os.Process + procLock sync.Mutex + err error + done = make(chan struct{}) + signals = make(chan os.Signal, 1) + now = time.Now() + endTime = now.Add(*timeout) + ) + signal.Notify(signals, os.Interrupt, syscall.SIGTERM) + go func() { + defer close(done) + sig := <-signals + procLock.Lock() + defer procLock.Unlock() + if proc != nil { + proc.Signal(sig) + } + }() + for i := 0; !isDone(i, now, endTime, done); i++ { + cmd = exec.Command(args[0], args[1:]...) + cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr + + // Immediately terminate if we cannot start the process. No point + // re-running a command that cannot run. + if err = cmd.Start(); err != nil { + break + } + procLock.Lock() + proc = cmd.Process + procLock.Unlock() + + // Record the error for the case this is the last run. We return + // that error. + err = cmd.Wait() + + now = time.Now() + } + + // We terminated due to some error trying to run the command. Return + // with that error. + var exitErr *exec.ExitError + if err != nil && !errors.As(err, &exitErr) { + return 1, err + } + + // Otherwise, just return the last exit code + return cmd.ProcessState.ExitCode(), nil +} + +// isDone returns true if we are done re-running the command; either we have +// reached the required number of runs, have reached the timeout, or the +// done channel is closed (via a signal). +func isDone(n int, now, endTime time.Time, ch <-chan struct{}) bool { + select { + case <-ch: + return true + default: + return (*count > 0 && n > *count) || (*timeout > 0 && !now.Before(endTime)) + } +} diff --git a/build.assets/tooling/go.mod b/build.assets/tooling/go.mod index 7b0ef9b9e695b..bbcfb9870f768 100644 --- a/build.assets/tooling/go.mod +++ b/build.assets/tooling/go.mod @@ -5,46 +5,46 @@ go 1.18 require ( github.com/alecthomas/kingpin/v2 v2.3.2 // replaced github.com/bmatcuk/doublestar/v4 v4.6.0 - github.com/bradleyfalzon/ghinstallation/v2 v2.4.0 + github.com/bradleyfalzon/ghinstallation/v2 v2.5.0 github.com/google/go-github/v41 v41.0.0 github.com/google/uuid v1.3.0 github.com/gravitational/trace v1.2.1 github.com/hashicorp/go-hclog v1.5.0 - github.com/hashicorp/go-retryablehttp v0.7.2 - github.com/sirupsen/logrus v1.9.2 + github.com/hashicorp/go-retryablehttp v0.7.4 + github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.8.4 github.com/waigani/diffparser v0.0.0-20190828052634-7391f219313d - golang.org/x/exp v0.0.0-20221114191408-850992195362 - golang.org/x/mod v0.10.0 - golang.org/x/oauth2 v0.8.0 + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df + golang.org/x/mod v0.11.0 + golang.org/x/oauth2 v0.9.0 howett.net/plist v1.0.0 ) require ( - github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230626094100-7e9e0395ebec // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/cloudflare/circl v1.3.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.15.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-github/v52 v52.0.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/go-github/v53 v53.2.0 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-multierror v1.0.0 // indirect - github.com/jonboulle/clockwork v0.2.2 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/jonboulle/clockwork v0.4.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/mitchellh/gon v0.2.5 github.com/pmezard/go-difflib v1.0.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - golang.org/x/crypto v0.7.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/build.assets/tooling/go.sum b/build.assets/tooling/go.sum index f39e63581fb51..db8b940990774 100644 --- a/build.assets/tooling/go.sum +++ b/build.assets/tooling/go.sum @@ -2,8 +2,9 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= +github.com/ProtonMail/go-crypto v0.0.0-20230626094100-7e9e0395ebec h1:vV3RryLxt42+ZIVOFbYJCH1jsZNTNmj2NYru5zfx+4E= +github.com/ProtonMail/go-crypto v0.0.0-20230626094100-7e9e0395ebec/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= @@ -12,9 +13,10 @@ github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:o github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc= github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/bradleyfalzon/ghinstallation/v2 v2.4.0 h1:zYSzkoIwekCQAr6GT6KxISLt4YRS6kd4/ixfzMN+7yc= -github.com/bradleyfalzon/ghinstallation/v2 v2.4.0/go.mod h1:4MwZLSgBJJgg4i3nJwZJ95AMooSqN8fJDmegLVn9Q2U= +github.com/bradleyfalzon/ghinstallation/v2 v2.5.0 h1:yaYcGQ7yEIGbsJfW/9z7v1sLiZg/5rSNNXwmMct5XaE= +github.com/bradleyfalzon/ghinstallation/v2 v2.5.0/go.mod h1:amcvPQMrRkWNdueWOjPytGL25xQGzox7425qMgzo+Vo= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -37,8 +39,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= @@ -59,8 +62,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -74,8 +78,9 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= -github.com/google/go-github/v52 v52.0.0 h1:uyGWOY+jMQ8GVGSX8dkSwCzlehU3WfdxQ7GweO/JP7M= -github.com/google/go-github/v52 v52.0.0/go.mod h1:WJV6VEEUPuMo5pXqqa2ZCZEdbQqua4zAk2MZTIo+m+4= +github.com/google/go-github/v53 v53.0.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= +github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI= +github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -86,8 +91,9 @@ github.com/gravitational/kingpin/v2 v2.1.11-0.20230515143221-4ec6b70ecd33/go.mod github.com/gravitational/trace v1.2.1 h1:Iaf43aqbKV5H8bdiRs1qByjEHgAfADJ0lt0JwRyu+q8= github.com/gravitational/trace v1.2.1/go.mod h1:n0ijrq6psJY0sOI/NzLp+xdd8xl79jjwzVOFHDY6+kQ= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= @@ -95,15 +101,17 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj github.com/hashicorp/go-hclog v0.9.3-0.20191025211905-234833755cb2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.6.3/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= -github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= +github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -113,13 +121,16 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gon v0.2.5 h1:mVWtqTzV03W0avJqmqjk9M0qls3TDUXfc9ETJaPIOWY= github.com/mitchellh/gon v0.2.5/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8= @@ -131,8 +142,8 @@ github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= -github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -157,18 +168,20 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20221114191408-850992195362 h1:NoHlPRbyl1VFI6FjwHtPQCN7wAMXI6cKcqrmXhOOfBQ= -golang.org/x/exp v0.0.0-20221114191408-850992195362/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -183,16 +196,17 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= +golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -221,23 +235,28 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= @@ -278,8 +297,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/constants.go b/constants.go index 25be2bb6cb452..24d3dc1049b2d 100644 --- a/constants.go +++ b/constants.go @@ -38,8 +38,8 @@ const ( // SSHTeleportUser is the current Teleport user that is logged in. SSHTeleportUser = "SSH_TELEPORT_USER" - // SSHSessionWebproxyAddr is the address the web proxy. - SSHSessionWebproxyAddr = "SSH_SESSION_WEBPROXY_ADDR" + // SSHSessionWebProxyAddr is the address the web proxy. + SSHSessionWebProxyAddr = "SSH_SESSION_WEBPROXY_ADDR" // SSHTeleportClusterName is the name of the cluster this node belongs to. SSHTeleportClusterName = "SSH_TELEPORT_CLUSTER_NAME" @@ -270,6 +270,9 @@ const ( // ComponentProxySecureGRPC represents secure gRPC server running on Proxy (used for Kube). ComponentProxySecureGRPC = "proxy:secure-grpc" + // ComponentAssist represents Teleport Assist + ComponentAssist = "assist" + // VerboseLogEnvVar forces all logs to be verbose (down to DEBUG level) VerboseLogsEnvVar = "TELEPORT_DEBUG" @@ -613,13 +616,31 @@ const ( // reading cluster events and playing back session records. PresetAuditorRoleName = "auditor" + // PresetReviewerRoleName is a name of a preset role that allows + // for reviewing access requests. + PresetReviewerRoleName = "reviewer" + + // PresetRequesterRoleName is a name of a preset role that allows + // for requesting access to resources. + PresetRequesterRoleName = "requester" + // PresetGroupAccessRoleName is a name of a preset role that allows // access to all user groups. PresetGroupAccessRoleName = "group-access" + + // SystemAutomaticAccessApprovalRoleName names a preset role that may + // automatically approve any Role Access Request + SystemAutomaticAccessApprovalRoleName = "@teleport-access-approver" ) var PresetRoles = []string{PresetEditorRoleName, PresetAccessRoleName, PresetAuditorRoleName} +const ( + // SystemAccessApproverUserName names a Teleport user that acts as + // an Access Request approver for access plugins + SystemAccessApproverUserName = "@teleport-access-approval-bot" +) + // MinClientVersion is the minimum client version required by the server. var MinClientVersion string diff --git a/devbox.json b/devbox.json new file mode 100644 index 0000000000000..a7c03bf584a73 --- /dev/null +++ b/devbox.json @@ -0,0 +1,41 @@ +{ + "packages": [ + "addlicense@1.0.0", + "bats@1.3.0", + "github:nixos/nixpkgs/d7f28652048b3bed6a512542e62ea1a50691e349#buf", + "clang@11.1.0", + "gci@0.9.1", + "github:nixos/nixpkgs/deb3d80ae0ccafe4f19d3edf32e2eb7fda283978#go", + "github:nixos/nixpkgs/22540da6c19a41512dd6bc575858e1215baeb3f9#golangci-lint", + "libiconvReal@1.16", + "libfido2@1.13.0", + "nodejs@16.18.1", + "github:nixos/nixpkgs/b39bfdc033e1d79f2b58e1630530e5d54b19e698#openssl", + "patchelf@0.15.0", + "protobuf3_20@3.20.3", + "python@3.11.2", + "shellcheck@0.9.0", + "yamllint@1.28.0", + "zlib@1.2.13", + "path:build.assets/flake#conditional", + "path:build.assets/flake#grpc-tools", + "path:build.assets/flake#helm", + "path:build.assets/flake#libpcsclite", + "path:build.assets/flake#node-protoc-ts", + "path:build.assets/flake#protoc-gen-gogo", + "path:build.assets/flake#rust", + "path:build.assets/flake#yarn", + "bash@latest", + "git@latest" + ], + "shell": { + "init_hook": [ + "export TELEPORT_DEVBOX=1", + "export PATH=\"$HOME/.cargo/bin:$PATH\"", + "unset GOROOT" + ] + }, + "nixpkgs": { + "commit": "b3f5bcf0be3e15226b0e9d698aa734ee098aa08f" + } +} diff --git a/devbox.lock b/devbox.lock new file mode 100644 index 0000000000000..133fbccc32d08 --- /dev/null +++ b/devbox.lock @@ -0,0 +1,77 @@ +{ + "lockfile_version": "1", + "packages": { + "addlicense@1.0.0": { + "last_modified": "2022-06-30T00:42:12Z", + "resolved": "github:NixOS/nixpkgs/d3248619647234b5dc74a6921bcdf6dd8323eb22#addlicense", + "version": "1.0.0" + }, + "bash@latest": { + "resolved": "github:NixOS/nixpkgs/f91ee3065de91a3531329a674a45ddcb3467a650#bash" + }, + "bats@1.3.0": { + "last_modified": "2021-09-01T12:51:06Z", + "resolved": "github:NixOS/nixpkgs/6cc260cfd60f094500b79e279069b499806bf6d8#bats", + "version": "1.3.0" + }, + "clang@11.1.0": { + "last_modified": "2023-05-01T16:53:22Z", + "resolved": "github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb#clang", + "version": "11.1.0" + }, + "gci@0.9.1": { + "last_modified": "2023-02-28T22:11:13Z", + "resolved": "github:NixOS/nixpkgs/995edc972ad3a1e291ac22d74b9610821357175f#gci", + "version": "0.9.1" + }, + "git@latest": { + "resolved": "github:NixOS/nixpkgs/f91ee3065de91a3531329a674a45ddcb3467a650#git" + }, + "libfido2@1.13.0": { + "last_modified": "2023-05-01T16:53:22Z", + "resolved": "github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb#libfido2", + "version": "1.13.0" + }, + "libiconvReal@1.16": { + "last_modified": "2023-05-01T16:53:22Z", + "resolved": "github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb#libiconvReal", + "version": "1.16" + }, + "nodejs@16.18.1": { + "last_modified": "2023-01-02T04:31:48Z", + "resolved": "github:NixOS/nixpkgs/a4379d2b0deefedc8dba360897557707ea9ee9a7#nodejs-16_x", + "version": "16.18.1" + }, + "patchelf@0.15.0": { + "last_modified": "2023-05-01T16:53:22Z", + "resolved": "github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb#patchelf", + "version": "0.15.0" + }, + "protobuf3_20@3.20.3": { + "last_modified": "2023-05-01T16:53:22Z", + "resolved": "github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb#protobuf3_20", + "version": "3.20.3" + }, + "python@3.11.2": { + "last_modified": "2023-03-31T22:52:29Z", + "plugin_version": "0.0.1", + "resolved": "github:NixOS/nixpkgs/242246ee1e58f54d2322227fc5eef53b4a616a31#python311", + "version": "3.11.2" + }, + "shellcheck@0.9.0": { + "last_modified": "2023-05-01T16:53:22Z", + "resolved": "github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb#shellcheck", + "version": "0.9.0" + }, + "yamllint@1.28.0": { + "last_modified": "2023-02-28T22:11:13Z", + "resolved": "github:NixOS/nixpkgs/995edc972ad3a1e291ac22d74b9610821357175f#yamllint", + "version": "1.28.0" + }, + "zlib@1.2.13": { + "last_modified": "2023-05-01T16:53:22Z", + "resolved": "github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb#zlib", + "version": "1.2.13" + } + } +} \ No newline at end of file diff --git a/docs/config.json b/docs/config.json index ebc5c1cd51685..e88ea882e97f8 100644 --- a/docs/config.json +++ b/docs/config.json @@ -4,13 +4,9 @@ "icon": "home", "title": "Home", "entries": [ - { - "title": "Introduction", - "slug": "/" - }, { "title": "Get Started with Teleport", - "slug": "/get-started/" + "slug": "/" }, { "title": "Core Concepts", @@ -35,9 +31,7 @@ { "title": "Teleport Assist", "slug": "/ai-assist/", - "forScopes": [ - "oss" - ] + "forScopes": ["oss"] } ] }, @@ -49,10 +43,10 @@ "title": "Introduction", "slug": "/choose-an-edition/introduction/" }, - { - "title": "Teleport Team", - "slug": "/choose-an-edition/teleport-team/" - }, + { + "title": "Teleport Team", + "slug": "/choose-an-edition/teleport-team/" + }, { "title": "Teleport Enterprise Cloud", "slug": "/choose-an-edition/teleport-cloud/introduction/", @@ -61,53 +55,39 @@ { "title": "Architecture", "slug": "/choose-an-edition/teleport-cloud/architecture/", - "forScopes": [ - "cloud" - ] + "forScopes": ["cloud"] }, { "title": "Downloads", "slug": "/choose-an-edition/teleport-cloud/downloads/", - "forScopes": [ - "cloud" - ] + "forScopes": ["cloud"] }, { "title": "FAQ", "slug": "/choose-an-edition/teleport-cloud/faq/", - "forScopes": [ - "cloud" - ] + "forScopes": ["cloud"] } ] }, { "title": "Teleport Enterprise", "slug": "/choose-an-edition/teleport-enterprise/introduction/", - "forScopes": [ - "enterprise" - ], + "forScopes": ["enterprise"], "entries": [ { "title": "HSM", "slug": "/choose-an-edition/teleport-enterprise/hsm/", - "forScopes": [ - "enterprise" - ] + "forScopes": ["enterprise"] }, { "title": "Google Cloud KMS", "slug": "/choose-an-edition/teleport-enterprise/gcp-kms/", - "forScopes": [ - "enterprise" - ] + "forScopes": ["enterprise"] }, { "title": "Enterprise License File", "slug": "/choose-an-edition/teleport-enterprise/license/", - "forScopes": [ - "enterprise" - ] + "forScopes": ["enterprise"] } ] } @@ -124,116 +104,74 @@ { "title": "High Availability Deployments", "slug": "/deploy-a-cluster/high-availability/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "Deploy with Helm", "slug": "/deploy-a-cluster/helm-deployments/", - "forScopes": [ - "oss", - "enterprise" - ], + "forScopes": ["oss", "enterprise"], "entries": [ { "title": "Deploy Teleport on Kubernetes", "slug": "/deploy-a-cluster/helm-deployments/kubernetes-cluster/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "AWS EKS Cluster", "slug": "/deploy-a-cluster/helm-deployments/aws/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "Google Cloud GKE Cluster", "slug": "/deploy-a-cluster/helm-deployments/gcp/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "DigitalOcean Kubernetes Cluster", "slug": "/deploy-a-cluster/helm-deployments/digitalocean/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "Customize Deployment Config", "slug": "/deploy-a-cluster/helm-deployments/custom/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "Migrating from v11 to v12", "slug": "/deploy-a-cluster/helm-deployments/migration-v12/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "Kubernetes 1.25 and PSP removal", "slug": "/deploy-a-cluster/helm-deployments/migration-kubernetes-1-25-psp/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] } ] }, { "title": "Deploy to your Cloud", "slug": "/deploy-a-cluster/deployments/", - "forScopes": [ - "oss", - "enterprise" - ], + "forScopes": ["oss", "enterprise"], "entries": [ { "title": "AWS Terraform", "slug": "/deploy-a-cluster/deployments/aws-terraform/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "AWS Multi-Region Proxy Deployment", "slug": "/deploy-a-cluster/deployments/aws-gslb-proxy-peering-ha-deployment/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "GCP", "slug": "/deploy-a-cluster/deployments/gcp/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "IBM", "slug": "/deploy-a-cluster/deployments/ibm/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] } ] } @@ -278,10 +216,7 @@ { "title": "Dual Authorization", "slug": "/access-controls/guides/dual-authz/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Impersonation", @@ -290,26 +225,12 @@ { "title": "Moderated Sessions", "slug": "/access-controls/guides/moderated-sessions/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Hardware Key Support (Preview)", "slug": "/access-controls/guides/hardware-key-support/", - "forScopes": [ - "enterprise", - "cloud" - ] - }, - { - "title": "Device Trust (Preview)", - "slug": "/access-controls/guides/device-trust/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Headless WebAuthn (Preview)", @@ -318,160 +239,136 @@ { "title": "IP Pinning (Preview)", "slug": "/access-controls/guides/ip-pinning/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] } ] }, { "title": "Single Sign-On (SSO)", "slug": "/access-controls/sso/", - "forScopes": [ - "enterprise", - "oss", - "cloud" - ], + "forScopes": ["enterprise", "oss", "cloud"], "entries": [ { "title": "Active Directory (ADFS)", "slug": "/access-controls/sso/adfs/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Azure Active Directory", "slug": "/access-controls/sso/azuread/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "GitHub", "slug": "/access-controls/sso/github-sso/", - "forScopes": [ - "enterprise", - "cloud", - "oss" - ] + "forScopes": ["enterprise", "cloud", "oss"] }, { "title": "GitLab", "slug": "/access-controls/sso/gitlab/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Google Workspace", "slug": "/access-controls/sso/google-workspace/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "OIDC", "slug": "/access-controls/sso/oidc/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Okta", "slug": "/access-controls/sso/okta/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "OneLogin", "slug": "/access-controls/sso/one-login/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] } ] }, { "title": "Teleport as an IdP", "slug": "/access-controls/idps/", - "forScopes": [ - "enterprise", - "cloud" - ], + "forScopes": ["enterprise", "cloud"], "entries": [ { "title": "SAML Identity Provider Guide", "slug": "/access-controls/idps/saml-guide/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Authenticate to Grafana with Teleport SAML", "slug": "/access-controls/idps/saml-grafana/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "SAML Identity Provider Reference", "slug": "/access-controls/idps/saml-reference/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] } ] }, { "title": "Login Rules", "slug": "/access-controls/login-rules/", - "forScopes": [ - "enterprise", - "cloud" - ], + "forScopes": ["enterprise", "cloud"], "entries": [ { "title": "Set Up Login Rules", "slug": "/access-controls/login-rules/guide/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Login Rules Reference", "slug": "/access-controls/login-rules/reference/", + "forScopes": ["enterprise", "cloud"] + }, + { + "title": "Terraform", + "slug": "/access-controls/login-rules/terraform/", + "forScopes": ["enterprise", "cloud"] + }, + { + "title": "Kubernetes Operator", + "slug": "/access-controls/login-rules/kubernetes/", + "forScopes": ["enterprise"] + } + ] + }, + { + "title": "Device Trust", + "slug": "/access-controls/device-trust/", + "forScopes": [ + "enterprise", + "cloud" + ], + "entries": [ + { + "title": "Set Up Device Trust", + "slug": "/access-controls/device-trust/guide/", "forScopes": [ "enterprise", "cloud" ] }, { - "title": "Terraform", - "slug": "/access-controls/login-rules/terraform/", + "title": "Set Up Auto-Enrollment", + "slug": "/access-controls/device-trust/auto-enrollment/", "forScopes": [ "enterprise", "cloud" ] }, { - "title": "Kubernetes Operator", - "slug": "/access-controls/login-rules/kubernetes/", + "title": "Jamf Integration", + "slug": "/access-controls/device-trust/jamf-integration/", "forScopes": [ - "enterprise" + "enterprise", + "cloud" ] } ] @@ -479,11 +376,7 @@ { "title": "Access Requests", "slug": "/access-controls/access-requests/", - "forScopes": [ - "oss", - "enterprise", - "cloud" - ], + "forScopes": ["oss", "enterprise", "cloud"], "entries": [ { "title": "Role Requests", @@ -492,110 +385,71 @@ { "title": "Resource Requests", "slug": "/access-controls/access-requests/resource-requests/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Role Requests in OSS Teleport", "slug": "/access-controls/access-requests/oss-role-requests/", - "forScopes": [ - "oss", - "enterprise", - "cloud" - ] + "forScopes": ["oss", "enterprise", "cloud"] } ] }, { "title": "Access Request Plugins", "slug": "/access-controls/access-request-plugins/", - "forScopes": [ - "enterprise", - "cloud" - ], + "forScopes": ["enterprise", "cloud"], "entries": [ { "title": "Mattermost", "slug": "/access-controls/access-request-plugins/ssh-approval-mattermost/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Microsoft Teams", "slug": "/access-controls/access-request-plugins/ssh-approval-msteams/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "PagerDuty", "slug": "/access-controls/access-request-plugins/ssh-approval-pagerduty/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Jira", "slug": "/access-controls/access-request-plugins/ssh-approval-jira/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Slack", "slug": "/access-controls/access-request-plugins/ssh-approval-slack/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Email", "slug": "/access-controls/access-request-plugins/ssh-approval-email/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Discord", "slug": "/access-controls/access-request-plugins/ssh-approval-discord/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] } ] }, { "title": "Compliance Frameworks", "slug": "/access-controls/compliance-frameworks/", - "forScopes": [ - "enterprise", - "cloud" - ], + "forScopes": ["enterprise", "cloud"], "entries": [ { "title": "FedRAMP", "slug": "/access-controls/compliance-frameworks/fedramp/", - "forScopes": [ - "enterprise" - ] + "forScopes": ["enterprise"] }, { "title": "SOC 2", "slug": "/access-controls/compliance-frameworks/soc2/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] } ] }, @@ -613,40 +467,20 @@ "title": "Introduction", "slug": "/management/introduction/" }, - { - "title": "Joining Teleport Services", - "slug": "/management/join-services-to-your-cluster/", - "entries": [ - { - "title": "Via AWS EC2", - "slug": "/management/join-services-to-your-cluster/aws-ec2/", - "forScopes": [ - "oss", - "enterprise" - ] - }, - { - "title": "Via AWS IAM", - "slug": "/management/join-services-to-your-cluster/aws-iam/" - }, - { - "title": "Via Azure", - "slug": "/management/join-services-to-your-cluster/azure/" - }, - { - "title": "Joining Services via Kubernetes ServiceAccount", - "slug": "/management/join-services-to-your-cluster/kubernetes/", - "forScopes": [ - "oss", - "enterprise" - ] + { + "title": "Using Dynamic Resources", + "slug": "/management/dynamic-resources/", + "entries": [ + { + "title": "Kubernetes Operator (Preview)", + "slug": "/management/dynamic-resources/teleport-operator/" }, { - "title": "Via a Join Token", - "slug": "/management/join-services-to-your-cluster/join-token/" + "title": "Terraform Provider", + "slug": "/management/dynamic-resources/terraform-provider/" } - ] - }, + ] + }, { "title": "Admin Guides", "slug": "/management/admin/", @@ -666,11 +500,7 @@ { "title": "Troubleshooting", "slug": "/management/admin/troubleshooting/", - "forScopes": [ - "oss", - "enterprise", - "cloud" - ] + "forScopes": ["oss", "enterprise", "cloud"] }, { "title": "Upgrading the Teleport Binary", @@ -697,10 +527,7 @@ { "title": "Scaling", "slug": "/management/operations/scaling/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "Upgrading a Cluster", @@ -709,10 +536,7 @@ { "title": "Backup and Restore", "slug": "/management/operations/backup-restore/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "Cert Authority Rotation", @@ -721,32 +545,22 @@ { "title": "TLS Routing Migration", "slug": "/management/operations/tls-routing/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "Proxy Peering Migration (Preview)", "slug": "/management/operations/proxy-peering/", - "forScopes": [ - "enterprise" - ] + "forScopes": ["enterprise"] }, { "title": "Self-hosted automatic updates", "slug": "/management/operations/self-hosted-automatic-agent-updates/", - "forScopes": [ - "enterprise" - ] + "forScopes": ["enterprise"] }, { "title": "Enroll agent in automatic updates", "slug": "/management/operations/enroll-agent-into-automatic-updates/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] } ] }, @@ -764,14 +578,6 @@ "title": "Integrations", "slug": "/management/guides/", "entries": [ - { - "title": "Kubernetes Operator (Preview)", - "slug": "/management/guides/teleport-operator/" - }, - { - "title": "Terraform Provider", - "slug": "/management/guides/terraform-provider/" - }, { "title": "EC2 Tags", "slug": "/management/guides/ec2-tags/" @@ -789,38 +595,22 @@ { "title": "Health Monitoring", "slug": "/management/diagnostics/monitoring/", - "forScopes": [ - "oss", - "enterprise", - "cloud" - ] + "forScopes": ["oss", "enterprise", "cloud"] }, { "title": "Metrics", "slug": "/management/diagnostics/metrics/", - "forScopes": [ - "oss", - "enterprise", - "cloud" - ] + "forScopes": ["oss", "enterprise", "cloud"] }, { "title": "Collecting Profiles", "slug": "/management/diagnostics/profiles/", - "forScopes": [ - "oss", - "enterprise", - "cloud" - ] + "forScopes": ["oss", "enterprise", "cloud"] }, { "title": "Distributed Tracing", "slug": "/management/diagnostics/tracing/", - "forScopes": [ - "oss", - "enterprise", - "cloud" - ] + "forScopes": ["oss", "enterprise", "cloud"] } ] }, @@ -831,34 +621,22 @@ { "title": "Export Audit Events to Fluentd", "slug": "/management/export-audit-events/fluentd/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Export Audit Events to Datadog", "slug": "/management/export-audit-events/datadog/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Export Audit Events to the Elastic Stack", "slug": "/management/export-audit-events/elastic-stack/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Export Audit Events to Splunk", "slug": "/management/export-audit-events/splunk/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] } ] } @@ -890,6 +668,50 @@ } ] }, + { + "title": "Run Teleport Agents", + "icon": "layers", + "entries": [ + { + "title": "Introduction", + "slug": "/agents/introduction/" + }, + { + "title": "Deploy via Terraform", + "slug": "/agents/deploy-agents-terraform/" + }, + { + "title": "Join Services to Your Cluster", + "slug": "/agents/join-services-to-your-cluster/", + "entries": [ + { + "title": "Via AWS EC2", + "slug": "/agents/join-services-to-your-cluster/aws-ec2/" + }, + { + "title": "Via AWS IAM", + "slug": "/agents/join-services-to-your-cluster/aws-iam/" + }, + { + "title": "Via Azure", + "slug": "/agents/join-services-to-your-cluster/azure/" + }, + { + "title": "Joining Services via Kubernetes ServiceAccount", + "slug": "/agents/join-services-to-your-cluster/kubernetes/" + }, + { + "title": "Via GCP", + "slug": "/agents/join-services-to-your-cluster/gcp/" + }, + { + "title": "Via a Join Token", + "slug": "/agents/join-services-to-your-cluster/join-token/" + } + ] + } + ] + }, { "icon": "window", "title": "Application Access", @@ -971,18 +793,22 @@ { "title": "Protect Okta Applications and Groups (Preview)", "slug": "/application-access/okta/", + "forScopes": ["enterprise", "cloud"], "entries": [ { "title": "Okta Service", - "slug": "/application-access/okta/guide/" + "slug": "/application-access/okta/guide/", + "forScopes": ["enterprise", "cloud"] }, { "title": "Architecture", - "slug": "/application-access/okta/architecture/" + "slug": "/application-access/okta/architecture/", + "forScopes": ["enterprise", "cloud"] }, { "title": "Reference", - "slug": "/application-access/okta/reference/" + "slug": "/application-access/okta/reference/", + "forScopes": ["enterprise", "cloud"] } ] }, @@ -1023,10 +849,7 @@ { "title": "Recording Proxy Mode", "slug": "/server-access/guides/recording-proxy-mode/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "BPF Session Recording", @@ -1157,12 +980,12 @@ "slug": "/database-access/guides/", "entries": [ { - "title": "AWS Cross-Account", - "slug": "/database-access/guides/aws-cross-account/" + "title": "AWS Cross-Account", + "slug": "/database-access/guides/aws-cross-account/" }, { - "title": "AWS DynamoDB", - "slug": "/database-access/guides/aws-dynamodb/" + "title": "AWS DynamoDB", + "slug": "/database-access/guides/aws-dynamodb/" }, { "title": "AWS ElastiCache & MemoryDB", @@ -1266,10 +1089,7 @@ }, { "title": "Self-Hosted Oracle (Preview)", - "forScopes": [ - "enterprise", - "cloud" - ], + "forScopes": ["enterprise", "cloud"], "slug": "/database-access/guides/oracle-self-hosted/" }, { @@ -1339,10 +1159,7 @@ { "title": "Getting Started", "slug": "/desktop-access/getting-started/", - "forScopes": [ - "enterprise", - "cloud" - ] + "forScopes": ["enterprise", "cloud"] }, { "title": "Active Directory", @@ -1551,10 +1368,7 @@ { "title": "Storage Backends", "slug": "/reference/backends/", - "forScopes": [ - "oss", - "enterprise" - ] + "forScopes": ["oss", "enterprise"] }, { "title": "Networking", @@ -1663,10 +1477,10 @@ "title": "How to Contribute", "slug": "/contributing/documentation/how-to-contribute/" }, - { - "title": "Reviewing Documentation Changes", - "slug": "/contributing/documentation/reviewing-docs/" - }, + { + "title": "Reviewing Documentation Changes", + "slug": "/contributing/documentation/reviewing-docs/" + }, { "title": "Creating Documentation Issues", "slug": "/contributing/documentation/issues/" @@ -1693,8 +1507,8 @@ "aws_secret_access_key": "zyxw9876-this-is-an-example" }, "cloud": { - "version": "12.4.5", - "major_version": "12", + "version": "13.1.5", + "major_version": "13", "sla": { "monthly_percentage": "99.9%", "monthly_downtime": "44 minutes" @@ -1873,7 +1687,7 @@ }, { "source": "/cloud/", - "destination": "/choose-an-edition/teleport-cloud/", + "destination": "/choose-an-edition/teleport-cloud/introduction/", "permanent": true }, { @@ -1898,7 +1712,7 @@ }, { "source": "/quickstart/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { @@ -1908,7 +1722,7 @@ }, { "source": "/preview/cloud/", - "destination": "/choose-an-edition/teleport-cloud/", + "destination": "/choose-an-edition/teleport-cloud/introduction/", "permanent": true }, { @@ -1963,7 +1777,7 @@ }, { "source": "/setup/guides/joining-nodes-aws/", - "destination": "/management/join-services-to-your-cluster/aws-iam/", + "destination": "/agents/join-services-to-your-cluster/aws-iam/", "permanent": true }, { @@ -1998,7 +1812,7 @@ }, { "source": "/getting-started/digitalocean/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { @@ -2203,7 +2017,7 @@ }, { "source": "/setup/deployments/digitalocean/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { @@ -2253,7 +2067,7 @@ }, { "source": "/getting-started/linux-server/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { @@ -2278,7 +2092,7 @@ }, { "source": "/cloud/introduction/", - "destination": "/choose-an-edition/teleport-cloud/", + "destination": "/choose-an-edition/teleport-cloud/introduction/", "permanent": true }, { @@ -2313,7 +2127,7 @@ }, { "source": "/setup/admin/adding-nodes/", - "destination": "/management/join-services-to-your-cluster/join-token/", + "destination": "/agents/join-services-to-your-cluster/join-token/", "permanent": true }, { @@ -2368,12 +2182,12 @@ }, { "source": "/setup/guides/joining-nodes-aws-ec2/", - "destination": "/management/join-services-to-your-cluster/aws-ec2/", + "destination": "/agents/join-services-to-your-cluster/aws-ec2/", "permanent": true }, { "source": "/setup/guides/joining-nodes-aws-iam/", - "destination": "/management/join-services-to-your-cluster/aws-iam/", + "destination": "/agents/join-services-to-your-cluster/aws-iam/", "permanent": true }, { @@ -2383,12 +2197,12 @@ }, { "source": "/setup/guides/teleport-operator/", - "destination": "/management/guides/teleport-operator/", + "destination": "/management/dynamic-resources/teleport-operator/", "permanent": true }, { "source": "/setup/guides/terraform-provider/", - "destination": "/management/guides/terraform-provider/", + "destination": "/management/dynamic-resources/terraform-provider/", "permanent": true }, { @@ -2508,12 +2322,12 @@ }, { "source": "/getting-started/docker-compose/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { "source": "/getting-started/local-kubernetes/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { @@ -2548,7 +2362,7 @@ }, { "source": "/deploy-a-cluster/teleport-cloud/introduction/", - "destination": "/choose-an-edition/teleport-cloud/", + "destination": "/choose-an-edition/teleport-cloud/introduction/", "permanent": true }, { @@ -2578,17 +2392,17 @@ }, { "source": "/deploy-a-cluster/deployments/digitalocean/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { "source": "/deploy-a-cluster/open-source/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { "source": "/getting-started/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { @@ -2653,7 +2467,7 @@ }, { "source": "/try-out-teleport/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { @@ -2718,52 +2532,52 @@ }, { "source": "/management/guides/joining-nodes-aws-ec2/", - "destination": "/management/join-services-to-your-cluster/aws-ec2/", + "destination": "/agents/join-services-to-your-cluster/aws-ec2/", "permanent": true }, { "source": "/management/guides/joining-nodes-aws-iam/", - "destination": "/management/join-services-to-your-cluster/aws-iam/", + "destination": "/agents/join-services-to-your-cluster/aws-iam/", "permanent": true }, { "source": "/management/admin/adding-nodes/", - "destination": "/management/join-services-to-your-cluster/join-token/", + "destination": "/agents/join-services-to-your-cluster/join-token/", "permanent": true }, { "source": "/management/guides/joining-nodes-azure/", - "destination": "/management/join-services-to-your-cluster/azure/", + "destination": "/agents/join-services-to-your-cluster/azure/", "permanent": true }, { "source": "/management/guides/joining-services-kubernetes-serviceaccount/", - "destination": "/management/join-services-to-your-cluster/kubernetes/", + "destination": "/agents/join-services-to-your-cluster/kubernetes/", "permanent": true }, { "source": "/try-out-teleport/browser-labs/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { "source": "/try-out-teleport/digitalocean/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { "source": "/try-out-teleport/docker-compose/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { "source": "/try-out-teleport/introduction/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { "source": "/try-out-teleport/local-kubernetes/", - "destination": "/get-started/", + "destination": "/", "permanent": true }, { @@ -2790,6 +2604,26 @@ "source": "/choose-an-edition/teleport-cloud/", "destination": "/choose-an-edition/teleport-cloud/introduction/", "permanent": true + }, + { + "source": "/access-controls/guides/device-trust/", + "destination": "/access-controls/device-trust/guide/", + "permanent": true + }, + { + "source": "/management/guides/teleport-operator/", + "destination": "/management/dynamic-resources/teleport-operator/", + "permanent": true + }, + { + "source": "/management/guides/terraform-provider/", + "destination": "/management/dynamic-resources/terraform-provider/", + "permanent": true + }, + { + "source": "/get-started/", + "destination": "/", + "permanent": true } ] } diff --git a/docs/cspell.json b/docs/cspell.json index 8ad3564be15e6..7ebcf3eb9d828 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -8,6 +8,7 @@ "AICPA", "AICPA’s", "AKIA", + "ALPN", "AMAZ", "ANPAW", "APPDATA", @@ -21,7 +22,6 @@ "Aqxs", "Archlinux", "Authy", - "autoload", "BDRVJUSUZ", "BSFD", "BUCKETNAME", @@ -33,8 +33,8 @@ "CHANGEME", "CLOUDSDK", "CTAP", + "CXXXXXXXXX", "Cgajq", - "compinit", "DBSIZE", "DEBU", "DHDR", @@ -48,11 +48,13 @@ "Divio's", "EBSCSI", "ECMWF", + "EKCert", "ERRO", "Elastcsearch", "Elasticvue", "Exrch", "FGHIJ", + "FIPS", "FLUSHALL", "FLUSHDB", "FMPFM", @@ -64,12 +66,12 @@ "GCP's", "GENPASS", "GHES", + "GODEBUG", "GOMAXPROCS", + "GSLB", "Gbps", "Goland", "Grafana's", - "gslb", - "GSLB", "Gtczk", "HSTS", "Hqlo", @@ -89,6 +91,7 @@ "JDBC", "JWTs", "JYAUAA", + "Jamf", "Jetstack", "Jlbm", "Jlbn", @@ -118,18 +121,19 @@ "NOKEY", "NOPASSWD", "NVGJ", - "Obxo", "ODBC", "OIDC", + "OTLP", + "Obxo", "Olsi", "Olsia", "OpenAI", "Opsgenie", "Orapki", - "OTLP", "PFDEBUG", "PFSELFTEST", "PGPASSWORD", + "POSIX", "POSTALCODE", "PSUBSCRIBE", "PSYNC", @@ -145,17 +149,20 @@ "REPLCONF", "REPLICAOF", "RPID", + "RSQL", "Rdik", "Relogging", "Relogin", "SAMLIDP", "SECURITYADMIN", "SIEM", + "SIGINT", "SLAVEOF", "SLOWLOG", "SSUBSCRIBE", "SSWS", "SUNSUBSCRIBE", + "SUPATH", "Shockbyte", "Slackbot", "Sllavd", @@ -168,16 +175,17 @@ "TCPS", "TELEPORTING", "TENANTID", + "TESTDEVICE", "TOTP", "TOUCHID", "Tele", "Templating", - "TESTDEVICE", "Tmkx", "Toboth", "Traefik", "Upsert", "Upserted", + "Upserts", "Uwhp", "VSVZY", "Vhka", @@ -237,8 +245,10 @@ "authteleportconfig", "authz", "autodiscovery", + "autoload", "automount", "autoscale", + "awly", "awsapp", "awsathena", "awscli", @@ -248,6 +258,7 @@ "azuread", "azuredatabases", "backoff", + "backported", "backporting", "backports", "behaviour", @@ -255,6 +266,7 @@ "bfhunter", "bjoerger", "bluemix", + "boltdb", "boto", "buildbox", "cacerts", @@ -291,6 +303,8 @@ "clusterroles", "cockroachdb", "codingllama", + "compat", + "compinit", "cond", "configmap", "connectorname", @@ -310,6 +324,7 @@ "dbeaver", "dbgroup", "dbname", + "dbreviewer", "dbuser", "deanonymize", "deregisters", @@ -360,6 +375,7 @@ "fedmeatadataxml", "fedramp", "fedrampfips", + "fips", "firstname", "fklvk", "flexi", @@ -380,11 +396,13 @@ "goroutines", "goteleport", "gots", + "goxmldsig", "gpupdate", "grafana", "grav", "groupclaim", "gserviceaccount", + "gslb", "gsutil", "gworkspace", "hashfile", @@ -448,6 +466,8 @@ "libcloudhsm", "libdefaults", "libfido", + "libgcc", + "libm", "lmnop", "loadbalancer", "localca", @@ -491,6 +511,7 @@ "myauth", "mycluster", "mycommand", + "mydevice", "myelastic", "myendpoint", "mygroup", @@ -561,8 +582,8 @@ "pagerduty", "pagerdutyapikey", "pagerdutyapikeyfromsecret", - "pastable", "parquetlog", + "pastable", "pasteable", "pgaadauth", "pidof", @@ -595,6 +616,7 @@ "rbacv", "rdbms", "rdns", + "rdpsnd", "rdsca", "rdsproxy", "readall", @@ -608,6 +630,7 @@ "relogged", "replaceall", "replicaset", + "requestable", "requirepass", "reversetunnel", "reviewee", @@ -621,6 +644,7 @@ "rtrzn", "runcommand", "runscript", + "russellhaering", "russjones", "sadas", "samlauthentication", @@ -640,6 +664,7 @@ "serviceaccountname", "serviceaccounts", "serviceacct", + "servicecfg", "serviceid", "session", "setspn", @@ -663,14 +688,18 @@ "storageenabled", "strslice", "structs", + "subgroups", "subkind", "sudoer", "syscalls", + "sysvinit", "tadmin", "tbot", "tbotrole", + "tcpip", "tcpout", "tctl", + "teleadmins", "telenode", "teleportauditlogssofailed", "teleportdemo", @@ -682,6 +711,7 @@ "teleportyaml", "tenantname", "testuser", + "tfvars", "thisisunsafe", "thred", "timechart", @@ -710,11 +740,13 @@ "updaterversionserver", "uqcje", "urandom", + "userdata", "userdel", "usermod", "usernameclaim", "usernameless", "userprincipalname", + "utmp", "uuidgen", "viewstore", "vkxz", @@ -723,6 +755,7 @@ "walkthrough", "watcherjob", "webapi", + "webapps", "webauthn", "webauthnwin", "webclient", @@ -731,10 +764,12 @@ "webproxy", "webui", "westeurope", + "winadj", "windowsaccountname", "windowsdesktop", "winserver", "workgroups", + "wtmp", "xample", "xauth", "xclip", @@ -751,9 +786,8 @@ "yubikey", "yubishm", "znmqk", - "zxvf" + "zxvf", + "zztop" ], - "flagWords": [ - "hte" - ] -} \ No newline at end of file + "flagWords": ["hte"] +} diff --git a/docs/img/access-controls/device-trust/jamf-setup-1.png b/docs/img/access-controls/device-trust/jamf-setup-1.png new file mode 100644 index 0000000000000..473c83906e787 Binary files /dev/null and b/docs/img/access-controls/device-trust/jamf-setup-1.png differ diff --git a/docs/img/access-controls/device-trust/jamf-setup-2.png b/docs/img/access-controls/device-trust/jamf-setup-2.png new file mode 100644 index 0000000000000..fb376dee8e5ae Binary files /dev/null and b/docs/img/access-controls/device-trust/jamf-setup-2.png differ diff --git a/docs/img/adfs-add-provider-trust.png b/docs/img/adfs-add-provider-trust.png new file mode 100644 index 0000000000000..4822b79ed16f8 Binary files /dev/null and b/docs/img/adfs-add-provider-trust.png differ diff --git a/docs/img/adfs-add-teleport-cert.png b/docs/img/adfs-add-teleport-cert.png new file mode 100644 index 0000000000000..7b38942ee2d5a Binary files /dev/null and b/docs/img/adfs-add-teleport-cert.png differ diff --git a/docs/img/database-access/guides/atlas/atlas-add-aws-iam-user.png b/docs/img/database-access/guides/atlas/atlas-add-aws-iam-user.png new file mode 100644 index 0000000000000..6d6f0b75ea746 Binary files /dev/null and b/docs/img/database-access/guides/atlas/atlas-add-aws-iam-user.png differ diff --git a/docs/img/desktop-access/session-recording@2x.png b/docs/img/desktop-access/session-recording@2x.png index 9126c554bfe32..c7830c584e963 100644 Binary files a/docs/img/desktop-access/session-recording@2x.png and b/docs/img/desktop-access/session-recording@2x.png differ diff --git a/docs/img/googleoidc/clientid-creation.png b/docs/img/googleoidc/clientid-creation.png deleted file mode 100644 index f6e16f2588717..0000000000000 Binary files a/docs/img/googleoidc/clientid-creation.png and /dev/null differ diff --git a/docs/img/googleoidc/clientid-data.png b/docs/img/googleoidc/clientid-data.png deleted file mode 100644 index ba00ce48d2d0a..0000000000000 Binary files a/docs/img/googleoidc/clientid-data.png and /dev/null differ diff --git a/docs/img/googleoidc/consent-screen-1.png b/docs/img/googleoidc/consent-screen-1.png deleted file mode 100644 index fb1794813a46c..0000000000000 Binary files a/docs/img/googleoidc/consent-screen-1.png and /dev/null differ diff --git a/docs/img/googleoidc/consent-screen-2.png b/docs/img/googleoidc/consent-screen-2.png deleted file mode 100644 index 7cb9429d690b1..0000000000000 Binary files a/docs/img/googleoidc/consent-screen-2.png and /dev/null differ diff --git a/docs/img/googleoidc/domainwidedelegation.png b/docs/img/googleoidc/domainwidedelegation.png deleted file mode 100644 index 4dc6186007079..0000000000000 Binary files a/docs/img/googleoidc/domainwidedelegation.png and /dev/null differ diff --git a/docs/img/googleoidc/new-project.png b/docs/img/googleoidc/new-project.png deleted file mode 100644 index a455bc4340ef8..0000000000000 Binary files a/docs/img/googleoidc/new-project.png and /dev/null differ diff --git a/docs/img/googleoidc/serviceacct-creation.png b/docs/img/googleoidc/serviceacct-creation.png deleted file mode 100644 index 521096416591c..0000000000000 Binary files a/docs/img/googleoidc/serviceacct-creation.png and /dev/null differ diff --git a/docs/img/googleoidc/serviceacct-key.png b/docs/img/googleoidc/serviceacct-key.png deleted file mode 100644 index bd1da8d008044..0000000000000 Binary files a/docs/img/googleoidc/serviceacct-key.png and /dev/null differ diff --git a/docs/img/googleoidc/serviceacct-uniqueid.png b/docs/img/googleoidc/serviceacct-uniqueid.png deleted file mode 100644 index d0259621095e7..0000000000000 Binary files a/docs/img/googleoidc/serviceacct-uniqueid.png and /dev/null differ diff --git a/docs/img/linux-server-diagram.png b/docs/img/linux-server-diagram.png new file mode 100644 index 0000000000000..fb8cb23ea2519 Binary files /dev/null and b/docs/img/linux-server-diagram.png differ diff --git a/docs/img/management/spacelift/apply-success.png b/docs/img/management/spacelift/apply-success.png new file mode 100644 index 0000000000000..84be9b4cca6f9 Binary files /dev/null and b/docs/img/management/spacelift/apply-success.png differ diff --git a/docs/img/management/spacelift/id-file.png b/docs/img/management/spacelift/id-file.png new file mode 100644 index 0000000000000..7b321912356c1 Binary files /dev/null and b/docs/img/management/spacelift/id-file.png differ diff --git a/docs/img/management/spacelift/newstack.png b/docs/img/management/spacelift/newstack.png new file mode 100644 index 0000000000000..0d7aeba18146e Binary files /dev/null and b/docs/img/management/spacelift/newstack.png differ diff --git a/docs/img/management/spacelift/pr-run.png b/docs/img/management/spacelift/pr-run.png new file mode 100644 index 0000000000000..07aeb918b0aa3 Binary files /dev/null and b/docs/img/management/spacelift/pr-run.png differ diff --git a/docs/img/sso/gitlab/gitlab-oidc-0.png b/docs/img/sso/gitlab/gitlab-oidc-0.png index 48fba082abefd..214e15cb9d248 100644 Binary files a/docs/img/sso/gitlab/gitlab-oidc-0.png and b/docs/img/sso/gitlab/gitlab-oidc-0.png differ diff --git a/docs/img/sso/gitlab/gitlab-oidc-1.png b/docs/img/sso/gitlab/gitlab-oidc-1.png index e783af931ce99..e3219584d73f0 100644 Binary files a/docs/img/sso/gitlab/gitlab-oidc-1.png and b/docs/img/sso/gitlab/gitlab-oidc-1.png differ diff --git a/docs/img/sso/googleoidc/clientid-creation.png b/docs/img/sso/googleoidc/clientid-creation.png new file mode 100644 index 0000000000000..dae4d7b62b8fe Binary files /dev/null and b/docs/img/sso/googleoidc/clientid-creation.png differ diff --git a/docs/img/sso/googleoidc/clientid-data.png b/docs/img/sso/googleoidc/clientid-data.png new file mode 100644 index 0000000000000..623f2f68564be Binary files /dev/null and b/docs/img/sso/googleoidc/clientid-data.png differ diff --git a/docs/img/sso/googleoidc/consent-screen-1.png b/docs/img/sso/googleoidc/consent-screen-1.png new file mode 100644 index 0000000000000..5089bd2b43721 Binary files /dev/null and b/docs/img/sso/googleoidc/consent-screen-1.png differ diff --git a/docs/img/sso/googleoidc/consent-screen-2.png b/docs/img/sso/googleoidc/consent-screen-2.png new file mode 100644 index 0000000000000..b0b63a948abad Binary files /dev/null and b/docs/img/sso/googleoidc/consent-screen-2.png differ diff --git a/docs/img/sso/googleoidc/create-oauth-client-id.png b/docs/img/sso/googleoidc/create-oauth-client-id.png new file mode 100644 index 0000000000000..972d6343429f2 Binary files /dev/null and b/docs/img/sso/googleoidc/create-oauth-client-id.png differ diff --git a/docs/img/sso/googleoidc/create-service-account.png b/docs/img/sso/googleoidc/create-service-account.png new file mode 100644 index 0000000000000..a935d6eb7526a Binary files /dev/null and b/docs/img/sso/googleoidc/create-service-account.png differ diff --git a/docs/img/sso/googleoidc/domainwidedelegation.png b/docs/img/sso/googleoidc/domainwidedelegation.png new file mode 100644 index 0000000000000..dc310832502b0 Binary files /dev/null and b/docs/img/sso/googleoidc/domainwidedelegation.png differ diff --git a/docs/img/sso/googleoidc/new-project.png b/docs/img/sso/googleoidc/new-project.png new file mode 100644 index 0000000000000..0b4798a003abe Binary files /dev/null and b/docs/img/sso/googleoidc/new-project.png differ diff --git a/docs/img/sso/googleoidc/serviceacct-creation.png b/docs/img/sso/googleoidc/serviceacct-creation.png new file mode 100644 index 0000000000000..bfe362ac6ae26 Binary files /dev/null and b/docs/img/sso/googleoidc/serviceacct-creation.png differ diff --git a/docs/img/sso/googleoidc/serviceacct-key.png b/docs/img/sso/googleoidc/serviceacct-key.png new file mode 100644 index 0000000000000..2791620e3d07b Binary files /dev/null and b/docs/img/sso/googleoidc/serviceacct-key.png differ diff --git a/docs/img/sso/googleoidc/serviceacct-uniqueid.png b/docs/img/sso/googleoidc/serviceacct-uniqueid.png new file mode 100644 index 0000000000000..a04d789860bb4 Binary files /dev/null and b/docs/img/sso/googleoidc/serviceacct-uniqueid.png differ diff --git a/docs/img/sso/okta/setup-redirection.png b/docs/img/sso/okta/setup-redirection.png index 026d926d5fe58..b70d53c96595c 100644 Binary files a/docs/img/sso/okta/setup-redirection.png and b/docs/img/sso/okta/setup-redirection.png differ diff --git a/docs/img/sso/teleportauditlogssofailed.png b/docs/img/sso/teleportauditlogssofailed.png index 6488882188ed3..af386991364bf 100644 Binary files a/docs/img/sso/teleportauditlogssofailed.png and b/docs/img/sso/teleportauditlogssofailed.png differ diff --git a/docs/pages/access-controls/access-request-plugins/ssh-approval-slack.mdx b/docs/pages/access-controls/access-request-plugins/ssh-approval-slack.mdx index 8bc1c324f0cbb..e3ddb2a5c5709 100644 --- a/docs/pages/access-controls/access-request-plugins/ssh-approval-slack.mdx +++ b/docs/pages/access-controls/access-request-plugins/ssh-approval-slack.mdx @@ -5,9 +5,9 @@ description: How to set up Teleport's Slack plugin for privilege elevation appro This guide will explain how to set up Slack to receive Access Request messages from Teleport. Teleport's Slack integration notifies individuals and channels of -Access Requests. Users can then approve and deny Access Requests from within -Slack, making it easier to implement security best practices without -compromising productivity. +Access Requests. Users are then directed to log in to the Teleport cluster where +they can approve and deny Access Requests, making it easier to implement security +best practices without compromising productivity. (!docs/pages/includes/plugins/diagram.mdx api="Slack" action="Listen for Access Requests" messages="Slack messages" !) diff --git a/docs/pages/access-controls/access-requests/resource-requests.mdx b/docs/pages/access-controls/access-requests/resource-requests.mdx index 92c7bf621324e..74f5be34441d2 100644 --- a/docs/pages/access-controls/access-requests/resource-requests.mdx +++ b/docs/pages/access-controls/access-requests/resource-requests.mdx @@ -41,6 +41,14 @@ upgraded to version 10. ## Step 1/8. Create the requester role + +As of version 13.1.2, Teleport comes with built-in `reviewer` and `requester` roles that +are defined similarly to the ones presented here. If you are looking to quickly try out +Access Requests, you can skip to step 3 and use these built-in roles. However, if you are +using an earlier version of Teleport or you are looking to get general guidance for creating +roles for Access Requests, steps 1 and 2 are still useful. + + This role allows the requester to search for resources accessible by the `access` role (all resources by default) and request access to them. diff --git a/docs/pages/access-controls/compliance-frameworks/soc2.mdx b/docs/pages/access-controls/compliance-frameworks/soc2.mdx index 46f998acedc00..1ebbc51a4b06e 100644 --- a/docs/pages/access-controls/compliance-frameworks/soc2.mdx +++ b/docs/pages/access-controls/compliance-frameworks/soc2.mdx @@ -56,7 +56,7 @@ Each principle has many “Points of Focus” which will apply differently to di | CC6.1 - Manages Points of Access | Points of access by outside entities and the types of data that flow through the points of access are identified, inventoried, and managed. The types of individuals and systems using each point of access are identified, documented, and managed. | [Label Nodes to inventory and create rules](../../management/admin/labels.mdx)

[Create Labels from AWS Tags](../../management/guides/ec2-tags.mdx)

Teleport maintains a live list of all nodes within a cluster. This node list can be queried by users (who see a subset they have access to) and administrators any time. | | CC6.1 - Restricts Access to Information Assets | Combinations of data classification, separate data structures, port restrictions, access protocol restrictions, user identification, and digital certificates are used to establish access-control rules for information assets. | [Teleport uses Certificates to grant access and create access control rules](../../core-concepts.mdx) | | CC6.1 - Manages Identification and Authentication | Identification and authentication requirements are established, documented, and managed for individuals and systems accessing entity information, infrastructure, and software. | Teleport makes setting policies for SSH requirements easy since it works in the cloud and on premise with the same authentication security standards. | -| CC6.1 - Manages Credentials for Infrastructure and Software | New internal and external infrastructure and software are registered, authorized, and documented prior to being granted access credentials and implemented on the network or access point. Credentials are removed and access is disabled when access is no longer required or the infrastructure and software are no longer in use. | [Invite nodes to your cluster with short lived tokens](../../management/join-services-to-your-cluster/join-token.mdx) | +| CC6.1 - Manages Credentials for Infrastructure and Software | New internal and external infrastructure and software are registered, authorized, and documented prior to being granted access credentials and implemented on the network or access point. Credentials are removed and access is disabled when access is no longer required or the infrastructure and software are no longer in use. | [Invite nodes to your cluster with short lived tokens](../../agents/join-services-to-your-cluster/join-token.mdx) | | CC6.1 - Uses Encryption to Protect Data | The entity uses encryption to supplement other measures used to protect data at rest, when such protections are deemed appropriate based on assessed risk. | Teleport Audit logs can use DynamoDB encryption at rest. | | CC6.1 - Protects Encryption Keys | Processes are in place to protect encryption keys during generation, storage, use, and destruction. | Teleport acts as a Certificate Authority to issue SSH and x509 user certificates that are signed by the CA and are (by default) short-lived. SSH host certificates are also signed by the CA and rotated automatically | | CC6.2 - Controls Access Credentials to Protected Assets | Information asset access credentials are created based on an authorization from the system's asset owner or authorized custodian. | [Request Approval from the command line](../../reference/cli.mdx#tctl-request-approve)

[Build Approval Workflows with Access Requests](../../access-controls/access-requests.mdx)

[Use Plugins to send approvals to tools like Slack or Jira](../../access-controls/access-requests.mdx) | diff --git a/docs/pages/access-controls/device-trust.mdx b/docs/pages/access-controls/device-trust.mdx new file mode 100644 index 0000000000000..7bffc3c6c8c3a --- /dev/null +++ b/docs/pages/access-controls/device-trust.mdx @@ -0,0 +1,31 @@ +--- +title: Device Trust (Preview) +description: Use and enforce trusted devices with Teleport +layout: tocless-doc +--- + + +Device Trust is currently in Preview mode. + + +Device Trust allows Teleport admins to enforce the use of trusted devices. +Resources protected by the device mode "required" will enforce the use of a +trusted device, in addition to establishing the user's identity and enforcing +the necessary roles. Furthermore, users using a trusted device leave audit +trails that include the device's information. + +The device trust preview works on macOS and Windows devices and supports the +following Teleport features: + +- SSH access enforcement +- Database access enforcement +- Kubernetes access enforcement + +Support for other operating systems and access features is planned for upcoming +Teleport versions. + +## Guides + +- [Set Up Device Trust](./device-trust/guide.mdx) +- [Set Up Auto-Enrollment](./device-trust/auto-enrollment.mdx) +- [Jamf Integration](./device-trust/jamf-integration.mdx) diff --git a/docs/pages/access-controls/device-trust/auto-enrollment.mdx b/docs/pages/access-controls/device-trust/auto-enrollment.mdx new file mode 100644 index 0000000000000..13fbdd107a9f3 --- /dev/null +++ b/docs/pages/access-controls/device-trust/auto-enrollment.mdx @@ -0,0 +1,88 @@ +--- +title: Set Up Auto-Enrollment (Preview) +description: Set Up Automatic Enrollment for Registered Devices +--- + +Auto-enrollment allows `tsh` to automatically enroll devices already registered +in Teleport during the user's login. The registration may be +[manual](./guide.mdx#step-12-register-a-trusted-device) or performed using an +integration, like the [Jamf integration](./jamf-integration.mdx). + + +Device Trust is currently in Preview mode. + + +## Prerequisites + +(!docs/pages/includes/commercial-prereqs-tabs.mdx!) + +(!docs/pages/includes/device-trust/prereqs.mdx!) + +- [A previously-registered device]( + ./guide.mdx#step-12-register-a-trusted-device) is necessary for + auto-enrollment to take place. + +## Step 1/2. Enable auto-enrollment + +Enable auto-enrollment in your cluster settings: + + + +Modify the dynamic config resource using `tctl edit cluster_auth_preference`: + +```diff +kind: cluster_auth_preference +version: v2 +metadata: + name: cluster-auth-preference +spec: + # ... + device_trust: + mode: "required" ++ auto_enroll: true +``` + + + +Edit the Auth Server's `teleport.yaml` file: + +```diff +auth_service: + authentication: + # ... + device_trust: ++ auto_enroll: true +``` + +After saving the changes, restart the Teleport service. + + + + +## Step 2/2. Login using a registered device + +Using a device previously registered in Teleport, logout and login again: + +```code +$ tsh logout +$ tsh login --proxy=teleport.example.com --user=alice +All users logged out. +Enter password for Teleport user alice: +Tap any security key +Detected security key tap +> Profile URL: https://teleport.example.com:443 + Logged in as: alice + Cluster: teleport.example.com + Roles: access, editor + Logins: alice + Kubernetes: enabled + Valid until: 2023-06-23 02:47:05 -0300 -03 [valid for 12h0m0s] + Extensions: teleport-device-asset-tag, teleport-device-credential-id, teleport-device-id +``` + +The presence of the **teleport-device-\*** extensions shows that the device was +successfully enrolled and authenticated. + +## Troubleshooting + +(!docs/pages/includes/device-trust/auto-enroll-troubleshooting.mdx!) diff --git a/docs/pages/access-controls/guides/device-trust.mdx b/docs/pages/access-controls/device-trust/guide.mdx similarity index 58% rename from docs/pages/access-controls/guides/device-trust.mdx rename to docs/pages/access-controls/device-trust/guide.mdx index d4e30b2250c81..6f399b50a69ce 100644 --- a/docs/pages/access-controls/guides/device-trust.mdx +++ b/docs/pages/access-controls/device-trust/guide.mdx @@ -1,36 +1,27 @@ --- -title: "Device Trust (Preview)" +title: Set Up Device Trust (Preview) description: Learn how to use and enforce trusted devices with Teleport videoBanner: gBQyj_X1LVw --- Device Trust is currently in Preview mode. - -Device Trust requires Teleport Enterprise v12+. -Device Trust allows Teleport admins to enforce the use of trusted devices. -Resources protected by the device mode "required" will enforce the use of a -trusted device, in addition to establishing the user's identity and enforcing -the necessary roles. Furthermore, users using a trusted device leave audit -trails that include the device's information. - -The device trust preview works only with macOS devices and supports the -following Teleport features: - -- SSH access enforcement -- Database access enforcement -- Kubernetes access enforcement +## Concepts -Support for other operating systems and access features is planned for upcoming -Teleport versions. +Device Trust leverages dedicated secure hardware in devices to store sensitive +credentials. The specific implementation varies between types of devices. -## Concepts +On macOS devices, Device Trust uses the Secure Enclave in order to store a +device private key. That key is used to solve device challenges issued by the +Teleport Auth Server, proving the identity of the trusted device. -Device Trust uses the Secure Enclave in macOS devices to store a device private -key. That key is used to solve device challenges issued by the Teleport Auth -Server, proving the identity of the trusted device. +On Windows devices, a Trusted Platform Module (TPM) is used to perform an +attestation as to the state of the device. This attestation is signed by a +private key that is also protected by the TPM. The signed attestation ensures +that the Teleport Auth Server knows both the state of the device and that the +request has come from the device. Device management is divided into two separate phases: inventory management and device enrollment. @@ -63,9 +54,7 @@ layer of protection. (!docs/pages/includes/commercial-prereqs-tabs.mdx!) -- A signed and notarized `tsh` binary for enrollment. - [Download the macOS tsh installer](../../installation.mdx#macos). -- A macOS device to register and enroll. +(!docs/pages/includes/device-trust/prereqs.mdx!) ## Step 1/2. Register a trusted device @@ -115,39 +104,64 @@ demonstrated in the following section. Make sure your user has the `device-admin` role: -```code -$ tctl edit users/alice -``` - -```diff -kind: user -metadata: - name: alice - # unrelated fields omitted. -spec: - roles: - - access -+ - device-admin # add this line -version: v2 -``` +(!/docs/pages/includes/add-role-to-user.mdx role="device-admin"!) Relogin to fetch updated certificates: ```code -$ tsh logout; tsh login --proxy=example.com --user=alice +$ tsh logout; tsh login --proxy=teleport.example.com --user=alice ``` -Having the necessary permissions, let's add a device to the inventory. Replace -the `$SERIAL` below with your macOS device serial number (visible under Apple -> -"About This Mac" -> "Serial number", or use the command below). +Before you can enroll the device, you need to register it. To register +a device, you first need to determine its serial number. + + + + The serial number of a macOS device can be determined in two ways. + + Through the UI, visible under Apple -> "About This Mac" -> "Serial number". + + Through the terminal: + ```code + $ ioreg -c IOPlatformExpertDevice -d 2 | grep -i IOPlatformSerialNumber | awk -F'"' '{print $4}' + (=devicetrust.asset_tag=) + ``` + + + + Determining the serial number for a device running Windows is a little more + complicated than on macOS. This is because Windows devices can have multiple + serial numbers depending on the configuration made by the manufacturer. + + Teleport will pick the first available value from the following: + + - System asset tag + - System serial number + - Baseboard serial number + + To find the value chosen by Teleport, run the following command: + + ```code + $ tsh device collect + DeviceCollectedData { + ... + "serial_number": "(=devicetrust.asset_tag=)", + ... + } + ``` + + + +Replace +with the serial number obtained from the device you wish to enroll and +with `macos` or `windows`, and execute the following command: ```code -$ SERIAL="$(ioreg -c IOPlatformExpertDevice -d 2 | grep -i IOPlatformSerialNumber | awk -F'"' '{print $4}')" -$ tctl devices add --os=macos --asset-tag="$SERIAL" -Device (=devicetrust.asset_tag=)/macOS added to the inventory +$ tctl devices add --os=" --asset-tag=" +Device / added to the inventory ``` -View registered devices: +Use `tctl` to check that the device has been registered: ```code $ tctl devices ls @@ -156,9 +170,6 @@ Asset Tag OS Enroll Status Device ID (=devicetrust.asset_tag=) macOS not enrolled (=devicetrust.device_id=) ``` -A registered device is a device that Teleport knows about. Once a registered -device is enrolled, it becomes a trusted device. - A device that is no longer in use may be removed using `tctl devices rm --device-id=` or `tctl devices rm --asset-tag=`. @@ -170,8 +181,9 @@ A registered device becomes a trusted device after it goes through the enrollment ceremony. Enrollment exchanges an enrollment token, created by a device admin, for the opportunity to enroll the corresponding device. -macOS enrollments are tied to the current user in the device. If the same device -is handed to a new user, they will need to perform enrollment again. +A device enrollment is specifically linked to the user who performed the +enrollment. If the same device is handed to a new user, that user must enroll +the device again. To create an enrollment token run the following command, where `--asset-tag` is the serial number of the device we want to enroll. @@ -189,11 +201,95 @@ command printed by `tctl devices enroll`: $ tsh device enroll --token=(=devicetrust.enroll_token=) Device "(=devicetrust.asset_tag=)"/macOS enrolled -$ tsh logout; tsh login --proxy=example.com --user=alice # fetch new certificates +$ tsh logout +$ tsh login --proxy=teleport.example.com --user=alice # fetch new certificates ``` + +On Windows, the `tsh device enroll` command attempts to elevate to +administrator privileges on the device. Privilege elevation is required to +perform a TPM Credential Activation. This step is only required for +enrollment and is not required on future device authentications. + + The device above is now a trusted device. +## Recommended: Configuring a TPM EKCert CA allow-list + +This advice only applies to Device Trust on platforms that use TPMs. For now, +this is just Windows. + +Some TPMs include a certificate—known as an EKCert—signed by the +manufacturer's certificate authority (CA). This certificate allows a third party +(such a Teleport cluster) to know that the TPM it is communicating with is +legitimate. This significantly reduces the burden on the administrator to ensure +that the device has not been tampered with prior to enrollment. + +By default, the Teleport cluster does not verify the EKCert. This is because +not all TPMs include an EKCert, and it is not possible to verify an EKCert +without knowledge of the manufacturer's CA. This verification is enabled by the +inclusion of the Teleport configuration field called `ekcert_allowed_cas`. + +Once configured, only devices that include a TPM with an EKCert signed by a +CA specified in the field will be able to enroll. Previously-enrolled devices +will not be affected. + +To configure `ekcert_allowed_cas`, you must first obtain the CA certificate in +PEM format from the manufacturer of the TPM included in your devices. This step +varies from manufacturer to manufacturer. + +After you obtain the CA certificate in PEM format, there are two ways of +configuring `ekcert_allowed_cas`: + +- Statically using the Teleport configuration file. This is the simplest + option, but is not possible for Teleport Cloud clusters and not recommended + for clusters in a highly available configuration. +- Dynamically using `cluster_auth_preference` resource. This works with all + clusters and is the most flexible. + + + +Modify the dynamic config resource using `tctl edit cluster_auth_preference`: + +```diff +kind: cluster_auth_preference +version: v2 +metadata: + name: cluster-auth-preference +spec: + ... + device_trust: + mode: "required" # add this line ++ ekcert_allowed_cas: ++ # The CA is configured inline within the resource: ++ - | ++ -----BEGIN CERTIFICATE----- ++ --snip-- ++ -----END CERTIFICATE----- +``` + + + +Edit the Auth Server's `teleport.yaml` file and restart: + +```diff +auth_service: + authentication: + ... + device_trust: ++ ekcert_allowed_cas: ++ # The CA can be configured inline within the configuration file: ++ - | ++ -----BEGIN CERTIFICATE----- ++ --snip-- ++ -----END CERTIFICATE----- ++ # Or, it can be configured in the configuration file using a path: ++ - /path/to/my/ekcert-ca.pem +``` + + + + ## Optional: Cluster-wide trusted device enforcement Cluster-wide configuration enforces trusted device access at the cluster level. @@ -202,8 +298,8 @@ by the `device_trust.mode` authentication setting: - `off` - disables device trust. Device authentication is not performed and device-aware audit logs are absent. -- `optional` - enables device authentication and device-aware audit, but does not - require a trusted device to access resources. +- `optional` - enables device authentication and device-aware audit, but does + not require a trusted device to access resources. - `required` - enables device authentication and device-aware audit. Additionally, it requires a trusted device for all SSH, Database and Kubernetes connections. @@ -234,7 +330,7 @@ spec: type: local second_factor: "on" webauthn: - rp_id: example.com + rp_id: teleport.example.com device_trust: + mode: "required" # add this line ``` @@ -262,7 +358,7 @@ auth_service: type: local second_factor: "on" webauthn: - rp_id: example.com + rp_id: teleport.example.com device_trust: + mode: "required" # add this line ``` @@ -292,9 +388,10 @@ leaf clusters. Role-based configuration enforces trusted device access at the role level. It can be configured with the `spec.options.device_trust_mode` (`required`, `optional`, `off`) option and applies to the resources in its `allow` rules. It -works similar to [`require_session_mfa`](./per-session-mfa.mdx). +works similar to [`require_session_mfa`](../guides/per-session-mfa.mdx). -To enforce authenticated device checks for a specific role, update the role with the following: +To enforce authenticated device checks for a specific role, update the role with +the following: ```diff kind: role @@ -325,8 +422,8 @@ trusted device. ## Optional: Locking a device -Similar to [session and identity locking](./locking.mdx), a device can be locked -using `tctl lock`. +Similar to [session and identity locking](../guides/locking.mdx), a device can +be locked using `tctl lock`. Locking blocks certificate issuance and ongoing or future accesses originating from a locked device. Locking a device only works if device trust is enabled and @@ -348,28 +445,18 @@ $ tctl lock --device (=devicetrust.device_id=) --ttl=12h Created a lock with name "5444970a-39a0-4814-968d-e58b4a8fa686". ``` -Now, if a user on that device tries to access an SSH server for example, Teleport will deny access: +Now, if a user on that device tries to access an SSH server for example, +Teleport will deny access: ```code $ tsh ssh server1 ERROR: ssh: rejected: administratively prohibited (lock targeting Device:"(=devicetrust.device_id=)" is in force) ``` -## Troubleshooting +## Optional: Enable auto-enrollment -### "binary missing signature or entitlements" on `tsh device enroll` +Refer to the [auto-enrollment guide](./auto-enrollment.mdx). -A signed and notarized `tsh` binary is necessary to enroll and use a a trusted -device. [Download the macOS tsh installer](../../installation.mdx#macos) to fix -the problem. - -### "unauthorized device" errors using a trusted device - -A signed and notarized `tsh` binary is necessary to use a trusted device. Make -sure to download and use the -[macOS tsh installer](../../installation.mdx#macos). +## Troubleshooting -A trusted device needs to be registered and enrolled before it is recognized by -Teleport as such. Follow the [registration](#step-12-register-a-trusted-device) -and [enrollment steps](#step-22-enroll-a-trusted-device) and make sure to `tsh -logout` and `tsh login` after enrollment is done. +(!docs/pages/includes/device-trust/auto-enroll-troubleshooting.mdx!) diff --git a/docs/pages/access-controls/device-trust/jamf-integration.mdx b/docs/pages/access-controls/device-trust/jamf-integration.mdx new file mode 100644 index 0000000000000..34533a9815bab --- /dev/null +++ b/docs/pages/access-controls/device-trust/jamf-integration.mdx @@ -0,0 +1,303 @@ +--- +title: Jamf Integration (Preview) +description: Sync your Jamf inventory into Teleport +--- + +Device Trust Jamf integration lets you automatically sync your Jamf computer +inventory into Teleport. + +The Teleport Jamf service is a distinct `teleport` process that periodically +reads your computer inventory from Jamf and syncs it to Teleport. It performs +both incremental (called "partial") and full syncs, as well as removals from +Teleport if a computer is removed from Jamf. + +Syncing devices from Jamf is an **inventory management** step, equivalent to +automatically running the corresponding `tctl devices add` commands. If you want +to automatically enroll synced devices on user login, refer to the +[auto-enrollment](#optional-enable-auto-enrollment) section. + +See the [Device Trust guide](./guide.mdx) for fundamental Device Trust concepts +and behavior. + +## Prerequisites + +(!docs/pages/includes/commercial-prereqs-tabs.mdx!) + +(!docs/pages/includes/device-trust/prereqs.mdx!) + +## Step 1/4. Create a Jamf user + +Create a readonly Jamf user for inventory sync. + +1. Access `https://yourtenant.jamfcloud.com/accounts.html`, replacing + `yourtenant` with your Jamf Pro account. + +2. Create a new Standard Account with the following settings: + + - Username: teleport (change as desired) + - Access Level: Full Access + - Privilege Set: Custom + - Access Status: Enabled + - Password: (a strong password of your choice) + - Privileges: + - Advanced Computer Searches: Read + - Computers: Read + + Take note of the user and password created here for the next step. + + User account setup: ![Jamf user setup]( + ../../../img/access-controls/device-trust/jamf-setup-1.png) + + Privileges setup: ![Jamf privileges setup]( + ../../../img/access-controls/device-trust/jamf-setup-2.png) + +## Step 2/4. Configure Jamf service + +Jamf inventory sync is performed by a separate `teleport` process, configured +using the `jamf_service` key. It is recommended to run the service isolated from +other Teleport processes, as it requires the Jamf credentials created in the +step above. + +Save the following file as `/var/lib/teleport.yaml` and edit as needed: + +```yaml +version: v3 +teleport: + # Necessary to write devices back to Teleport. + proxy_server: teleport.example.com:443 # CHANGEME + +jamf_service: + enabled: true + name: jamf + api_endpoint: https://yourtenant.jamfcloud.com # CHANGEME + username: teleport # CHANGEME + password_file: /var/lib/teleport/jamf_password.txt + +auth_service: + enabled: false + +proxy_service: + enabled: false + +ssh_service: + enabled: false +``` + +Change the following settings, as appropriate: + +- teleport.proxy_server +- jamf_service.api_endpoint +- jamf_service.username + +Finally, write your Jamf password to the `/var/lib/teleport/jamf_password` file: + +```code +$ nano /var/lib/teleport/jamf_password # or use your favorite editor + +# Only the OS user that runs `teleport` should have access to the password file. +$ chmod 400 /var/lib/teleport/jamf_password +$ chown teleport /var/lib/teleport/jamf_password +``` + +## Step 3/4. Create a join token + +Jamf service requires an MDM token to write devices to Teleport. +On your local workstation, create the token as shown below: + +```code +$ tctl tokens add --type=mdm +The invite token: 07c0565aa280595d7645b2964c36ebd1 +This token will expire in 30 minutes. + +From the Jamf service host, use this token to add an MDM service to Teleport. + +> teleport start \ + --token=(=presets.tokens.second=) \ + --ca-pin=(=presets.ca_pin=)\ + --config=/path/to/teleport.yaml +``` + +## Step 4/4. Start Jamf service + +Using the token created above, start the service: + +```code +$ teleport start --config=/var/lib/teleport.yaml \ + --token=07c0565aa280595d7645b2964c36ebd1 \ + --ca-pin=sha256:4b32d9c54b2b3332019d5f0720b8f9a603de03ace07d308bcd743465eee1f200 +``` + +The initial sync should happen in a few minutes. You can confirm from the Teleport service logs: + +``` +2023-06-21T17:26:40-03:00 INFO [JAMF:1] Jamf service successfully started pid:25757.1 service/service.go:228 +2023-06-21T17:26:40-03:00 INFO [JAMF:1] Starting sync CutTime:0001-01-01 00:00:00 +0000 UTC FilterRSQL: Mode:1 OnMissing:DELETE pid:25757.1 service/service.go:261 +2023-06-21T17:26:40-03:00 INFO [JAMF:1] Device sync report, page #0 deletes:0 failures:0 pid:25757.1 upserts:1 service/service.go:666 +2023-06-21T17:26:40-03:00 INFO [JAMF:1] Sync complete pid:25757.1 service/service.go:277 +``` + +Using the default configuration, the service will sync devices from Jamf every +few hours. Once a day a full inventory sync is performed, enumerating all +devices from Jamf and reflecting any additions or removals on Teleport. + +After the initial sync happens, you may verify the synced devices using `tctl +devices ls`: + +```code +$ tctl devices ls +Asset Tag OS Enroll Status Device ID +------------ ------- ------------- ------------------------------------ +CXXXXXXXXX17 macOS not enrolled 20ec6373-9e8e-46e0-8f1c-47ad6b06a768 +CXXXXXXXXX2T macOS not enrolled 79755778-7cbe-4e2c-83ec-7eaa3d4d7e36 +CXXXXXXXXX3T macOS not enrolled 665e59d5-393a-4894-841d-edad06329717 +CXXXXXXXXX4T macOS not enrolled dd032e90-bfb0-47d5-bce5-e57545f6788f +CXXXXXXXXX5T macOS not enrolled bf189863-a94a-40dc-9013-d96f8dada2f1 +(...) +``` + +## Optional: Customize the sync schedule + +When using the minimal configuration, described in the steps above, Jamf service +utilizes a default sync schedule. It is possible to customize sync intervals, as +well as the set of devices synced from Jamf, by applying RSQL filters provided +by the [Jamf Pro API]( +https://developer.jamf.com/jamf-pro/reference/get_v1-computers-inventory). + +The default "inventory" configuration is roughly equivalent to the one below: + +```yaml +jamf_service: + enabled: true + # ... + inventory: + - sync_period_partial: 6h + sync_period_full: 24h + on_missing: DELETE + filter_rsql: general.remoteManagement.managed==true +``` + +Unpacking the configuration, we have the following keys: + +### `sync_period_*` + +- `sync_period_partial`: period for partial syncs. A partial sync attempts to + fetch new and modified devices, but won't scan the entire Jamf inventory. +- `sync_period_full`: period for full syncs. A full sync scans the entire Jamf + inventory, processing new/modified devices and removals from Jamf. + +Both sync periods may be disabled by setting the period to `0` or `-1`. It is +recommended to do a full sync with some regularity, so Teleport has the chance +to fully synchronize both inventories. + +### `on_missing` + +The `on_missing` key determines what to do with devices deleted from Jamf, but +present in Teleport. The possible actions are: + +- `DELETE`: devices removed from Jamf are eventually removed from Teleport. + (Requires a full sync.) +- `NOOP`: devices removed from Jamf are allowed to remain in the Teleport + inventory. + +Only devices synced by Jamf are susceptible to deletion in this manner. Devices +written manually via `tctl devices add` or written by other sources won't be +deleted. + +For immediate removal of unwanted devices first lock the device on Teleport, +then remove it from Jamf: + +```code +$ tctl devices lock --asset-tag=SERIAL_NUMBER --message='reason for locking' +Created a lock with name "a2f1491c-4a3e-4daf-9c83-2fe931668076". +``` + +Manual removal via `tctl devices rm` is possible, but note that if the device is +still in the Jamf inventory, it'll be recreated during the next sync. + +### `filter_rsql` + +The `filter_rsql` key applies a Jamf Pro API filter when querying for devices. +Refer to +https://developer.jamf.com/jamf-pro/reference/get_v1-computers-inventory for the +possible filter values. + +## Optional: Sync multiple sources + +When syncing inventory, Jamf service claims ownership of all synced devices. +This can be verified by inspecting a device's `source` field: + +```yaml +# tctl get device/mydevice +kind: device +metadata: + name: 20ec6373-9e8e-46e0-8f1c-47ad6b06a768 +spec: + asset_tag: mydevice + os_type: macos + # ... + source: # Set during inventory sync + name: jamf # Copied from jamf_service.name + origin: jamf # Always "jamf" for Jamf service + update_time: "2023-06-21T19:44:40.40601Z" +version: v1 +``` + +Device ownership is important in a few situations, but it is particularly +important when running "on\_missing=DELETE" syncs, as only the devices owned by +the sync source are considered for deletion. + +If you want to run multiple Jamf sources you can simply run multiple Jamf +services, each with its configuration and credentials. Just make sure that each +service has a different "jamf\_service.name". For example: + +`teleport.yaml` - Service #1: + +```diff +version: v3 +teleport: + proxy_server: teleport.example.com:443 + +jamf_service: + enabled: true ++ name: jamf1 ++ api_endpoint: https://tenant1.jamfcloud.com ++ username: tenant1 ++ password_file: /var/lib/teleport/jamf1_password.txt + +auth_service: + enabled: false + +proxy_service: + enabled: false + +ssh_service: + enabled: false +``` + +`teleport.yaml` - Service #2: + +```diff +version: v3 +teleport: + proxy_server: teleport.example.com:443 + +jamf_service: + enabled: true ++ name: jamf2 ++ api_endpoint: https://tenant2.jamfcloud.com ++ username: tenant2 ++ password_file: /var/lib/teleport/jamf2_password.txt + +auth_service: + enabled: false + +proxy_service: + enabled: false + +ssh_service: + enabled: false +``` + +## Optional: Enable auto-enrollment + +Refer to the [auto-enrollment guide](./auto-enrollment.mdx). diff --git a/docs/pages/access-controls/getting-started.mdx b/docs/pages/access-controls/getting-started.mdx index 0e308d1cb921e..28aca2be7ab8f 100644 --- a/docs/pages/access-controls/getting-started.mdx +++ b/docs/pages/access-controls/getting-started.mdx @@ -20,19 +20,38 @@ wrap up with creating your own role. ## Step 1/3. Add local users with preset roles -Teleport provides several preset roles: `editor`, `auditor` and `access`. The -`editor` role authorizes users to modify cluster configuration, the `auditor` -role to view audit logs, and `access` role to access cluster resources. +Teleport provides several preset roles: `editor`, `auditor`, and `access`. +- The `editor` role authorizes users to modify cluster configuration. +- The `auditor` role authorizes users to view audit logs. +- The `access` role authorizes users to access cluster resources. + +
+Teleport Enterprise contains two additional preset roles: `reviewer` and `requester`. + +- The `reviewer` role authorizes users to review Access Requests. +- The `requester` role authorizes users to request resources. +
+ + Invite the local user Alice as cluster `editor`: ```code $ tctl users add alice --roles=editor ``` + + +Invite the local user Alice as cluster `editor` and `reviewer`: + +```code +$ tctl users add alice --roles=editor,reviewer +``` + Once Alice signs up, she will be able to edit cluster configuration. You can list users and their roles using `tctl users ls`. + ```code $ tctl users ls @@ -40,15 +59,33 @@ $ tctl users ls # -------------------- -------------- # alice editor ``` + + +```code +$ tctl users ls + +# User Roles +# -------------------- -------------- +# alice editor, reviewer +``` + You can update the user's roles using the `tctl users update` command: + ```code # Once Alice logs back in, she will be able to view audit logs $ tctl users update alice --set-roles=editor,auditor ``` + + +```code +# Once Alice logs back in, she will be able to view audit logs +$ tctl users update alice --set-roles=editor,reviewer,auditor +``` + -Because Alice has two roles, permissions from those roles create a union. She +Because Alice has two or more roles, permissions from those roles create a union. She will be able to act as a system administrator and auditor at the same time. ## Step 2/3. Map SSO users to roles diff --git a/docs/pages/access-controls/guides/dual-authz.mdx b/docs/pages/access-controls/guides/dual-authz.mdx index 59f0bcdabb849..8ce47c6a3fc13 100644 --- a/docs/pages/access-controls/guides/dual-authz.mdx +++ b/docs/pages/access-controls/guides/dual-authz.mdx @@ -117,13 +117,13 @@ Alice and Ivan are reviewers. They can approve requests for assuming role `dbadmin`. Bob is a DevOps engineer and can assume the `dbadmin` role if two members of the `reviewer` role approve the request. -Create the following `dbadmin`, `reviewer` and `devops` roles: +Create the following `dbadmin`, `dbreviewer` and `devops` roles: ```yaml kind: role version: v5 metadata: - name: reviewer + name: dbreviewer spec: allow: review_requests: @@ -157,8 +157,8 @@ The commands below create the local users Bob, Alice, and Ivan. ```code $ tctl users add bob@example.com --roles=devops -$ tctl users add alice@example.com --roles=reviewer -$ tctl users add ivan@example.com --roles=reviewer +$ tctl users add alice@example.com --roles=dbreviewer +$ tctl users add ivan@example.com --roles=dbreviewer ``` ### Create an Access Request diff --git a/docs/pages/access-controls/guides/hardware-key-support.mdx b/docs/pages/access-controls/guides/hardware-key-support.mdx index 8adc155a72e43..17b73a8a1f945 100644 --- a/docs/pages/access-controls/guides/hardware-key-support.mdx +++ b/docs/pages/access-controls/guides/hardware-key-support.mdx @@ -111,7 +111,7 @@ Once hardware key support is enforced, affected users will be required to have t These users will be prompted to connect and touch their YubiKey on log in: - + ```code $ tsh login --user=dev --proxy=proxy.example.com:3080 @@ -129,6 +129,24 @@ $ tsh login --user=dev --proxy=proxy.example.com:3080 + + +```code +$ tsh login --user=dev --proxy=proxy.example.com:3080 +# Enter password for Teleport user dev: +# Tap your YubiKey +# > Profile URL: https://example.com +# Logged in as: dev +# Cluster: example.com +# Roles: access, editor, reviewer +# Logins: bjoerger +# Kubernetes: enabled +# Valid until: 2022-10-11 01:53:44 -0700 PDT [valid for 8h0m0s] +# Extensions: permit-X11-forwarding, permit-agent-forwarding, permit-port-forwarding, permit-pty, private-key-policy +``` + + + ```code @@ -138,7 +156,7 @@ $ tsh login --proxy=mytenant.teleport.sh # > Profile URL: https://example.com # Logged in as: dev # Cluster: example.com -# Roles: access, editor +# Roles: access, editor, reviewer # Logins: bjoerger # Kubernetes: enabled # Valid until: 2022-10-11 01:53:44 -0700 PDT [valid for 8h0m0s] diff --git a/docs/pages/access-controls/guides/headless.mdx b/docs/pages/access-controls/guides/headless.mdx index 1916b2e8b5460..3fd5b30440350 100644 --- a/docs/pages/access-controls/guides/headless.mdx +++ b/docs/pages/access-controls/guides/headless.mdx @@ -32,8 +32,9 @@ For example: - A v12.2+ Teleport cluster with WebAuthn configured. See the [Second Factor: WebAuthn](./webauthn.mdx) guide. - WebAuthn hardware device, such as YubiKey. -- A Web browser with [WebAuthn support]( - https://developers.yubico.com/WebAuthn/WebAuthn_Browser_Support/). +- Machines for Headless WebAuthn activities have [Linux](../../installation.mdx#linux), [macOS](../../installation.mdx#macos) or [Windows](../../installation.mdx#windows-tsh-client-only) `tsh` binary v12.2+ installed. +- Machines used to approve Headless WebAuthn requests have a Web browser with [WebAuthn support]( + https://developers.yubico.com/WebAuthn/WebAuthn_Browser_Support/) or `tsh` binary v12.2+ installed. ## Step 1/3. Configuration @@ -102,6 +103,14 @@ $ tctl create -f cap.yaml ## Step 2/3. Initiate Headless WebAuthn +First open a terminal on the remote machine and confirm the `tsh` binary +is v12.2+ with `tsh version`. + +```code +$ tsh version +Teleport v(=teleport.version=) git: go(=teleport.golang=) +``` + Run a headless `tsh` command with the `--headless` flag. This will initiate headless authentication, printing a URL and `tsh` command. @@ -127,6 +136,7 @@ Unlike a standard login session, headless sessions are only available for the lifetime of a single `tsh` request. This means that for each `tsh --headless` command, you will need to go through the Headless WebAuthn flow: +### Example: Listing SSH servers ```code $ tsh ls --headless --proxy=proxy.example.com --user=alice # Complete headless authentication in your local web browser: @@ -140,8 +150,11 @@ $ tsh ls --headless --proxy=proxy.example.com --user=alice # Node Name Address Labels # --------- -------------- ----------- # server01 127.0.0.1:3022 arch=x86_64 -# -$ tsh ssh --headless --proxy=proxy.example.com --user=alice server01 +``` + +### Example: Initiating an SSH session +```code +$ tsh ssh --headless --proxy=proxy.example.com --user=alice alice@server01 # Complete headless authentication in your local web browser: # # https://proxy.example.com:3080/web/headless/864cccd9-2425-46d9-a9f2-636387e66ebf @@ -149,9 +162,23 @@ $ tsh ssh --headless --proxy=proxy.example.com --user=alice server01 # or execute this command in your local terminal: # # tsh headless approve --user=alice --proxy=proxy.example.com 864cccd9-2425-46d9-a9f2-636387e66ebf -# # User approves through link +# # User approves through link and a ssh terminal starts +alice@server01 $ ``` + + The Teleport user, `--user` parameter, is the Teleport user requesting Headless WebAuthn activity. + If no `--user` parameter or environment variables set the OS user in the machine terminal is used. + + The login username, `--login` parameter or login@hostname, for `tsh ssh` commands is the user + to open a SSH session as. If no login username for the SSH session is set the OS terminal username is used. + A Teleport user must have access to that login user for that server or they will receive + an access denied message. The user could receive an access denied message after being approved + for their Headless WebAuthn activity since the same access rights are granted or denied as if running from + your local terminal. + + + ## Troubleshooting ### "WARN: Failed to lock system memory for headless login: ..." @@ -183,4 +210,4 @@ for the best level of security on shared machines. If the above solutions are not feasible in your environment, you can also disable the memory locking requirement by setting the `--mlock` flag or `TELEPORT_MLOCK_MODE` environment variable to `off` or `best_effort`. This is not recommended in production -environments on shared systems where a memory swap attack is possible. \ No newline at end of file +environments on shared systems where a memory swap attack is possible. diff --git a/docs/pages/access-controls/guides/locking.mdx b/docs/pages/access-controls/guides/locking.mdx index a9e701207d02f..e51edd869103e 100644 --- a/docs/pages/access-controls/guides/locking.mdx +++ b/docs/pages/access-controls/guides/locking.mdx @@ -1,6 +1,6 @@ --- title: Session and Identity Locking -description: How to lock compromised users or nodes +description: How to lock compromised users or agents ---
-System administrators can disable a compromised user or node—or +System administrators can disable a compromised user or Teleport agent—or prevent access during cluster maintenance—by placing a lock on a session, user or host identity. @@ -27,10 +27,11 @@ A lock can target the following objects or attributes: - a Teleport user by the user's name - a Teleport [RBAC](../reference.mdx) role by the role's name -- a Teleport [trusted device](device-trust.mdx#optional-locking-a-device) by the device ID +- a Teleport [trusted device]( + ../device-trust/guide.mdx#optional-locking-a-device) by the device ID - an MFA device by the device's UUID - an OS/UNIX login -- a Teleport Node by the Node's UUID (effectively unregistering it from the +- a Teleport agent by the agent's server UUID (effectively unregistering it from the cluster) - a Windows desktop by the desktop's name - an [Access Request](../access-requests.mdx) by UUID @@ -74,10 +75,10 @@ with one of the following options: # Created a lock with name "d6c06a18-e147-4232-9dfe-6f83a28d5850". ``` - - All connections to the specified node will be locked. + + All connections to the specified agent will be locked and the agent will be excluded from the Teleport cluster. ```code - $ tctl lock --node=363256df-f78a-4d99-803c-bae19da9ede4 --message="The node is under investigation." --ttl=10h + $ tctl lock --server-id=363256df-f78a-4d99-803c-bae19da9ede4 --message="The server running the Kubernetes Service and Database Service is under investigation." --ttl=10h # Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1". ``` diff --git a/docs/pages/access-controls/guides/passwordless.mdx b/docs/pages/access-controls/guides/passwordless.mdx index b365b4e6c40f7..d484ee6d3e84a 100644 --- a/docs/pages/access-controls/guides/passwordless.mdx +++ b/docs/pages/access-controls/guides/passwordless.mdx @@ -69,6 +69,7 @@ between `tsh`, the Teleport Web UI, and different computers. Authenticate using your passwordless credential: + ```code $ tsh login --proxy=example.com --auth=passwordless # Tap your security key @@ -81,6 +82,21 @@ $ tsh login --proxy=example.com --auth=passwordless # Valid until: 2021-10-04 23:32:29 -0700 PDT [valid for 12h0m0s] # Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty ``` + + +```code +$ tsh login --proxy=example.com --auth=passwordless +# Tap your security key +# > Profile URL: https://example.com +# Logged in as: codingllama +# Cluster: example.com +# Roles: access, editor, reviewer +# Logins: codingllama +# Kubernetes: enabled +# Valid until: 2021-10-04 23:32:29 -0700 PDT [valid for 12h0m0s] +# Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty +``` + A fully passwordless cluster defaults to passwordless logins, making `--auth=passwordless` unnecessary. See the next section to learn how to enable diff --git a/docs/pages/access-controls/guides/role-templates.mdx b/docs/pages/access-controls/guides/role-templates.mdx index 9fb7ff07dfde3..999e6a7fc5d88 100644 --- a/docs/pages/access-controls/guides/role-templates.mdx +++ b/docs/pages/access-controls/guides/role-templates.mdx @@ -332,7 +332,7 @@ spec: # Functions transform variables. database_users: ['{{email.local(external.email)}}'] - database_labels: + db_labels: 'env': '{{regexp.replace(external.access["env"], "^(staging)$", "$1")}}' # Labels can mix template and hard-coded values. @@ -372,7 +372,7 @@ spec: database_users: ['alice'] # The function regexp.replace will transform and filter only matching values. - database_labels: + db_labels: 'env': 'staging' # Node labels have 'env' replaced from a variable and 'region' hard-coded. diff --git a/docs/pages/access-controls/guides/webauthn.mdx b/docs/pages/access-controls/guides/webauthn.mdx index aa4e3822d7aa0..44966f99334d6 100644 --- a/docs/pages/access-controls/guides/webauthn.mdx +++ b/docs/pages/access-controls/guides/webauthn.mdx @@ -179,7 +179,7 @@ Reference](../../reference/cli.mdx#tsh-global-flags) page. Once a WebAuthn device is registered, the user will be prompted for it on login: - + ```code $ tsh login --proxy=example.com @@ -197,6 +197,24 @@ $ tsh login --proxy=example.com + + +```code +$ tsh login --proxy=example.com +# Enter password for Teleport user codingllama: +# Tap any security key or enter a code from a OTP device: +# > Profile URL: https://example.com +# Logged in as: codingllama +# Cluster: example.com +# Roles: access, editor, reviewer +# Logins: codingllama +# Kubernetes: enabled +# Valid until: 2021-10-04 23:32:29 -0700 PDT [valid for 12h0m0s] +# Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty +``` + + + ```code @@ -206,7 +224,7 @@ $ tsh login --proxy=mytenant.teleport.sh # > Profile URL: https://mytenant.teleport.sh # Logged in as: codingllama # Cluster: mytenant.teleport.sh -# Roles: access, editor +# Roles: access, editor, reviewer # Logins: codingllama # Kubernetes: enabled # Valid until: 2021-10-04 23:32:29 -0700 PDT [valid for 12h0m0s] diff --git a/docs/pages/access-controls/idps/saml-grafana.mdx b/docs/pages/access-controls/idps/saml-grafana.mdx index 6a1ba82e57700..249735a24b7f7 100644 --- a/docs/pages/access-controls/idps/saml-grafana.mdx +++ b/docs/pages/access-controls/idps/saml-grafana.mdx @@ -66,6 +66,8 @@ From the Grafana host, edit `grafana.ini` by adding a `[auth.saml]` section: [auth.saml] enabled = true auto_login = false +allow_idp_initiated = true +relay_state = "" private_key_path = '/path/to/certs/grafana-host-key.pem' certificate_path = '/path/to/certs/grafana-host.pem' idp_metadata = 'PEVudGl0eURl.....' @@ -75,14 +77,16 @@ assertion_attribute_email = uid assertion_attribute_groups = eduPersonAffiliation ``` -| Key | Value | -|--------------------|----------------------------------------------------------------| -| `enabled` | Set to `true` to enable SAML authentication. | -| `auto_login` | When set to `true`, enables auto-login using SAML. | -| `private_key_path` | Path to the TLS key used to identify Grafana. | -| `certificate_path` | Path to the TLS certificate used to identify Grafana. | -| `idp_metadata` | The base64-encoded contents of the Teleport metadata XML file. | -| `assertion_*` | Various Grafana user fields to be mapped to SAML assertions. | +| Key | Value | +|-----------------------|---------------------------------------------------------------------------------------| +| `enabled` | Set to `true` to enable SAML authentication. | +| `auto_login` | When set to `true`, enables auto-login using SAML. | +| `allow_idp_initiated` | Set to `true` to allow IdP-initiated login. | +| `relay_state` | Relay state for IdP-initiated login. Must be set to `""` to work with Teleport's IdP. | +| `private_key_path` | Path to the TLS key used to identify Grafana. | +| `certificate_path` | Path to the TLS certificate used to identify Grafana. | +| `idp_metadata` | The base64-encoded contents of the Teleport metadata XML file. | +| `assertion_*` | Various Grafana user fields to be mapped to SAML assertions. | For more information on editing `grafana.ini` for SAML, you can review their [Configure SAML authentication in Grafana](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/saml/) diff --git a/docs/pages/access-controls/introduction.mdx b/docs/pages/access-controls/introduction.mdx index 50c5802b14a25..3e1d53d274eab 100644 --- a/docs/pages/access-controls/introduction.mdx +++ b/docs/pages/access-controls/introduction.mdx @@ -6,7 +6,7 @@ layout: tocless-doc After [deploying a Teleport cluster](../deploy-a-cluster/introduction.mdx), the next step is to manage the access that Teleport users have to resources in your -infrastructure. +infrastructure. Teleport's role-based access control (RBAC) enables you to set fine-grained policies for who can perform certain actions against specific resources. For @@ -16,7 +16,7 @@ example: database. - Interns can't access production databases. - SREs can access a production server only when using a [trusted hardware - device](./guides/device-trust.mdx). + device](./device-trust/guide.mdx). - Members of a team can access the production Kubernetes cluster if approved by someone else from the same team. @@ -30,7 +30,7 @@ Started](./getting-started.mdx) guide. The heart of Teleport's RBAC system is the **role**, a configuration document that specifies access policies for resources in your Teleport cluster. Assigning a role to a Teleport user applies the policies listed in the role to -the user. +the user. See the [Cluster Access and RBAC](./guides.mdx) section for instructions on setting up Teleport roles. @@ -39,7 +39,7 @@ setting up Teleport roles. While you can create Teleport users directly on the Auth Service, the more scalable approach is to integrate Teleport with a Single Sign-On identity -provider (IdP), such as Okta or GitHub. +provider (IdP), such as Okta or GitHub. When a user authenticates to your Teleport cluster via your IdP, Teleport automatically assigns roles to the user based on data provided by the IdP. This diff --git a/docs/pages/access-controls/login-rules/kubernetes.mdx b/docs/pages/access-controls/login-rules/kubernetes.mdx index 16cbe2520bedd..e1405b88f795b 100644 --- a/docs/pages/access-controls/login-rules/kubernetes.mdx +++ b/docs/pages/access-controls/login-rules/kubernetes.mdx @@ -44,7 +44,7 @@ This guide is applicable if you self-host Teleport in Kubernetes using the - Follow Step 1 of the - [Teleport operator guide](../../management/guides/teleport-operator.mdx#step-13-install-teleport-cluster-helm-chart-with-the-operator) + [Teleport operator guide](../../management/dynamic-resources/teleport-operator.mdx#step-13-install-teleport-cluster-helm-chart-with-the-operator) to install the Teleport Operator in your Kubernetes cluster. Make sure to follow the Enterprise instructions. @@ -250,7 +250,7 @@ logins: ## Next Steps -- Read the [Teleport Operator Guide](../../management/guides/teleport-operator.mdx) to +- Read the [Teleport Operator Guide](../../management/dynamic-resources/teleport-operator.mdx) to learn more about the Teleport Operator. - Read the [Login Rules reference](./reference.mdx) to learn mode about the Login Rule expression syntax. diff --git a/docs/pages/access-controls/login-rules/terraform.mdx b/docs/pages/access-controls/login-rules/terraform.mdx index 913faf0a26e6a..d406714584625 100644 --- a/docs/pages/access-controls/login-rules/terraform.mdx +++ b/docs/pages/access-controls/login-rules/terraform.mdx @@ -31,7 +31,7 @@ For simplicity, this guide will configure the Terraform provider to use your current logged-in user's Teleport credentials obtained from `tsh login`. -The [Terraform provider guide](../../management/guides/terraform-provider.mdx) +The [Terraform provider guide](../../management/dynamic-resources/terraform-provider.mdx) includes instructions for configuring a dedicated `terraform` user and role, which is a better option when running Terraform in a non-interactive environment. @@ -156,7 +156,7 @@ logins: ## Next Steps -- Read the [Terraform Guide](../../management/guides/terraform-provider.mdx) to +- Read the [Terraform Guide](../../management/dynamic-resources/terraform-provider.mdx) to learn more about configuring the Terraform provider. - Read the [Login Rules reference](./reference.mdx) to learn mode about the Login Rule expression syntax. diff --git a/docs/pages/access-controls/reference.mdx b/docs/pages/access-controls/reference.mdx index 64f70654605e9..e6e556c2aec7b 100644 --- a/docs/pages/access-controls/reference.mdx +++ b/docs/pages/access-controls/reference.mdx @@ -12,7 +12,7 @@ controls (RBAC) in your Teleport cluster. A Teleport `role` works by having two lists of rules: `allow` rules and `deny` rules. When declaring access rules, keep in mind the following: -- Everything is denied by default. +- Nothing is allowed by default. - Deny rules get evaluated first and take priority. A rule consists of two parts: the resources and verbs. Here's an example of an @@ -25,10 +25,10 @@ allow: verbs: [list] ``` -If this rule was declared in the `deny` section of a role definition, it -would prohibit users from getting a list of Trusted Clusters and -sessions. You can see all of the available resources and verbs under the `allow` -section in the example role configuration below. +If this rule was declared in the `deny` section of a role definition, it would +prohibit users from getting a list of active sessions. You can see all of the +available resources and verbs under the `allow` section in the example role +configuration below. To manage cluster roles, a Teleport administrator can use the Web UI or the command line using [tctl resource commands](../reference/resources.mdx). @@ -116,7 +116,7 @@ The table below documents the behavior of each option if multiple roles are assi | `desktop_clipboard` | Allow clipboard sharing for desktop sessions | Logical "AND" i.e. evaluates to "yes" if all roles enable clipboard sharing | | `pin_source_ip` | Enable source IP pinning for SSH certificates. **Note:** IP pinning is currently in Preview mode | Logical "OR" i.e. evaluates to "yes" if at least one role requires session termination | | `cert_extensions` | Specifies extensions to be included in SSH certificates | | -| `create_host_user` | Allow users to be automatically created on a host | Logical "AND" i.e. evaluates to "yes" if all roles matching a Node enable host user creation | +| `create_host_user_mode` | Allow users to be automatically created on a host | Logical "AND" i.e. if all roles matching a server specify host user creation (`off`, `drop`, `keep`), it will evaluate to the option specified by all of the roles. If some roles specify both `drop` or `keep` it will evaluate to `keep`| ## Preset roles @@ -127,6 +127,8 @@ Teleport provides several pre-defined roles out-of-the-box: | `editor` | Allows editing of cluster configuration settings. | | `auditor`| Allows reading cluster events, audit logs, and playing back session records. | | `access`| Allows access to cluster resources. | +| `requester`| Enterprise-only role that allows a user to create Access Requests. | +| `reviewer`| Enterprise-only role that allows review of Access Requests. | ### Role versions @@ -140,7 +142,7 @@ Label | `v3` Default | `v4`, `v5` and `v6` Default `node_labels` | `[{"*": "*"}]` if the role has any logins, else `[]` | `[]` `app_labels` | `[{"*": "*"}]` | `[]` `kubernetes_labels` | `[{"*": "*"}]` | `[]` -`database_labels` | `[{"*": "*"}]` | `[]` +`db_labels` | `[{"*": "*"}]` | `[]` Role `v6` introduced a new field `kubernetes_resources` that allows fine-grained control over Kubernetes resources. See [Kubernetes RBAC](../kubernetes-access/manage-access/rbac.mdx) for more details. @@ -151,15 +153,17 @@ Label | `v3`, `v4` and `v5` Default | `v6` Default ## RBAC for resources -A Teleport role defines which resources (e.g., applications, servers, and databases) a user can have access to. -This works by [labeling resources](../management/admin/labels.mdx) and listing -allow/deny labels in a role definition. +A Teleport role defines which resources (e.g., applications, servers, and +databases) a user can access. +This works by [labeling resources](../management/admin/labels.mdx) and +configuring allow/deny labels in a role definition. Consider the following use case: The infrastructure is split into staging/production environments using labels -like `environment=production` and `environment=staging`. You can create roles -that only have access to one environment. Let's say you create an intern role with the allow rule for label `environment=staging`. +like `environment=production` and `environment=staging`. +You can create roles that only have access to one environment. +Let's say you create an intern role with the allow rule for label `environment=staging`. ### Example @@ -187,8 +191,8 @@ spec: ``` Teleport handles multiple label entries with logical "AND" operations. -As an example this entry would match to databases that have the `env: prod` label and a -`region` label of either `us-west-1` or `eu-central-1`: +As an example, this entry would match to databases that have the `env: prod` +label *and* a `region` label of either `us-west-1` or `eu-central-1`: ```yaml db_labels: @@ -200,12 +204,13 @@ As an example this entry would match to databases that have the `env: prod` labe type="tip" title="Dynamic RBAC" > - Resource labels can be dynamic, i.e. determined at runtime by an output of an executable. In this case, you can implement "permissions follow workload" + Resource labels can be dynamic, i.e. determined at runtime by an output of an executable. + In this case, you can implement "permissions follow workload" policies (eg., any server where PostgreSQL is running becomes *automatically* accessible only by the members of the "DBA" group and nobody else). -### Extended labels syntax +### Extended label matching syntax Below are a few examples for more complex filtering using various regexes. @@ -228,6 +233,65 @@ spec: 'environment': '^test|staging$' ``` +### Label expressions + + +Label expressions are available starting in Teleport version `13.1.1`. +All components of your Teleport cluster must be upgraded to version `13.1.1` +or newer before you will be able to use label expressions. +This includes the Auth Service and **all** Teleport agents. + + +Teleport roles also support matching resource labels with predicate expressions +when you need to: + +- combine logic with OR and AND operators +- perform matching on label keys +- implement negative matches + +The following example role would allow access to any nodes labeled `env=staging` +or labeled `team=`, where `` is one of the values of the user's +`teams` trait: + +```yaml +kind: role +version: v6 +metadata: + name: example-role +spec: + allow: + node_labels_expression: | + labels["env"] == "staging" || + contains(user.spec.traits["teams"], labels["team"]) +``` + +The `_labels_expression` fields have the same purpose of the +matching `_labels` fields, but support predicate expressions instead +of label matchers. +They can be used in the following fields of role `spec.allow` and `spec.deny` +conditions: + +- `node_labels_expression` +- `app_labels_expression` +- `cluster_labels_expression` +- `kubernetes_labels_expression` +- `db_labels_expression` +- `db_service_labels_expression` +- `windows_desktop_labels_expression` +- `group_labels_expression` + +Check out our +[predicate language](../reference/predicate-language.mdx#label-expressions) +guide for a more in depth explanation of the language. + +Typically you will only want to use one of `_labels` or +`_labels_expression` in a single role, but you are allowed to specify +both. +If you have both in a deny rule, the matching is greedy, if either one matches +access will be denied. +In an allow rule, the matching is not greedy, if both are set they both have to +match for access to be allowed. + ## Teleport resources RBAC lets teams limit what resources are available to Teleport users. This can be helpful if, for example, diff --git a/docs/pages/access-controls/sso.mdx b/docs/pages/access-controls/sso.mdx index 75b1c11997362..301f98989defb 100644 --- a/docs/pages/access-controls/sso.mdx +++ b/docs/pages/access-controls/sso.mdx @@ -453,7 +453,7 @@ flow. These provider-specific changes can be enabled by setting the values to match your identity provider: - `adfs` (SAML): Required for compatibility with Active Directory (ADFS); refer - to the full [ADFS guide](./sso/adfs.mdx#create-teleport-roles) for details. + to the full [ADFS guide](./sso/adfs.mdx#step-23-create-teleport-roles) for details. - `netiq` (OIDC): Used to enable NetIQ-specific ACR value processing; refer to the [OIDC guide](./sso/oidc.mdx#optional-acr-values) for details. - `ping` (SAML and OIDC): Required for compatibility with Ping Identity (including diff --git a/docs/pages/access-controls/sso/adfs.mdx b/docs/pages/access-controls/sso/adfs.mdx index 7d3c75fd3183a..d2603056f6464 100644 --- a/docs/pages/access-controls/sso/adfs.mdx +++ b/docs/pages/access-controls/sso/adfs.mdx @@ -1,15 +1,14 @@ --- title: SSO with Active Directory Federation Services -description: How to configure SSH access with Active Directory Federation Services using Teleport +description: How to configure Teleport access with Active Directory Federation Services h1: Single Sign-On with Active Directory Federation Services --- This guide will explain how to configure Active Directory Federation Services ([ADFS](https://en.wikipedia.org/wiki/Active_Directory_Federation_Services)) to be -a single sign-on (SSO) provider to issue -SSH credentials to specific groups of users. When used in combination with role -based access control (RBAC), it allows SSH administrators to define policies -like: +a single sign-on (SSO) provider to issue login credentials to specific groups +of users. When used in combination with role based access control (RBAC), it +allows Teleport administrators to define policies like: - Only members of "DBA" group can SSH into machines running PostgreSQL. - Developers must never SSH into production servers. @@ -23,42 +22,49 @@ like: - (!docs/pages/includes/tctl.mdx!) -(!docs/pages/includes/enterprise/samlauthentication.mdx!) - -## Configure ADFS +## Step 1/3. Configure ADFS You'll need to configure ADFS to export claims about a user (Claims Provider Trust in ADFS terminology) and you'll need to configure ADFS to trust Teleport (a Relying Party Trust in ADFS terminology). -For Claims Provider Trust configuration, you'll need to specify at least the -following two incoming claims: `Name ID` and `Group`. `Name ID` should be a -mapping of the LDAP Attribute `E-Mail-Addresses` to `Name ID`. A group -membership claim should be used to map users to roles (for example to -separate normal users and admins). +For Claims Provider Trust configuration, open the **AD FS** management window. +Under **Claims Provider Trusts**, right-click on **Active Directory** and +select **Edit Claim Rules**. You'll need to specify at least the following two +incoming claims: `Name ID` and `Group`. + +- `Name ID` should be a mapping of the LDAP Attribute `E-Mail-Addresses` to + `Name ID`. + + ![Name ID Configuration](../../../img/adfs-1.png) + +- A group membership claim should be used to map users to roles (for example to + separate normal users and admins). -![Name ID Configuration](../../../img/adfs-1.png) -![Group Configuration](../../../img/adfs-2.png) + ![Group Configuration](../../../img/adfs-2.png) -In addition, if you are using dynamic roles (see below), it may be useful to map -the LDAP Attribute `SAM-Account-Name` to `Windows account name` and create -another mapping of `E-Mail-Addresses` to `UPN`. +- If you are using dynamic roles (see below), it may be useful to map the LDAP + Attribute `SAM-Account-Name` to `Windows account name`: -![WAN Configuration](../../../img/adfs-3.png) -![UPN Configuration](../../../img/adfs-4.png) + ![WAN Configuration](../../../img/adfs-3.png) + +- And create another mapping of `E-Mail-Addresses` to `UPN`: + + ![UPN Configuration](../../../img/adfs-4.png) You'll also need to create a Relying Party Trust. Use the below information to -help guide you through the Wizard. Note that for development purposes we recommend -using `https://localhost:3080/v1/webapi/saml/acs` as the Assertion Consumer -Service (ACS) URL, but for production you'll want to change this to a domain -that can be accessed by other users as well. +help guide you through the Wizard. -- Create a claims aware trust. +- Create a Relaying Party Trust: + ![Add a Claims Provider Trust](../../../img/adfs-add-provider-trust.png) - Enter data about the relying party manually. - Set the display name to something along the lines of `Teleport`. - Skip the token encryption certificate. -- Select *"Enable support for SAML 2.0 Web SSO protocol"* and set the URL to `https://localhost:3080/v1/webapi/saml/acs`. -- Set the relying party trust identifier to `https://localhost:3080/v1/webapi/saml/acs` as well. +- Select *"Enable support for SAML 2.0 Web SSO protocol"* and set the URL to + `https://teleport.example.com/v1/webapi/saml/acs`, replacing the domain name + with your Teleport proxy URL. +- Set the relying party trust identifier to + `https://teleport.example.com/v1/webapi/saml/acs` as well. - For access control policy select *"Permit everyone"*. Once the Relying Party Trust has been created, update the Claim Issuance Policy @@ -72,7 +78,7 @@ associated with it. To check this open Server Manager then *"Tools -> Active Directory Users and Computers"* and select the user and right click and open properties. Make sure the email address field is filled out. -## Create Teleport roles +## Step 2/3. Create Teleport roles Let's create two Teleport roles: one for administrators and the other for normal users. You can create them using the `tctl create {file name}` CLI command @@ -121,17 +127,24 @@ This role declares: re-configure the Teleport cluster. The login -`{{external["http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]}}` +`{{external["http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]}}` configures Teleport to look at the `http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname` ADFS claim and use that field as an allowed login for each user. Note the double quotes (`"`) and square brackets (`[]`) around the claim name—these are important. -Next, create a SAML connector [resource](../../reference/resources.mdx): +## Step 3/3. Create a SAML connector -```yaml -(!examples/resources/adfs-connector.yaml!) +Create a SAML connector resource using `tctl`: + +```code +$ tctl sso configure saml --acs https://teleport.example.com/v1/webapi/saml/acs \ + --preset adfs \ + --entity-descriptor https://adfs.example.com/FederationMetadata/2007-06/FederationMetadata.xml \ + --attributes-to-roles http://schemas.xmlsoap.org/claims/Group,teleadmins,editor \ + --attributes-to-roles http://schemas.xmlsoap.org/claims/Group,Users,access \ + > adfs.yaml ``` The `acs` field should match the value you set in ADFS earlier and you can @@ -139,23 +152,31 @@ obtain the `entity_descriptor_url` from ADFS under *"ADFS -> Service -> Endpoint The `attributes_to_roles` is used to map attributes to the Teleport roles you just created. In our situation, we are mapping the *"Group"* attribute whose full -name is `http://schemas.xmlsoap.org/claims/Group` with a value of *"admins"* -to the *"admin"* role. Groups with the value *"users"* is being mapped to the +name is `http://schemas.xmlsoap.org/claims/Group` with a value of *"teleadmins"* +to the *"editor"* role. Groups with the value *"users"* is being mapped to the *"users"* role. -## Export the signing key +You can test this connector before applying it (`cat adfs.yaml | tctl sso test`), +but until we complete the next step the authentication process will not complete. + +Apply the connector: + +```code +$ tctl create -f adfs.yaml +``` + +### Export the signing key For the last step, you'll need to export the signing key: ```code -$ tctl saml export adfs +$ tctl saml export adfs > saml.cer ``` -Save the output to a file named `saml.crt`, return back to ADFS, open the -"Relying Party Trust" and add this file as one of the signature verification -certificates. +Copy `saml.cer`, to ADFS server, open the "Relying Party Trust" and add this +file as one of the signature verification certificates: -## Testing +![adfs-add-teleport-cert.png](../../../img/adfs-add-teleport-cert.png) The Web UI will now contain a new button: "Login with MS Active Directory". The CLI is the same as before: @@ -175,6 +196,8 @@ automatically in a browser. can be passed via `tsh login --auth=connector_name` +(!docs/pages/includes/enterprise/samlauthentication.mdx!) + ## Troubleshooting (!docs/pages/includes/sso/loginerrortroubleshooting.mdx!) diff --git a/docs/pages/access-controls/sso/github-sso.mdx b/docs/pages/access-controls/sso/github-sso.mdx index 2b93ce3bc7331..870a3ff08433a 100644 --- a/docs/pages/access-controls/sso/github-sso.mdx +++ b/docs/pages/access-controls/sso/github-sso.mdx @@ -10,10 +10,13 @@ Teleport. ## Prerequisites -- A GitHub organization with at least one team. This organization must not have external SSO set up, or Teleport -will refuse to create the GitHub authentication connector.This organization can be hosted -from either GitHub Cloud or GitHub Enterprise Server. -- Teleport role with access to maintaining `github` resources for using `tctl` from the Desktop. This is available in the default `editor` role. +- A GitHub organization with at least one team. This + organization must not have external SSO set up, or Teleport will refuse to + create the GitHub authentication connector.This organization can be hosted from either + GitHub Cloud or GitHub Enterprise Server. +- Teleport role with access to maintaining `github` resources for using `tctl` + from the Desktop. This is available in the default `editor` role. (!docs/pages/includes/edition-prereqs-tabs.mdx!) @@ -32,6 +35,9 @@ https://PROXY_ADDRESS/v1/webapi/github/ address of the Teleport Proxy Serviceyour Teleport Cloud tenant address. +The app must have the `read:org` scope in order to be able to read org and team +membership details. + Instructions for creating a GitHub OAuth app are available in [GitHub's documentation](https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app) @@ -43,6 +49,7 @@ Create a client secret to use along with the client ID in the next step: Define a GitHub authentication connector using `tctl`. Update this example command with: + - Your OAuth app's client ID and client secret created during the previous step. - The roles you want to map from your GitHub organization to Teleport roles. Roles are defined in the **Repository roles** section of your organization's @@ -61,6 +68,30 @@ $ tctl sso configure github \ The contents of `github.yaml` should resemble the following: + +```yaml +kind: github +metadata: + name: github +spec: + api_endpoint_url: "" + client_id: + client_secret: + display: GitHub + endpoint_url: "" + redirect_url: https:///v1/webapi/github/callback + teams_to_logins: null + teams_to_roles: + - organization: ORG-NAME + roles: + - access + - editor + team: GITHUB-TEAM +version: v3 +``` + + + ```yaml kind: github metadata: @@ -78,9 +109,11 @@ spec: roles: - access - editor + - reviewer team: GITHUB-TEAM version: v3 ``` +
You can add multiple instances of the `--teams-to-roles` flag or edit the connector @@ -245,14 +278,32 @@ After logging in successfully, you will see the following: You will receive the details of your user session within the CLI: - + ```code > Profile URL: https://tele.example.com:443 Logged in as: jeff Cluster: tele.example.com Roles: access - Logins: jeff, ubuntu, debian, -teleport-internal-join + Logins: jeff, ubuntu, debian + Kubernetes: enabled + Kubernetes users: dev + Kubernetes groups: developer + Valid until: 2023-03-08 17:13:50 -0600 CST [valid for 7h51m0s] + Extensions: permit-port-forwarding, permit-pty, private-key-policy +``` + + + + + + +```code +> Profile URL: https://tele.example.com:443 + Logged in as: jeff + Cluster: tele.example.com + Roles: access, requester + Logins: jeff, ubuntu, debian Kubernetes: enabled Kubernetes users: dev Kubernetes groups: developer @@ -268,8 +319,8 @@ You will receive the details of your user session within the CLI: > Profile URL: https://mytenant.teleport.sh:443 Logged in as: jeff Cluster: mytenant.teleport.sh - Roles: access - Logins: jeff, ubuntu, debian, -teleport-internal-join + Roles: access, requester + Logins: jeff, ubuntu, debian Kubernetes: enabled Kubernetes users: dev Kubernetes groups: developer diff --git a/docs/pages/access-controls/sso/gitlab.mdx b/docs/pages/access-controls/sso/gitlab.mdx index 160225fa6ef8e..f92a35ea23823 100644 --- a/docs/pages/access-controls/sso/gitlab.mdx +++ b/docs/pages/access-controls/sso/gitlab.mdx @@ -4,60 +4,92 @@ description: How to configure Teleport access using GitLab for SSO h1: Teleport SSO Authentication with GitLab --- -## How to use GitLab as a single sign-on (SSO) provider with Teleport - This guide will cover how to configure [GitLab](https://www.gitlab.com/) to issue -SSH credentials to specific groups of users. When used in combination with role +credentials to specific groups of users. When used in combination with role based access control (RBAC), it allows administrators to define policies like: -- Only members of "DBA" group can SSH into machines running PostgreSQL. +- Only members of the "DBA" group can access PostgreSQL databases. - Only members of "ProductionKubernetes" can access production Kubernetes clusters - Developers must never SSH into production servers. ## Prerequisites -- At least two groups in GitLab with users assigned. -- Teleport role with access to maintaining `oidc` resources. This is available in the default `editor` role. +- At least two groups in GitLab with users assigned. In our examples below, + we'll assume a group named `company` with two subgroups, `admin` and `dev`. +- Teleport role with access to maintaining `oidc` resources. This is available + in the default `editor` role. (!docs/pages/includes/commercial-prereqs-tabs.mdx!) - (!docs/pages/includes/tctl.mdx!) -## Enable default OIDC authentication - -(!docs/pages/includes/enterprise/oidcauthentication.mdx!) - ## Configure GitLab -You should have at least one group configured in GitLab to map to Teleport roles. In this example we use the names `gitlab-dev` and `gitlab-admin`. Assign users to each of these groups. - -1. Create a Application in one of your Groups that will allow using GitLab as a OAuth provider to Teleport. +You should have at least one group configured in GitLab to map to Teleport roles. +In this example we use the names `gitlab-dev` and `gitlab-admin`. Assign users +to each of these groups. -Settings +1. Create an application in one of your groups (**Group overview** -> + **Settings** -> **Applications**) that will allow using GitLab as an OAuth + provider to Teleport. -- Redirect URL `https:///v1/webapi/oidc/callback` such as `https://teleport.example.com:3080/v1/webapi/oidc/callback` -- Check `Confidential`, `openid`, `profile`, and `email`. + Settings: -![Create App](../../../img/sso/gitlab/gitlab-oidc-0.png) + - Redirect URL: `https:///v1/webapi/oidc/callback`. + - Check `Confidential`, `openid`, `profile`, and `email`. -2. Collect the `Application ID` and `Secret` in the Application + ![Create App](../../../img/sso/gitlab/gitlab-oidc-0.png) -These will be used in the Teleport OIDC Auth Connector. +2. Collect the `Application ID` and `Secret` in the Application. These will be + used in the Teleport OIDC auth connector: -![Collection Information](../../../img/sso/gitlab/gitlab-oidc-1.png) + ![Collection Information](../../../img/sso/gitlab/gitlab-oidc-1.png) -3. Confirm the GitLab Issuer Address +3. Confirm the GitLab issuer address. -For GitLab cloud that is `https://gitlab.com`. That allows accessing the Open-ID configuration at `https://gitlab.com/.well-known/openid-configuration`. -If you are self hosting that is likely another local address. + For GitLab.com, the issuer address is `https://gitlab.com`. This allows + Teleport to access the Open-ID configuration at + `https://gitlab.com/.well-known/openid-configuration`. If you are self + hosting the issuer address is the path to your GitLab instance. ## Configure Teleport ### Create a OIDC Connector -Create a OIDC connector [resource](../../reference/resources.mdx): -Replace the Application ID and the Secret with the values from GitLab. +Create an OIDC connector resource using `tctl`. + + + +Replace the application ID and secret with the values from GitLab: + +```code +$ tctl sso configure oidc --preset gitlab \ +--id \ +--secret \ +--claims-to-roles groups,company/admin,admin \ +--claims-to-roles groups,company/dev,dev > oidc.yaml +``` + + + +Replace the application ID and secret with the values from GitLab, and replace +`https://gitlab.company.com` with the path to your self-hosted GitLab instance: + +```code +$ tctl sso configure oidc --preset gitlab \ +--id \ +--issuer-url https://gitlab.company.com \ +--secret \ +--claims-to-roles groups,company/admin,admin \ +--claims-to-roles groups,company/dev,dev > oidc.yaml +``` + + + + +This example maps the two subgroups `admin` and `dev` of the parent group +`company` to the `admin` and `dev` roles in Teleport, and creates the `oidc.yaml` file: ```yaml kind: oidc @@ -68,33 +100,35 @@ spec: - claim: groups roles: - admin - value: gitlab-admin + value: company/admin - claim: groups roles: - dev - value: gitlab-dev - client_id: Application_ID - client_secret: Secret - display: GitLab + value: company/gitlab-dev + client_id: + client_secret: + display: Gitlab issuer_url: https://gitlab.com - prompt: "none" - redirect_url: https://teleport.example.com:3080/v1/webapi/oidc/callback - scope: - - email -version: v2 + prompt: none + redirect_url: https://teleport.example.com:443/v1/webapi/oidc/callback +version: v3 + ``` - - The `prompt` value must be `none`. Setting to `none` means Teleport will not send this as a parameter sending the `select_account` parameter will result in an error from GitLab. - +Test the connector resource by piping the file to `tctl sso test`: + +```code +$ cat oidc.yaml | tctl sso test +``` + +After authorizing the application in GitLab you should get a +**Login Successful** message in your web browser. Otherwise, consult the output +of the command to diagnose. Create the connector using `tctl` tool: ```code -$ tctl create oidc-connector.yaml +$ tctl create -f oidc.yaml.yaml ``` ## Create Teleport Roles @@ -145,11 +179,13 @@ spec: Create both roles on the auth server: ```code -$ tctl create admin.yaml -$ tctl create dev.yaml +$ tctl create -f admin.yaml +$ tctl create -f dev.yaml ``` -## Testing +## Enable default OIDC authentication + +(!docs/pages/includes/enterprise/oidcauthentication.mdx!) The Web UI will now contain a new button: "Login with GitLab". The CLI is the same as before: diff --git a/docs/pages/access-controls/sso/google-workspace.mdx b/docs/pages/access-controls/sso/google-workspace.mdx index a1e5c513e24d9..7d127cf918b90 100644 --- a/docs/pages/access-controls/sso/google-workspace.mdx +++ b/docs/pages/access-controls/sso/google-workspace.mdx @@ -1,36 +1,35 @@ --- -title: SSH Authentication With Google Workspace (G Suite) -description: How to configure SSH access with Google Workspace (formerly known as G Suite) using Teleport -h1: SSH Authentication with Google Workspace (G Suite) +title: Teleport Authentication with Google Workspace (G Suite) +description: How to configure Teleport access with Google Workspace (formerly known as G Suite) videoBanner: WTLWc6nnPfk --- -This guide will explain how to configure [Google Workspace](https://workspace.google.com/) to be a -single sign-on (SSO) provider to issue SSH credentials to specific groups of users. -When used in combination with role based access control (RBAC) it allows SSH administrators -to define policies like: +This guide will explain how to configure [Google Workspace](https://workspace.google.com/) +to be a single sign-on (SSO) provider to issue Teleport credentials to specific +groups of users. When used in combination with role-based access control (RBAC) +it allows Teleport administrators to define policies like: -- Only members of "DBA" Google group can SSH into machines running PostgreSQL. +- Only members of the "DBA" Google group can connect to PostgreSQL databases. - Developers must never SSH into production servers. ## Prerequisites Before you get started you’ll need: -- A Google Workspace super administrator account. We recommend setting up a separate super admin account with 2FA as opposed to granting your daily user super admin privileges. -- Ability to create a Google Cloud project, which requires signing up for Google Cloud. Note that this guide will not require using any paid Google Cloud services. +- A Google Workspace super administrator account. We recommend setting up a + separate super admin account with 2FA as opposed to granting your daily user + super admin privileges. +- Ability to create a Google Cloud project, which requires signing up for Google + Cloud. Note that this guide will not require using any paid Google Cloud services. - Ability to set up Google Workspace groups. -- Teleport role with access to maintaining `oidc` resources. This is available in the default `editor` role. +- Teleport role with access to maintaining `oidc` resources. This is available + in the default `editor` role. (!docs/pages/includes/commercial-prereqs-tabs.mdx!) - (!docs/pages/includes/tctl.mdx!) -## Step 1/4. Enable default OIDC authentication - -(!docs/pages/includes/enterprise/oidcauthentication.mdx!) - -## Step 2/4. Configure Google Workspace +## Step 1/4. Configure Google Workspace The setup will consist of: @@ -80,19 +79,8 @@ We will show you how to configure the connector later in the guide, but for now, you should ensure that your Google Workspace plan allows you to use Teleport as you intend. -We currently support OIDC connector versions `v2` and `v3`. - - - -Teleport versions prior to 8.1.2 only support `v2` of the OIDC connector. - - - - - - -The OIDC connector maps a user's roles to the Google Workspace groups they -belong to. +We currently support version `v3` of the OIDC connector. The OIDC connector maps a +user's roles to the Google Workspace groups they belong to. In order to list a user's Google Workspace groups, Teleport will first attempt to fetch credentials for calling Cloud Identity API methods, then use these @@ -103,25 +91,13 @@ Directory API instead, and will use this API to list the user's groups in your entire Google Workspace account. Groups that the user belongs to that are external to the workspace will not be listed. - - - -The OIDC connector maps a user's roles to the Google Workspace groups they belong to. - -If these credentials do not exist, Teleport will fetch credentials for the -Directory API instead, and will use this API to list the user's groups within -your Google Workspace domain. Any group registered on a different domain or -subdomain than the user's will be ignored. - - - - #### How to check your current plan To troubleshoot whether your Google Workspace plan supports querying transitive group memberships, you can visit the [Groups Inspection](https://admin.google.com/ac/groupsinspection) page in the -Google Admin Console, which relies on the Cloud Identity API. +Google Admin Console, which relies on the Cloud Identity API. Select "List all +groups for a member" and "Include external groups" to test. If your Google Workspace plan does not support the Cloud Identity API, you must ensure that your RBAC does not depend on transitive group memberships. @@ -134,9 +110,9 @@ all groups external to the workspace) will prevent users from logging in. ### Create a new project -In the GCP console, choose to [Create a new project](https://console.cloud.google.com/projectselector2/apis/dashboard). +In the GCP console, choose the project dropdown menu, and [create a new project](https://console.cloud.google.com/projectselector2/apis/dashboard). - ![creation of a Google Cloud Platform project](../../../img/googleoidc/new-project.png) + ![creation of a Google Cloud Platform project](../../../img/sso/googleoidc/new-project.png) ### Configure OAuth consent @@ -144,14 +120,17 @@ On the [OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent) page of the GCP console, select"Internal" as your User Type. -![configuration of the OAuth consent screen](../../../img/googleoidc/consent-screen-1.png) +![configuration of the OAuth consent screen](../../../img/sso/googleoidc/consent-screen-1.png) - Configure the appearance of your connector by picking a visible name, user support email, etc. +On the next page, configure the appearance of your connector by picking a +visible name, user support email, etc. ### Select scopes +On the next page, click on **ADD OR REMOVE SCOPES**. Select the `.../auth/userinfo.email` and `openid` scopes. - ![select email and openid scopes](../../../img/googleoidc/consent-screen-2.png) + +![select email and openid scopes](../../../img/sso/googleoidc/consent-screen-2.png) Enable the [Cloud Identity API](https://console.cloud.google.com/apis/library/cloudidentity.googleapis.com) @@ -170,87 +149,226 @@ correct Google Workspace plan. ### Create an OAuth client ID -In the [Create an OAuth client ID](https://console.cloud.google.com/apis/credentials/oauthclient) page of the GCP console, select "Web application" as the Application type, pick a name, then add the following as an authorized redirect URI. +Under **Credentials**, select **CREATE CREDENTIALS**, then **OAuth client ID**: -```txt -https://
:3080/v1/webapi/oidc/callback -``` +![Create an OAuth Client ID](../../../img/sso/googleoidc/create-oauth-client-id.png) + +Select "Web application" as the Application type, pick a name, then set the +redirect URI based on the address of your Teleport Proxy Service or cloud tenant: +`/v1/webapi/oidc/callback` - ![OAuth client ID creation](../../../img/googleoidc/clientid-creation.png) +![OAuth client ID creation](../../../img/sso/googleoidc/clientid-creation.png) - Copy the Client ID and Client Secret from the next screen or by clicking "Download OAuth client". - ![OAuth client data](../../../img/googleoidc/clientid-data.png) +Copy the Client ID and Client Secret from the next screen or click **DOWNLOAD JSON**: + +![OAuth client data](../../../img/sso/googleoidc/clientid-data.png) ### Create a service account -On the [Create a service account](https://console.cloud.google.com/iam-admin/serviceaccounts/create) page, pick a name for your service account. Leave project access grants and user access grants empty. - ![service account creation](../../../img/googleoidc/serviceacct-creation.png) +From the GCP **IAM & Admin** menu select **Service Accounts**. From the kebab +menu click **CREATE SERVICE ACCOUNT**: + +![Create a service account](../../../img/sso/googleoidc/create-service-account.png) + +On the [Create a +service account](https://console.cloud.google.com/iam-admin/serviceaccounts/create) +page, pick a name for your service account. Leave project access grants and user +access grants empty. + +![service account creation](../../../img/sso/googleoidc/serviceacct-creation.png) - Click the newly-created account to view its details, and copy the Unique ID for later. - ![service account unique ID](../../../img/googleoidc/serviceacct-uniqueid.png) +Click the newly-created account to view its details, and copy the Unique ID for later. - Create a new key for the service account, select JSON as the key type, and save the resulting JSON file. - ![service account key creation](../../../img/googleoidc/serviceacct-key.png) - Later, we will make this JSON available to the Teleport Auth Server via the OIDC Connector configuration, either by referencing a local file or pasting the JSON into the configuration YAML. If you plan to take the first approach, you will need to upload the JSON to the Auth Server. +![service account unique ID](../../../img/sso/googleoidc/serviceacct-uniqueid.png) + +Create a new key for the service account, select JSON as the key type, and save +the resulting JSON file. + +![service account key creation](../../../img/sso/googleoidc/serviceacct-key.png) + +Later, we will make this JSON available to the Teleport Auth Service via the +OIDC Connector configuration, either by referencing a local file or pasting the +JSON into the `tctl` command creating the connector. If you plan to take the +first approach, you will need to upload the JSON to the Auth Service. - Teleport requires the service account JSON to be available to all Teleport Auth Server hosts when deploying Teleport in a High Availability configuration. Unless you paste the JSON into the OIDC Connector configuration, you will need to upload the JSON file to all Auth Server hosts. +Teleport requires the service account JSON to be available to all Teleport Auth +Service hosts when deploying Teleport in a High Availability configuration. +For high availability or cloud deployments, we suggest providing the JSON when +creating the connector resource. ### Configure domain-wide delegation Configure [domain-wide - delegation](https://admin.google.com/ac/owl/domainwidedelegation) for your - newly-created service account: +delegation](https://admin.google.com/ac/owl/domainwidedelegation) for your +newly-created service account: - Click "Add new" and add the numeric Unique ID that you've copied earlier. - ![domain-wide delegation](../../../img/googleoidc/domainwidedelegation.png) +Click "Add new" and add the numeric Unique ID that you've copied earlier from +the service account: - Add either the - `https://www.googleapis.com/auth/cloud-identity.groups.readonly` scope or - the `https://www.googleapis.com/auth/admin.directory.group.readonly` scope. - The scope granted to the service account will determine if Teleport will - fetch both direct and indirect groups or just direct groups, respectively. +![domain-wide delegation](../../../img/sso/googleoidc/domainwidedelegation.png) -## Step 3/4. Create an OIDC connector +Add **one** of the following scopes depending on your Google Workspace: +- Direct and Indirect Groups (*Transitive Group Membership Support*) + - `https://www.googleapis.com/auth/cloud-identity.groups.readonly` +- Direct Groups Only + - `https://www.googleapis.com/auth/admin.directory.group.readonly` -Create the following OIDC connector [resource spec](../../reference/resources.mdx) as `gworkspace-connector.yaml`. We will explain how to choose values for fields within the resource spec below. +## Step 2/4. Create an OIDC connector + +Create the OIDC connector resource using `tctl`. We will explain how to choose +values for fields within the resource spec below: - - ```yaml - (!examples/resources/gworkspace-connector.yaml!) - ``` - - - - ```yaml - (!examples/resources/gworkspace-connector-inline.yaml!) - ``` - + + +Use this method to define the service account JSON in the connector resource. +This method doesn't require providing the JSON file to the host(s) running the +Auth Service. + +```code +$ tctl sso configure oidc --preset google --id \ +--secret \ +--claims-to-roles groups,auditor@example.com,auditor \ +--claims-to-roles groups,teleport-developers@example.com,access \ +--google-admin= \ +--google-acc ' +{ + "type": "service_account", + ... + "universe_domain": "googleapis.com" +}' +``` + +The file created will resemble: + +```yaml +kind: oidc +metadata: + name: google +spec: + claims_to_roles: + - claim: groups + roles: + - auditor + value: auditor@example.com + - claim: groups + roles: + - access + value: teleport-developers@example.com + client_id: + client_secret: + display: Google + google_admin_email: + google_service_account: |2- + + { + "type": "service_account", + ... + "universe_domain": "googleapis.com" + } + issuer_url: https://accounts.google.com + redirect_url: https://example.teleport.sh:443/v1/webapi/oidc/callback +version: v3 +``` + + + + +Use this method for single self-hosted Teleport Auth instances, or when you can +easily and reliably make the JSON file available to all hosts running the Auth +service. + +```code +$ tctl sso configure oidc --preset google --id \ +--secret \ +--google-acc-uri .json \ +--claims-to-roles groups,auditor@example.com,auditor \ +--claims-to-roles groups,teleport-developers@example.com,access \ +--google-admin= > gworkspace-connector.yaml +``` + +The file created will resemble: + +```yaml +kind: oidc +metadata: + name: google +spec: + claims_to_roles: + - claim: groups + roles: + - auditor + value: auditor@example.com + - claim: groups + roles: + - access + value: teleport-developers@example.com + client_id: + client_secret: + display: Google + google_admin_email: + google_service_account_uri: /PATH/TO/SERVICE-ACCOUNT-KEY.json + issuer_url: https://accounts.google.com + redirect_url: https://teleport.example.com/v1/webapi/oidc/callback +version: v3 +``` + + -The email that you set for `google_admin_email` **must** be the email address of a user that has permission to list all groups, users, and group membership in your Google Workspace account. This user will generally need super admin or group admin privileges. + + Be sure to remove < > brackets around tokens in the sample configuration above. + For example, replace `` with `admin@yourdomain.com`. + + +The email that you set for `google_admin_email` **must** be the email address of +a user that has permission to list all groups, users, and group membership in +your Google Workspace account. This user will generally need super admin or group +admin privileges. + +Do not use the email of the service account for `google_admin_email`. The +configuration display will look the same, but the service account will not have +the required domain-wide delegation. + +The `client_id` field must be the unique ID number captured from the Google Cloud +Platform UI. An indicator that this is misconfigured is if you see "invalid Google +Workspace credentials for scopes [...]" in your audit log, accessible from the +Auth service host or the **Management** section of the web UI. -Do not use the email of the service account for `google_admin_email`. The configuration display will look the same, but the service account will not have the required domain-wide delegation. +Test the connector: -The `client_id` field must be the unique ID number captured from the Google Cloud Platform UI. An indicator that this is misconfigured is if you see "invalid Google Workspace credentials for scopes [...]" in your log. +```code +$ cat gworkspace-connector.yaml | tctl sso test +``` + +This will open your browser and attempt to sign you in to your Teleport cluster +using Google. If it fails, the CLI output will provide useful troubleshooting +information. Create the connector using the `tctl` tool: ```code -$ tctl create gworkspace-connector.yaml +$ tctl create -f gworkspace-connector.yaml ``` -If you have a configured connector from a version of Teleport older than 8.1.2, you can upgrade your connector from `v2` to `v3`: +
+If you have a configured connector from a version of Teleport older than 8.1.2, +you can upgrade your connector from `v2` to `v3`: First, fetch the connector data: + ```code $ umask 077 $ tctl get --with-secrets oidc/connectorname > connector.yaml ``` -Next, edit `connector.yaml` to change the version number from `v2` to `v3`, and then update the connector: +Next, edit `connector.yaml` to change the version number from `v2` to `v3`, and +then update the connector: ```code $ tctl create -f connector.yaml @@ -269,25 +387,23 @@ While a `v3` connector is configured, you can no longer downgrade Teleport to a version before 8.1.2. Before such a downgrade, follow the above instructions and change the version number back to `v2`. -## Step 4/4. Test your Google Workspace OIDC connector +
-The Web UI will now contain a new button: "Login with Google". The CLI is -the same as before: +## Step 3/4. Test your Google Workspace OIDC connector + +The Web UI will now contain a new button: "Login with Google". To log in with +the CLI: ```code -$ tsh --proxy=proxy.example.com login +$ tsh --proxy=proxy.example.com login --auth=google ``` This command will print the SSO login URL (and will try to open it automatically in a browser). - - Teleport can use multiple OIDC connectors. In this case a connector name - can be passed via `tsh login --auth=google` - +## Step 4/4. Enable default OIDC authentication + +(!docs/pages/includes/enterprise/oidcauthentication.mdx!) ## Troubleshooting @@ -298,4 +414,3 @@ automatically in a browser). - [Google Workspace Cloud Identity API](https://cloud.google.com/identity) - [Google Workspace Directory API](https://developers.google.com/admin-sdk/directory) - [How nested Google Workspace groups work](https://support.google.com/a/answer/167100?hl=en) - diff --git a/docs/pages/access-controls/sso/okta.mdx b/docs/pages/access-controls/sso/okta.mdx index 14de1ab57b606..365a47d7923fc 100644 --- a/docs/pages/access-controls/sso/okta.mdx +++ b/docs/pages/access-controls/sso/okta.mdx @@ -23,7 +23,16 @@ Teleport administrators to define policies like: - A Teleport role with access to edit and maintain `saml` resources. This is available in the default `editor` role. -- (!docs/pages/includes/tctl.mdx!) + + + +- (!docs/pages/includes/enterprise/tctl-tsh-prerequisite.mdx!) + + +- (!docs/pages/includes/cloud/tctl-tsh-prerequisite.mdx!) + + + (!docs/pages/includes/enterprise/samlauthentication.mdx!) @@ -67,13 +76,14 @@ Provide the following values to their respective fields: #### General -- Single sign on URL: `https:///v1/webapi/saml/acs/new_saml_connector` -- Audience URI (SP Entity ID): `https:///v1/webapi/saml/acs/new_saml_connector` +- Single sign on URL: `https://:/v1/webapi/saml/acs/okta` +- Audience URI (SP Entity ID): `https://:/v1/webapi/saml/acs/okta` - Name ID format `EmailAddress` - Application username `Okta username` Replace `` with your Teleport Proxy Service address or Enterprise -Cloud tenant (e.g. `mytenant.teleport.sh`). +Cloud tenant (e.g. `mytenant.teleport.sh`). Replace `` with your Proxy +Service listening port (`443` by default). #### Attribute Statements @@ -134,22 +144,98 @@ You can also right click on the "View IdP metadata" link and select ## Step 3/4. Create a SAML connector -Define a SAML connector resource in a local file named `okta-connector.yaml`: +Define an Okta SAML connector using `tctl`. Update this example command with +the path to your metadata file, and edit the `--attributes-to-roles` values for +custom group assignment to roles. See [tctl sso configure +saml](../../reference/cli.mdx#tctl-sso-configure-saml) for a full reference of +flags for this command: -```yaml -(!examples/resources/saml-connector.yaml!) +```code +$ tctl sso configure saml --preset=okta \ +--entity-descriptor \ +--attributes-to-roles=groups,okta-admin,editor \ +--attributes-to-roles=groups,okta-dev,access > okta.yaml ``` -Update the value of `acs` with your Teleport Proxy address or Enterprise Cloud tenant -(e.g. `mytenant.teleport.sh`), and replace the value of `entity_descriptor_url` -with the path you copied in the previous step. +The contents of `okta.yaml` should resemble the following: + +```yaml +kind: saml +metadata: + name: okta +spec: + acs: https://teleport.example.com:443/v1/webapi/saml/acs/okta + attributes_to_roles: + - name: groups + roles: + - editor + value: okta-admin + - name: groups + roles: + - access + value: okta-dev + audience: https://teleport.example.com:443/v1/webapi/saml/acs/okta + cert: "" + display: "Okta" + entity_descriptor: "" + entity_descriptor_url: https://example.okta.com/app/000000/sso/saml/metadata + issuer: "" + service_provider_issuer: https://teleport.example.com:443/v1/webapi/saml/acs/okta + sso: "" +version: v2 +``` The `attributes_to_roles` field in the connector resource maps key/value-like attributes of the assertion from Okta into a list of Teleport roles to apply to the session. (!docs/pages/includes/sso/idp-initiated.mdx!) -Create the connector using `tctl` tool: +You can test the connector before applying it to your cluster. This is strongly +encouraged to avoid interruption to active clusters: + +```code +$ cat okta.yaml | tctl sso test +If browser window does not open automatically, open it by clicking on the link: + http://127.0.0.1:52519/0222b1ca... +Success! Logged in as: alice@example.com +-------------------------------------------------------------------------------- +Authentication details: + roles: + - editor + - access + traits: + groups: + - Everyone + - okta-admin + - okta-dev + username: + - alice@example.com + username: alice@example.com +-------------------------------------------------------------------------------- +[SAML] Attributes to roles: +- name: groups + roles: + - editor + value: okta-admin +- name: groups + roles: + - access + value: okta-dev + +-------------------------------------------------------------------------------- +[SAML] Attributes statements: +groups: +- Everyone +- okta-admin +- okta-dev +username: +- alice@example.com + +-------------------------------------------------------------------------------- +For more details repeat the command with --debug flag. +``` + +Create the connector using `tctl`: ```code $ tctl create okta-connector.yaml diff --git a/docs/pages/agents/deploy-agents-terraform.mdx b/docs/pages/agents/deploy-agents-terraform.mdx new file mode 100644 index 0000000000000..ae40ca7ac31b4 --- /dev/null +++ b/docs/pages/agents/deploy-agents-terraform.mdx @@ -0,0 +1,308 @@ +--- +title: "Deploy Teleport Agents with Terraform" +description: "In this guide, we will show you how to deploy a pool of Teleport agents so you can apply dynamic resources to enroll your infrastructure with Teleport." +--- + +An agent is a Teleport instance configured to run one or more Teleport services +in order to proxy infrastructure resources. For a brief architectural overview +of how agents run in a Teleport cluster, read the [Introduction to Teleport +Agents](introduction.mdx). + +This guide shows you how to deploy a pool of Teleport agents by declaring it as +code using Terraform. + +There are several methods you can use to join a Teleport agent to your cluster, +which we discuss in the [Joining Services to your +Cluster](join-services-to-your-cluster.mdx) guide. In this guide, we will use +the **join token** method, where the operator stores a secure token on the Auth +Service, and an agent presents the token in order to join a cluster. + +No matter which join method you use, it will involve the following Terraform +resources: + +- Compute instances to run Teleport services +- A join token for each compute instance in the agent pool + +```mermaid +flowchart TB +subgraph agent1["Teleport agent"] + service1["Teleport service"] + service2["Teleport service"] + join1["Join token"] +end + +subgraph agent2["Teleport agent"] + join2["Join token"] + service3["Teleport service"] + service4["Teleport service"] +end + +subgraph auth["Auth Service"] + join3["Join token"] + join4["Join token"] +end + +join1<-.Matches.->join3 +join2<-.Matches.->join4 +``` + +## Prerequisites + +(!docs/pages/includes/edition-prereqs-tabs.mdx!) + + + +We recommend following this guide on a fresh Teleport demo cluster so you can +see how an agent pool works. After you are familiar with the setup, apply the +lessons from this guide to protect your infrastructure. You can get started with +a demo cluster using: +- A demo deployment on a [Linux server](../index.mdx) +- A [Teleport Team trial](https://goteleport.com/signup) + + + +- An AWS account with permissions to create EC2 instances. +- Terraform v(=terraform.version=). +- An identity file for the Teleport Terraform provider. Make sure you are + familiar with [how to set up the Teleport Terraform + provider](../management/dynamic-resources/terraform-provider.mdx) before following this + guide. +- (!docs/pages/includes/tctl.mdx!) + +## Step 1/3. Fetch the example Terraform configuration + +Fetch the Teleport code repository and copy the example Terraform configuration +for this project into your current working directory: + +```code +$ git clone --depth=1 https://github.com/gravitational/teleport +$ cp -R teleport/examples/agent-pool-terraform . +$ rm -rf teleport +``` + +Move the identity file for the Teleport Terraform provider into your project +directory so the Terraform provider an access it. Name the file +`terraform-identity`. + + + +If you don't have an identify file available, make sure you have followed the +[prerequisites for this guide](#prerequisites). + + + +## Step 2/3. Prepare your Terraform configuration + +After you have copied the example Terraform configuration, you will assign input +variables and apply your new resources. First, we will explain the Terraform +resource configuration you copied so you can understand how to deploy an agent +pool in your infrastructure. + +### Instances and tokens + +The file `agent-pool.tf` configures EC2 instances and Teleport join tokens: + +```text +(!examples/agent-pool-terraform/agent-pool.tf!) +``` + +In this minimal example, we deploy one EC2 instance for each Teleport agent. +Each agent joins the cluster using a token. We create each token using the +`teleport_provision_token` Terraform resource, specifying the token's value with +a `random_string` resource. + +When we apply the `teleport_provision_token` resources, the Teleport Terraform +provider creates them on the Teleport Auth Service backend. Each EC2 instance +presents the token in order to establish trust with the cluster. + +The Auth Service associates the join token with one or more roles, identifying +the Teleport service that is allowed to use the token. The configuration above +generates tokens for the following Teleport services: + +- Teleport SSH Service (`Node`) +- Teleport Application Service (`App`) +- Teleport Database Service (`Db`) +- Teleport Kubernetes Service (`Kube`) + +### Startup script + +Each EC2 instance runs a script on startup, which we configured above using the +`user_data` field within the `aws_instance.teleport_agent` resource +(`examples/agent-pool-terraform/userdata`): + +```text +(!examples/agent-pool-terraform/userdata!) +``` + +This script installs Teleport Community Edition on the host, then writes a +configuration file to the default location, `/etc/teleport.yaml`. The +configuration file enables each Teleport service we associated with our token. + +The configuration also adds the `role: agent-pool` label to the Teleport SSH +Service on each instance. This will make it easier to access hosts in the agent +pool later. + +Finally, the script restarts Teleport on the host to apply the new +configuration. + +### Input variables + +The Terraform configuration we show in this guide relies on the following inputs +(`examples/agent-pool-terraform/inputs.tf`): + +```text +(!examples/agent-pool-terraform/inputs.tf!) +``` + +In your `agent-pool-terraform` project directory, create a file called +`main.auto.tfvars` with the following content: + +```text +agent_count=2 +proxy_service_address="mytenant.teleport.sh" +aws_region="" +teleport_version=(=teleport.version=) +subnet_id="" +``` + +Assign `agent_count` to `2` for high availability. As you scale your Teleport +usage, you can increase this count to ease the load on each agent. You can +consider adding your agents to an Auto Scaling group as well. + +Assign `proxy_service_address` to the host and HTTPS port of your Teleport Proxy +Service, e.g., `mytenant.teleport.sh:443`. + + + +Make sure to include the port. + + + +Assign `aws_region` to your AWS region, e.g., `us-east-1`. + +For `subnet_id`, include the ID of the AWS subnet where you will deploy Teleport +agents. + +Finally, make sure you are using the latest supported version of the Teleport +Terraform provider. The `required_providers` block for the Teleport provider +includes a placeholder value: + +```text +(!examples/agent-pool-terraform/provider.tf!) +``` + +Replace the placeholder value with the latest version: + +```code +$ sed -i "" "s/TELEPORT_VERSION/(=teleport.plugin.version=)/" provider.tf +``` + +## Step 3/3. Verify the deployment + +Make sure your AWS credentials are available to Terraform using the standard +approach for your organization. + +Apply the Terraform configuration: + +```code +$ terraform apply +``` + +Once the `apply` command completes, run the following command to verify that the +two agents have deployed successfully: + +```code +$ tsh ls role=agent-pool +Node Name Address Labels +-------------------------- ---------- --------------- +ip-10-1-1-187.ec2.internal ⟵ Tunnel role=agent-pool +ip-10-1-1-24.ec2.internal ⟵ Tunnel role=agent-pool +``` + +## Next step: Enroll infrastructure resources + +There are two ways to configure your agent pool to protect infrastructure +resources with Teleport, which we describe below. + +### Define dynamic resources in Terraform + +You can declare Terraform resources that enroll your infrastructure with +Teleport. The Teleport Terraform provider currently supports the following: + +|Infrastructure Resource|Terraform Resource| +|---|---| +|Application|`teleport_app`| +|Database|`teleport_database`| + +To declare a dynamic resource with Terraform, add a configuration block similar +to the ones below to a `*.tf` file in your `agent-pool-terraform` project +directory. + +The Teleport Terraform provider creates these on the Auth Service backend, and +the relevant Teleport services query them in order to proxy user traffic. For a +full list of supported resources and fields, see the [Terraform provider +reference](../reference/terraform-provider.mdx). + + + + +```text +resource "teleport_app" "example" { + metadata = { + name = "example" + description = "Test app" + labels = { + // Teleport adds this label by default, so add it here to + // ensure a consistent state. + "teleport.dev/origin" = "dynamic" + } + } + + spec = { + uri = "localhost:3000" + } +} +``` + + + + +```text +resource "teleport_database" "example" { + metadata = { + name = "example" + description = "Test database" + labels = { + // Teleport adds this label by default, so add it here to + // ensure a consistent state. + "teleport.dev/origin" = "dynamic" + } + } + + spec = { + protocol = "postgres" + uri = "localhost" + } +} +``` + + + + +### Configure Teleport services in the agent pool + +Each Teleport service reads its local configuration file (`/etc/teleport.yaml` +by default) to determine which infrastructure resources to proxy. You can edit +this configuration file to enroll resources with Teleport. + +In the setup we explored in this guide, you can edit the user data script for +each instance to add configuration settings to, for example, the +`database_service` or `kubernetes_service` sections. + +To see how to configure each service, read its section of the documentation: + +- [SSH Service](../server-access/introduction.mdx) +- [Database Service](../database-access/introduction.mdx) +- [Kubernetes Service](../kubernetes-access/introduction.mdx) +- [Windows Desktop Service](../desktop-access/introduction.mdx) +- [Application Service](../application-access/introduction.mdx) diff --git a/docs/pages/agents/introduction.mdx b/docs/pages/agents/introduction.mdx new file mode 100644 index 0000000000000..e32a0156a6c2b --- /dev/null +++ b/docs/pages/agents/introduction.mdx @@ -0,0 +1,101 @@ +--- +title: "Teleport Agents" +description: Deploy agents to enroll resources in your infrastructure with Teleport. You can run multiple Teleport services per agent." +--- + +Teleport agents are Teleport instances that are configured to proxy traffic to +resources in your infrastructure, such as servers, databases, and Kubernetes +clusters. + +This section shows you how to use Teleport agents to enable secure access to +your infrastructure. + +## Architecture overview + +### Services + +Each Teleport agent can run one or more services. A Teleport instance runs a +service if it is enabled within the instance's configuration file. See the +[Teleport Configuration +Reference](../reference/config.mdx#enabling-teleport-services) for which +services are enabled by default and how to enable a particular service. + +### Agent pools + +Agents typically run in the same private networks as the resources they proxy. +They should be the only clients that can access a resource without Teleport. + +In this setup, agents dial the Teleport Proxy Service in order to establish +reverse SSH tunnels. While the Proxy Service remains open to the public internet +via its HTTPS port, agents require no open ports or public address. + +The Teleport Proxy Service uses these reverse tunnels to forward traffic in +Teleport's supported protocols to an available agent. Agents apply RBAC +rules and forward the traffic to resources in your infrastructure. + +```mermaid +%%{init: {"flowchart": {"curve": "linear"}}}%% +flowchart LR + proxy["Teleport Proxy Service"] + Clients--->proxy + subgraph private["Private network"] + db["Self-hosted database"] + app["Internal web application"] + subgraph agent2["Teleport agent"] + service3["Teleport Database Service"] + service4["Teleport Application Service"] + end + + subgraph agent1["Teleport agent"] + service1["Teleport Kubernetes Service"] + service2["Teleport SSH Service"] + end + + kubernetes["Kubernetes API server"] + ssh["SSH server"] + agent1 -.-> kubernetes & ssh + agent2 -.-> db + agent2 -.-> app + end + + agent1 & agent2--Reverse tunnel---->proxy + agent2-.->cloud["Cloud provider API"] +``` + +Read our guide for how to use Terraform to [deploy a pool of +agents](deploy-agents-terraform.mdx). + +## Joining agents + +Teleport agents need to establish trust with the Teleport Auth Service in order +to authorize users to access your infrastructure. There are several ways to join +an agent to your Teleport cluster, making it possible to automate the join +process for your environment. Read about the available join methods in our [Join +Services to your Cluster](./join-services-to-your-cluster.mdx) guides. + +## Enrolling infrastructure + +There are two ways to enroll infrastructure resources with Teleport agents: + +1. **Static**: Edit an agent's configuration file to configure a specific + infrastructure resource to proxy. +2. **Dynamic**: Apply a [configuration + resource](../management/dynamic-resources.mdx) that configures a resource to + proxy. + +The dynamic method allows Teleport to discover resources automatically. The +Discovery Service polls your cloud provider APIs and modifies dynamic +infrastructure resources as required. + +[Read our guide](deploy-agents-terraform.mdx) to deploying a pool of agents +via Terraform and enrolling infrastructure resources dynamically. + +To learn how to enroll resources via static configuration files, plus all the +ways Teleport supports enrolling infrastructure, consult our guides to each of +Teleport's services: + +- [SSH Service](../server-access/introduction.mdx) +- [Database Service](../database-access/introduction.mdx) +- [Kubernetes Service](../kubernetes-access/introduction.mdx) +- [Windows Desktop Service](../desktop-access/introduction.mdx) +- [Application Service](../application-access/introduction.mdx) diff --git a/docs/pages/management/join-services-to-your-cluster.mdx b/docs/pages/agents/join-services-to-your-cluster.mdx similarity index 90% rename from docs/pages/management/join-services-to-your-cluster.mdx rename to docs/pages/agents/join-services-to-your-cluster.mdx index a5a540091d9f8..2c746f9fa6ab3 100644 --- a/docs/pages/management/join-services-to-your-cluster.mdx +++ b/docs/pages/agents/join-services-to-your-cluster.mdx @@ -17,5 +17,6 @@ Service. Choose the method that best suits your infrastructure: |[AWS IAM](./join-services-to-your-cluster/aws-iam.mdx)|A Teleport process uses AWS credentials to join the cluster, whether running on EC2 or not.|At least some of your infrastructure runs on AWS and your Teleport cluster is self hosted.| |[Azure Managed Identity](./join-services-to-your-cluster/azure.mdx)|A Teleport process demonstrates that it runs in your Azure subscription by sending a signed attested data document and access token to the Teleport Auth Service.|Your Teleport process will run on Azure.| |[Kubernetes ServiceAccount](./join-services-to-your-cluster/kubernetes.mdx)|A Teleport process uses a Kubernetes-signed proof to establish a trust relationship with your Teleport cluster.|Your Teleport process will run on Kubernetes.| +|[GCP IAM](./join-services-to-your-cluster/gcp.mdx)|A Teleport process uses a GCP-signed token to establish a trust relationship with your Teleport cluster.|Your Teleport process will run on a GCP VM.| |[Join Token](./join-services-to-your-cluster/join-token.mdx)|A Teleport process presents a join token provided when starting the service.|There is no other supported method for your cloud provider.| diff --git a/docs/pages/management/join-services-to-your-cluster/aws-ec2.mdx b/docs/pages/agents/join-services-to-your-cluster/aws-ec2.mdx similarity index 100% rename from docs/pages/management/join-services-to-your-cluster/aws-ec2.mdx rename to docs/pages/agents/join-services-to-your-cluster/aws-ec2.mdx diff --git a/docs/pages/management/join-services-to-your-cluster/aws-iam.mdx b/docs/pages/agents/join-services-to-your-cluster/aws-iam.mdx similarity index 100% rename from docs/pages/management/join-services-to-your-cluster/aws-iam.mdx rename to docs/pages/agents/join-services-to-your-cluster/aws-iam.mdx diff --git a/docs/pages/management/join-services-to-your-cluster/azure.mdx b/docs/pages/agents/join-services-to-your-cluster/azure.mdx similarity index 100% rename from docs/pages/management/join-services-to-your-cluster/azure.mdx rename to docs/pages/agents/join-services-to-your-cluster/azure.mdx diff --git a/docs/pages/agents/join-services-to-your-cluster/gcp.mdx b/docs/pages/agents/join-services-to-your-cluster/gcp.mdx new file mode 100644 index 0000000000000..a5d922d5adc09 --- /dev/null +++ b/docs/pages/agents/join-services-to-your-cluster/gcp.mdx @@ -0,0 +1,101 @@ +--- +title: Join Services with GCP +description: Use the GCP join method to add services to your Teleport cluster. +--- + +This guide will explain how to use the **GCP join method** to configure Teleport +processes to join your Teleport cluster without sharing any secrets when they +are running in a GCP VM. + +The GCP join method is available to any Teleport process running on a GCP VM. +The VM must have a +[service account](https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances) +assigned to it (the default service account is fine). No IAM roles are required +on the Teleport process joining the cluster. + +## Prerequisites + +(!docs/pages/includes/edition-prereqs-tabs.mdx!) + +- A GCP VM to host a Teleport service, with a service account assigned to it + and with the Teleport binary installed. +- (!docs/pages/includes/tctl.mdx!) + +## Step 1/3. Create the GCP joining token + +Configure your Teleport Auth Service with a special dynamic token which will +allow services from your GCP projects to join your Teleport cluster. + +Under the hood, services will prove that they are running in your GCP project +by sending a signed ID token which matches an allow rule configured in your GCP +joining token. + +Create the following `token.yaml` file with a `gcp.allow` rule specifying your GCP +project ID(s), service account(s), and location(s) in which your GCP instances +will run: + +```yaml +# token.yaml +kind: token +version: v2 +metadata: + # the token name is not a secret because instances must prove that they are + # running in your GCP project to use this token + name: gcp-token +spec: + # use the minimal set of roles required (e.g. Node, Proxy, App, Kube, DB, WindowsDesktop) + roles: [Node] + + # set the join method allowed for this token + join_method: gcp + + gcp: + allow: + # The GCP project ID(s) that VMs can join from. + - project_ids: ["example-project-id"] + # (Optional) The locations that VMs can join from. Note: both regions and + # zones are accepted. + locations: ["us-west1", "us-west2-a"] + # (Optional) The email addresses of service accounts that VMs can join + # with. + service_accounts: ["example@example.com"] +``` + +Run the following command to create the token: + +```code +$ tctl create token.yaml +``` + +## Step 2/3. Configure your services + +The GCP join method can be used for Teleport processes running the SSH (`Node`), Proxy, +Kubernetes, Application, Database, or Windows Desktop Services. The Teleport +process should be run directly on a GCP VM. + +Configure your Teleport process with a custom `teleport.yaml` file. Use the +`join_params` section with `token_name` matching your token created in Step 1 +and `method: gcp` as shown in the following example config: + +```yaml +# /etc/teleport.yaml +version: v3 +teleport: + join_params: + token_name: gcp-token + method: gcp + proxy_server: https://teleport.example.com:443 +ssh_service: + enabled: yes +auth_service: + enabled: no +proxy_service: + enabled: no +``` + +## Step 3/3. Launch your Teleport process + +(!docs/pages/includes/start-teleport.mdx!) + +Once you have started Teleport, confirm that your service is able to connect to +and join your cluster. \ No newline at end of file diff --git a/docs/pages/management/join-services-to-your-cluster/join-token.mdx b/docs/pages/agents/join-services-to-your-cluster/join-token.mdx similarity index 99% rename from docs/pages/management/join-services-to-your-cluster/join-token.mdx rename to docs/pages/agents/join-services-to-your-cluster/join-token.mdx index d4ab0145c92d6..67ca62d13f17f 100644 --- a/docs/pages/management/join-services-to-your-cluster/join-token.mdx +++ b/docs/pages/agents/join-services-to-your-cluster/join-token.mdx @@ -335,4 +335,4 @@ $ tctl tokens rm - If you have workloads split across different networks or clouds, we recommend setting up Trusted Clusters. Read how to get started in our [Trusted Clusters - guide](../admin/trustedclusters.mdx). + guide](../../management/admin/trustedclusters.mdx). diff --git a/docs/pages/management/join-services-to-your-cluster/kubernetes.mdx b/docs/pages/agents/join-services-to-your-cluster/kubernetes.mdx similarity index 100% rename from docs/pages/management/join-services-to-your-cluster/kubernetes.mdx rename to docs/pages/agents/join-services-to-your-cluster/kubernetes.mdx diff --git a/docs/pages/ai-assist.mdx b/docs/pages/ai-assist.mdx index 875ff3fa94c72..d24a7f0489a83 100644 --- a/docs/pages/ai-assist.mdx +++ b/docs/pages/ai-assist.mdx @@ -35,7 +35,7 @@ Community Edition. Before you get started with Teleport Assist, make sure you have the following: - A running Teleport Community Edition cluster. For details on how to set this - up, see one of our [Getting Started](/docs/getting-started) guides. + up, see our [Getting Started](./index.mdx) guide. - **OpenAI Account**: You will need an active OpenAI account with GPT-4 API access as Teleport Assist relies on OpenAI services. @@ -45,13 +45,9 @@ Assist by signing up for a [Teleport Team plan](https://goteleport.com/pricing/). -Teleport Assist currently doesn't support: -- Teleport clusters using the etcd backend -- Per-session MFA (support coming soon) - -If your installation is using etcd or requires per-session MFA, you can create a -new cluster with any other backend without per-session MFA or sign up for the -Teleport Team plan. +Teleport Assist currently doesn't support Teleport clusters using the etcd backend. +If your installation is using etcd, you can create a new cluster with +any other backend or sign up for the Teleport Team plan. ## Step 1/3. Generate an OpenAI API key @@ -104,7 +100,7 @@ proxy_service: Make sure that your Teleport user has the `assistant` permission. By default, users -with built-in `auditor` and `editor` roles have this permission. You can also +with built-in `access` and `editor` roles have this permission. You can also add it to a custom role. Here is an example: ```yaml diff --git a/docs/pages/api/automatically-register-agents.mdx b/docs/pages/api/automatically-register-agents.mdx index 0132cd5d34fca..933b7e806bbf8 100644 --- a/docs/pages/api/automatically-register-agents.mdx +++ b/docs/pages/api/automatically-register-agents.mdx @@ -216,7 +216,7 @@ The program, which you can find in |---|---| |`context`|Includes the `context.Context` type. `context.Context` is an abstraction for controlling long-running routines, such as connections to external services, that might fail or time out. Programs can cancel contexts or assign them timeouts and metadata. | |`crypto/rand`|Includes cryptographic randomization functions, which we will use to generate join tokens for Application Services to use to establish trust with the Teleport Auth Service.| -|`encoding/hex`|The number generator we use from `crypto/rand` returns data in bytes, so we will encode these as hexadecimal strings using this package.| +|`encoding/hex`|The number generator we use from `crypto/rand` returns data in bytes, so we will encode these as hexadecimal strings using this package.| |`fmt`|Formats data for printing, strings, or errors.| |`net`|Deals with network I/O.| |`net/url`|Parses URLs.| @@ -228,7 +228,7 @@ The client imports the following third-party code: |Package|Description| |---|---| |`github.com/docker/docker/api/types`|Types used in the Docker daemon API. Aliased as `dtypes` here. | -|`github.com/docker/docker/api/types/container`|Container-specific types used in the Docker daemon API.| +|`github.com/docker/docker/api/types/container`|Container-specific types used in the Docker daemon API.| |`github.com/docker/docker/api/types/filters`|Types used for filtering containers in the Docker daemon API.| |`github.com/docker/docker/api/types/strslice`|A utility package for working with slices of strings in Docker's API client library. (In Go, slices are similar to arrays, but with variable lengths and capacities. Arrays have a fixed size.)| |`github.com/docker/docker/client`|The Docker API client library, aliased as `docker` here.| @@ -266,7 +266,7 @@ want to change later, including: |`proxyAddr`|The host and port of the Teleport Proxy Service, e.g., `mytenant.teleport.sh:443`, which we will use to connect the client to your cluster. **Assign this to your own Proxy Service's host and port.**| |`teleportImage`|The name of the Teleport container image, which the program will use to run instances of the Teleport Application Service.| |`initTimeout`|The timeout for connecting to the Teleport cluster (30 seconds).| -|`updateInterval`|How often the program will wait between reconciling Application Service instances and application containers (5 seconds).| +|`updateInterval`|How often the program will wait between reconciling Application Service instances and application containers (5 seconds).| |`tokenTTL`|How long of a TTL to set for join tokens that Application Service instances will use to establish trust with the Teleport cluster. This client application will use join tokens immediately after creating them, so we can set this TTL to a small value (5 minutes) to prevent this credential from leaking.| |`networkName`|The name of the Docker network to search for application containers. `bridge` is the default local network managed by the Docker daemon.| |`managementPort`|The management API port of our RabbitMQ containers.| @@ -529,8 +529,9 @@ corresponding role permissions with the `create` verb: |Resource|Method|Within a Role| |---|---|---| |Database|`*client.Client.CreateDatabase`|`db`| -|Kubernetes cluster|`*client.Client.CreateKubernetesCluster`|`kube_cluster`| -|Windows Desktop|`*client.Client.CreateWindowsDesktop`|`windows_desktop`| +|Kubernetes cluster|`*client.Client.CreateKubernetesCluster`|`kube_cluster`| +|Windows Desktop|`*client.Client.CreateWindowsDesktop`|`windows_desktop`| + Since a server must run an instance of the Teleport Service in order to join a Teleport cluster, API clients can only register servers by using tokens. diff --git a/docs/pages/api/rbac.mdx b/docs/pages/api/rbac.mdx index 8d09ff8a7c52b..06a7c3f2ebf9b 100644 --- a/docs/pages/api/rbac.mdx +++ b/docs/pages/api/rbac.mdx @@ -445,7 +445,7 @@ Here are the packages our client application imports from Go's standard library: |Package|Description| |---|---| -| `context` |Includes the `context.Context` type. `context.Context` is an abstraction for controlling long-running routines, such as connections to external services, that might fail or time out. Programs can cancel contexts or assign them timeouts and metadata.| +| `context`|Includes the `context.Context` type. `context.Context` is an abstraction for controlling long-running routines, such as connections to external services, that might fail or time out. Programs can cancel contexts or assign them timeouts and metadata.| |`fmt`|Formatting data for printing, strings, or errors.| |`io`|Dealing with I/O operations, e.g., reading files or network sockets.| |`os`|Interacting with the operating system, e.g., to open files.| @@ -455,12 +455,12 @@ The client imports the following third-party code: |Package|Description| |---|---| -|`github.com/gravitational/``teleport/api/client`|A library for authenticating to the Auth Service's gRPC API and making requests, aliased as `teleport`.| -|`github.com/gravitational/``teleport/api/types`|Types used in the Auth Service API, e.g., Application Service records.| +|`github.com/gravitational/teleport/api/client`|A library for authenticating to the Auth Service's gRPC API and making requests, aliased as `teleport`.| +|`github.com/gravitational/teleport/api/types`|Types used in the Auth Service API, e.g., Application Service records.| |`github.com/gravitational/trace`|Presenting errors with more useful detail than the standard library provides.| |`google.golang.org/grpc`|The gRPC client and server library.| |`k8s.io/api/rbac/v1`|The Kubernetes RBAC API client library.| -|`k8s.io/apimachinery/``pkg/apis/meta/v1`|Code common to Kubernetes' API client libraries.| +|`k8s.io/apimachinery/pkg/apis/meta/v1`|Code common to Kubernetes' API client libraries.| |`k8s.io/client-go/kubernetes`|Setting up an general-purpose Kubernetes client.| |`k8s.io/client-go/kubernetes/typed/rbac/v1`|Types for the Kubernetes RBAC API.| |`k8s.io/client-go/tools/clientcmd`|Another general-purpose Kubernetes client library.| @@ -490,7 +490,7 @@ want to change later, including: |`initTimeout`|The timeout for connecting to the Teleport cluster. We have defined this as 30 seconds.| |`identityFilePath`|The path to the Teleport identity file you created earlier.| |`clusterName`|The name of the Kubernetes cluster you will fetch RBAC resources from. In this guide, the cluster's name is `minikube`.| -|`roleAnnotationKey`|In Kubernetes, annotations are arbitrary key/value pairs that you can add to resources. The role and cluster role bindings we created earlier have the annotation key we specify here so our client application can fetch them.| +|`roleAnnotationKey`|In Kubernetes, annotations are arbitrary key/value pairs that you can add to resources. The role and cluster role bindings we created earlier have the annotation key we specify here so our client application can fetch them.| ### Initializing a Kubernetes RBAC client @@ -615,7 +615,7 @@ client's role type, based on the cluster role binding: |---|---|---| |`allow.kubernetes_labels`|Labels for Teleport-registered Kubernetes clusters that a user with this role is allowed to access.|Based on the Teleport-registered Kubernetes cluster that the cluster role binding belongs to.| |`allow.kubernetes_resources`|Kubernetes pods in specific namespaces that that a user with this role is allowed to access.|Allow access to all namespaces, since cluster role bindings are not restricted by namespace.| -|`allow.kubernetes_users` and `allow.kubernetes_groups`|The Kubernetes groups and users that a Teleport user with this role will assume when interacting with the Kubernetes cluster.|Supply the names of any users or groups connected to the cluster role binding.| +|`allow.kubernetes_users` and `allow.kubernetes_groups`|The Kubernetes groups and users that a Teleport user with this role will assume when interacting with the Kubernetes cluster.|Supply the names of any users or groups connected to the cluster role binding.| ### Creating a Teleport role from a Kubernetes role binding diff --git a/docs/pages/application-access/getting-started.mdx b/docs/pages/application-access/getting-started.mdx index 8b2b318998acc..c20fee2f19120 100644 --- a/docs/pages/application-access/getting-started.mdx +++ b/docs/pages/application-access/getting-started.mdx @@ -6,15 +6,15 @@ videoBanner: 5Uwhp3IQMHY Let's connect to Grafana using Teleport in three steps: -- Launch Grafana in a Docker container. -- Install the Teleport Application Service on a node and configure it to proxy Grafana. +- Launch Grafana in a Docker container or Kubernetes cluster. +- Install the Teleport Application Service and configure it to proxy Grafana. - Access Grafana through Teleport. ![Teleport Application Access Grafana Self-Hosted](../../img/application-access/grafana_selfhosted.png) -![Teleport Database Access CockroachDB Cloud](../../img/application-access/grafana_cloud.png) +![Teleport Application Access Grafana Cloud](../../img/application-access/grafana_cloud.png) ## Prerequisites @@ -22,102 +22,208 @@ Let's connect to Grafana using Teleport in three steps: (!docs/pages/includes/edition-prereqs-tabs.mdx!) - (!docs/pages/includes/tctl.mdx!) -- A Docker installation, which we will use to launch Grafana in a container. Alternatively, if you have another web application you'd like to protect with Teleport, you can use that instead. - A host where you will run the Teleport Application Service. + + +- A Docker installation, which we will use to launch Grafana in a container. + Alternatively, if you have another web application you'd like to protect with + Teleport, you can use that instead. + + + +(!docs/pages/includes/kubernetes-access/helm-k8s.mdx!) + +- Administrative rights to deploy within a cluster. + + + + -If you have not yet deployed the Auth Service and Proxy Service, you should follow one of our [getting started guides](../get-started.mdx) or try our Teleport Application Access [interactive learning track](https://play.instruqt.com/teleport/invite/rgvuva4gzkon). +{/*lint ignore messaging*/} +If you have not yet deployed the Auth Service and Proxy Service, you should +follow one of our [getting started guides](../index.mdx) or try our +Teleport Application Access [interactive learning track](https://play.instruqt.com/teleport/invite/rgvuva4gzkon). -We will assume your Teleport cluster is accessible at `teleport.example.com` and `*.teleport.example.com`. You can substitute the address of your Teleport Proxy Service. (For Teleport Cloud customers, this will be similar to `mytenant.teleport.sh`.) + - (!docs/pages/includes/dns-app-access.mdx!) + +Teleport Cloud will automatically provide a subdomain and signed TLS certificate +for your application under your tenant address. -## Step 1/3. Start Grafana +## Step 1/4. Generate a token + +A join token is required to authorize a Teleport Application Service instance to +join the cluster. Generate a short-lived join token and save it, for example, +in `/tmp/token`: + +```code +$ tctl tokens add \ + --type=app \ + --app-name=grafana \ + --app-uri=http://localhost:3000 +``` + + + + +## Step 2/4. Start Grafana We've picked Grafana for this tutorial since it's very easy to run with zero configuration required. If you have another web application you'd like to -expose, skip over to **Step 2**. +expose, skip over to **Step 3**. Grafana can be launched in a Docker container with a single command: ```code -$ docker run -d -p 3000:3000 grafana/grafana +$ docker run -d --name grafana -p 3000:3000 grafana/grafana ``` -## Step 2/3. Install and configure Teleport -(!docs/pages/includes/permission-warning.mdx!) +Next, we need to edit `/etc/grafana/grafana.ini` in the container. Under +`[server]`, uncomment the `domain` key and set the value to your Teleport +cluster domain, (e.g., `teleport.example.com`). Since there is no text editor +installed in the container, we can do this with `sed`: -On your Application Service host, download the latest version of Teleport for -your platform from our -[downloads page](https://goteleport.com/download). +```code +$ docker exec -u 0 grafana sed -i 's/;domain = localhost/domain = teleport.example.com/g' /etc/grafana/grafana.ini +``` -### Generate a token +Replace `teleport.example.com` with your Teleport cluster domain. -A join token is required to authorize a Teleport Application Service instance to -join the cluster. Generate a short-lived join token and save it, for example, -in `/tmp/token` on your Teleport Application Service host: +## Step 3/4. Install and configure Teleport -```code -$ tctl tokens add \ - --type=app \ - --app-name=grafana \ - --app-uri=http://localhost:3000 -``` +(!docs/pages/includes/permission-warning.mdx!) -### Start Teleport +### Configure and Start Teleport Install Teleport on the host where you will run the Teleport Application Service. See our [Installation](../installation.mdx) page for options besides Linux servers. (!docs/pages/includes/install-linux.mdx!) -Now start Teleport and point it to the application endpoint: +Create the Teleport Application Service configuration at `/etc/teleport.yaml`. +Replace with your Teleport Proxy Service +address (`teleport.example.com`) or Teleport Cloud tenant (e.g. `mytenant.teleport.sh`). ```code -$ sudo teleport app start \ - --name=grafana \ +$ sudo teleport configure \ + -o file \ + --proxy=:443 \ --token=/tmp/token \ - --uri=http://localhost:3000 \ - --auth-server=https://teleport.example.com:3080 + --roles=app \ + --app-name=grafana \ + --app-uri=http://localhost:3000 +``` + +Make sure to update `--app-name` and `--app-uri` accordingly if you're using your +own web application. + +The `--token` flag points to the file on the Application Service host where we +stored the token that we generated earlier. + +(!docs/pages/includes/start-teleport.mdx service="the Teleport Application Service"!) + + + + +## Step 2/4. Start Grafana + +We've picked Grafana for this tutorial since it's very easy to run with zero +configuration required. If you have another web application you'd like to +expose, skip over to **Step 3**. Install Grafana with these helm instructions +and it will be available at `http://example-grafana.example-grafana.svc.cluster.local` +within the Kubernetes cluster. + +```code +$ helm repo add grafana https://grafana.github.io/helm-charts +$ helm repo update +$ helm install example-grafana grafana/grafana \ + --create-namespace \ + --namespace example-grafana +``` + +## Step 3/4. Install and configure Teleport + + (!docs/pages/kubernetes-access/helm/includes/helm-repo-add.mdx!) + + +Install the Teleport Kubernetes Service into your Kubernetes Cluster +with the Teleport Application Service configuration. +Replace with +your Teleport Proxy Service address (`teleport.example.com`) or your +Teleport Enterprise Cloud tenant (e.g. `mytenant.teleport.sh`): + +```code +$ JOIN_TOKEN=$(cat /tmp/token) +$ helm install teleport-kube-agent teleport/teleport-kube-agent \ + --create-namespace \ + --namespace teleport-agent \ + --set roles=app \ + --set proxyAddr=:443 \ + --set authToken=${JOIN_TOKEN?} \ + --set "apps[0].name=grafana" \ + --set "apps[0].uri=http://example-grafana.example-grafana.svc.cluster.local" \ + --set "labels.env=dev" \ + --version (=teleport.version=) ``` -Change `https://teleport.example.com:3080` to the address and port of your Teleport Proxy Server. If you are a Teleport Cloud customer, use port 443 of your tenant's subdomain, e.g., `mytenant.teleport.sh:443`. + + +Install the Teleport Kubernetes Service into your Kubernetes Cluster +with the Teleport Application Service configuration. +Replace with +your Teleport Enterprise Cloud tenant address (`mytenant.teleport.sh`) +```code +$ JOIN_TOKEN=$(cat /tmp/token) +$ helm install teleport-kube-agent teleport/teleport-kube-agent \ + --create-namespace \ + --namespace teleport-agent \ + --set roles=app \ + --set proxyAddr=:443 \ + --set authToken=${JOIN_TOKEN?} \ + --set "apps[0].name=grafana" \ + --set "apps[0].uri=http://example-grafana.example-grafana.svc.cluster.local" \ + --set "labels.env=dev" \ + --version (=cloud.version=) +``` + -Make sure to update `--app-name` and `--app-uri` accordingly if you're using your own web application. +Make sure to update `apps[0].name` and `apps[0].uri` accordingly if you're using +your own web application. -The `--token` flag points to the file on the Application Service host where we stored the token that we generated earlier. + + ### Create a user -Next, let's create a user to access the application we've just connected. Teleport has a built-in role called `access` that allows users to access cluster resources. Create a local user assigned this role: +Next, let's create a user to access the application we've just connected. +Teleport has a built-in role called `access` that allows users to access +cluster resources. Create a local user assigned this role: ```code $ tctl users add --roles=access alice ``` -The command will output a signup link. Use it to choose a password and set up a second factor. After that, it will take you to the Teleport Web UI. +The command will output a signup link. Use it to choose a password and set up a +second factor. After that, it will take you to the Teleport Web UI. -## Step 3/3. Access the application +## Step 4/4. Access the application There are a couple of ways to access the proxied application. -Every application is assigned a public address that you can use to navigate to -the application directly. In our sample Grafana application we have provided a public address with -the `--app-public-addr` flag, so go to `https://grafana.teleport.example.com` -to access the app. - -Replace `grafana` with the value of the `--app-name` flag you used when starting the Teleport Application Service and `teleport.example.com` with the address of your Proxy Service. - -If you're not logged into Teleport, -you will need to authenticate before the application will show. +Log in to the Teleport Web UI at your Proxy Service address. All available +applications are displayed on the Applications tab. Click Launch on the Grafana +application tile to access it. -Alternatively, log in to the Teleport Web Interface at `https://teleport.example.com` (replace with your Proxy Service's public address). All available applications are displayed on the Applications tab. Click on the Grafana application tile to access it. +Alternatively call the application directly with its name as the sub-domain, +e.g. `https://grafana.teleport.example.com` or `https://grafana.mytenant.teleport.sh` +for a Teleport Cloud tenant. You will need to log in if you weren't already authenticated. ## Next steps -Dive deeper into the topics relevant to your Application Access use-case: +Dive deeper into protecting applications with Teleport: - Learn in more detail about [connecting applications](./guides/connecting-apps.mdx). - Learn about integrating with [JWT tokens](./jwt/introduction.mdx) for auth. diff --git a/docs/pages/application-access/guides/connecting-apps.mdx b/docs/pages/application-access/guides/connecting-apps.mdx index b2f14109173c3..7508b65242eea 100644 --- a/docs/pages/application-access/guides/connecting-apps.mdx +++ b/docs/pages/application-access/guides/connecting-apps.mdx @@ -96,6 +96,12 @@ a reverse tunnel. ### Application name +{/* +Note: this section of the docs is linked to from error messages in the product. +Please make sure to update lib/srv/servicecfg/app.go if you change this section +header or move this page. +*/} + An application name should make a valid sub-domain (\<=63 characters, no spaces, only `a-z 0-9 -` allowed). After Teleport is running, users can access the app at `app-name.proxy_public_addr.com` diff --git a/docs/pages/application-access/okta/guide.mdx b/docs/pages/application-access/okta/guide.mdx index 9318b466343c4..4cccb29ed1591 100644 --- a/docs/pages/application-access/okta/guide.mdx +++ b/docs/pages/application-access/okta/guide.mdx @@ -16,13 +16,48 @@ configurations to enable it. ## Prerequisites -(!docs/pages/includes/edition-prereqs-tabs.mdx!) +(!docs/pages/includes/commercial-prereqs-tabs.mdx!) - (!docs/pages/includes/tctl.mdx!) -- An Okta organization with an [Okta API token](https://developer.okta.com/docs/guides/create-an-api-token) provisioned. - A running Teleport cluster with Okta login configured. - An instance where you will run the Okta Service. This can live anywhere with outbound access to Okta and must be running Linux. +- An Okta organization with an [Okta API token](https://developer.okta.com/docs/guides/create-an-api-token) created. + +
+ +Okta API tokens inherit the permissions of the user who created them. These can +be controlled by using [custom admin roles](https://help.okta.com/en-us/Content/Topics/Security/custom-admin-role/about-creating-custom-admin-roles.htm) +and assigning them to a user who will then create the API token. We recommend +creating a user dedicated to the Teleport Okta API service to manage this token. + +The permissions required are: + +### User permissions + +- View users and their details +- Edit users' group membership +- Edit users' application assignments + +### Group permissions + +- View groups and their details +- Manage group membership + +### Application permissions + +- View applications and their details +- Edit application's user assignments + +Additionally, the resource set associated with the target user must have unconstrained +access to Users, Applications, and Groups. + +One caveat here is that it's impossible to assign API token creation permissions to a +custom role. However, the Okta built in role "Group Membership Admin" has permissions +to create an API token. See more information about built in roles +[here](https://help.okta.com/en-us/Content/Topics/Security/administrators-admin-comparison.htm). + +
## Step 1/3. Create Okta import rules @@ -30,7 +65,7 @@ Before setting up the Okta Service, you should create Okta import rules in order to ensure that our Okta applications are set up with appropriate labeling before you attempt to synchronize them. First, you'll need to get the group and application IDs from Okta. The easiest way to do this is to use the -provisioned earlier. +that was created when when evaluating the prerequisites. To get group IDs: @@ -152,8 +187,8 @@ ssh_service: enabled: no okta_service: enabled: yes - api_endpoint: - api_token_path: + api_endpoint: + api_token_path: ``` Edit `/etc/teleport.yaml` to replace `teleport.example.com:443` with the host diff --git a/docs/pages/architecture/authentication.mdx b/docs/pages/architecture/authentication.mdx index 7a66f3c2546c9..e229f47e07f2d 100644 --- a/docs/pages/architecture/authentication.mdx +++ b/docs/pages/architecture/authentication.mdx @@ -143,7 +143,7 @@ services and rotates SSH and X.509 certificates. Teleport internal services - Auth, Proxy and Nodes use certificates to identify themselves within a cluster. To join proxies and nodes to the cluster and receive certificates, admins should use -[short-lived tokens or cloud identity services](../management/join-services-to-your-cluster/join-token.mdx). +[short-lived tokens or cloud identity services](../agents/join-services-to-your-cluster/join-token.mdx). Unlike users and services, internal services receive long-lived certificates. diff --git a/docs/pages/architecture/authorization.mdx b/docs/pages/architecture/authorization.mdx index 06b8b09881a51..41db7ead8f275 100644 --- a/docs/pages/architecture/authorization.mdx +++ b/docs/pages/architecture/authorization.mdx @@ -62,7 +62,7 @@ This list is called "role mappings". Teleport supports non-interactive users for automation services, e.g. Jenkins or micro-services running in your organization. -### Local non-interactive users +#### Local non-interactive users Local non-interactive users also have a user entry that maps their name to roles, but they do not have credentials stored in the database. @@ -79,7 +79,7 @@ of non-interactive users: ![Certificates for services](../../img/architecture/certs-machine-id@1.8x.svg) -### External non-interactive users +#### External non-interactive users External non-interactive users behave just like local ones, but it is another cluster or certificate authority that issues certificates for them. diff --git a/docs/pages/architecture/session-recording.mdx b/docs/pages/architecture/session-recording.mdx index 95f948c50cc04..c1f49e4d6b599 100644 --- a/docs/pages/architecture/session-recording.mdx +++ b/docs/pages/architecture/session-recording.mdx @@ -10,18 +10,41 @@ configuration options that apply to session recordings. The content that is captured depends on the type of the session. -- SSH sessions: Teleport captures the entire pseudo-terminal (PTY) output - of the session. -- Kubernetes sessions: Teleport captures the entire PTY output for - `kubectl exec` invocations. -- Desktop sessions: Teleport captures the contents of the desktop screen - and any mouse input. Teleport does not capture keystrokes in the remote - desktop. -- App sessions: Teleport captures a stream of `app.session.request` - audit events related to application access. The audit events are - bucketed into 5-minute time intervals informally referred to as "chunks." -- Database sessions: Teleport captures a stream of audit events - related to the database being accessed. +### SSH sessions + +Teleport captures the entire pseudo-terminal (PTY) output of the session. The +intention is for session recording to document what a user saw when they ran a +session. + +Note that the design of session recording carries some security risks. Namely, +users can conceal terminal commands by encoding them (e.g., using `base64`), +running scripts from disk or the internet, or changing the terminal settings. If +this presents an issue for your environment, consider using the BPF-based +[Enhanced Session Recording](../server-access/guides/bpf-session-recording.mdx) +instead. + +### Kubernetes sessions + +Teleport captures the entire PTY output for `kubectl exec` invocations. + +Kubernetes session recording carries the same security risks as SSH session +recording. + +### Desktop sessions + +Teleport captures the contents of the desktop screen and any mouse input. +Teleport does not capture keystrokes in the remote desktop. + +### App sessions + +Teleport captures a stream of `app.session.request` audit events related to +application access. The audit events are bucketed into 5-minute time intervals +informally referred to as "chunks." + +### Database sessions + +Teleport captures a stream of audit events related to the database being +accessed. ## Session recording configurations @@ -41,7 +64,7 @@ Teleport cluster. It can be configured by setting `session_recording` in the `auth_service` section of your `teleport.yaml`, or dynamically via the the `session_recording_config` resource. If you need to apply different recording configuration to different sets of resources, we recommend setting up -[Trusted Clusters](/docs/management/admin/trustedclusters/) with their own +[Trusted Clusters](../management/admin/trustedclusters.mdx) with their own recording configurations. diff --git a/docs/pages/choose-an-edition/introduction.mdx b/docs/pages/choose-an-edition/introduction.mdx index 08e95222c77fa..9df77665bd3e8 100644 --- a/docs/pages/choose-an-edition/introduction.mdx +++ b/docs/pages/choose-an-edition/introduction.mdx @@ -38,7 +38,7 @@ compliance. We provide a free, open source distribution of Teleport that enables you to get secure access to databases, Windows desktops, Kubernetes clusters, and more. -[Try out Teleport on a Linux server](../get-started.mdx). If you would like to +[Try out Teleport on a Linux server](../index.mdx). If you would like to take a look at the source, visit the [Teleport GitHub repository](https://github.com/gravitational/teleport). diff --git a/docs/pages/choose-an-edition/teleport-cloud/downloads.mdx b/docs/pages/choose-an-edition/teleport-cloud/downloads.mdx index 329299dcd697c..c3d2d18b97d12 100644 --- a/docs/pages/choose-an-edition/teleport-cloud/downloads.mdx +++ b/docs/pages/choose-an-edition/teleport-cloud/downloads.mdx @@ -19,7 +19,14 @@ Binaries include: |`teleport`| The Teleport binary that you can run within your private networks to enable access to resources in your infrastructure| |`tctl`| A client tool for managing Teleport resources| |`tsh`| A client tool for accessing resources within your cluster| -|`tbot`| A client tool you will use to associate a bot user with a machine identity| +|`tbot`| The agent for [Teleport's Machine ID](../../machine-id/introduction.mdx)| + + +For macOS, `tsh` comes in the main Teleport package and also in a separate client-only package. +The client-only package includes a signed variant of `tsh`. Certain functionality, such as Touch ID support, +only works when `tsh` has been signed. Therefore, if you are installing the main Teleport package on a macOS system, +we recommend you first install the main Teleport package and then install the client-only package over this. + Here are the available archives: @@ -27,7 +34,7 @@ Description | | | | | -----------------------------------|-|-|-|-| Linux (Debian/Ubuntu compatible) | [amd64](https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-linux-amd64-bin.tar.gz) | [arm64](https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-linux-arm64-bin.tar.gz) | [armv7](https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-linux-arm-bin.tar.gz) | [i386](https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-linux-386-bin.tar.gz) | Linux (RHEL/CentOS 7.x compatible) | [amd64](https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-linux-amd64-centos7-bin.tar.gz) | -macOS | [amd64](https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-darwin-amd64-bin.tar.gz) | +macOS | [universal amd64/arm64](https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-darwin-universal-bin.tar.gz) | [amd64](https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-darwin-amd64-bin.tar.gz) | [arm64](https://cdn.teleport.dev/teleport-v(=cloud.version=)-darwin-arm64-bin.tar.gz) | ## Teleport packages @@ -41,7 +48,7 @@ Binaries include: |`teleport`| The Teleport binary that you can run within your private networks to enable access to resources in your infrastructure| |`tctl`| A client tool for managing Teleport resources| |`tsh`| A client tool for accessing resources within your cluster| -|`tbot`| A client tool you will use to associate a bot user with a machine identity| +|`tbot`| The agent for [Teleport's Machine ID](../../machine-id/introduction.mdx)| Here are the available archives: @@ -49,47 +56,14 @@ Description | | | | | -----------------------------------|-|-|-|-| Linux Debian Packages | [amd64](https://cdn.teleport.dev/teleport-ent_(=cloud.version=)_amd64.deb) | [arm64](https://cdn.teleport.dev/teleport-ent_(=cloud.version=)_arm64.deb) | [armv7](https://cdn.teleport.dev/teleport-ent_(=cloud.version=)_arm.deb) | [i386](https://cdn.teleport.dev/teleport-ent_(=cloud.version=)_i386.deb) | Linux RPM Packages | [amd64](https://cdn.teleport.dev/teleport-ent-(=cloud.version=)-1.x86_64.rpm) | [arm64](https://cdn.teleport.dev/teleport-ent-(=cloud.version=)-1.arm64.rpm) | [armv7](https://cdn.teleport.dev/teleport-ent-(=cloud.version=)-1.arm.rpm) | [i386](https://cdn.teleport.dev/teleport-ent-(=cloud.version=)-1.i386.rpm) | -macOS Packages | [amd64](https://cdn.teleport.dev/teleport-ent-(=cloud.version=).pkg) | +macOS Packages | [universal amd64/arm64](https://cdn.teleport.dev/teleport-ent-(=cloud.version=).pkg) | ## Teleport package repositories Teleport currently maintains DEB and RPM package repositories. Follow these instructions to add a package repository and install Teleport. - - - ```code - # Download Teleport's PGP public key - $ sudo curl https://apt.releases.teleport.dev/gpg \ - -o /usr/share/keyrings/teleport-archive-keyring.asc - # Source variables about OS version - $ source /etc/os-release - # Add the Teleport APT repository for v(=cloud.major_version=). You'll need to update this - # file for each major (breaking) release of Teleport. - # Note: if using a fork of Debian or Ubuntu you may need to use '$ID_LIKE' - # and the codename your distro was forked from instead of '$ID' and '$VERSION_CODENAME'. - # Supported versions are listed here: https://github.com/gravitational/teleport/blob/master/build.assets/tooling/cmd/build-apt-repos/main.go#L26 - $ echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] \ - https://apt.releases.teleport.dev/${ID?} ${VERSION_CODENAME?} stable/v(=cloud.major_version=)" \ - | sudo tee /etc/apt/sources.list.d/teleport.list > /dev/null - $ sudo apt-get update - $ sudo apt-get install teleport-ent - ``` - - - ```code - # Source variables about OS version - $ source /etc/os-release - # Add the Teleport YUM repository for v(=cloud.major_version=). You'll need to update this - # file for each major release of Teleport. - # Note: if using a fork of RHEL/CentOS or Amazon Linux you may need to use '$ID_LIKE' - # and the codename your distro was forked from instead of '$ID' - $ sudo yum-config-manager \ - --add-repo $(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/v(=cloud.major_version=)/teleport.repo") - $ sudo yum install teleport-ent - ``` - - +(!docs/pages/includes/cloud/install-linux-cloud.mdx!) ## Teleport client-only packages @@ -106,5 +80,5 @@ Here are the available archives: Description | | -----------------------------------|-| -macOS | [amd64](https://cdn.teleport.dev/tsh-(=cloud.version=).pkg) | +macOS | [universal amd64/arm64 signed](https://cdn.teleport.dev/tsh-(=cloud.version=).pkg) | Windows | [amd64](https://cdn.teleport.dev/teleport-v(=cloud.version=)-windows-amd64-bin.zip) | diff --git a/docs/pages/choose-an-edition/teleport-cloud/faq.mdx b/docs/pages/choose-an-edition/teleport-cloud/faq.mdx index 019d508d2a1e3..8b752cfc3cb65 100644 --- a/docs/pages/choose-an-edition/teleport-cloud/faq.mdx +++ b/docs/pages/choose-an-edition/teleport-cloud/faq.mdx @@ -35,8 +35,7 @@ related information on the [Teleport Trust Portal](https://trust.goteleport.com) ### How do you store passwords? -Password hashes are generated using -[Golang's bcrypt](https://pkg.go.dev/golang.org/x/crypto/bcrypt). +Password hashes are generated using [bcrypt](https://pkg.go.dev/golang.org/x/crypto/bcrypt). ### Do you encrypt data at rest? @@ -61,9 +60,9 @@ Enterprise Cloud. We do not have plans to offer support for inbound connection IP allowlists. -We believe mTLS with strong user and [device -identity](../../access-controls/guides/device-trust.mdx) provides the best -available security for client authentication. +We believe mTLS with strong user and [device identity]( +../../access-controls/device-trust/guide.mdx) provides the best available +security for client authentication. For customers that require IP-based control for compliance purposes, we do support IP Pinning. For more information see `pin_source_ip` in our [Teleport @@ -77,8 +76,9 @@ S3, are established using encryption provided by AWS, both at rest and in transi ### How do I add resources to Teleport Enterprise Cloud? -You can connect servers, Kubernetes clusters, databases and applications using -[reverse tunnels](../../management/join-services-to-your-cluster.mdx). +You can connect servers, Kubernetes clusters, databases, desktops, and +applications using [reverse +tunnels](../../agents/join-services-to-your-cluster.mdx). There is no need to open any ports on your infrastructure for inbound traffic. @@ -89,7 +89,7 @@ If you plan on connecting more than 10,000 nodes or agents, please contact your ### Are dynamic node tokens available? After [connecting](#how-can-i-access-the-tctl-admin-tool) `tctl` to Teleport Enterprise Cloud, users can generate -[dynamic tokens](../../management/join-services-to-your-cluster/join-token.mdx): +[dynamic tokens](../../agents/join-services-to-your-cluster/join-token.mdx): ```code $ tctl nodes add --ttl=5m --roles=node,proxy --token=$(uuid) @@ -135,8 +135,8 @@ The ability to download recordings for offline viewing will be available in a fu ### Will Teleport be automatically upgraded with each release? -Teleport Cloud follows the Teleport [Production -readiness](../../upcoming-releases.mdx) guidelines. +Teleport Cloud follows the Teleport [Upcoming +Releases](../../upcoming-releases.mdx) timelines. - Major version upgrades for customer Auth and Proxy Servers occur after the first minor release (for example (=teleport.major_version=).1.0) of Teleport. @@ -144,6 +144,8 @@ readiness](../../upcoming-releases.mdx) guidelines. becoming available. - After the first minor release, subsequent minor and patch upgrades typically occur within a week. +- Your Teleport tenant will NOT be automatically upgraded to the next major version if any + Teleport agents connected to the cluster are not compatible (> 1 major version behind). ### Are upgrades times configurable for my Teleport Enterprise Cloud tenant? @@ -299,5 +301,3 @@ address traffic to any individual software instance within the cluster. ### How do I set up recovery codes for my account so I don't lose access? We have a [short step-by-step guide](https://github.com/gravitational/teleport/discussions/12379) on setting up recovery codes. - - diff --git a/docs/pages/choose-an-edition/teleport-cloud/introduction.mdx b/docs/pages/choose-an-edition/teleport-cloud/introduction.mdx index 9ce2191030607..fde45c015d001 100644 --- a/docs/pages/choose-an-edition/teleport-cloud/introduction.mdx +++ b/docs/pages/choose-an-edition/teleport-cloud/introduction.mdx @@ -7,9 +7,10 @@ videoBanner: 1jhKOtBinm4 Teleport Enterprise Cloud is a managed service to provide access to secure infrastructure all over the world without passwords or shared secrets. -When you [sign up for a Teleport Enterprise Cloud account](https://goteleport.com/signup/), you will receive a subdomain of -`teleport.sh` that is dedicated to your tenant and points to the Teleport Proxy -Service. +When you [sign up for a Teleport Team account](https://goteleport.com/signup/) +(which you can upgrade to a Teleport Enterprise Cloud account), you will receive +a subdomain of `teleport.sh` that is dedicated to your tenant and points to the +Teleport Proxy Service. Our Teleport Enterprise Cloud team handles the following tasks for you: diff --git a/docs/pages/choose-an-edition/teleport-enterprise/introduction.mdx b/docs/pages/choose-an-edition/teleport-enterprise/introduction.mdx index e03695dc77990..d1f30d94db181 100644 --- a/docs/pages/choose-an-edition/teleport-enterprise/introduction.mdx +++ b/docs/pages/choose-an-edition/teleport-enterprise/introduction.mdx @@ -22,7 +22,14 @@ The table below gives a quick overview of the benefits of Teleport Enterprise. type="tip" title="Contact Information" > - Try Teleport Enterprise for [free in the cloud](https://goteleport.com/signup/) or [contact sales](https://goteleport.com/signup/enterprise/). + + To get started with self-hosted Teleport Enterprise, [contact + sales](https://goteleport.com/signup/enterprise/). + + You can also sign up for a [free trial](https://goteleport.com/signup) of + Teleport Team, which manages the Auth Service and Proxy Service for you. You + can then upgrade your account to Teleport Enterprise Cloud. + ## SSO @@ -53,13 +60,6 @@ Moreover, SSO can be used in combination with role-based access control (RBAC) to enforce SSH access policies like *"developers must not touch production data"*. See the [SSO](../../access-controls/sso.mdx) chapter for more details. - - Try Teleport Enterprise for [free in the cloud](https://goteleport.com/signup/) or [contact sales](https://goteleport.com/signup/enterprise/). - - ## FedRAMP/FIPS With Teleport we have built the foundation to meet FedRAMP requirements for the purposes of accessing infrastructure. This includes support for [FIPS 140-2](https://en.wikipedia.org/wiki/FIPS\_140-2), also known as the Federal Information Processing Standard, which is the US government approved standard for cryptographic modules. @@ -123,5 +123,5 @@ Unless your organization requires the Enterprise-specific features we outlined above, you can use Teleport Enterprise Cloud to achieve secure access to your infrastructure without needing to maintain the Auth and Proxy Services. -[Sign up for a free trial of Teleport Enterprise -Cloud](https://goteleport.com/signup/). +[Sign up for a free trial of Teleport Team](https://goteleport.com/signup/), +which you can upgrade to a Teleport Enterprise Cloud account. diff --git a/docs/pages/choose-an-edition/teleport-team.mdx b/docs/pages/choose-an-edition/teleport-team.mdx index 9d25d01b276b7..35f7089976d23 100644 --- a/docs/pages/choose-an-edition/teleport-team.mdx +++ b/docs/pages/choose-an-edition/teleport-team.mdx @@ -217,24 +217,15 @@ infrastructure by registering a server with your Teleport Team cluster. From here, you can explore more of the documentation to see how to set up secure access for your infrastructure. -### Register resources +To enroll your infrastructure with Teleport, you deploy one or more Teleport +**agents**, which proxy traffic to resources like servers, databases, Kubernetes +clusters, cloud provider APIs, and Windows desktops. -Read about how you can register resources in your infrastructure, including: +You can use Terraform to declare a pool of Teleport agents and configure them to +proxy your infrastructure. Read [Deploy Teleport Agents with +Terraform](../agents/deploy-agents-terraform.mdx). - - [Additional SSH servers](../server-access/introduction.mdx) - - [Cloud provider tools and internal web applications](../application-access/introduction.mdx) - - [Databases](../database-access/introduction.mdx) - - [Kubernetes clusters](../kubernetes-access/introduction.mdx) - - [Service accounts](../machine-id/introduction.mdx) - - [Windows desktops](../desktop-access/introduction.mdx) - -### Connect to your infrastructure - -Aside from `tsh` and the Web UI, you can also connect to Teleport with our -desktop application, [Teleport -Connect](../connect-your-client/teleport-connect.mdx). - -### Subscribe +## Subscribe After you finish your free trial, Teleport Team will charge based on usage. Check the [pricing page](https://goteleport.com/pricing/) for detailed diff --git a/docs/pages/connect-your-client/introduction.mdx b/docs/pages/connect-your-client/introduction.mdx index 0bb8476056230..a0640106c4be4 100644 --- a/docs/pages/connect-your-client/introduction.mdx +++ b/docs/pages/connect-your-client/introduction.mdx @@ -17,6 +17,7 @@ Teleport, and includes links to more detailed documentation at the end. [downloading](https://goteleport.com/download/) and installing `tsh`, sign in to your Teleport cluster: + ```code @@ -33,6 +34,48 @@ Tap any security key Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty, private-key-policy ``` + + + +```code +$ tsh login --proxy= --auth=github +If browser window does not open automatically, open it by clicking on the link: + http://127.0.0.1:49927/1d80e257-ec61-4ed2-9403-784f8d35b2fe +> Profile URL: https://teleport.example.com:443 + Logged in as: user@example.com + Cluster: example.com + Roles: access + Logins: ubuntu, ec2-user + Kubernetes: enabled + Valid until: 2022-11-01 22:37:05 -0500 CDT [valid for 12h0m0s] + Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty, private-key-policy +``` + +Depending on how Teleport was configured for your network, you may not need +the additional flags `--auth`. Your administrator should provide the details +required for your particular use case. + + + + + + + + +```code +$ tsh login --proxy= --user= +Enter password for Teleport user alice: +Tap any security key +> Profile URL: https://teleport.example.com:443 + Logged in as: alice + Cluster: example.com + Roles: access, requester + Logins: ubuntu, ec2-user + Kubernetes: enabled + Valid until: 2022-11-01 22:37:05 -0500 CDT [valid for 12h0m0s] + Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty, private-key-policy +``` + @@ -43,7 +86,7 @@ If browser window does not open automatically, open it by clicking on the link: > Profile URL: https://teleport.example.com:443 Logged in as: user@example.com Cluster: example.com - Roles: access + Roles: access, requester Logins: ubuntu, ec2-user Kubernetes: enabled Valid until: 2022-11-01 22:37:05 -0500 CDT [valid for 12h0m0s] @@ -56,6 +99,7 @@ required for your particular use case. + ### Teleport Connect diff --git a/docs/pages/connect-your-client/teleport-connect.mdx b/docs/pages/connect-your-client/teleport-connect.mdx index 94d1c166d75dc..6acd9b7e8c737 100644 --- a/docs/pages/connect-your-client/teleport-connect.mdx +++ b/docs/pages/connect-your-client/teleport-connect.mdx @@ -196,6 +196,9 @@ Below is the list of the supported config properties. | Property | Default | Description | |-------------------------------|----------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------| +| `theme` | `system` | Color theme for the app. Available modes: `light`, `dark`, `system`. | +| `terminal.fontFamily` | `Menlo, Monaco, monospace` on macOS
`Consolas, monospace` on Windows
`'Droid Sans Mono', monospace` on Linux | Font family for the terminal. | +| `terminal.fontSize` | 15 | Font size for the terminal. | | `usageReporting.enabled` | `false` | Enables collecting anonymous usage data (see [Telemetry](#telemetry)). | | `keymap.tab1` - `keymap.tab9` | `Command+1` - `Command+9` on macOS
`Ctrl+1` - `Ctrl+9` on Windows
`Alt+1` - `Alt+9` on Linux | Shortcut to open tab 1–9. | | `keymap.closeTab` | `Command+W` on macOS
`Ctrl+W` on Windows/Linux | Shortcut to close a tab. | @@ -207,8 +210,6 @@ Below is the list of the supported config properties. | `keymap.openClusters` | `Command+E` on macOS
`Ctrl+E` on Windows/Linux | Shortcut to open the cluster selector. | | `keymap.openProfiles` | `Command+I` on macOS
`Ctrl+I` on Windows/Linux | Shortcut to open the profile selector. | | `keymap.openSearchBar` | `Command+K` on macOS
`Ctrl+K` on Windows/Linux | Shortcut to open the search bar. | -| `terminal.fontFamily` | `Menlo, Monaco, monospace` on macOS
`Consolas, monospace` on Windows
`'Droid Sans Mono', monospace` on Linux | Font family for the terminal. | -| `terminal.fontSize` | 15 | Font size for the terminal. | + with your Proxy Service address (e.g. `mytenant.teleport.sh` for Teleport + Enterprise Cloud): + + ```code + $ curl https:///webapi/find | jq '.server_version' + "(=teleport.version=)" + ``` + +(!docs/pages/includes/install-tsh.mdx!) ## User identities @@ -149,7 +167,7 @@ $ tsh login --proxy=mytenant.teleport.sh | Port | Description | | - | - | -| https_proxy_port | the HTTPS port the proxy host is listening to (defaults to `3080`). | +| https_proxy_port | the HTTPS port the proxy host is listening to (defaults to `443` and `3080`). | The login command retrieves a user's certificate and stores it in `~/.tsh` directory as well as in the [ssh agent](https://en.wikipedia.org/wiki/Ssh-agent) if there is one running. @@ -878,5 +896,11 @@ exit end of session playback ``` +## Uninstalling tsh + +To remove `tsh` and associated user data see +[Uninstalling Teleport](../management/admin/uninstall-teleport.mdx). + ## Further reading - [CLI Reference](../reference/cli.mdx). + diff --git a/docs/pages/core-concepts.mdx b/docs/pages/core-concepts.mdx index 3ebe6080c6ac8..b6868be61cacd 100644 --- a/docs/pages/core-concepts.mdx +++ b/docs/pages/core-concepts.mdx @@ -17,7 +17,7 @@ within your infrastructure, such as Kubernetes clusters and Windows desktops. A minimal Teleport cluster consists of the **Teleport Auth Service** and **Teleport Proxy Service**. In a demo environment, you can run these two services from a single `teleport` process on a [Linux -host](./get-started.mdx). +host](./index.mdx). ### Teleport Auth Service diff --git a/docs/pages/database-access/getting-started.mdx b/docs/pages/database-access/getting-started.mdx index 360f822c8ac8f..38d5caf3f1e2c 100644 --- a/docs/pages/database-access/getting-started.mdx +++ b/docs/pages/database-access/getting-started.mdx @@ -167,9 +167,16 @@ EOF Create the Teleport user assigned the `db` role we've just created: + ```code $ tctl users add --roles=access,db alice ``` + + +```code +$ tctl users add --roles=access,requester,db alice +``` + ## Step 4/4. Connect diff --git a/docs/pages/database-access/guides/aws-cassandra-keyspaces.mdx b/docs/pages/database-access/guides/aws-cassandra-keyspaces.mdx index ee21c7f4640bc..0a860ca91cd40 100644 --- a/docs/pages/database-access/guides/aws-cassandra-keyspaces.mdx +++ b/docs/pages/database-access/guides/aws-cassandra-keyspaces.mdx @@ -33,7 +33,6 @@ This guide will help you to: - AWS Account with AWS Keyspaces database and permissions to create and attach IAM policies - The `cqlsh` Cassandra client installed and added to your system's `PATH` environment variable. - A host, e.g., an Amazon EC2 instance, where you will run the Teleport Database Service. - - (!docs/pages/includes/tctl.mdx!) ## Step 1/5. Set up the Teleport Database Service diff --git a/docs/pages/database-access/guides/aws-dynamodb.mdx b/docs/pages/database-access/guides/aws-dynamodb.mdx index 00eaacd981637..0cd6435f0aa8a 100644 --- a/docs/pages/database-access/guides/aws-dynamodb.mdx +++ b/docs/pages/database-access/guides/aws-dynamodb.mdx @@ -31,7 +31,6 @@ This guide will help you to: - A host, e.g., an EC2 instance, where you will run the Teleport Database Service. This guide assumes an EC2 instance when creating and applying IAM roles, and must be adjusted accordingly for custom configurations. - - (!docs/pages/includes/tctl.mdx!) diff --git a/docs/pages/database-access/guides/aws-opensearch.mdx b/docs/pages/database-access/guides/aws-opensearch.mdx index 7e1e616794788..321908968f370 100644 --- a/docs/pages/database-access/guides/aws-opensearch.mdx +++ b/docs/pages/database-access/guides/aws-opensearch.mdx @@ -177,8 +177,8 @@ Teleport: - [Configure Teleport to Automatically Enroll EC2 instances (Preview)](../../server-access/guides/ec2-discovery.mdx) - [Joining Nodes via AWS IAM - Role](../../management/join-services-to-your-cluster/aws-iam.mdx) -- [Joining Nodes via AWS EC2 Identity Document](../../management/join-services-to-your-cluster/aws-ec2.mdx) + Role](../../agents/join-services-to-your-cluster/aws-iam.mdx) +- [Joining Nodes via AWS EC2 Identity Document](../../agents/join-services-to-your-cluster/aws-ec2.mdx)
diff --git a/docs/pages/database-access/guides/azure-postgres-mysql.mdx b/docs/pages/database-access/guides/azure-postgres-mysql.mdx index 17b0830eae930..bb288df65f07c 100644 --- a/docs/pages/database-access/guides/azure-postgres-mysql.mdx +++ b/docs/pages/database-access/guides/azure-postgres-mysql.mdx @@ -142,9 +142,9 @@ spec: | Flag | Description | |----------------------------|------------------------------------------------------------------------------------------------------------------------------------------| -| `--db-users` | List of database usernames the user will be allowed to use when connecting to the databases. A wildcard allows any user. | -| `--db-names` | List of logical databases (aka schemas) the user will be allowed to connect to within a database server. A wildcard allows any database. | -| `--db-labels` | List of labels assigned to the database the user will be able to access. A wildcard entry allows any database. | +| `--db-users` | List of database usernames the user will be allowed to use when connecting to the databases. A wildcard allows any user. | +| `--db-names` | List of logical databases (aka schemas) the user will be allowed to connect to within a database server. A wildcard allows any database. | +| `--db-labels` | List of labels assigned to the database the user will be able to access. A wildcard entry allows any database. | Save this file and apply it to your Teleport cluster: diff --git a/docs/pages/database-access/guides/cassandra-self-hosted.mdx b/docs/pages/database-access/guides/cassandra-self-hosted.mdx index 1988e25321b93..18cb6099d4682 100644 --- a/docs/pages/database-access/guides/cassandra-self-hosted.mdx +++ b/docs/pages/database-access/guides/cassandra-self-hosted.mdx @@ -145,7 +145,7 @@ databases: ```code - $ tsh login --proxy=teleport.example.com --user=testuser + $ tsh login --proxy=teleport.example.com --user=alice $ tsh db ls # Name Description Allowed Users Labels Connect # --------- ----------------- ------------- ------- ------- @@ -156,7 +156,7 @@ databases: ```code - $ tsh login --proxy=mytenant.teleport.sh --user=testuser + $ tsh login --proxy=mytenant.teleport.sh --user=alice $ tsh db ls # Name Description Allowed Users Labels Connect # --------- ----------------- ------------- ------- ------- diff --git a/docs/pages/database-access/guides/mongodb-atlas.mdx b/docs/pages/database-access/guides/mongodb-atlas.mdx index bf401306bfde3..2f0071818ebee 100644 --- a/docs/pages/database-access/guides/mongodb-atlas.mdx +++ b/docs/pages/database-access/guides/mongodb-atlas.mdx @@ -7,7 +7,7 @@ videoBanner: mu_ZKTjnFJ8 In this guide you will: 1. Configure Teleport for accessing your MongoDB Atlas cluster. -2. Configure self-managed X.509 authentication on your Atlas cluster. +2. Configure MongoDB Atlas authentication. 3. Connect to your Atlas cluster via Teleport. @@ -183,13 +183,17 @@ You can then use `/tmp/isrgrootx1.pem` as the value of the `db_service.databases (!docs/pages/includes/database-access/create-user.mdx!) -## Step 3/4. Configure Atlas +(!docs/pages/includes/database-access/mongodb-required-database-access.mdx!) -### Enable self-managed X.509 authentication +## Step 3/4. Configure Atlas -Teleport will authenticate with MongoDB Atlas using -[self-managed X.509 authentication](https://docs.atlas.mongodb.com/security-self-managed-x509/). +Teleport MongoDB Atlas integration supports two methods of authentication: +- Self-managed X.509: This method relies on certificates for authentication, + with MongoDB Atlas trusting the Teleport certificates. +- AWS IAM: The authentication is done using AWS credentials fetched by Teleport. + + First, obtain Teleport CA certificate by running the following `tctl auth sign` command against your Teleport cluster: @@ -209,8 +213,9 @@ toggle "Self-managed X.509 Authentication" on: Paste the contents of `mongo.cas` file in the Certificate Authority edit box and click Save. -### Create MongoDB user +### Create a MongoDB user +{/*lint ignore messaging*/} On the Security / Database Access page add a new database user with Certificate authentication method: @@ -225,6 +230,58 @@ certificate with `CN=alice` subject. Case matters so make sure to specify Common Name in the username with capital letters `CN=`. + + + + +You must provide the Teleport Database Service access to AWS credentials. + +(!docs/pages/includes/aws-credentials.mdx service="the Database Service"!) + +### Create a MongoDB IAM role + +Navigate to the [AWS IAM console](https://console.aws.amazon.com/iam/). In the +navigation pane, choose **Roles** and then choose **Create role**. Next, select +the "Custom trust policy" type. Edit the trust policy to allow the Teleport +Database service IAM role to assume this role so that the Teleport can fetch the +necessary credentials to authenticate to MongoDB: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Statement1", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::111111111111:role/teleport-database-access", + "Service": "ec2.amazonaws.com" + }, + "Action": "sts:AssumeRole" + } + ] +} +``` + +Your role won’t require any permission, so you can leave it empty on the +**Add Permissions** step. Then, choose a name for it and create it. In this +guide, we will the name `teleport-access`. + +### Create a MongoDB User + +{/*lint ignore messaging*/} +On the Security / Database Access page add a new database user with **AWS IAM** +authentication method, and choose "IAM Role" as the **IAM User type**. Then, fill in +the AWS ARN field with the ARN of the newly created IAM role. In the **Database +User Privileges** section, give the user sufficient privileges to access the +desired database data. + +![Create AWS IAM database user](../../../img/database-access/guides/atlas/atlas-add-aws-iam-user.png) + +Please note that Teleport does not support authentication using AWS IAM users; +it exclusively supports authentication using AWS IAM roles. + + ## Step 4/4. Connect @@ -253,6 +310,8 @@ $ tsh db ls
+ + To retrieve credentials for a database and connect to it: ```code @@ -265,6 +324,23 @@ when connecting to the database instance: ```code $ tsh db connect --db-user=alice mongodb-atlas ``` + + +To retrieve credentials for a database and connect to it, you must provide the +database username in the `role/` format: + +```code +$ tsh db connect --db-user=role/teleport-access mongodb-atlas +``` + +Alternatively, you provide the full ARN as the database username when connecting +to the database instance: + +```code +$ tsh db connect --db-user=arn:aws:iam::111111111111:role/teleport-access mongodb-atlas +``` + + Either the `mongosh` or `mongo` command-line clients should be available in `PATH` in order to be @@ -288,3 +364,5 @@ $ tsh db logout ## Further reading - [Which certificate authority signs MongoDB Atlas cluster TLS certificates?](https://docs.atlas.mongodb.com/reference/faq/security/#which-certificate-authority-signs-mongodb-atlas-cluster-tls-certificates-) +- [Self-managed X.509 authentication](https://docs.atlas.mongodb.com/security-self-managed-x509/) +- [AWS IAM authentication](https://www.mongodb.com/docs/atlas/security/passwordless-authentication/) diff --git a/docs/pages/database-access/guides/mongodb-self-hosted.mdx b/docs/pages/database-access/guides/mongodb-self-hosted.mdx index 371899b0587d2..bf0db20f8134a 100644 --- a/docs/pages/database-access/guides/mongodb-self-hosted.mdx +++ b/docs/pages/database-access/guides/mongodb-self-hosted.mdx @@ -79,6 +79,8 @@ $ --uri="mongodb://mongo1.example.com:27017,mongo2.example.com:27017/?replicaSet (!docs/pages/includes/database-access/create-user.mdx!) +(!docs/pages/includes/database-access/mongodb-required-database-access.mdx!) + ## Step 2/3. Configure MongoDB ### Create a MongoDB user diff --git a/docs/pages/database-access/guides/mysql-self-hosted.mdx b/docs/pages/database-access/guides/mysql-self-hosted.mdx index 12bb81d129fa8..d088c7e774bb9 100644 --- a/docs/pages/database-access/guides/mysql-self-hosted.mdx +++ b/docs/pages/database-access/guides/mysql-self-hosted.mdx @@ -164,7 +164,7 @@ databases: ```code -$ tsh login --proxy=teleport.example.com --user=testuser +$ tsh login --proxy=teleport.example.com --user=alice $ tsh db ls # Name Description Labels # ------------- ------------- -------- @@ -175,7 +175,7 @@ $ tsh db ls ```code -$ tsh login --proxy=mytenant.teleport.sh --user=testuser +$ tsh login --proxy=mytenant.teleport.sh --user=alice $ tsh db ls # Name Description Labels # ------------- ------------- -------- diff --git a/docs/pages/database-access/guides/oracle-self-hosted.mdx b/docs/pages/database-access/guides/oracle-self-hosted.mdx index 1e78196cb6027..82148b432aa0f 100644 --- a/docs/pages/database-access/guides/oracle-self-hosted.mdx +++ b/docs/pages/database-access/guides/oracle-self-hosted.mdx @@ -115,7 +115,7 @@ databases: ```code -$ tsh login --proxy=teleport.example.com --user=testuser +$ tsh login --proxy=teleport.example.com --user=alice $ tsh db ls # Name Description Allowed Users Labels Connect # ------ -------------- ------------- ------- ------- @@ -124,7 +124,7 @@ $ tsh db ls ```code -$ tsh login --proxy=mytenant.teleport.sh --user=testuser +$ tsh login --proxy=mytenant.teleport.sh --user=alice $ tsh db ls # Name Description Allowed Users Labels Connect # ------ -------------- ------------- ------- ------- diff --git a/docs/pages/database-access/guides/postgres-cloudsql.mdx b/docs/pages/database-access/guides/postgres-cloudsql.mdx index 73fea24d5013a..b58682d07c1b6 100644 --- a/docs/pages/database-access/guides/postgres-cloudsql.mdx +++ b/docs/pages/database-access/guides/postgres-cloudsql.mdx @@ -206,6 +206,7 @@ teleport: # because the Database Service always connects to the cluster over a reverse # tunnel. proxy_server: teleport.example.com:3080 + auth_token: "/tmp/token" db_service: enabled: "yes" # This section contains definitions of all databases proxied by this @@ -248,6 +249,7 @@ teleport: nodename: test # Proxy address to connect to. Use your Teleport Cloud tenant address here. proxy_server: mytenant.teleport.sh:443 + auth_token: "/tmp/token" db_service: enabled: "yes" # This section contains definitions of all databases proxied by this @@ -308,6 +310,12 @@ earlier. See [Authenticating as a service account](https://cloud.google.com/docs/authentication/production) in the Google Cloud documentation for more details. +If you are using `systemd` to start `teleport`, then you should edit the service's `EnvironmentFile` +to include the following env var: +```code +$ echo 'GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json' | sudo tee -a /etc/default/teleport +``` + ## Step 7/7. Connect Once the Database Service has joined the cluster, log in to see the available diff --git a/docs/pages/database-access/guides/postgres-self-hosted.mdx b/docs/pages/database-access/guides/postgres-self-hosted.mdx index d9b0b826a083c..50edb728d08c4 100644 --- a/docs/pages/database-access/guides/postgres-self-hosted.mdx +++ b/docs/pages/database-access/guides/postgres-self-hosted.mdx @@ -113,7 +113,7 @@ databases: ```code -$ tsh login --proxy=teleport.example.com --user=testuser +$ tsh login --proxy=teleport.example.com --user=alice $ tsh db ls # Name Description Labels # ---------------- ------------------ -------- @@ -124,7 +124,7 @@ $ tsh db ls ```code -$ tsh login --proxy=mytenant.teleport.sh --user=testuser +$ tsh login --proxy=mytenant.teleport.sh --user=alice $ tsh db ls # Name Description Labels # ---------------- ------------------ -------- diff --git a/docs/pages/database-access/guides/redis-cluster.mdx b/docs/pages/database-access/guides/redis-cluster.mdx index bb643d89137ed..c328a8343de13 100644 --- a/docs/pages/database-access/guides/redis-cluster.mdx +++ b/docs/pages/database-access/guides/redis-cluster.mdx @@ -195,16 +195,16 @@ returns the `ERR Teleport: command not supported` error. Teleport conducts additional processing on the following commands before communicating with Redis Cluster: -| Command | Description | -|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `DBSIZE` | Sends the query to all nodes and returns the number of keys in the whole cluster. | -| `KEYS` | Sends the query to all nodes and returns a list of all keys in the whole cluster. | -| `MGET` | Translates the commands to multiple `GET`s and sends them to multiple nodes. Result is merged in Teleport and returned back to the client. If Teleport fails to fetch at least one key an error is returned. | -| `FLUSHDB` | Sends the query to all nodes. | -| `FLUSHALL` | Works the same as `FLUSHDB`. | -| `SCRIPT EXISTS` | Sends the query to all nodes. `1` is returned only if script exists on all nodes. | -| `SCRIPT LOAD` | Sends the script to all nodes. | -| `SCRIPT FLUSH` | Sends the query to all nodes. `ASYNC` parameter is ignored. | +| Command | Description | +|-----------------|------------------------------------------------------------------------------------| +| `DBSIZE` | Sends the query to all nodes and returns the number of keys in the whole cluster. | +| `KEYS` | Sends the query to all nodes and returns a list of all keys in the whole cluster. | +| `MGET` | Translates the commands to multiple `GET`s and sends them to multiple nodes. Result is merged in Teleport and returned back to the client. If Teleport fails to fetch at least one key an error is returned. | +| `FLUSHDB` | Sends the query to all nodes. | +| `FLUSHALL` | Works the same as `FLUSHDB`. | +| `SCRIPT EXISTS` | Sends the query to all nodes. `1` is returned only if script exists on all nodes. | +| `SCRIPT LOAD` | Sends the script to all nodes. | +| `SCRIPT FLUSH` | Sends the query to all nodes. `ASYNC` parameter is ignored. | ## Next steps diff --git a/docs/pages/deploy-a-cluster/deployments/aws-terraform.mdx b/docs/pages/deploy-a-cluster/deployments/aws-terraform.mdx index 4ad11b3098b28..54bfd380b6378 100644 --- a/docs/pages/deploy-a-cluster/deployments/aws-terraform.mdx +++ b/docs/pages/deploy-a-cluster/deployments/aws-terraform.mdx @@ -487,6 +487,7 @@ $ ssh -i ${TF_VAR_key_name}.pem -o ProxyCommand="ssh -i ${TF_VAR_key_name}.pem - 4 - Use the `tctl` command to create an admin user for Teleport: + ```code # From EC2 host $ sudo tctl users add teleport-admin --roles=editor,access --logins=root @@ -494,8 +495,20 @@ $ sudo tctl users add teleport-admin --roles=editor,access --logins=root # https://teleport.example.com:443/web/newuser/6489ae886babf4232826076279bcb2fb # NOTE: Make sure teleport.example.com:443 points at a Teleport proxy which users can access. -# When the user 'teleport-admin' activates their account, they will be assigned roles [admin] +# When the user 'teleport-admin' activates their account, they will be assigned roles [editor, access] ``` + + +```code +# From EC2 host +$ sudo tctl users add teleport-admin --roles=editor,access,reviewer --logins=root +# Signup token has been created and is valid for 1 hours. Share this URL with the user: +# https://teleport.example.com:443/web/newuser/6489ae886babf4232826076279bcb2fb + +# NOTE: Make sure teleport.example.com:443 points at a Teleport proxy which users can access. +# When the user 'teleport-admin' activates their account, they will be assigned roles [editor, access, reviewer] +``` + 5 - Click the link to launch the Teleport web UI and finish setting up your user. You will need to scan the QR code with an TOTP-compatible app like Google Authenticator or Authy. You will also set a password for the @@ -511,6 +524,7 @@ You can [download the Teleport package containing the `tsh` client from here](ht - the client is the same for both OSS and Enterprise versions of Teleport. + ```code $ tsh login --proxy=${TF_VAR_route53_domain} --user=teleport-admin # Enter password for Teleport user teleport-admin: @@ -532,6 +546,30 @@ $ tsh ls $ tsh ssh root@ip-172-31-11-69-ec2-internal # [root@ip-172-31-11-69 ~]# ``` + + +```code +$ tsh login --proxy=${TF_VAR_route53_domain} --user=teleport-admin +# Enter password for Teleport user teleport-admin: +# Enter your OTP token: +# 567989 +# > Profile URL: https://teleport.example.com:443 +# Logged in as: teleport-admin +# Cluster: example-cluster +# Roles: editor,access,reviewer +# Logins: root +# Valid until: 2020-03-06 22:07:11 -0400 AST [valid for 12h0m0s] +# Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty + +$ tsh ls +# Node Name Address Labels +# ---------------------------- ----------------- ------ +# ip-172-31-11-69-ec2-internal 172.31.11.69:3022 + +$ tsh ssh root@ip-172-31-11-69-ec2-internal +# [root@ip-172-31-11-69 ~]# +``` + ## Restarting/checking Teleport services @@ -730,7 +768,7 @@ To add new nodes/EC2 servers that you can "SSH into" you'll need to: - [Run Teleport - we recommend using systemd](../../management/admin/daemon.mdx) - [Set the correct settings in /etc/teleport.yaml](../../reference/config.mdx) - [Add Nodes to the Teleport - cluster](../../management/join-services-to-your-cluster.mdx) + cluster](../../agents/join-services-to-your-cluster.mdx) ### Getting the CA pin hash @@ -752,7 +790,7 @@ $ aws ssm get-parameter --region ${TF_VAR_region} --name "/teleport/${TF_VAR_clu # 992a9725-0a64-428d-8e5e-308e6877743d ``` -You can also generate a Node join token using `tctl tokens add --type=node` [as detailed here in our admin guide](../../management/join-services-to-your-cluster/join-token.mdx). +You can also generate a Node join token using `tctl tokens add --type=node` [as detailed here in our admin guide](../../agents/join-services-to-your-cluster/join-token.mdx). ### Joining Nodes via the Teleport Auth Service @@ -773,7 +811,7 @@ auth_server: example-cluster-auth-c5b0fc2764ee015b.elb.us-east-1.amazonaws.com:3 ### Joining Nodes via Teleport IoT/Node tunneling To join Teleport Nodes from outside the same VPC, you will either need to investigate VPC peering/gateways (out of scope -for this document) or join your nodes using [Teleport's node tunneling](../../management/join-services-to-your-cluster/join-token.mdx) functionality. +for this document) or join your nodes using [Teleport's node tunneling](../../agents/join-services-to-your-cluster/join-token.mdx) functionality. With this method, you can join the nodes using the public facing proxy address - `teleport.example.com:443` for our example. diff --git a/docs/pages/deploy-a-cluster/helm-deployments/aws.mdx b/docs/pages/deploy-a-cluster/helm-deployments/aws.mdx index 88cbf780cb040..d80df9a170839 100644 --- a/docs/pages/deploy-a-cluster/helm-deployments/aws.mdx +++ b/docs/pages/deploy-a-cluster/helm-deployments/aws.mdx @@ -3,8 +3,7 @@ title: Running an HA Teleport cluster using AWS, EKS, and Helm description: Install and configure an HA Teleport cluster using an AWS EKS cluster --- -In this guide, we'll go through how to set up a High Availability Teleport cluster with multiple replicas in Kubernetes -using Teleport Helm charts and AWS products (DynamoDB and S3). +In this guide, we'll use Teleport Helm charts to set up a high-availability Teleport cluster that runs on AWS EKS. If you are already running Teleport on another platform, you can use your @@ -19,23 +18,18 @@ cluster to Teleport. (!docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx!) -## Step 1/7. Install Helm - -(!docs/pages/kubernetes-access/helm/includes/teleport-cluster-install.mdx!) - -## Step 2/7. Add the Teleport Helm chart repository +## Step 1/6. Add the Teleport Helm chart repository (!docs/pages/kubernetes-access/helm/includes/helm-repo-add.mdx!) -## Step 3/7. Set up AWS IAM configuration +## Step 2/6. Set up AWS IAM configuration For Teleport to be able to manage the DynamoDB tables, indexes, and the S3 storage bucket it needs, you'll need to configure AWS IAM policies to allow access. - These IAM policies should be added to your AWS account, then granted to the instance role associated with the - EKS nodegroups which are running your Kubernetes nodes. + Add these IAM policies to your AWS account and then grant it to the role associated with your EKS node group(s). ### DynamoDB IAM policy @@ -46,7 +40,7 @@ access. (!docs/pages/includes/s3-iam-policy.mdx!) -## Step 4/7. Configure TLS certificates for Teleport +## Step 3/6. Configure TLS certificates for Teleport The `teleport-cluster` chart deploys a Kubernetes `LoadBalancer` to handle incoming connections to the Teleport Proxy Service. @@ -261,7 +255,7 @@ Edit your `values.yaml` file to refer to the name of your secret: -## Step 5/7. Set values to configure the cluster +## Step 4/6. Set values to configure the cluster @@ -430,7 +424,7 @@ replicaset.apps/teleport-auth-57989d4cbd 2 2 2 22h replicaset.apps/teleport-proxy-c6bf55cfc 2 2 2 22h ``` -## Step 6/7. Set up DNS +## Step 5/6. Set up DNS You'll need to set up a DNS `A` record for `teleport.example.com`. In our example, this record is an alias to an ELB. @@ -498,11 +492,12 @@ $ aws route53 get-change --id "${CHANGEID?}" | jq '.ChangeInfo.Status' # "INSYNC" ``` -## Step 7/7. Create a Teleport user +## Step 6/6. Create a Teleport user Create a user to be able to log into Teleport. This needs to be done on the Teleport auth server, so we can run the command using `kubectl`: + ```code $ kubectl --namespace teleport exec deploy/teleport-auth -- tctl users add test --roles=access,editor @@ -511,6 +506,17 @@ https://teleport.example.com:443/web/invite/91cfbd08bc89122275006e48b516cc68 NOTE: Make sure teleport.example.com:443 points at a Teleport proxy that users can access. ``` + + +```code +$ kubectl --namespace teleport exec deploy/teleport-auth -- tctl users add test --roles=access,editor,reviewer + +User "test" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h: +https://teleport.example.com:443/web/invite/91cfbd08bc89122275006e48b516cc68 + +NOTE: Make sure teleport.example.com:443 points at a Teleport proxy that users can access. +``` + Load the user creation link to create a password and set up 2-factor authentication for the Teleport user via the web UI. @@ -621,4 +627,4 @@ users and setting up RBAC. See the [high availability section of our Helm chart reference](../../reference/helm-reference/teleport-cluster.mdx#highavailability) for more details on high availability. -Read the [`cert-manager` documentation](https://cert-manager.io/docs/). +Read the [`cert-manager` documentation](https://cert-manager.io/docs/). \ No newline at end of file diff --git a/docs/pages/deploy-a-cluster/helm-deployments/custom.mdx b/docs/pages/deploy-a-cluster/helm-deployments/custom.mdx index 8838d16f0cd7e..11ffab03db172 100644 --- a/docs/pages/deploy-a-cluster/helm-deployments/custom.mdx +++ b/docs/pages/deploy-a-cluster/helm-deployments/custom.mdx @@ -28,15 +28,11 @@ of this page to choose the correct version. (!docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx!) -## Step 1/4. Install Helm - -(!docs/pages/kubernetes-access/helm/includes/teleport-cluster-install.mdx!) - -## Step 2/4. Add the Teleport Helm chart repository +## Step 1/3. Add the Teleport Helm chart repository (!docs/pages/kubernetes-access/helm/includes/helm-repo-add.mdx!) -## Step 3/4. Setting up a Teleport cluster with Helm using a custom config +## Step 2/3. Setting up a Teleport cluster with Helm using a custom config `teleport-cluster` deploys two sets of pods: one for the Proxy Service and one for the Auth Service. You can provide two configurations, one for each pod type. @@ -208,12 +204,13 @@ replicaset.apps/teleport-auth-57989d4cbd 1 1 1 22h replicaset.apps/teleport-proxy-c6bf55cfc 2 2 2 22h ``` -## Step 4/4. Create a Teleport user (optional) +## Step 3/3. Create a Teleport user (optional) If you're not migrating an existing Teleport cluster, you'll need to create a user to be able to log into Teleport. This needs to be done on the Teleport auth server, so we can run the command using `kubectl`: + ```code $ kubectl --namespace teleport exec deployment/teleport-auth -- tctl users add test --roles=access,editor @@ -222,6 +219,17 @@ https://teleport.example.com:443/web/invite/91cfbd08bc89122275006e48b516cc68 NOTE: Make sure teleport.example.com:443 points at a Teleport proxy that users can access. ``` + + +```code +$ kubectl --namespace teleport exec deployment/teleport-auth -- tctl users add test --roles=access,editor,reviewer + +User "test" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h: +https://teleport.example.com:443/web/invite/91cfbd08bc89122275006e48b516cc68 + +NOTE: Make sure teleport.example.com:443 points at a Teleport proxy that users can access. +``` + If you didn't set up DNS for your hostname earlier, remember to replace diff --git a/docs/pages/deploy-a-cluster/helm-deployments/digitalocean.mdx b/docs/pages/deploy-a-cluster/helm-deployments/digitalocean.mdx index 471c76fa40cae..3803136b9ed4e 100644 --- a/docs/pages/deploy-a-cluster/helm-deployments/digitalocean.mdx +++ b/docs/pages/deploy-a-cluster/helm-deployments/digitalocean.mdx @@ -123,6 +123,7 @@ Once you get the value for the external IP (it may take a few minutes for this f ## Step 3/4. Create and set up Teleport user Now we create a Teleport user by executing the `tctl` command with `kubectl`. + ```code $ kubectl --namespace teleport-cluster exec deployment/teleport-cluster-auth -- tctl users add tadmin --roles=access,editor --logins=ubuntu @@ -131,6 +132,17 @@ https://tele.example.com:443/web/invite/ NOTE: Make sure tele.example.com:443 points at a Teleport proxy which users can access. ``` + + +```code +$ kubectl --namespace teleport-cluster exec deployment/teleport-cluster-auth -- tctl users add tadmin --roles=access,editor,reviewer --logins=ubuntu + +User "tadmin" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h: +https://tele.example.com:443/web/invite/ + +NOTE: Make sure tele.example.com:443 points at a Teleport proxy which users can access. +``` + Copy the link shown after executing the above command and open the link in a web browser to complete the user registration process (the link is `https://tele.example.com:443/web/invite/` in the above case).
@@ -201,6 +213,7 @@ $ export KUBECONFIG=${HOME?}/teleport-kubeconfig.yaml + ```code $ tsh login --proxy=tele.example.com:443 --auth=local --user=tadmin Enter password for Teleport user tadmin: @@ -215,6 +228,23 @@ Enter your OTP token: Valid until: 2021-10-27 06:37:15 +0000 UTC [valid for 12h0m0s] Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty ``` + + +```code +$ tsh login --proxy=tele.example.com:443 --auth=local --user=tadmin +Enter password for Teleport user tadmin: +Enter your OTP token: +540255 +> Profile URL: https://tele.example.com:443 + Logged in as: tadmin + Cluster: tele.example.com + Roles: access, editor, reviewer, member + Logins: ubuntu + Kubernetes: enabled + Valid until: 2021-10-27 06:37:15 +0000 UTC [valid for 12h0m0s] + Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty +``` + ### Select the Kubernetes cluster diff --git a/docs/pages/deploy-a-cluster/helm-deployments/gcp.mdx b/docs/pages/deploy-a-cluster/helm-deployments/gcp.mdx index 5415b356406d1..5ddf416553f04 100644 --- a/docs/pages/deploy-a-cluster/helm-deployments/gcp.mdx +++ b/docs/pages/deploy-a-cluster/helm-deployments/gcp.mdx @@ -17,11 +17,7 @@ cluster to Teleport. (!docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx!) -## Step 1/7. Install Helm - -(!docs/pages/kubernetes-access/helm/includes/teleport-cluster-install.mdx!) - -## Step 2/7. Add the Teleport Helm chart repository +## Step 1/6. Add the Teleport Helm chart repository (!docs/pages/kubernetes-access/helm/includes/helm-repo-add.mdx!) @@ -32,7 +28,7 @@ cluster to Teleport. The steps below apply to Google Cloud Google Kubernetes Engine (GKE) Standard deployments. -## Step 3/7. Google Cloud IAM configuration +## Step 2/6. Google Cloud IAM configuration For Teleport to be able to create the Firestore collections, indexes, and the Google Cloud Storage bucket it needs, you'll need to configure a Google Cloud service account with permissions to use these services. @@ -207,7 +203,7 @@ secret/teleport-gcp-credentials created The credentials file stored in any secret used must have the key name `gcp-credentials.json`. -## Step 4/7. Install and configure cert-manager +## Step 3/6. Install and configure cert-manager Reference the [cert-manager docs](https://cert-manager.io/docs/). @@ -275,7 +271,7 @@ After you have created the `Issuer` and updated the values, add it to your clust $ kubectl --namespace teleport create -f gcp-issuer.yaml ``` -## Step 5/7. Set values to configure the cluster +## Step 4/6. Set values to configure the cluster
@@ -388,7 +384,7 @@ replicaset.apps/teleport-auth-57989d4cbd 2 2 2 22h replicaset.apps/teleport-proxy-c6bf55cfc 2 2 2 22h ``` -## Step 6/7. Set up DNS +## Step 5/6. Set up DNS You'll need to set up a DNS `A` record for `teleport.example.com`. @@ -414,19 +410,31 @@ $ gcloud dns record-sets transaction describe --zone="${MYZONE?}" $ gcloud dns record-sets transaction execute --zone="${MYZONE?}" ``` -## Step 7/7. Create a Teleport user +## Step 6/6. Create a Teleport user Create a user to be able to log into Teleport. This needs to be done on the Teleport auth server, so we can run the command using `kubectl`: + +```code +$ kubectl --namespace teleport exec deploy/teleport-auth -- tctl users add test --roles=access,editor + +User "test" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h: +https://teleport.example.com:443/web/invite/91cfbd08bc89122275006e48b516cc68 + +NOTE: Make sure teleport.example.com:443 points at a Teleport proxy that users can access. +``` + + ```code -$ kubectl --namespace teleport exec deployment/teleport-auth -- tctl users add test --roles=access,editor +$ kubectl --namespace teleport exec deploy/teleport-auth -- tctl users add test --roles=access,editor,reviewer User "test" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h: https://teleport.example.com:443/web/invite/91cfbd08bc89122275006e48b516cc68 -NOTE: Make sure teleport.example.com:443 points at a Teleport proxy which users can access. +NOTE: Make sure teleport.example.com:443 points at a Teleport proxy that users can access. ``` + Load the user creation link to create a password and set up 2-factor authentication for the Teleport user via the web UI. diff --git a/docs/pages/deploy-a-cluster/helm-deployments/kubernetes-cluster.mdx b/docs/pages/deploy-a-cluster/helm-deployments/kubernetes-cluster.mdx index ecc9a4a67c787..03ba38243d212 100644 --- a/docs/pages/deploy-a-cluster/helm-deployments/kubernetes-cluster.mdx +++ b/docs/pages/deploy-a-cluster/helm-deployments/kubernetes-cluster.mdx @@ -226,9 +226,9 @@ Obtain the address of your load balancer by following the instructions below. Get information about the Proxy Service load balancer: ```code -$ kubectl get services/teleport-cluster-proxy -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -teleport-cluster-proxy LoadBalancer 10.4.4.73 192.0.2.0 443:31204/TCP 89s +$ kubectl get services/teleport-cluster +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +teleport-cluster LoadBalancer 10.4.4.73 192.0.2.0 443:31204/TCP 89s ``` The `teleport-cluster` service directs traffic to the Teleport Proxy Service. diff --git a/docs/pages/deploy-a-cluster/high-availability.mdx b/docs/pages/deploy-a-cluster/high-availability.mdx index 7e83ce50cb6a7..fb82f05e7998e 100644 --- a/docs/pages/deploy-a-cluster/high-availability.mdx +++ b/docs/pages/deploy-a-cluster/high-availability.mdx @@ -161,7 +161,7 @@ These ports are required: | Load Balancer Port | Proxy Service Port | Description | | - | - | - | -| `3023` | `3023` | SSH port for clients connect to. | +| `3023` | `3023` | SSH port for clients connect to. | | `3024` | `3024` | SSH port used to create reverse SSH tunnels from behind-firewall environments. | | `443` | `3080` | HTTPS connections to authenticate `tsh` users into the cluster. The same connection is used to serve a Web UI. | @@ -183,7 +183,7 @@ services: The Auth Service load balancer must forward traffic to the Auth Service's gRPC port. In this guide, we are assuming that you have configured the Auth Service load balancer to forward traffic from port `3025` to port `3025` on an available -Auth Service instance. +Auth Service instance. ## Cluster state backend @@ -497,7 +497,7 @@ Ensure that, on each Auth Service instance, the following ports are open: | Port | Description | | - | - | -| `3025` | gRPC port to open to Proxy Service instances.| +| `3025` | gRPC port to open to Proxy Service instances.| #### License file @@ -507,7 +507,7 @@ and make it available to your Teleport Auth Service instances. (!docs/pages/includes//enterprise/obtainlicense.mdx!) The license file must be available to each Teleport Auth Service instance at -`/var/lib/teleport/license.pem`. +`/var/lib/teleport/license.pem`. #### Configuration @@ -516,9 +516,9 @@ instances at `/etc/teleport.yaml`. We will explain the required configuration fields for a high-availability Teleport deployment below. These are the minimum requirements, and when planning your high-availability deployment, you will want to follow a more specific [deployment guide](introduction.mdx) for your -environment. +environment. -#### `storage` +#### `storage` The first configuration section to write is the `storage` section, which configures the cluster state backend and session recording backend for the Auth diff --git a/docs/pages/desktop-access/active-directory-manual.mdx b/docs/pages/desktop-access/active-directory-manual.mdx index 967658f64d6e5..7c0b8fa998473 100644 --- a/docs/pages/desktop-access/active-directory-manual.mdx +++ b/docs/pages/desktop-access/active-directory-manual.mdx @@ -193,7 +193,7 @@ certificate-based smart card authentication, and ensuring RDP is enabled. The following step requires an existing cluster. If you don't already have a Teleport cluster up and running, see our general [Getting -Started](../get-started.mdx) guide to set up a demo cluster. +Started](../index.mdx) guide to set up a demo cluster. These steps will need to be repeated if Teleport's user certificate authority is rotated. @@ -204,7 +204,7 @@ machine where you can manage your group policy, assigning to the address of your Teleport Proxy Service: ```code -$ curl 'https:///webapi/auth/export?type=windows' > user-ca.cer +$ curl -o user-ca.cer https:///webapi/auth/export?type=windows ``` diff --git a/docs/pages/desktop-access/directory-sharing.mdx b/docs/pages/desktop-access/directory-sharing.mdx index 72d57016b448c..b434fd38d2843 100644 --- a/docs/pages/desktop-access/directory-sharing.mdx +++ b/docs/pages/desktop-access/directory-sharing.mdx @@ -27,6 +27,7 @@ after the session ends. your cluster. If you have not yet configured Desktop Access, read [Getting Started with Desktop Access](./getting-started.mdx) before beginning this guide. + - A browser on your local machine that supports the File System Access API, which Teleport uses for Directory Sharing. We support the latest versions of Chromium-based browsers like Google Chrome, Brave, and Microsoft Edge. diff --git a/docs/pages/desktop-access/getting-started.mdx b/docs/pages/desktop-access/getting-started.mdx index 2189757bfa025..db843155794a5 100644 --- a/docs/pages/desktop-access/getting-started.mdx +++ b/docs/pages/desktop-access/getting-started.mdx @@ -50,22 +50,9 @@ Export the Teleport user certificate authority by running the following from `cmd.exe` on your Windows system: ```code -$ curl -o teleport.cer 'https://teleport-proxy.example.com:443/webapi/auth/export?type=windows' +$ curl -o teleport.cer https://teleport-proxy.example.com/webapi/auth/export?type=windows ``` - -Be sure to run the above command in `cmd.exe`. In PowerShell, `curl` is an alias for -[`Invoke-WebRequest`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.3) -which has different semantics. - -If you must use PowerShell, remove the alias before running curl with the -following command: - -``` -> Remove-Item alias:curl -``` - - ### Install the Teleport service for Windows From the Windows system, download the [Teleport Windows Auth diff --git a/docs/pages/desktop-access/reference/sessions.mdx b/docs/pages/desktop-access/reference/sessions.mdx index 7b2dbb348f967..c73af58ae628a 100644 --- a/docs/pages/desktop-access/reference/sessions.mdx +++ b/docs/pages/desktop-access/reference/sessions.mdx @@ -15,9 +15,8 @@ To disable session recording at the cluster level, edit your `teleport.yaml` configuration file. ```yaml -teleport: - auth_service: - session_recording: off +auth_service: + session_recording: off ``` @@ -59,9 +58,9 @@ for all possible settings in the `record_session` section. ## Playback -Recorded sessions can be viewed in the *Session Recordings* page. Desktop -recordings show a desktop icon in the first column to distinguish them from -SSH recordings. +Recorded sessions can be viewed in the *Session Recordings* page under the +*Activity* section in the *Management* area. Desktop recordings show a +desktop icon in the first column to distinguish them from SSH recordings. ![Desktop Session Recording](../../../img/desktop-access/session-recording@2x.png) diff --git a/docs/pages/desktop-access/troubleshooting.mdx b/docs/pages/desktop-access/troubleshooting.mdx index 7db9fb8522e8d..ac0fd9502290b 100644 --- a/docs/pages/desktop-access/troubleshooting.mdx +++ b/docs/pages/desktop-access/troubleshooting.mdx @@ -59,7 +59,7 @@ Teleport CA was rotated since the last import, you will have to fetch the new CA using the following command, assigning to the address of your Teleport Proxy Service: ```code -$ curl 'https:///webapi/auth/export?type=windows' > user-ca.cer +$ curl -o user-ca.cer https:///webapi/auth/export?type=windows ``` If that doesn't help, log into the target host directly, open PowerShell and diff --git a/docs/pages/faq.mdx b/docs/pages/faq.mdx index 3ccdc3d451ca5..a8b70da1fab24 100644 --- a/docs/pages/faq.mdx +++ b/docs/pages/faq.mdx @@ -13,29 +13,18 @@ the stability of Teleport from a security perspective. ## Can Teleport be deployed in agentless mode? -Yes. +Yes. All Teleport services support agentless mode, where the service proxies +traffic to an upstream infrastructure resource not available on `localhost`. With Teleport in agentless mode, you can easily control access to SSH servers, -Kubernetes clusters, desktops, databases, and internal applications without running any -additional software on your servers. Agentless mode supports session recordings -and audit logs for deep understanding into user behavior. - -For capabilities such as kernel-level logging and user provisioning, -we recommend Teleport as a drop in replacement for OpenSSH. Since Teleport -replaces the OpenSSH agent while preserving OpenSSH's functionality, you get -more functionality without a net addition of an agent on your system. - -Here are details about running each of Teleport's resource services in agentless -mode. All resource services except for the Node/SSH Service act as proxies for -client traffic: - -|Service|Supports agent mode|Supports agentless mode|Notes| -|---|---|---|---| -|[Application Service](./application-access/introduction.mdx)|✔|✔|Proxies HTTP requests to a user-configured list of applications, which can run on the same host as the `teleport` daemon or at a remote endpoint.| -|[Database Service](./database-access/introduction.mdx)|✔|✔|Proxies database-specific protocol traffic to a user-configured list of databases, which can run on the same host as the `teleport` daemon or at a remote endpoint.| -|[Kubernetes Service](./kubernetes-access/introduction.mdx)|✖|✔|Proxies client traffic to the API server of a registered Kubernetes cluster.| -|[Node/SSH Service](./server-access/introduction.mdx)|✔|✔|You can configure OpenSSH clients and servers to trust Teleport's CA. See our [OpenSSH guide](./server-access/guides/openssh.mdx).

For full functionality, you can run the Node Service, which implements SSH, on each server in your infrastructure.| -|[Windows Desktop Service](./desktop-access/introduction.mdx)|✖|✔|Proxies RDP traffic from client browsers to remote Windows servers.| +Kubernetes clusters, desktops, databases, and internal applications without +running any additional software on your servers. Agentless mode supports session +recordings and audit logs for deep understanding into user behavior. + +For capabilities such as kernel-level logging and user provisioning, we +recommend Teleport as a drop in replacement for OpenSSH. Since Teleport replaces +the OpenSSH agent while preserving OpenSSH's functionality, you get more +functionality without a net addition of an agent on your system. ## Can I use OpenSSH with a Teleport cluster? @@ -54,7 +43,7 @@ Yes. When running a Teleport agent, use the `--auth-server` flag to point to the Proxy Service address (this would be `public_addr` and `web_listen_addr` in your file configuration). For more information, see [Adding Nodes to the -Cluster](./management/join-services-to-your-cluster/join-token.mdx). +Cluster](./agents/join-services-to-your-cluster/join-token.mdx). ## Can Nodes use a single port for reverse tunnels? @@ -63,6 +52,12 @@ Yes, Teleport supports tunnel multiplexing on a single port. Set the setting in the `proxy_service` configuration. Teleport will automatically use multiplexing with that configuration. +## Can I copy files from one Teleport node to another? + +Yes, Teleport supports [Headless WebAuthn authentication](./access-controls/guides/headless.mdx), +which allows you to perform operations like `tsh ssh` or `tsh scp` from remote systems where you +are not logged in to Teleport or may not have access to a browser. + ## I'm getting `ssh: subsystem request failed` while I try to copy files, what to do? Make sure that all Teleport components are at least at version 10.3.0. Older versions diff --git a/docs/pages/get-started.mdx b/docs/pages/get-started.mdx deleted file mode 100644 index b950b25bbd10e..0000000000000 --- a/docs/pages/get-started.mdx +++ /dev/null @@ -1,257 +0,0 @@ ---- -title: Try out Teleport on a Linux Server -description: This tutorial will guide you through the steps needed to install and run Teleport on a Linux server -videoBanner: BJWbSqiDLeU ---- - -This tutorial will show you how to install and run a demo Teleport cluster -(=teleport.version=) on a Linux host using Teleport Community Edition. Once you -deploy the cluster, you can configure RBAC, register resources, and protect your -small-scale demo environments or home lab. - -We will run the following Teleport services: - -- **Teleport Auth Service:** The certificate authority for your cluster. It - issues certificates and conducts authentication challenges. The Auth Service - is typically inaccessible outside your private network. -- **Teleport Proxy Service:** The cluster frontend, which handles user requests, - forwards user credentials to the Auth Service, and communicates with Teleport - instances that enable access to specific resources in your infrastructure. -- **Teleport SSH Service:** An SSH server implementation that takes advantage of - Teleport's short-lived certificates, sophisticated RBAC, session recording, - and other features. - -(!docs/pages/includes/cloud/call-to-action.mdx!) - -## Prerequisites - -- A Linux host with only port `443` open to ingress traffic. You must be able - to install and run software on the host. Either configure access to the host - via SSH for the initial setup (and open an SSH port in addition port `443`) - or enter the commands in this guide into an Amazon EC2 [user data - script](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html), - Google Compute Engine [startup - script](https://cloud.google.com/compute/docs/instances/startup-scripts), - or similar. - - - - For a quick demo environment you can use to follow this guide, consider - installing our DigitalOcean 1-Click droplet. View the installation page on - [DigitalOcean - Marketplace](https://marketplace.digitalocean.com/apps/teleport). Once your - droplet is ready, SSH into the droplet and follow the configuration wizard. - - - -- A two-factor authenticator app such as [Authy](https://authy.com/download/), - [Google Authenticator](https://www.google.com/landing/2step/), or [Microsoft - Authenticator](https://www.microsoft.com/en-us/account/authenticator) - -You must also have one of the following: -- A registered domain name. -- An authoritative DNS nameserver managed by your organization, plus an existing - certificate authority. If using this approach, ensure that your browser is - configured to use your organization's nameserver. - -This guide is not intended for local deployments. If your environment doesn't -meet the prerequisites above, you can get started with Teleport by signing up -for a [free trial of Teleport Enterprise Cloud](https://goteleport.com/signup/). - -## Step 1/4. Configure DNS - -Teleport uses TLS to provide secure access to its Proxy Service and Auth -Service, and this requires a domain name that clients can use to verify -Teleport's certificate. Set up two DNS `A` records, each pointing to the IP -address of your Linux host. Assuming `teleport.example.com` is your domain name, -set up records for: - -|Domain|Reason| -|---|---| -|`teleport.example.com`|Traffic to the Proxy Service from users and services.| -|`*.teleport.example.com`|Traffic to web applications registered with Teleport. Teleport issues a subdomain of your cluster's domain name to each application.| - -## Step 2/4. Set up Teleport on your Linux host - -### Install Teleport - -On your Linux host, run the following command to install the Teleport binary: - -```code -$ curl https://goteleport.com/static/install.sh | bash -s (=teleport.version=) -``` - -### Configure Teleport - -Generate a configuration file for Teleport using the `teleport configure` command. -This command requires information about a TLS certificate and private key. - -(!docs/pages/includes/tls-certificate-setup.mdx!) - -### Start Teleport - -(!docs/pages/includes/start-teleport.mdx!) - -Access Teleport's Web UI via HTTPS at the domain you created earlier (e.g., -`https://teleport.example.com`). You should see a welcome screen similar to the -following: - -![Teleport Welcome Screen](../img/quickstart/welcome.png) - -## Step 3/4. Create a Teleport user and set up two-factor authentication - -In this step, we'll create a new Teleport user, `teleport-admin`, which is -allowed to log into SSH hosts as any of the principals `root`, `ubuntu`, or -`ec2-user`. - -On your Linux host, run the following command: - -```code -# tctl is an administrative tool that is used to configure Teleport's auth service. -$ sudo tctl users add teleport-admin --roles=editor,access --logins=root,ubuntu,ec2-user -``` - -The command prints a message similar to the following: - -```text -User "teleport-admin" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h: -https://teleport.example.com:443/web/invite/123abc456def789ghi123abc456def78 - -NOTE: Make sure teleport.example.com:443 points at a Teleport proxy which users can access. -``` - -Visit the provided URL in order to create your Teleport user. - - - - The users that you specify in the `logins` flag (e.g., `root`, `ubuntu` and - `ec2-user` in our examples) must exist on your Linux host. Otherwise, you - will get authentication errors later in this tutorial. - - If a user does not already exist, you can create it with `adduser ` or - use [host user creation](./server-access/guides/host-user-creation.mdx). - - If you do not have the permission to create new users on the Linux host, run - `tctl users add teleport $(whoami)` to explicitly allow Teleport to - authenticate as the user that you have currently logged in as. - - - -Teleport enforces the use of two-factor authentication by default. It supports -one-time passwords (OTP) and second-factor authenticators (WebAuthn). In this -guide, you will need to enroll an OTP authenticator application using the QR -code on the Teleport welcome screen. - -
- -In addition to Teleport's Web UI, you can access resources in your -infrastructure via the `tsh` client tool. - -Install `tsh` on your local workstation: - - - - [Download the MacOS .pkg installer](https://goteleport.com/download?os=mac) (`tsh` client only, signed) and double-click to run it. - - - - ```code - $ brew install teleport - ``` - - - The Teleport package in Homebrew is not maintained by Teleport and we can't - guarantee its reliability or security. We recommend the use of our [own Teleport packages](https://goteleport.com/download?os=mac). - - If you choose to use Homebrew, you must verify that the versions of `tsh` and - `tctl` are compatible with the versions you run server-side. Homebrew usually - ships the latest release of Teleport, which may be incompatible with older - versions. See our [compatibility policy](./management/operations/upgrading.mdx#component-compatibility) for details. - - - - - ```code - $ curl -O https://cdn.teleport.dev/teleport-v(=teleport.version=)-windows-amd64-bin.zip - # Unzip the archive and move `tsh.exe` to your %PATH% - ``` - - - - For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) please see our [installation page](./installation.mdx). - - ```code - $ curl -O https://get.gravitational.com/teleport-v(=teleport.version=)-linux-amd64-bin.tar.gz - $ tar -xzf teleport-v(=teleport.version=)-linux-amd64-bin.tar.gz - $ cd teleport - $ sudo ./install - # Teleport binaries have been copied to /usr/local/bin - # To configure the systemd service for Teleport take a look at examples/systemd/README.mdx - ``` - - - -Log in to receive short-lived certificates from Teleport: - -```code -# Replace teleport.example.com with your Teleport cluster's public address as configured above. -$ tsh login --proxy= --user=teleport-admin -> Profile URL: https://teleport.example.com:443 - Logged in as: teleport-admin - Cluster: teleport.example.com - Roles: access, editor - Logins: root, ubuntu, ec2-user - Kubernetes: enabled - Valid until: 2022-04-26 03:04:46 -0400 EDT [valid for 12h0m0s] - Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty -``` - - -
- -## Step 4/4. Enroll your infrastructure - -With Teleport, you can protect all of the resources in your infrastructure -behind a single identity-aware access proxy, including servers, databases, -applications, Kubernetes clusters, Windows desktops, and cloud provider APIs. - -To enroll a resource with Teleport, visit the Web UI and click the name of a -resource on the sidebar, e.g., **Servers**, **Applications**, and -**Kubernetes**. The Web UI will show you the steps you can take to enroll that -resource. - -![Adding resources](../img/add-resources.png) - -In the **Servers** tab, you can see that you have already enrolled your Linux -server. - -## Next steps - -Now that you have launched your Teleport cluster and added your first resources, -see how to use Teleport to set up secure access to your infrastructure. - -Read the [Manage Access](./access-controls/introduction.mdx) documentation to -get started setting up role-based access controls for all of the resources you -registered. - -To learn about common Day Two operations when managing a Teleport cluster, read -the [Manage your Cluster](./management/introduction.mdx) guides. - -You can also read more about how to protect your infrastructure with Teleport, -including: - -- [Applications](./application-access/introduction.mdx) -- [Databases](./database-access/introduction.mdx) -- [Kubernetes clusters](./kubernetes-access/introduction.mdx) -- [Servers](./server-access/introduction.mdx) -- [Windows desktops](./desktop-access/introduction.mdx) -- [Service accounts](./machine-id/introduction.mdx) (via Machine ID) - -## Further reading - -- How Let's Encrypt uses the [ACME protocol](https://letsencrypt.org/how-it-works/) to issue certificates. -- Configuration for the `teleport` daemon relies on [systemd](https://www.freedesktop.org/wiki/Software/systemd/). For more information on how the -`teleport` service daemon is configured, see our guide on how to [Run Teleport as a Daemon](management/admin/daemon.mdx). diff --git a/docs/pages/includes/access-control-guides.mdx b/docs/pages/includes/access-control-guides.mdx index 01c1439da73e0..08ec27eb66071 100644 --- a/docs/pages/includes/access-control-guides.mdx +++ b/docs/pages/includes/access-control-guides.mdx @@ -7,6 +7,6 @@ - [Locking](../access-controls/guides/locking.mdx): Lock access to active user sessions or hosts. - [Moderated Sessions](../access-controls/guides/moderated-sessions.mdx): Require session auditors and allow fine-grained live session access. - [Hardware Key Support (Preview)](../access-controls/guides/hardware-key-support.mdx): Enforce the use of hardware-based private keys. -- [Device Trust (Preview)](../access-controls/guides/device-trust.mdx): Register and enforce trusted devices. +- [Device Trust (Preview)](../access-controls/device-trust/guide.mdx): Register and enforce trusted devices. - [Headless WebAuthn (Preview)](../access-controls/guides/headless.mdx): Login with Webauthn from a remote device. - [IP Pinning (Preview)](../access-controls/guides/ip-pinning.mdx): Pin a user's certificates to a login IP address. diff --git a/docs/pages/includes/cloud/call-to-action.mdx b/docs/pages/includes/cloud/call-to-action.mdx index 169dbd7bbbf60..9e595dfaf4d0a 100644 --- a/docs/pages/includes/cloud/call-to-action.mdx +++ b/docs/pages/includes/cloud/call-to-action.mdx @@ -3,10 +3,10 @@ type="tip" scope={["oss", "enterprise"]} > -Teleport Cloud takes care of this setup for you so you can provide secure access +Teleport Team takes care of this setup for you so you can provide secure access to your infrastructure right away. Get started with a [free trial](https://goteleport.com/signup?t_source=docs) of -Teleport Cloud. +Teleport Team. diff --git a/docs/pages/includes/cloud/install-linux-cloud.mdx b/docs/pages/includes/cloud/install-linux-cloud.mdx new file mode 100644 index 0000000000000..e964a0a8e80e7 --- /dev/null +++ b/docs/pages/includes/cloud/install-linux-cloud.mdx @@ -0,0 +1,74 @@ + + + + Add the Teleport repository to your repository list: + + ```code + # Download Teleport's PGP public key + $ sudo curl https://apt.releases.teleport.dev/gpg \ + -o /usr/share/keyrings/teleport-archive-keyring.asc + # Source variables about OS version + $ source /etc/os-release + # Add the Teleport apt repository for cloud. + $ echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] \ + https://apt.releases.teleport.dev/${ID?} ${VERSION_CODENAME?} stable/cloud" \ + | sudo tee /etc/apt/sources.list.d/teleport.list > /dev/null + + $ sudo apt-get update + $ sudo apt-get install teleport-ent + ``` + + + + + ```code + # Source variables about OS version + $ source /etc/os-release + # Add the Teleport yum repository for cloud. + # First, get the major version from $VERSION_ID so this fetches the correct + # package version. + $ VERSION_ID=$(echo $VERSION_ID | grep -Eo "^[0-9]+") + $ sudo yum-config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/cloud/teleport.repo")" + $ sudo yum install teleport-ent + # + # Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs) + # echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path + ``` + + + + + ```code + # Source variables about OS version + $ source /etc/os-release + # Add the Teleport yum repository for cloud. + # Use the dnf config manager plugin to add the teleport RPM repo + $ sudo dnf config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/cloud/teleport.repo")" + + # Install teleport + $ sudo dnf install teleport-ent + + # Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs) + # echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path + ``` + + + + + In the example commands below, update `$SYSTEM_ARCH` with the appropriate + value (`amd64`, `arm64`, or `arm`). All example commands using this variable + will update after one is filled out. + + ```code + $ curl https://get.gravitational.com/teleport-ent-v(=cloud.version=)-linux--bin.tar.gz.sha256 + # + $ curl -O https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-linux-amd64-bin.tar.gz + $ shasum -a 256 teleport-ent-v(=cloud.version=)-linux-amd64-bin.tar.gz + # Verify that the checksums match + $ tar -xvf teleport-ent-v(=cloud.version=)-linux-amd64-bin.tar.gz + $ cd teleport-ent + $ sudo ./install + ``` + + + \ No newline at end of file diff --git a/docs/pages/includes/cloud/install-macos.mdx b/docs/pages/includes/cloud/install-macos.mdx new file mode 100644 index 0000000000000..3482e4f8411e5 --- /dev/null +++ b/docs/pages/includes/cloud/install-macos.mdx @@ -0,0 +1,20 @@ + You can download one of the following .pkg installers for macOS: + + | Link | Binaries | + |-----------------------------------------------------------------------------------------------------------|--------------------------------------------| + | [`teleport-ent-(=cloud.version=).pkg`](https://cdn.teleport.dev/teleport-ent-(=cloud.version=).pkg) | `teleport`
`tctl`
`tsh`
`tbot` | + | [`tsh-(=cloud.version=).pkg`](https://cdn.teleport.dev/tsh-(=cloud.version=).pkg) | `tsh` | + + You can also fetch an installer from the command line: + + ```code + $ curl -O https://cdn.teleport.dev/teleport-ent-(=cloud.version=).pkg + # Install on Macintosh HD + $ sudo installer -pkg teleport-ent-(=cloud.version=).pkg -target / + Password: + installer: Package name is teleport-ent-(=cloud.version=) + installer: Upgrading at base path / + installer: The upgrade was successful. + $ which teleport + /usr/local/bin/teleport + ``` diff --git a/docs/pages/includes/commercial-prereqs-tabs.mdx b/docs/pages/includes/commercial-prereqs-tabs.mdx index e2d61a277385c..e5f3cdfb0a5d2 100644 --- a/docs/pages/includes/commercial-prereqs-tabs.mdx +++ b/docs/pages/includes/commercial-prereqs-tabs.mdx @@ -4,7 +4,7 @@ - A running Teleport Enterprise cluster, including the Auth Service and Proxy Service. For details on how to set this up, see our Enterprise [Getting - Started](/docs/enterprise/getting-started) guide. + Started](../choose-an-edition/teleport-enterprise/introduction.mdx) guide. - The Enterprise `tctl` admin tool and `tsh` client tool version >= (=teleport.version=), which you can download by visiting your [Teleport account](https://teleport.sh). @@ -19,11 +19,11 @@ + label="Teleport Enterprise Cloud"> -- A Teleport Cloud account, which includes a running Auth Service and Proxy - Service. If you do not have a Teleport Cloud account, visit the [sign up - page](https://goteleport.com/signup/) to begin your free trial. +- A Teleport Enterprise Cloud account. If you do not have one, visit the [signup + page](https://goteleport.com/signup/) to begin a free trial of Teleport Team + and upgrade to Teleport Enterprise Cloud. - The `tctl` admin tool and `tsh` client tool version >= (=cloud.version=). To download these tools, visit the [Downloads](../choose-an-edition/teleport-cloud/downloads.mdx) page. diff --git a/docs/pages/includes/config-reference/auth-service.yaml b/docs/pages/includes/config-reference/auth-service.yaml index d47ebc0551989..7f705240f75c5 100644 --- a/docs/pages/includes/config-reference/auth-service.yaml +++ b/docs/pages/includes/config-reference/auth-service.yaml @@ -238,6 +238,11 @@ auth_service: # and Kubernetes connections. mode: optional # always "off" for OSS + # Determines the default time to live for user certificates + # issued by this auth server, defaults to 12 hours. Examples: + # "14h30m", "1h" etc. + default_session_ttl: 12h + # IP and the port to bind to. Other Teleport Nodes will be connecting to # this port (AKA "Auth API" or "Cluster API") to validate client # certificates diff --git a/docs/pages/includes/config-reference/desktop-config.yaml b/docs/pages/includes/config-reference/desktop-config.yaml index 4d00e03fd17df..6915b8599c85a 100644 --- a/docs/pages/includes/config-reference/desktop-config.yaml +++ b/docs/pages/includes/config-reference/desktop-config.yaml @@ -69,16 +69,15 @@ windows_desktop_service: # objects in Teleport. These hosts must be part of the Active Directory # domain configured to grant Teleport access. hosts: - - win1.example.com - - win2.example.com - - ... + - win1.dev.example.com + - win2.dev.example.com # (optional) non_ad_hosts is a list of hostnames that are not part of an # Active Diretory domain to register as WindowsDesktop objects in Teleport. # These hosts require the Teleport CA certificate and service, as described in # https://goteleport.com/docs/desktop-access/getting-started/ non_ad_hosts: - - win3.example.com - - win4.example.com + - win3.prod.example.com + - win4.prod.example.com # (optional) settings for enabling automatic desktop discovery via LDAP discovery: # The wildcard '*' character tells Teleport to discover all the hosts in @@ -97,13 +96,20 @@ windows_desktop_service: # Rules for applying labels to Windows hosts based on regular expressions # matched against the host name. If multiple rules match, the desktop will # get the union of all matching labels. + # + # The rules for matching static hosts (hosts and non_ad_hosts) and discovered hosts + # are slightly different. See https://goteleport.com/docs/desktop-access/rbac/ + # for details. host_labels: - - match: '^.*\.dev\.example\.com$' + - match: '^.*\.dev\.example\.com' labels: environment: dev - - match: '^.*\.prod\.example\.com$' + - match: '^.*\.prod\.example\.com' labels: environment: prod + - match: '^EC2AMAZ-' + labels: + environment: discovered-in-aws # Labels to attach to the Windows Desktop Service. This is used internally, so # any custom labels added won't affect the Windows hosts. diff --git a/docs/pages/includes/config-reference/jamf-service.yaml b/docs/pages/includes/config-reference/jamf-service.yaml new file mode 100644 index 0000000000000..96477304c80e6 --- /dev/null +++ b/docs/pages/includes/config-reference/jamf-service.yaml @@ -0,0 +1,70 @@ +# This section configures the Jamf service. +jamf_service: + # Enables the Jamf service. Default is 'no' + enabled: yes + + # Name of the sync source corresponding to the service. + # Jamf service sources with the same name manage the same devices, which is + # particularly relevant during device removal. + # If you have multiple Jamf sources, make sure to give them distinct, + # descriptive names. + # Default is 'jamf'. + name: jamf + + # API endpoint for the Jamf Pro API. + # Required. + api_endpoint: https://yourtenant.jamfcloud.com + + # Username for the Jamf Pro API. + # Required. + username: teleport + + # Path to a file containing the password for the Jamf Pro API. + # It is recommended to set the permissions for the file as restrictively as + # possible. + # Required. + password_file: /var/lib/teleport/jamf_password.txt + + # Delay for initial syncs. + # Set to zero for syncs to start after a short random delay (a couple minutes + # max). + # Set to -1 for immediate syncs on startup. + # Default is '0'. + sync_delay: 0 + + # If `true` the Teleport process runs all Jamf syncs immediately and exits as + # soon as they are done. Implies `sync_delay=-1`. + # Useful for cron-like executions of Jamf syncs. + # Default is `false`. + exit_on_sync: false + + # Inventory sync entries. + # Each entry corresponds to its own sync schedule and may have different + # filters and intervals. + # If the inventory section is absent a preset sync configuration is used. + inventory: + # Sync period for partial syncs. + # A partial sync attempts to fetch new and modified devices, but won't scan + # the entire Jamf inventory. + # Set to zero or -1 to disable partial syncs. + - sync_period_partial: 6h + + # Sync period for full syncs. + # A full sync scans the entire Jamf inventory, processing new/modified + # devices and removals from Jamf. + # Set to zero or -1 to disable partial syncs. + sync_period_full: 24h + + # Action to take against devices missing from Jamf but present in Teleport. + # Valid options are: + # 'DELETE' - devices removed from Jamf are removed from Teleport. + # (Requires a full sync.) + # 'NOOP' - devices removed from Jamf are left in Teleport. + # Default is 'NOOP'. + on_missing: NOOP + + # Device filters forwarded to the Jamf Pro API queries. + # Refer to https://developer.jamf.com/jamf-pro/reference/get_v1-computers-inventory + # for the possible filter values. + # Default is '' + filter_rsql: '' diff --git a/docs/pages/includes/configure-event-handler.mdx b/docs/pages/includes/configure-event-handler.mdx index 28045e0bdf76a..ef7cf67e77446 100644 --- a/docs/pages/includes/configure-event-handler.mdx +++ b/docs/pages/includes/configure-event-handler.mdx @@ -5,7 +5,7 @@ Run the `configure` command to generate a sample configuration. Replace `mytenant.teleport.sh` with the DNS name of your Teleport Enterprise Cloud tenant: ```code -$ ./teleport-event-handler configure . mytenant.teleport.sh:443 +$ teleport-event-handler configure . mytenant.teleport.sh:443 ``` @@ -16,7 +16,7 @@ Run the `configure` command to generate a sample configuration. Replace Service: ```code -$ ./teleport-event-handler configure . teleport.example.com:443 +$ teleport-event-handler configure . teleport.example.com:443 ``` @@ -54,10 +54,6 @@ Teleport event handler (=teleport.version=) [2] Generated sample teleport-event-handler role and user file teleport-event-handler-role.yaml [3] Generated sample fluentd configuration file fluent.conf [4] Generated plugin configuration file teleport-event-handler.toml - -Follow-along with our getting started guide: - -https://goteleport.com/docs/management/export-audit-events/fluentd/ ``` The plugin generates several setup files: @@ -82,3 +78,30 @@ $ ls -l | `client.crt` and `client.key` | Fluentd client certificate and key, all signed by the generated CA | | `teleport-event-handler-role.yaml` | `user` and `role` resource definitions for Teleport's event handler | | `fluent.conf` | Fluentd plugin configuration | + +
+ +This guide assumes that you are running the Event Handler on the same host or +Kubernetes pod as your log forwarder. If you are not, you will need to instruct +the Event Handler to generate mTLS certificates for subjects besides +`localhost`. To do this, use the `--cn` and `--dns-names` flags of the +`teleport-event-handler` configure command. + +For example, if your log forwarder is addressable at `forwarder.example.com` and the +Event Handler at `handler.example.com`, you would run the following `configure` +command: + +```code +$ teleport-event-handler configure --cn=handler.example.com --dns-names=forwarder.example.com +``` + +The command generates client and server certificates with the subjects set to +the value of `--cn`. + +The `--dns-names` flag accepts a comma-separated list of DNS names. It will +append subject alternative names (SANs) to the server certificate (the one you +will provide to your log forwarder) for each DNS name in the list. The Event +Handler looks up each DNS name before appending it as an SAN and exits with an +error if the lookup fails. + +
diff --git a/docs/pages/includes/database-access/alternative-methods-join.mdx b/docs/pages/includes/database-access/alternative-methods-join.mdx index 6c43c748266ae..c4d46cac6011b 100644 --- a/docs/pages/includes/database-access/alternative-methods-join.mdx +++ b/docs/pages/includes/database-access/alternative-methods-join.mdx @@ -6,7 +6,7 @@ Teleport: - [Configure Teleport to Automatically Enroll EC2 instances (Preview)](../../server-access/guides/ec2-discovery.mdx) - [Joining Teleport Services via AWS IAM - Role](../../management/join-services-to-your-cluster/aws-iam.mdx) -- [Joining Teleport Services via AWS EC2 Identity Document](../../management/join-services-to-your-cluster/aws-ec2.mdx) + Role](../../agents/join-services-to-your-cluster/aws-iam.mdx) +- [Joining Teleport Services via AWS EC2 Identity Document](../../agents/join-services-to-your-cluster/aws-ec2.mdx)
diff --git a/docs/pages/includes/database-access/create-user.mdx b/docs/pages/includes/database-access/create-user.mdx index a790902ad872a..395f602b4462f 100644 --- a/docs/pages/includes/database-access/create-user.mdx +++ b/docs/pages/includes/database-access/create-user.mdx @@ -4,6 +4,7 @@ To modify an existing user to provide access to the Database Service, see [Datab + Create a local Teleport user with the built-in `access` role: ```code @@ -13,12 +14,24 @@ $ tctl users add \ --db-names=\* \ alice ``` + + +Create a local Teleport user with the built-in `access` and `requester` roles: -| Flag | Description | -|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------| -| `--roles` | List of roles to assign to the user. The builtin `access` role allows them to connect to any database server registered with Teleport. | -| `--db-users` | List of database usernames the user will be allowed to use when connecting to the databases. A wildcard allows any user. | -| `--db-names` | List of logical databases (aka schemas) the user will be allowed to connect to within a database server. A wildcard allows any database. | +```code +$ tctl users add \ + --roles=access,requester \ + --db-users=\* \ + --db-names=\* \ + alice +``` + + +| Flag | Description | +|--------------|------------------------------------------------------------------------------------------------------------------------------------------| +| `--roles` | List of roles to assign to the user. The builtin `access` role allows them to connect to any database server registered with Teleport. | +| `--db-users` | List of database usernames the user will be allowed to use when connecting to the databases. A wildcard allows any user. | +| `--db-names` | List of logical databases (aka schemas) the user will be allowed to connect to within a database server. A wildcard allows any database. | Database names are only enforced for PostgreSQL and MongoDB databases. diff --git a/docs/pages/includes/database-access/mongodb-required-database-access.mdx b/docs/pages/includes/database-access/mongodb-required-database-access.mdx new file mode 100644 index 0000000000000..702db32442872 --- /dev/null +++ b/docs/pages/includes/database-access/mongodb-required-database-access.mdx @@ -0,0 +1,5 @@ +If you opt for a stricter selection of database names for your user, which +differs from the wildcard approach illustrated in this guide, it is essential +to include the `admin` database. This ensures MongoDB clients won't have +issues while connecting and executing operations such as retrieving server +information, listing databases, and aborting transactions. diff --git a/docs/pages/includes/device-trust/auto-enroll-troubleshooting.mdx b/docs/pages/includes/device-trust/auto-enroll-troubleshooting.mdx new file mode 100644 index 0000000000000..5f7d9dbd25a6f --- /dev/null +++ b/docs/pages/includes/device-trust/auto-enroll-troubleshooting.mdx @@ -0,0 +1,18 @@ +### "binary missing signature or entitlements" on `tsh device enroll` + +A signed and notarized `tsh` binary is necessary to enroll and use a a trusted +device. [Download the macOS tsh installer](../../installation.mdx#macos) to fix +the problem. + +### "unauthorized device" errors using a trusted device + +A signed and notarized `tsh` binary is necessary to use a trusted device. Make +sure to download and use the +[macOS tsh installer](../../installation.mdx#macos). + +A trusted device needs to be registered and enrolled before it is recognized by +Teleport as such. Follow the [registration]( +../../access-controls/device-trust/guide.mdx#step-12-register-a-trusted-device) and +[enrollment]( +../../access-controls/device-trust/guide.mdx#step-22-enroll-a-trusted-device) steps +and make sure to `tsh logout` and `tsh login` after enrollment is done. diff --git a/docs/pages/includes/device-trust/prereqs.mdx b/docs/pages/includes/device-trust/prereqs.mdx new file mode 100644 index 0000000000000..276397c3b9694 --- /dev/null +++ b/docs/pages/includes/device-trust/prereqs.mdx @@ -0,0 +1,9 @@ +- To enroll a macOS device, you need: + - A signed and notarized `tsh` binary for enrollment. + [Download the macOS tsh installer](../../installation.mdx#macos). + - A Teleport version newer than v12.0.0. +- To enroll a Windows device, you need: + - A device that includes a TPM with 2.0 support. + - `tsh` installed on the device. [Download the Windows tsh installer](../../installation.mdx#windows-tsh-client-only). + - Credentials for a user with administrator privileges for the device. This is only required during enrollment. + - A Teleport version newer than v13.1.2. diff --git a/docs/pages/includes/docker-images-oss.mdx b/docs/pages/includes/docker-images-oss.mdx deleted file mode 100644 index a7c86c82f03ca..0000000000000 --- a/docs/pages/includes/docker-images-oss.mdx +++ /dev/null @@ -1,27 +0,0 @@ -We provide a pre-built multi-arch Docker image for every version of Teleport, -including images for `amd64`, `arm`, and `arm64` architectures. Our images contain only Teleport binaries -and their application dependencies. - -These images are hosted on Amazon ECR Public. All tags under `public.ecr.aws/gravitational/teleport-distroless` [are Teleport Open Source images](https://gallery.ecr.aws/gravitational/teleport-distroless). - -The table below gives an idea of how our image naming scheme works. We offer -images that point to a static version of Teleport as well as images that are -automatically rebuilt every night. These nightly images point to the latest -version of Teleport from the three most recent release branches. They are -stable, and we recommend their use to keep your Teleport installation up to -date. - -|Image name|Teleport version|Image automatically updated?|Troubleshooting Tools?|Image base| -|-|-|-|-|-| -|`public.ecr.aws/gravitational/teleport-distroless:(=teleport.major_version=)`|The latest version of Teleport Open Source|Yes|No|[Distroless Debian 11](https://github.com/GoogleContainerTools/distroless)| -|`public.ecr.aws/gravitational/teleport-distroless-debug:(=teleport.major_version=)`|The latest version of Teleport Open Source|Yes|Yes|[Distroless Debian 11](https://github.com/GoogleContainerTools/distroless)| -|`(=teleport.latest_oss_docker_image=)`|The version specified in the image's tag (i.e. (=teleport.version=))|No|No|[Distroless Debian 11](https://github.com/GoogleContainerTools/distroless)| -|`(=teleport.latest_oss_debug_docker_image=)`|The version specified in the image's tag (i.e. (=teleport.version=))|No|Yes|[Distroless Debian 11](https://github.com/GoogleContainerTools/distroless)| - -For testing, we always recommend that you use the latest released version of Teleport, which is currently `(=teleport.latest_oss_docker_image=)`. - -The `*-debug` images include a Busybox shell and tool suite in addition to Teleport, and are intended for troubleshooting deployments only. They are not intended for production use. - -[Ubuntu 20.04](https://hub.docker.com/\_/ubuntu)-based images are available from our -[Legacy Amazon ECR Public repository](https://gallery.ecr.aws/gravitational/teleport-ent). -Their use is considered deprecated, and they may be removed in future releases. diff --git a/docs/pages/includes/edition-comparison.mdx b/docs/pages/includes/edition-comparison.mdx index 170bea097eca6..0df80bff8e2ae 100644 --- a/docs/pages/includes/edition-comparison.mdx +++ b/docs/pages/includes/edition-comparison.mdx @@ -6,7 +6,7 @@ |[Single Sign-On](../access-controls/sso.mdx)|GitHub|GitHub, Google Workspace, OIDC, SAML, Teleport|GitHub, Google Workspace, OIDC, SAML, Teleport|GitHub, Teleport| |[Role-Based Access Control](../access-controls/guides/role-templates.mdx)|✔|✔|✔|✔| |[Moderated Sessions](../access-controls/guides/moderated-sessions.mdx)|✖|✔|✔|✖| -|[Device Trust](../access-controls/guides/device-trust.mdx)|✖|✔|✔|✖| +|[Device Trust](../access-controls/device-trust/guide.mdx)|✖|✔|✔|✖| |[Dual Authorization](../access-controls/guides/dual-authz.mdx)|✖|✔|✔|✖| |[Hardware Key Support](../access-controls/guides/hardware-key-support.mdx)|✖|✔|✔|✖| diff --git a/docs/pages/includes/edition-prereqs-tabs.mdx b/docs/pages/includes/edition-prereqs-tabs.mdx index 8b5da01f95639..a460fc8c36581 100644 --- a/docs/pages/includes/edition-prereqs-tabs.mdx +++ b/docs/pages/includes/edition-prereqs-tabs.mdx @@ -1,13 +1,8 @@ -{/* -TODO: Since we can't control the directory level of the page that uses this -partial, and it is currently not possible to include absolute paths to MDX -files in partials, this partial uses relative URL paths instead. -*/} -- A running Teleport cluster. For details on how to set this up, see one of our - [Getting Started](/docs/getting-started) guides. +- A running Teleport cluster. For details on how to set this up, see our + [Getting Started](../index.mdx) guide. - The `tctl` admin tool and `tsh` client tool version >= (=teleport.version=). @@ -19,14 +14,14 @@ files in partials, this partial uses relative URL paths instead. # Teleport v(=teleport.version=) go(=teleport.golang=) ``` - See [Installation](/docs/installation.mdx) for details. + See [Installation](../installation.mdx) for details. - A running Teleport Enterprise cluster. For details on how to set this up, see our Enterprise - [Getting Started](/docs/enterprise/getting-started) guide. + [Getting Started](../choose-an-edition/teleport-enterprise/introduction.mdx) guide. - The Enterprise `tctl` admin tool and `tsh` client tool version >= (=teleport.version=), which you can download by visiting your [Teleport account](https://teleport.sh). @@ -43,8 +38,9 @@ files in partials, this partial uses relative URL paths instead. -- A Teleport Cloud account. If you do not have one, visit the - [sign up page](https://goteleport.com/signup/) to begin your free trial. +- A Teleport Enterprise Cloud account. If you do not have one, visit the [signup + page](https://goteleport.com/signup/) to begin a free trial of Teleport Team + and upgrade to Teleport Enterprise Cloud. - The Enterprise `tctl` admin tool and `tsh` client tool version >= (=cloud.version=). To download these tools, visit the [Downloads](../choose-an-edition/teleport-cloud/downloads.mdx) page. diff --git a/docs/pages/includes/enterprise/docker-images.mdx b/docs/pages/includes/enterprise/docker-images.mdx deleted file mode 100644 index 25ad0334044ed..0000000000000 --- a/docs/pages/includes/enterprise/docker-images.mdx +++ /dev/null @@ -1,37 +0,0 @@ -This table gives an idea of how our image naming scheme works. We offer images -which point to a static version of Teleport Enterprise, as well as images which are -automatically rebuilt every night. Our images contain only Teleport binaries and their application dependencies. - -Nightly images point to the latest version of Teleport Enterprise from the three -most recent release branches. They are stable, and we recommend their use to easily -keep your Teleport Enterprise installation up to date. - -These images are hosted on our [Amazon ECR Public repository](https://gallery.ecr.aws/gravitational/teleport-ent-distroless). -All tags under `public.ecr.aws/gravitational/teleport-ent-distroless` are -Teleport Enterprise images. Each tag points to a multi-arch image, containing -Teleport for `arm`, `arm64` and `amd64`. - -FIPS images are still posted to our [Legacy Amazon ECR Public repository](https://gallery.ecr.aws/gravitational/teleport-ent). -You can specify the architecture of a Teleport FIPS Docker image by adding a -postfix to the image tag, e.g., `public.ecr.aws/gravitational/teleport:(=teleport.major_version=)-arm64`. -Versions without an architecture postfix use the `amd64` architecture, e.g., -`public.ecr.aws/gravitational/teleport:(=teleport.major_version=)`. - -| Image name | Open Source or Enterprise? | Teleport version | Image automatically updated? | Includes troubleshooting tools | Image base | -| - | - | - | - | - | - | -| `public.ecr.aws/gravitational/teleport-ent-distroless:(=teleport.major_version=)` | Enterprise | The latest version of Teleport Enterprise (=teleport.major_version=) | Yes | No | [Distroless Debian 11](https://github.com/GoogleContainerTools/distroless) | -| `public.ecr.aws/gravitational/teleport-ent-distroless-debug:(=teleport.major_version=)` | Enterprise | The latest version of Teleport Enterprise (=teleport.major_version=) | Yes | Yes | [Distroless Debian 11](https://github.com/GoogleContainerTools/distroless) | -| `public.ecr.aws/gravitational/teleport-ent:(=teleport.major_version=)-fips` | Enterprise FIPS | The latest version of Teleport Enterprise (=teleport.major_version=) FIPS | Yes | Yes | [Ubuntu 20.04](https://hub.docker.com/\_/ubuntu) | -| `(=teleport.latest_ent_docker_image=)` | Enterprise | The version specified in the image's tag (i.e. (=teleport.version=)) | No | No | [Distroless Debian 11](https://github.com/GoogleContainerTools/distroless) | -| `(=teleport.latest_ent_debug_docker_image=)` | Enterprise | The version specified in the image's tag (i.e. (=teleport.version=)) | No | Yes | [Distroless Debian 11](https://github.com/GoogleContainerTools/distroless) | -| `(=teleport.latest_ent_docker_image=)-fips` | Enterprise FIPS | The version specified in the image's tag (i.e. (=teleport.version=)) | No | Yes | [Ubuntu 20.04](https://hub.docker.com/\_/ubuntu) | - -For testing, we always recommend that you use the latest release version of -Teleport Enterprise, which is currently `(=teleport.latest_ent_docker_image=)`. - -[Ubuntu 20.04](https://hub.docker.com/\_/ubuntu)-based images for non-FIPS -Teleport are available from our [Legacy Amazon ECR Public repository](https://gallery.ecr.aws/gravitational/teleport-ent). - -The `*-debug` images include a Busybox shell and tool suite in addition to Teleport, -and are intended for troubleshooting deployments only. They are not intended for production use. - diff --git a/docs/pages/includes/enterprise/samlauthentication.mdx b/docs/pages/includes/enterprise/samlauthentication.mdx index b9b8fbb8b247a..f105e636f6ef6 100644 --- a/docs/pages/includes/enterprise/samlauthentication.mdx +++ b/docs/pages/includes/enterprise/samlauthentication.mdx @@ -8,18 +8,7 @@ user database. - - - Update `/etc/teleport.yaml` in the `auth_service` section and restart the `teleport` daemon. - - ```yaml - auth_service: - authentication: - type: saml - ``` - - - + Use `tctl` to edit the `cluster_auth_preference` value: @@ -47,5 +36,22 @@ user database. cluster auth preference has been updated ``` + + + + Update `/etc/teleport.yaml` in the `auth_service` section and restart the `teleport` daemon. + + ```yaml + auth_service: + authentication: + type: saml + ``` + + + + + If you need to log in again before configuring your SAML provider, use the flag `--auth=local`. + + diff --git a/docs/pages/includes/install-event-handler.mdx b/docs/pages/includes/install-event-handler.mdx index 8e6550f8c01a9..9fb579b495e6b 100644 --- a/docs/pages/includes/install-event-handler.mdx +++ b/docs/pages/includes/install-event-handler.mdx @@ -4,6 +4,7 @@ ```code $ curl -L -O https://get.gravitational.com/teleport-event-handler-v(=teleport.plugin.version=)-linux-amd64-bin.tar.gz $ tar -zxvf teleport-event-handler-v(=teleport.plugin.version=)-linux-amd64-bin.tar.gz +$ sudo ./teleport-event-handler/install ``` We currently only build the Event Handler plugin for amd64 machines. For ARM @@ -16,6 +17,7 @@ architecture, you can build from source. ```code $ curl -L -O https://get.gravitational.com/teleport-event-handler-v(=teleport.plugin.version=)-darwin-amd64-bin.tar.gz $ tar -zxvf teleport-event-handler-v(=teleport.plugin.version=)-darwin-amd64-bin.tar.gz +$ sudo ./teleport-event-handler/install ``` We currently only build the event handler plugin for amd64 machines. If your diff --git a/docs/pages/includes/install-linux.mdx b/docs/pages/includes/install-linux.mdx index c2c08cb642d53..054ebf1f59c0a 100644 --- a/docs/pages/includes/install-linux.mdx +++ b/docs/pages/includes/install-linux.mdx @@ -1,77 +1,12 @@ -Use the appropriate commands for your environment to install your package. +Use the appropriate commands for your environment to install your package: - - ```code - # Download Teleport's PGP public key - $ sudo curl https://apt.releases.teleport.dev/gpg \ - -o /usr/share/keyrings/teleport-archive-keyring.asc - # Source variables about OS version - $ source /etc/os-release - # Add the Teleport APT repository for v(=teleport.major_version=). You'll need to update this - # file for each major release of Teleport. - $ echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] \ - https://apt.releases.teleport.dev/${ID?} ${VERSION_CODENAME?} stable/v(=teleport.major_version=)" \ - | sudo tee /etc/apt/sources.list.d/teleport.list > /dev/null - - $ sudo apt-get update - $ sudo apt-get install teleport + $ curl https://goteleport.com/static/install.sh | bash -s (=teleport.version=) ``` - - - - ```code - # Source variables about OS version - $ source /etc/os-release - # Add the Teleport YUM repository for v(=teleport.major_version=). You'll need to update this - # file for each major release of Teleport. - $ sudo yum-config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/v(=teleport.major_version=)/teleport.repo")" - $ sudo yum install teleport - # - # Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs) - # echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path - ``` - - - - ```code - # Source variables about OS version - $ source /etc/os-release - # Add the Teleport YUM repository for v(=teleport.major_version=). You'll need to update this - # file for each major release of Teleport. - # Use the dnf config manager plugin to add the teleport RPM repo - $ sudo dnf config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/v(=teleport.major_version=)/teleport.repo")" - - # Install teleport - $ sudo dnf install teleport - - # Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs) - # echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path - ``` - - - - In the example commands below, update `$SYSTEM_ARCH` with the appropriate - value (`amd64`, `arm64`, or `arm`). All example commands using this variable - will update after one is filled out. - - ```code - $ curl https://get.gravitational.com/teleport-v(=teleport.version=)-linux--bin.tar.gz.sha256 - # - $ curl -O https://cdn.teleport.dev/teleport-v(=teleport.version=)-linux--bin.tar.gz - $ shasum -a 256 teleport-v(=teleport.version=)-linux--bin.tar.gz - # Verify that the checksums match - $ tar -xvf teleport-v(=teleport.version=)-linux--bin.tar.gz - $ cd teleport - $ sudo ./install - ``` - - - @@ -107,6 +42,9 @@ Use the appropriate commands for your environment to install your package. $ source /etc/os-release # Add the Teleport YUM repository for v(=teleport.major_version=). You'll need to update this # file for each major release of Teleport. + # First, get the major version from $VERSION_ID so this fetches the correct + # package version. + $ VERSION_ID=$(echo $VERSION_ID | grep -Eo "^[0-9]+") $ sudo yum-config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/v(=teleport.major_version=)/teleport.repo")" $ sudo yum install teleport-ent # @@ -180,77 +118,7 @@ Use the appropriate commands for your environment to install your package. - - - - Add the Teleport repository to your repository list: - - ```code - # Download Teleport's PGP public key - $ sudo curl https://apt.releases.teleport.dev/gpg \ - -o /usr/share/keyrings/teleport-archive-keyring.asc - # Source variables about OS version - $ source /etc/os-release - # Add the Teleport apt repository for cloud. - $ echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] \ - https://apt.releases.teleport.dev/${ID?} ${VERSION_CODENAME?} stable/cloud" \ - | sudo tee /etc/apt/sources.list.d/teleport.list > /dev/null - - $ sudo apt-get update - $ sudo apt-get install teleport-ent - ``` - - - - - ```code - # Source variables about OS version - $ source /etc/os-release - # Add the Teleport yum repository for cloud. - $ sudo yum-config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/cloud/teleport.repo")" - $ sudo yum install teleport-ent - # - # Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs) - # echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path - ``` - - - - - ```code - # Source variables about OS version - $ source /etc/os-release - # Add the Teleport yum repository for cloud. - # Use the dnf config manager plugin to add the teleport RPM repo - $ sudo dnf config-manager --add-repo "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/stable/cloud/teleport.repo")" - - # Install teleport - $ sudo dnf install teleport-ent - - # Tip: Add /usr/local/bin to path used by sudo (so 'sudo tctl users add' will work as per the docs) - # echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" > /etc/sudoers.d/secure_path - ``` - - - - - In the example commands below, update `$SYSTEM_ARCH` with the appropriate - value (`amd64`, `arm64`, or `arm`). All example commands using this variable - will update after one is filled out. - - ```code - $ curl https://get.gravitational.com/teleport-ent-v(=cloud.version=)-linux--bin.tar.gz.sha256 - # - $ curl -O https://cdn.teleport.dev/teleport-ent-v(=cloud.version=)-linux-amd64-bin.tar.gz - $ shasum -a 256 teleport-ent-v(=cloud.version=)-linux-amd64-bin.tar.gz - # Verify that the checksums match - $ tar -xvf teleport-ent-v(=cloud.version=)-linux-amd64-bin.tar.gz - $ cd teleport-ent - $ sudo ./install - ``` - - - +(!docs/pages/includes/cloud/install-linux-cloud.mdx!)
Before installing a `teleport` binary with a version besides v(=cloud.major_version=), diff --git a/docs/pages/includes/install-tsh.mdx b/docs/pages/includes/install-tsh.mdx new file mode 100644 index 0000000000000..23fa63dc08059 --- /dev/null +++ b/docs/pages/includes/install-tsh.mdx @@ -0,0 +1,46 @@ + + + Download the signed macOS .pkg installer for `tsh`. In Finder double-click the `pkg` file to install it: + + ```code + $ curl -O https://cdn.teleport.dev/tsh-(=teleport.version=).pkg + ``` + + + + + ```code + $ brew install teleport + ``` + + + The Teleport package in Homebrew is not maintained by Teleport and we can't + guarantee its reliability or security. We recommend the use of our [own Teleport packages](https://goteleport.com/download?os=mac). + + If you choose to use Homebrew, you must verify that the versions of `tsh` and + `tctl` are compatible with the versions you run server-side. Homebrew usually + ships the latest release of Teleport, which may be incompatible with older + versions. See our [compatibility policy](../management/operations/upgrading.mdx#component-compatibility) for details. + + + + + ```code + $ curl.exe -O https://cdn.teleport.dev/teleport-v(=teleport.version=)-windows-amd64-bin.zip + # Unzip the archive and move `tsh.exe` to your %PATH% + ``` + + + + `tsh` is included with all of the Teleport binaries in Linux installations. + For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) please see our [installation page](../installation.mdx). + + ```code + $ curl -O https://cdn.teleport.dev/teleport-v(=teleport.version=)-linux-amd64-bin.tar.gz + $ tar -xzf teleport-v(=teleport.version=)-linux-amd64-bin.tar.gz + $ cd teleport + $ sudo ./install + # Teleport binaries have been copied to /usr/local/bin + ``` + + diff --git a/docs/pages/includes/install-windows-tsh.mdx b/docs/pages/includes/install-windows-tsh.mdx new file mode 100644 index 0000000000000..c62c1208e5131 --- /dev/null +++ b/docs/pages/includes/install-windows-tsh.mdx @@ -0,0 +1,28 @@ + ```code + # Set the TLS level to TLS 1.2 (required on Windows Server 2016 and lower) + $ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + # Get the expected checksum for the Windows tsh package + $ $Resp = Invoke-WebRequest https://get.gravitational.com/teleport-v{{ version }}-windows-amd64-bin.zip.sha256 + # PowerShell will return the binary representation of the response content + # by default, so you need to convert it to a string + $ [System.Text.Encoding]::UTF8.getstring($Resp.Content) + # + $ Invoke-WebRequest -OutFile teleport-v{{ version }}-windows-amd64-bin.zip -Uri https://cdn.teleport.dev/teleport-v{{ version }}-windows-amd64-bin.zip + $ certUtil -hashfile teleport-v{{ version }}-windows-amd64-bin.zip SHA256 + # SHA256 hash of teleport-v{{ version }}-windows-amd64-bin.zip: + # + # CertUtil: -hashfile command completed successfully. + ``` + + After you have verified that the checksums match, you can extract the archive. + The executable will be available at + `teleport-v{{ version }}-windows-amd64-bin\teleport\tsh.exe`. + + ```code + $ Expand-Archive teleport-v{{ .version }}-windows-amd64-bin.zip + $ cd teleport-v{{ version }}-windows-amd64-bin\teleport + $ .\tsh.exe version + Teleport v{{ version }} git:v{{ .version }} go(=teleport.golang=) + ``` + + Make sure to move `tsh.exe` into your PATH. \ No newline at end of file diff --git a/docs/pages/includes/install-windows.mdx b/docs/pages/includes/install-windows.mdx index 16eecad304ad6..b7920e0822071 100644 --- a/docs/pages/includes/install-windows.mdx +++ b/docs/pages/includes/install-windows.mdx @@ -1,32 +1,23 @@ -Starting with Teleport v7.2.0, most `tsh` features are supported for Windows 10 -1607+. The `tsh ssh` command can be run under `cmd.exe`, PowerShell, and Windows -Terminal. +Most `tsh` features are supported for Windows 10 1607+. The `tsh ssh` command +can be run under `cmd.exe`, PowerShell, and Windows Terminal. -To install `tsh` on Windows, run the following commands in PowerShell: +To install `tsh` on Windows, run the following commands in **PowerShell** (these commands will not work in `cmd.exe`): - ```code - # Get the expected checksum for the Windows tsh package - $ $Resp = Invoke-WebRequest https://get.gravitational.com/teleport-v(=teleport.version=)-windows-amd64-bin.zip.sha256 - # PowerShell will return the binary representation of the response content - # by default, so you need to convert it to a string - $ [System.Text.Encoding]::UTF8.getstring($Resp.Content) - # - $ curl -O https://cdn.teleport.dev/teleport-v(=teleport.version=)-windows-amd64-bin.zip - $ certUtil -hashfile teleport-v(=teleport.version=)-windows-amd64-bin.zip SHA256 - # SHA256 hash of teleport-v(=teleport.version=)-windows-amd64-bin.zip: - # - # CertUtil: -hashfile command completed successfully. - ``` + + - After you have verified that the checksums match, you can extract the archive. - The executable will be available at - `teleport-v(=teleport.version=)-windows-amd64-bin\teleport\tsh.exe`. + (!docs/pages/includes/install-windows-tsh.mdx version="(=teleport.version=)" !) + + + - ```code - $ Expand-Archive teleport-v(=teleport.version=)-windows-amd64-bin.zip - $ cd teleport-v(=teleport.version=)-windows-amd64-bin\teleport - $ .\tsh.exe version - Teleport v(=teleport.version=) git:v(=teleport.version=) go(=teleport.golang=) - ``` + (!docs/pages/includes/install-windows-tsh.mdx version="(=teleport.version=)" !) + + - Make sure to move `tsh.exe` into your PATH. + + + (!docs/pages/includes/install-windows-tsh.mdx version="(=cloud.version=)" !) + + + diff --git a/docs/pages/includes/metrics.mdx b/docs/pages/includes/metrics.mdx index 3b0c924966264..11d4e6c48f45e 100644 --- a/docs/pages/includes/metrics.mdx +++ b/docs/pages/includes/metrics.mdx @@ -15,7 +15,7 @@ | `backend_batch_write_seconds` | histogram | cache | Latency for backend batch write operations. | | `backend_read_requests_total` | counter | cache | Number of read requests to the backend. | | `backend_read_seconds` | histogram | cache | Latency for read operations. | -| `backend_requests` | counter | cache | Number of write requests to the backend. | +| `backend_requests` | counter | cache | Number of requests to the backend (reads, writes, and keepalives). | | `backend_write_seconds` | histogram | cache | Latency for backend write operations. | | `cluster_name_not_found_total` | counter | Teleport Auth | Number of times a cluster was not found. | | `dynamo_requests_total` | counter | DynamoDB | Total number of requests to the DynamoDB API. | @@ -114,6 +114,7 @@ | Name | Type | Component | Description | | - | - | - | - | +| `process_state` | gauge | Teleport | State of the teleport process: 0 - ok, 1 - recovering, 2 - degraded, 3 - starting. | | `certificate_mismatch_total` | counter | Teleport | Number of SSH server login failures due to a certificate mismatch. | | `reversetunnel_connected_proxies` | gauge | Teleport | Number of known proxies being sought. | | `rx` | counter | Teleport | Number of bytes received during an SSH connection. | @@ -123,45 +124,47 @@ | `teleport_cache_stale_events` | counter | Teleport | Number of stale events received by a Teleport service cache. A high percentage of stale events can indicate a degraded backend. | | `tx` | counter | Teleport | Number of bytes transmitted during an SSH connection. | -## Golang runtime metrics +## Go runtime metrics + +These metrics are surfaced by the Go runtime and are not specific to Teleport. | Name | Type | Component | Description | | - | - | - | - | -| `go_gc_duration_seconds` | summary | Internal Golang | A summary of GC invocation durations. | -| `go_goroutines` | gauge | Internal Golang | Number of goroutines that currently exist. | -| `go_info` | gauge | Internal Golang | Information about the Go environment. | -| `go_memstats_alloc_bytes_total` | counter | Internal Golang | Total number of bytes allocated, even if freed. | -| `go_memstats_alloc_bytes` | gauge | Internal Golang | Number of bytes allocated and still in use. | -| `go_memstats_buck_hash_sys_bytes` | gauge | Internal Golang | Number of bytes used by the profiling bucket hash table. | -| `go_memstats_frees_total` | counter | Internal Golang | Total number of frees. | -| `go_memstats_gc_cpu_fraction` | gauge | Internal Golang | The fraction of this program's available CPU time used by the GC since the program started. | -| `go_memstats_gc_sys_bytes` | gauge | Internal Golang | Number of bytes used for garbage collection system metadata. | -| `go_memstats_heap_alloc_bytes` | gauge | Internal Golang | Number of heap bytes allocated and still in use. | -| `go_memstats_heap_idle_bytes` | gauge | Internal Golang | Number of heap bytes waiting to be used. | -| `go_memstats_heap_inuse_bytes` | gauge | Internal Golang | Number of heap bytes that are in use. | -| `go_memstats_heap_objects` | gauge | Internal Golang | Number of allocated objects. | -| `go_memstats_heap_released_bytes` | gauge | Internal Golang | Number of heap bytes released to the OS. | -| `go_memstats_heap_sys_bytes` | gauge | Internal Golang | Number of heap bytes obtained from the system. | -| `go_memstats_last_gc_time_seconds` | gauge | Internal Golang | Number of seconds since the Unix epoch of the last garbage collection. | -| `go_memstats_lookups_total` | counter | Internal Golang | Total number of pointer lookups. | -| `go_memstats_mallocs_total` | counter | Internal Golang | Total number of mallocs. | -| `go_memstats_mcache_inuse_bytes` | gauge | Internal Golang | Number of bytes in use by mcache structures. | -| `go_memstats_mcache_sys_bytes` | gauge | Internal Golang | Number of bytes used for mcache structures obtained from system. | -| `go_memstats_mspan_inuse_bytes` | gauge | Internal Golang | Number of bytes in use by mspan structures. | -| `go_memstats_mspan_sys_bytes` | gauge | Internal Golang | Number of bytes used for mspan structures obtained from system. | -| `go_memstats_next_gc_bytes` | gauge | Internal Golang | Number of heap bytes when next the garbage collection will take place. | -| `go_memstats_other_sys_bytes` | gauge | Internal Golang | Number of bytes used for other system allocations. | -| `go_memstats_stack_inuse_bytes` | gauge | Internal Golang | Number of bytes in use by the stack allocator. | -| `go_memstats_stack_sys_bytes` | gauge | Internal Golang | Number of bytes obtained from the system for stack allocator. | -| `go_memstats_sys_bytes` | gauge | Internal Golang | Number of bytes obtained from the system. | -| `go_threads` | gauge | Internal Golang | Number of OS threads created. | -| `process_cpu_seconds_total` | counter | Internal Golang | Total user and system CPU time spent in seconds. | -| `process_max_fds` | gauge | Internal Golang | Maximum number of open file descriptors. | -| `process_open_fds` | gauge | Internal Golang | Number of open file descriptors. | -| `process_resident_memory_bytes` | gauge | Internal Golang | Resident memory size in bytes. | -| `process_start_time_seconds` | gauge | Internal Golang | Start time of the process since the Unix epoch in seconds. | -| `process_virtual_memory_bytes` | gauge | Internal Golang | Virtual memory size in bytes. | -| `process_virtual_memory_max_bytes` | gauge | Internal Golang | Maximum amount of virtual memory available in bytes. | +| `go_gc_duration_seconds` | summary | Internal Go | A summary of GC invocation durations. | +| `go_goroutines` | gauge | Internal Go | Number of goroutines that currently exist. | +| `go_info` | gauge | Internal Go | Information about the Go environment. | +| `go_memstats_alloc_bytes_total` | counter | Internal Go | Total number of bytes allocated, even if freed. | +| `go_memstats_alloc_bytes` | gauge | Internal Go | Number of bytes allocated and still in use. | +| `go_memstats_buck_hash_sys_bytes` | gauge | Internal Go | Number of bytes used by the profiling bucket hash table. | +| `go_memstats_frees_total` | counter | Internal Go | Total number of frees. | +| `go_memstats_gc_cpu_fraction` | gauge | Internal Go | The fraction of this program's available CPU time used by the GC since the program started. | +| `go_memstats_gc_sys_bytes` | gauge | Internal Go | Number of bytes used for garbage collection system metadata. | +| `go_memstats_heap_alloc_bytes` | gauge | Internal Go | Number of heap bytes allocated and still in use. | +| `go_memstats_heap_idle_bytes` | gauge | Internal Go | Number of heap bytes waiting to be used. | +| `go_memstats_heap_inuse_bytes` | gauge | Internal Go | Number of heap bytes that are in use. | +| `go_memstats_heap_objects` | gauge | Internal Go | Number of allocated objects. | +| `go_memstats_heap_released_bytes` | gauge | Internal Go | Number of heap bytes released to the OS. | +| `go_memstats_heap_sys_bytes` | gauge | Internal Go | Number of heap bytes obtained from the system. | +| `go_memstats_last_gc_time_seconds` | gauge | Internal Go | Number of seconds since the Unix epoch of the last garbage collection. | +| `go_memstats_lookups_total` | counter | Internal Go | Total number of pointer lookups. | +| `go_memstats_mallocs_total` | counter | Internal Go | Total number of mallocs. | +| `go_memstats_mcache_inuse_bytes` | gauge | Internal Go | Number of bytes in use by mcache structures. | +| `go_memstats_mcache_sys_bytes` | gauge | Internal Go | Number of bytes used for mcache structures obtained from system. | +| `go_memstats_mspan_inuse_bytes` | gauge | Internal Go | Number of bytes in use by mspan structures. | +| `go_memstats_mspan_sys_bytes` | gauge | Internal Go | Number of bytes used for mspan structures obtained from system. | +| `go_memstats_next_gc_bytes` | gauge | Internal Go | Number of heap bytes when next the garbage collection will take place. | +| `go_memstats_other_sys_bytes` | gauge | Internal Go | Number of bytes used for other system allocations. | +| `go_memstats_stack_inuse_bytes` | gauge | Internal Go | Number of bytes in use by the stack allocator. | +| `go_memstats_stack_sys_bytes` | gauge | Internal Go | Number of bytes obtained from the system for stack allocator. | +| `go_memstats_sys_bytes` | gauge | Internal Go | Number of bytes obtained from the system. | +| `go_threads` | gauge | Internal Go | Number of OS threads created. | +| `process_cpu_seconds_total` | counter | Internal Go | Total user and system CPU time spent in seconds. | +| `process_max_fds` | gauge | Internal Go | Maximum number of open file descriptors. | +| `process_open_fds` | gauge | Internal Go | Number of open file descriptors. | +| `process_resident_memory_bytes` | gauge | Internal Go | Resident memory size in bytes. | +| `process_start_time_seconds` | gauge | Internal Go | Start time of the process since the Unix epoch in seconds. | +| `process_virtual_memory_bytes` | gauge | Internal Go | Virtual memory size in bytes. | +| `process_virtual_memory_max_bytes` | gauge | Internal Go | Maximum amount of virtual memory available in bytes. | ## Prometheus diff --git a/docs/pages/includes/okta-import-rule.mdx b/docs/pages/includes/okta-import-rule.mdx index 81ba42837e8fd..c68bcc96c248d 100644 --- a/docs/pages/includes/okta-import-rule.mdx +++ b/docs/pages/includes/okta-import-rule.mdx @@ -27,4 +27,16 @@ spec: # These labels will be added to the groups. add_labels: label1: value1 + - match: + # Regexes based on the app name can be used to create matches. + - app_name_regexes: ["^okta.*$", "app*"] + # These labels will be added to matching applications. + add_labels: + app_label: app_label_value + - match: + # Similarly, regexes based on the group name can be used as well. + - group_name_regexes: ["^okta.*$", "app*"] + # These labels will be added to the groups. + add_labels: + label1: value1 ``` \ No newline at end of file diff --git a/docs/pages/includes/permission-warning.mdx b/docs/pages/includes/permission-warning.mdx index ab9fb6b934fa9..f3c08a4b3a586 100644 --- a/docs/pages/includes/permission-warning.mdx +++ b/docs/pages/includes/permission-warning.mdx @@ -12,7 +12,10 @@ numbered < `1024` (e.g. `443`). - Follow the "Principle of Least Privilege" (PoLP). Don't give users permissive roles when giving them more restrictive roles will do instead. - For example, assign users the built-in `access,editor` roles. + For example, don't assign users the built-in `access,editor` roles, which give + them permissions to access and edit all cluster resources. Instead, define + RBAC roles with the minimum required permissions for each user and configure + Access Requests for elevated permissions. - When joining a Teleport resource service (e.g., the Database Service or Application Service) to a cluster, save the invitation token to a file. Otherwise, the token will be visible when examining the `teleport` command diff --git a/docs/pages/includes/plugins/identity-export.mdx b/docs/pages/includes/plugins/identity-export.mdx index 2c8ead98c5605..813e1b2561a05 100644 --- a/docs/pages/includes/plugins/identity-export.mdx +++ b/docs/pages/includes/plugins/identity-export.mdx @@ -1,6 +1,8 @@ -Like all Teleport users, `{{ user }}` needs signed credentials in -order to connect to your Teleport cluster. You will use the `tctl auth sign` -command to request these credentials for your plugin. +{{ client="The plugin" }} + +Like all Teleport users, `{{ user }}` needs signed credentials in order to +connect to your Teleport cluster. You will use the `tctl auth sign` command to +request these credentials. The following `tctl auth sign` command impersonates the `{{ user }}` user, generates signed credentials, and writes an identity file to the local @@ -10,16 +12,14 @@ directory: $ tctl auth sign --user={{ user }} --out=auth.pem ``` -The plugin connects to the Teleport Auth Service's gRPC endpoint over TLS. +{{ client }} connects to the Teleport Auth Service's gRPC endpoint over TLS. -The identity file, `auth.pem`, includes both TLS and SSH credentials. The plugin +The identity file, `auth.pem`, includes both TLS and SSH credentials. {{ client }} uses the SSH credentials to connect to the Proxy Service, which establishes a -reverse tunnel connection to the Auth Service. The plugin uses this reverse +reverse tunnel connection to the Auth Service. {{ client }} uses this reverse tunnel, along with your TLS credentials, to connect to the Auth Service's gRPC endpoint. -You will refer to this file later when configuring the plugin. - diff --git a/docs/pages/includes/role-spec.mdx b/docs/pages/includes/role-spec.mdx index 3ecdb82b34931..d0c30867150db 100644 --- a/docs/pages/includes/role-spec.mdx +++ b/docs/pages/includes/role-spec.mdx @@ -98,7 +98,9 @@ spec: name: login@github.com value: "{{ external.github_login }}" # Controls whether this role supports auto provisioning of SSH users. - create_host_user: true + # Options: drop (remove user on session end), keep (keep users at session end) + # and off (disable host user creation) + create_host_user_mode: drop create_host_user: true # Controls whether this role requires automatic database user provisioning. create_db_user: true # Specifies role specific options for identity provider access. @@ -120,7 +122,7 @@ spec: windows_desktop_logins: [Administrator, '{{internal.logins}}'] # node_labels: a user with this role will be allowed to connect to - # SSH nodes, which labels match expressions below. + # SSH nodes with labels matching below. node_labels: # literal strings: 'env': 'test' @@ -128,9 +130,11 @@ spec: '*': '*' # a list of alternative options: 'region': ['us-west-1', 'eu-central-1'] - # regular expressions start with ^ and end with $ - # Teleport uses golang regexp syntax. - # of the list example above can be expressed as: + # Regular expressions start with ^ and end with $. + # Teleport uses Go's regular expression syntax: + # https://github.com/google/re2/wiki/Syntax + # The list example above can be expressed as: + # 'region': '^us-west-1|eu-central-1$' 'reg': '^us-west-1|eu-central-1$' # kubernetes_groups specifies Kubernetes groups a user with this role will assume. @@ -143,14 +147,17 @@ spec: kubernetes_users: ['IAM#{{external.foo}};'] # kubernetes_labels: a user with this role will be allowed to connect to - # k8s clusters, which labels match expressions below. + # k8s clusters with labels matching below. kubernetes_labels: # A user can only access prod environments 'env': 'prod' # User can access any region in us-west, e.g us-west-1, us-west-2 'region': 'us-west-*' - # regular expressions start with ^ and ending with $ - # Teleport uses golang regexp syntax. + # Regular expressions start with ^ and end with $. + # Teleport uses Go's regular expression syntax: + # https://github.com/google/re2/wiki/Syntax + # The list example above can be expressed as: + # 'region': '^us-west-1|eu-central-1$' 'cluster_name': '^us.*\.example\.com$' # kubernetes_resources indicates the Kubernetes resources that a user with @@ -178,7 +185,7 @@ spec: 'env': '{{regexp.replace(external.access["env"], "^(staging)$", "$1")}}' # app_labels: a user with this role will be allowed to connect to - # applications, which labels match expressions below. + # applications with labels matching below. app_labels: # A user can only access prod environments 'env': 'prod' @@ -198,6 +205,30 @@ spec: # A user is given group membership to production related groups. 'env': 'prod' + # cluster_labels: a user with this role will be allowed to connect to remote + # clusters with labels matching below. + cluster_labels: + 'env': 'prod' + + # node_labels_expression has the same purpose as node_labels but + # supports predicate expressions to configure custom logic. + # A user with this role will be allowed to access nodes if they are in the + # staging environment *or* if they belong to one of the user's own teams. + node_labels_expression: | + labels["env"] == "staging" || + contains(user.spec.traits["teams"] , labels["team"]) + + # The below _labels_expression fields have the same purpose of the + # matching _labels fields, but support predicate expressions instead + # of label matchers. + app_labels_expression: 'labels["env"] == "staging"' + cluster_labels_expression: 'labels["env"] == "staging"' + kubernetes_labels_expression: 'labels["env"] == "staging"' + db_labels_expression: 'labels["env"] == "staging"' + db_service_labels_expression: 'labels["env"] == "staging"' + windows_desktop_labels_expression: 'labels["env"] == "staging"' + group_labels_expression: 'labels["env"] == "staging"' + # aws_role_arns allows a user with this role to assume AWS roles when # accessing AWS console using UI or AWS API using CLI aws_role_arns: @@ -245,12 +276,12 @@ spec: # the `claims_to_roles` mapping works the same as it does in # the OIDC connector, with the added benefit that the roles being mapped to - # can also be matchers. + # can also be matchers. # - # This example leverages Teleport's regular expression support, which allows + # This example leverages Teleport's regular expression support, which allows # for dynamic mapping from claims. The below mapping says that users with - # claims that match "projects: project-(.*)" can request roles that match - # "$1-admin", where "$1" is the first capture group in the + # claims that match "projects: product-(.*)" can request roles that match + # "$1-admin", where "$1" is the first capture group in the # regular expression. # Example: the "projects: product-foo" claim allows a user to request the # "foo-admin" role diff --git a/docs/pages/includes/server-access/custom-installer.mdx b/docs/pages/includes/server-access/custom-installer.mdx new file mode 100644 index 0000000000000..5a8816b5e0e6a --- /dev/null +++ b/docs/pages/includes/server-access/custom-installer.mdx @@ -0,0 +1,84 @@ +{{ cloud="foo" matcher="bar" matchTypes="baz" }} +To customize the default installer script, execute the following command on +your workstation: + +```code +$ tctl get installer/default-installer > teleport-default-installer.yaml +``` + +The resulting `teleport-default-installer.yaml` can be edited to +change what gets executed when enrolling discovered instances. + +After making the desired changes to the default installer, the +resource can be updated by executing: + +```code +$ tctl create -f teleport-default-installer.yaml +``` + +Multiple `installer` resources can exist and be specified in the +`{{ matcher }}.install.script_name` section of a `discovery_service.{{ matcher }}` list item in +`teleport.yaml`: + +```yaml +discovery_service: + {{ matcher }}: + - types: {{ matchTypes }} + tags: + - "env": "prod" + install: # optional section when default-installer is used. + script_name: "default-installer" + - types: {{ matchTypes }} + tags: + - "env": "devel" + install: + script_name: "devel-installer" +``` + +--- + +The `installer` resource has the following templating options: + +- `{{ .MajorVersion }}`: the major version of Teleport to use when + installing from the repository. +- `{{ .PublicProxyAddr }}`: the public address of the Teleport Proxy Service to +connect to. +- `{{ .RepoChannel }}`: Optional package repository (apt/yum) channel name. +Has format `/` e.g. stable/v(=teleport.major_version=). See [installation](../../installation.mdx#linux) for more details. +- `{{ .AutomaticUpgrades }}`: indicates whether Automatic Upgrades are enabled or disabled. + Its value is either `true` or `false`. See + [self-hosted automatic agent updates](../../management/operations/self-hosted-automatic-agent-updates.mdx) + for more information. +- `{{ .TeleportPackage }}`: the Teleport package to use. + Its value is either `teleport-ent` or `teleport` depending on whether the + cluster is enterprise or not. + +These can be used as follows: + +```yaml +kind: installer +metadata: + name: default-installer +spec: + script: | + echo {{ .PublicProxyAddr }} + echo Teleport-{{ .MajorVersion }} + echo Repository Channel: {{ .RepoChannel }} +version: v1 +``` + +Which, when retrieved for installation, will evaluate to a script +with the following contents: + +```sh +echo teleport.example.com +echo Teleport-(=teleport.version=) +echo Repository Channel: stable/v(=teleport.version=) +``` + +The default installer will take the following actions: + +- Add an official Teleport repository to supported Linux distributions. +- Install Teleport via `apt` or `yum`. +- Generate the Teleport config file and write it to `/etc/teleport.yaml`. +- Enable and start the Teleport service. diff --git a/docs/pages/includes/sso/idp-initiated.mdx b/docs/pages/includes/sso/idp-initiated.mdx index 9af9706df51ce..9003c75652bba 100644 --- a/docs/pages/includes/sso/idp-initiated.mdx +++ b/docs/pages/includes/sso/idp-initiated.mdx @@ -1,5 +1,5 @@
- Enabling the `allow_idp_initiated` flag in SAML connectors allows users to + Enabling the `spec.allow_idp_initiated` flag in SAML connectors allows users to log in to Teleport with one click from the dashboard provided by the IdP. This feature is potentially unsafe and should be used with caution. diff --git a/docs/pages/includes/sso/loginerrortroubleshooting.mdx b/docs/pages/includes/sso/loginerrortroubleshooting.mdx index 322f30b8a01b5..6a3897e7ee9fe 100644 --- a/docs/pages/includes/sso/loginerrortroubleshooting.mdx +++ b/docs/pages/includes/sso/loginerrortroubleshooting.mdx @@ -17,7 +17,8 @@ If something is not working, we recommend to: ### Using the Web UI If you get "access denied" or other login errors, the number one place to check is the Audit -Log. You can access it in the **Activity** tab of the Teleport Web UI. +Log. Under the **Management** area you can access it within the **Activity** tab in the +Teleport Web UI. ![Audit Log Entry for SSO Login error](../../../img/sso/teleportauditlogssofailed.png) diff --git a/docs/pages/includes/tls-certificate-setup.mdx b/docs/pages/includes/tls-certificate-setup.mdx index 7387db5b5fce5..ca362e7483b5e 100644 --- a/docs/pages/includes/tls-certificate-setup.mdx +++ b/docs/pages/includes/tls-certificate-setup.mdx @@ -12,26 +12,13 @@ deployments, use your own private key and certificate. verification process when it starts up. On the host where you will start the Teleport Auth Service and Proxy Service, - run the following `teleport configure` command, where `tele.example.com` is the - domain name of your Teleport cluster and `user@example.com` is an email address - used for notifications (you can use any domain): + run the following `teleport configure` command. Assign + to the + domain name of your Teleport cluster and to + an email address used for notifications (you can use any domain): ```code - $ teleport configure --acme --acme-email= --cluster-name= | \ - sudo tee /etc/teleport.yaml > /dev/null - ``` - - The `--acme`, `--acme-email`, and `--cluster-name` flags will add the following - settings to your Teleport configuration file: - - ```yaml - proxy_service: - enabled: "yes" - web_listen_addr: 0.0.0.0:443 - public_addr: tele.example.com:443 - acme: - enabled: "yes" - email: user@example.com + $ teleport configure --acme --acme-email= --cluster-name= | sudo tee /etc/teleport.yaml > /dev/null ``` Port 443 on your Teleport Proxy Service host must allow traffic from all sources. @@ -43,12 +30,14 @@ deployments, use your own private key and certificate. The leaf certificate must have a subject that corresponds to the domain of your Teleport host, e.g., `*.teleport.example.com`. - Configure Teleport, changing the values of the `--cluster-name` and `--public-addr` flags to match the domain name of your Teleport host. + On the host where you will start the Teleport Auth Service and Proxy Service, + run the following `teleport configure` command. Assign to the domain name of your Teleport cluster. ```code $ sudo teleport configure -o file \ - --cluster-name=tele.example.com \ - --public-addr=tele.example.com:443 \ + --cluster-name= \ + --public-addr=:443 \ --cert-file=/var/lib/teleport/fullchain.pem \ --key-file=/var/lib/teleport/privkey.pem ``` diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index 188710951857b..671f19769f0dc 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -1,175 +1,220 @@ --- -title: Introduction to Teleport -description: Teleport is an identity-aware, multi-protocol access proxy with native support for SSH, RDP, Kubernetes, and more. Get started with the Teleport documentation. -layout: tocless-doc -videoBanner: ki-uVTSocGE +title: Get Started with Teleport +description: This tutorial will guide you through the steps needed to install and run Teleport on a Linux server +videoBanner: BJWbSqiDLeU +tocDepth: 3 --- Teleport is an identity-aware, multi-protocol access proxy. Teleport understands the SSH, HTTPS, RDP, Kubernetes API, MySQL, MongoDB and PostgreSQL wire -protocols, plus many others. +protocols, plus many others. It can integrate with Single Sign-On providers and +enables you to apply access policies using infrastructure-as-code and GitOps +tools. -With Teleport you can: +See how Teleport works by completing the tutorial below. This shows you how to +spin up a single-instance Teleport cluster on a Linux server using Teleport +Community Edition. Once you deploy the cluster, you can configure RBAC, register +resources, and protect your small-scale demo environments or home lab. -- Replace a mix of vaults, passwords, API keys and tokens with short-lived SSH and X.509 certs. -- Have a single access point and Single-Sign-On provider for all of your - infrastructure, including SSH servers, Kubernetes clusters, databases, - desktops, web applications, and more. -- Write policies with Terraform or Kubernetes resources for all clouds, - environments and protocols and manage them with GitOps. -- Record SSH and `kubectl exec` sessions, DB queries, Windows desktop sessions, - web sessions and API requests. -- Use mutual TLS tunnels to protect your infrastructure endpoints. +You can also get started right away with a production-ready Teleport cluster by +signing up for a [free trial of Teleport +Team](./choose-an-edition/teleport-team.mdx). - +## Set up a demo cluster -If your organization is already using Teleport and you want to learn how to -access infrastructure, read our [Connect your -Client](./connect-your-client/introduction.mdx) guides for instructions. +
+![Architecture of the setup you will complete in this +guide](../img/linux-server-diagram.png) +
+ +We will run the following Teleport services: + +- **Teleport Auth Service:** The certificate authority for your cluster. It + issues certificates and conducts authentication challenges. The Auth Service + is typically inaccessible outside your private network. +- **Teleport Proxy Service:** The cluster frontend, which handles user requests, + forwards user credentials to the Auth Service, and communicates with Teleport + instances that enable access to specific resources in your infrastructure. +- **Teleport SSH Service:** An SSH server implementation that takes advantage of + Teleport's short-lived certificates, sophisticated RBAC, session recording, + and other features. + +### Prerequisites + + + +You will need the following to deploy a demo Teleport cluster. If your +environment doesn't meet the prerequisites above, you can get started with +Teleport by signing up for a [free trial of Teleport +Team](https://goteleport.com/signup/). -## Try out Teleport +- A Linux host with only port `443` open to ingress traffic. You must be able + to install and run software on the host. Either configure access to the host + via SSH for the initial setup (and open an SSH port in addition port `443`) + or enter the commands in this guide into an Amazon EC2 [user data + script](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html), + Google Compute Engine [startup + script](https://cloud.google.com/compute/docs/instances/startup-scripts), + or similar. -If you are curious to see how Teleport works, you can get started by [spinning -up a demo cluster](./get-started.mdx) on a Linux server. After seeing how your -demo Teleport cluster lets you securely access a server and play back your SSH -sessions, you can configure RBAC, add resources, and protect your home lab with -Teleport. + -You can also get started right away with a production-ready Teleport cluster. -[Sign up for a free trial](https://goteleport.com/signup/) of Teleport -Team. + For a quick demo environment you can use to follow this guide, consider + installing our DigitalOcean 1-Click droplet. View the installation page on + [DigitalOcean + Marketplace](https://marketplace.digitalocean.com/apps/teleport). Once your + droplet is ready, SSH into the droplet and follow the configuration wizard. -Once you are ready to learn more about Teleport, read our [Core Concepts -guide](./core-concepts.mdx), which introduces the components of a Teleport -cluster. You can refer to this glossary as you continue through the -documentation. + -## Choose an edition +- A two-factor authenticator app such as [Authy](https://authy.com/download/), + [Google Authenticator](https://www.google.com/landing/2step/), or + [1Password](https://support.1password.com/one-time-passwords/). -After trying out Teleport, you are ready to deploy a cluster to your -infrastructure. Teleport has four editions: +You must also have **one** of the following: +- A registered domain name. +- An authoritative DNS nameserver managed by your organization, plus an existing + certificate authority. If using this approach, ensure that your browser is + configured to use your organization's nameserver. -- Teleport Team -- Teleport Enterprise Cloud -- Teleport Enterprise -- Teleport Community Edition +### Step 1/4. Configure DNS -You can compare these in our [Choose an -Edition](./choose-an-edition/introduction.mdx) section. +Teleport uses TLS to provide secure access to its Proxy Service and Auth +Service, and this requires a domain name that clients can use to verify +Teleport's certificate. Set up two DNS `A` records, each pointing to the IP +address of your Linux host. Assuming `teleport.example.com` is your domain name, +set up records for: - +|Domain|Reason| +|---|---| +|`teleport.example.com`|Traffic to the Proxy Service from users and services.| +|`*.teleport.example.com`|Traffic to web applications registered with Teleport. Teleport issues a subdomain of your cluster's domain name to each application.| -You can view information specific to an edition of Teleport by using the "Open -Source", "Enterprise", and "Cloud" buttons at the top of the page. +### Step 2/4. Set up Teleport on your Linux host - +#### Install Teleport + +On your Linux host, run the following command to install the Teleport binary: + +```code +$ curl https://goteleport.com/static/install.sh | bash -s (=teleport.version=) +``` + +#### Configure Teleport + +Generate a configuration file for Teleport using the `teleport configure` command. +This command requires information about a TLS certificate and private key. + +(!docs/pages/includes/tls-certificate-setup.mdx!) + +#### Start Teleport + +(!docs/pages/includes/start-teleport.mdx!) + +Access Teleport's Web UI via HTTPS at the domain you created earlier (e.g., +`https://teleport.example.com`). You should see a welcome screen similar to the +following: + +![Teleport Welcome Screen](../img/quickstart/welcome.png) + +### Step 3/4. Create a Teleport user and set up two-factor authentication + +In this step, we'll create a new Teleport user, `teleport-admin`, which is +allowed to log into SSH hosts as any of the principals `root`, `ubuntu`, or +`ec2-user`. + +On your Linux host, run the following command: + +```code +# tctl is an administrative tool that is used to configure Teleport's auth service. +$ sudo tctl users add teleport-admin --roles=editor,access --logins=root,ubuntu,ec2-user +``` + +The command prints a message similar to the following: + +```text +User "teleport-admin" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h: +https://teleport.example.com:443/web/invite/123abc456def789ghi123abc456def78 + +NOTE: Make sure teleport.example.com:443 points at a Teleport proxy which users can access. +``` + +Visit the provided URL in order to create your Teleport user. + + + + The users that you specify in the `logins` flag (e.g., `root`, `ubuntu` and + `ec2-user` in our examples) must exist on your Linux host. Otherwise, you + will get authentication errors later in this tutorial. + + If a user does not already exist, you can create it with `adduser ` or + use [host user creation](./server-access/guides/host-user-creation.mdx). + + If you do not have the permission to create new users on the Linux host, run + `tctl users add teleport $(whoami)` to explicitly allow Teleport to + authenticate as the user that you have currently logged in as. + + + +Teleport enforces the use of two-factor authentication by default. It supports +one-time passwords (OTP) and second-factor authenticators (WebAuthn). In this +guide, you will need to enroll an OTP authenticator application using the QR +code on the Teleport welcome screen. + +
+ +In addition to Teleport's Web UI, you can access resources in your +infrastructure via the `tsh` client tool. + +Install `tsh` on your local workstation: + +(!docs/pages/includes/install-tsh.mdx!) + +Log in to receive short-lived certificates from Teleport: + +```code +# Replace teleport.example.com with your Teleport cluster's public address as configured above. +$ tsh login --proxy= --user=teleport-admin +> Profile URL: https://teleport.example.com:443 + Logged in as: teleport-admin + Cluster: teleport.example.com + Roles: access, editor + Logins: root, ubuntu, ec2-user + Kubernetes: enabled + Valid until: 2022-04-26 03:04:46 -0400 EDT [valid for 12h0m0s] + Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty +``` + +
+ +### Step 4/4. Enroll your infrastructure + +With Teleport, you can protect all of the resources in your infrastructure +behind a single identity-aware access proxy, including servers, databases, +applications, Kubernetes clusters, Windows desktops, and cloud provider APIs. + +To enroll a resource with Teleport, visit the Web UI and click the name of a +resource on the sidebar, e.g., **Servers**, **Applications**, and +**Kubernetes**. The Web UI will show you the steps you can take to enroll that +resource. + +![Adding resources](../img/add-resources.png) + +In the **Servers** tab, you can see that you have already enrolled your Linux +server. + +### Next step: deploy agents + +Teleport **agents** proxy traffic to infrastructure resources like servers, +databases, Kubernetes clusters, cloud provider APIs, and Windows desktops. -## Deploy a cluster - -Once you know which edition you would like to deploy, read our [Deploy a -Cluster](./deploy-a-cluster/introduction.mdx) documentation for how to launch a -fully fledged Teleport cluster in production. (If you are using Teleport -Enterprise Cloud, you can skip this step.) This section shows you the best -practices to follow for a high-availability Teleport cluster, and how to deploy -Teleport on your cloud provider of choice. - -## Manage access - -Now that you have a running Teleport cluster, set up role-based access controls -to enable secure access to your infrastructure. You can define roles with -granular permissions and use Teleport's integrations with Single Sign-On -providers to automatically map these roles to users. You can also set up Access -Requests to enable just-in-time access to your infrastructure. Read [Manage -Access](./access-controls/introduction.mdx) to get started. - -## Manage your cluster - -With your Teleport cluster configured, you can now begin Day Two operations -such as upgrades, adding agents to the cluster, and integrating Teleport with -third-party tools. Read [Manage your -Cluster](./management/introduction.mdx) for more information. - -## Add your infrastructure - -Teleport is protocol aware and provides functionality that is unique to each -protocol it supports. To enable access to a protocol, deploy the appropriate -Teleport service and configure it to communicate with resources in your -infrastructure. - -Read about how to enable access to: - -- [Servers](./server-access/getting-started.mdx), including OpenSSH servers that - [do not have Teleport installed](./server-access/guides/openssh.mdx) -- [Kubernetes clusters](./kubernetes-access/introduction.mdx) -- [Databases](./database-access/introduction.mdx) -- [Applications](./application-access/introduction.mdx) -- [Remote desktops](./desktop-access/introduction.mdx) - -You can also set up [Machine ID](./machine-id/introduction.mdx) to enable -service accounts to access resources in your infrastructure with short-lived -credentials. - -## Extend Teleport for your organization - -Teleport is highly customizable, exposing much of its functionality via a gRPC -API. For example, you can build API clients to register infrastructure -automatically or manage Access Requests using your organization's unique -workflows. Read how to build applications that interact with Teleport's API in -our [API guides](./api/introduction.mdx). - -## Learn more about Teleport - -Get more information about Teleport by reading our library of architecture, -reference, and developer guides. See the -[Upcoming Releases](./upcoming-releases.mdx) section for a glimpse of features we -will release in the next Teleport version. Consult our -[Reference](./reference/introduction.mdx) guides for comprehensive lists of -configuration options, CLI flags, and more. For detailed explanations of how -Teleport works, see the [Architecture](./architecture/introduction.mdx) section. - -Finally, if you're interested in adding to Teleport's documentation, view -our [contribution guide](./contributing/documentation.mdx). - - - - - Collaborate through session sharing. - - - Discover servers and clusters with dynamic labels. - - - Connect to computing resources located behind firewalls or without static IPs. - - - - - Capture sessions and manage certificates for an existing OpenSSH fleet. - - - Replace static keys and passwords with short-lived certificates. - - - Enforce two-factor authentication for all of your infrastructure. - - - - - Ask a question in the discussion forum. - - - Join our Slack channel to get help with your setup. - - - Create an issue on GitHub. - - - Reach out to sales for a demo of Teleport Enterprise. - - - Start a free trial of Teleport Cloud. - - - +Step 4 showed you how to install agents manually, and you can also launch agents +and enroll resources with them using infrastructure-as-code tools. For example, +you can use Terraform to declare a pool of Teleport agents and configure them to +proxy your infrastructure. Read [Deploy Teleport Agents with +Terraform](agents/deploy-agents-terraform.mdx) to get started. diff --git a/docs/pages/installation.mdx b/docs/pages/installation.mdx index 5212be1ff35a5..3429d6dc6cb7c 100644 --- a/docs/pages/installation.mdx +++ b/docs/pages/installation.mdx @@ -2,7 +2,7 @@ title: Installing Teleport description: How to install Teleport and Teleport's client tools on your platform, including binaries and instructions for Docker and Helm. h1: Installation -videoBanner: VifXROQFjwg +videoBanner: fjk29wqXm1A --- This guide shows you how to install Teleport binaries on your platform, @@ -13,7 +13,7 @@ including: - `tbot` If you are new to Teleport, we recommend following our [getting started -guide](./get-started.mdx). +guide](./index.mdx). For best results, Teleport clients (`tsh`, `tctl`, `tbot`) should be the same major version as the cluster they are connecting to. Teleport servers are compatible @@ -35,8 +35,8 @@ running Teleport on UNIX variants other than Linux \[1]. | macOS v10.13+ (High Sierra)| yes | yes | yes | yes | yes | | Windows 10+ (rev. 1607) \[4] | no | no | yes | yes | no | -\[1] *Teleport is written in Go and it's possible to build it on -any OS supported by the [Golang toolchain](https://github.com/golang/go/wiki/MinimumRequirements)*. +\[1] *Teleport is written in Go and many of these system requirements are due to the requirements +of the [Go toolchain](https://github.com/golang/go/wiki/MinimumRequirements)*. \[2] *`tsh` is a Command Line Client (CLI) and Teleport Connect is a Graphical User Interface (GUI) desktop client. See [Using Teleport Connect](connect-your-client/teleport-connect.mdx) for usage and installation*. @@ -107,21 +107,230 @@ information on obtaining Teleport binaries compatible with Teleport Cloud. ## Docker +### Images + +We provide a pre-built Docker image for every version of Teleport. This section +describes the available Docker images. + +These images are hosted on [Amazon ECR +Public](https://gallery.ecr.aws/gravitational). + +#### Image suffixes + +For each of the image names listed in this section, you can specify attributes +of the image by appending a suffix to the repository name or tag. + +Images with the `-distroless` suffix within the repository name include only the +`teleport` binary and its runtime dependencies, with no shell or utility +applications. An example is `public.ecr.aws/gravitational/teleport-distroless` +for Teleport Community Edition. + +Images with the `*-distroless-debug` suffix within the repository name include a +Busybox shell and tool suite in addition to Teleport, and are intended for +troubleshooting deployments only. They are not intended for production use. An +example is `public.ecr.aws/gravitational/teleport-distroless-debug`. + +You can specify the architecture of an image by appending a suffix to its tag. +We support the following architecture suffixes: `amd64`, `arm`, and `arm64`. For +example, if you want to pull the ARM64 image for +`public.ecr.aws/gravitational/teleport`, you can use +`public.ecr.aws/gravitational/teleport:(=teleport.version=)-arm64`. + +`*-distroless` and `*-distroless-debug` images support multiple architectures +natively, and do not require (or support) image suffixes. You can specify an +architecture using the `--platform` flag of `docker pull` to pull the `arm`, +`arm64` or `amd64` version of an image. + +#### Version tags + +Images point to a static version of Teleport. Use the image's tag to specify +either: + +- The major, minor, and patch version (e.g., `(=teleport.version=)` for the + latest version of Teleport Community Edition). +- The major version only, which implies the latest minor and patch numbers for + that major version. For example, `(=teleport.major_version=)` implies + `(=teleport.version=)`. + - + -(!docs/pages/includes/docker-images-oss.mdx!) +|Image name|Troubleshooting Tools?|Image base| +|-|-|-| +|`(=teleport.latest_oss_docker_image=)`|No|[Distroless Debian 11](https://github.com/GoogleContainerTools/distroless)| +|`(=teleport.latest_oss_debug_docker_image=)`|Yes|[Distroless Debian 11](https://github.com/GoogleContainerTools/distroless)| + +For testing, we always recommend that you use the latest released version of +Teleport, which is currently `(=teleport.latest_oss_docker_image=)`. + +[Ubuntu 20.04](https://hub.docker.com/\_/ubuntu)-based images are available from +our [Legacy Amazon ECR Public +repository](https://gallery.ecr.aws/gravitational/teleport-ent). Their use is +considered deprecated, and they may be removed in future releases. - + + +| Image name | Includes troubleshooting tools | Image base | +| - | - | - | +| `(=teleport.latest_ent_docker_image=)` | No | [Distroless Debian 11](https://github.com/GoogleContainerTools/distroless) | +| `(=teleport.latest_ent_debug_docker_image=)` | Yes | [Distroless Debian 11](https://github.com/GoogleContainerTools/distroless) | -We provide pre-built `amd64`, `arm`, and `arm64` Docker images for every version of Teleport Enterprise. +We also provide the following images for FIPS builds of Teleport Enterprise: -(!docs/pages/includes/enterprise/docker-images.mdx!) +| Image name | Includes troubleshooting tools | Image base | +| - | - | - | +| `gravitational/teleport-ent-fips-distroless` | No | [Distroless Debian 11](https://github.com/GoogleContainerTools/distroless) | +| `gravitational/teleport-ent-fips-distroless-debug` | Yes | [Distroless Debian 11](https://github.com/GoogleContainerTools/distroless) | + +For testing, we always recommend that you use the latest release version of +Teleport Enterprise, which is currently `(=teleport.latest_ent_docker_image=)`. + +[Ubuntu 20.04](https://hub.docker.com/\_/ubuntu)-based images for non-FIPS +Teleport are available from our [Legacy Amazon ECR Public repository](https://gallery.ecr.aws/gravitational/teleport-ent). +### Running Teleport on Docker + +When running a container from one of the images listed above, consider the +container equivalent to running the `teleport` binary. The Teleport container +requires access to a file system and network ports. + +#### Configuration + +Teleport processes read their configuration from a local file path, which is +`/etc/teleport.yaml` by default. Make sure this file path is mounted to your +Teleport container. + +#### Data directory + +All Teleport processes read from and write to a data directory, which by default +is `/var/lib/teleport`. Make sure the data directory is mounted to your Teleport +container. + +#### License file + +If your Teleport Enterprise container runs the Auth Service, you will need to +give it access to a license file at the path named in the configuration, which +is `/var/lib/teleport/license.pem` by default. Make sure a license exists at +this location in the Teleport container's data directory. + +#### Other file paths + +Depending on the configuration settings you assign on your Teleport container, +you will need to make sure that any file paths you name are mounted on the +container. + +For example, if you are running the Teleport Proxy Service on a container, you +need to mount the directory containing TLS credentials to your Teleport +container, then assign the following fields in the container's configuration +file to the appropriate paths: + +```yaml +proxy_service: + https_keypairs: + - key_file: /my/path/key.pem + cert_file: /my/path/cert.pem +``` + +See the Teleport [Configuration Reference](reference/config.mdx) for whether a +field you would like to assign requires a file path. + +#### Ports + +A single Teleport process can run multiple services, each of which listens on a +specific set of ports depending on your configuration. See our [Networking +Reference](reference/networking.mdx#ports) for the ports on your Teleport +container to expose. + +### Example of running a Teleport container + +In this example, we will show you how to run the Teleport Auth and Proxy +Services on a local Docker container using Teleport Community Edition. + +Since this container uses a self-signed certificate, we do not recommend using +this configuration to protect any infrastructure outside your workstation. You +can, however, join other local Docker containers to it using the [token +method](./agents/join-services-to-your-cluster/join-token.mdx). + +First, create directories in your home directory to mount to the container. The +Teleport container will write its configuration and data to these directories: + +```code +$ mkdir -p ~/teleport/config ~/teleport/data +``` + +Run `teleport configure` from the Teleport container to generate a configuration +file. This sets the container's name to `localhost` so your browser can trust +the Proxy Service's self-signed TLS certificate: + +```code +$ docker run --hostname localhost --rm \ + --entrypoint=/usr/local/bin/teleport \ + configure --roles=proxy,auth > ~/teleport/config/teleport.yaml +``` + +Start Teleport on your container: + +```code +$ docker run --hostname localhost --name teleport \ + -v ~/teleport/config:/etc/teleport \ + -v ~/teleport/data:/var/lib/teleport \ + -p 3025:3025 -p 3080:3080 \ + +``` + +From there, open another terminal and make sure your Teleport container's web +API is functioning as intended: + +```code +$ curl --insecure https://localhost:3080/webapi/ping +``` + +You should see JSON output similar to the following: + +```json +{ + "auth": { + "type": "local", + "second_factor": "otp", + "preferred_local_mfa": "otp", + "local": { + "name": "" + }, + "private_key_policy": "none", + "device_trust_disabled": true, + "has_motd": false + }, + "proxy": { + "kube": { + "enabled": true, + "listen_addr": "0.0.0.0:3080" + }, + "ssh": { + "listen_addr": "0.0.0.0:3080", + "tunnel_listen_addr": "0.0.0.0:3080", + "web_listen_addr": "0.0.0.0:3080" + }, + "db": { + "postgres_listen_addr": "0.0.0.0:3080", + "mysql_listen_addr": "0.0.0.0:3080" + }, + "tls_routing_enabled": true + }, + "server_version": "12.1.5", + "min_client_version": "11.0.0", + "cluster_name": "localhost", + "automatic_upgrades": false +} +``` + +We are using the `--insecure` flag to trust Teleport's self-signed certificate. +In production, you will want to provision TLS credentials to the Proxy Service +from a trusted CA, e.g., Let's Encrypt. + ## Helm (!docs/pages/kubernetes-access/helm/includes/helm-repo-add.mdx!) @@ -136,8 +345,10 @@ chart. ## macOS - - + + + + You can download one of the following .pkg installers for macOS: |Link|Binaries| @@ -160,7 +371,7 @@ chart. ``` - + @@ -200,10 +411,17 @@ chart. against `tsh version` and `tctl version`. - + + + (!docs/pages/includes/enterprise/install-macos.mdx!) + + + +(!docs/pages/includes/cloud/install-macos.mdx!) + diff --git a/docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx b/docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx index 0c49b5efbf7d0..8131a74d02107 100644 --- a/docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx +++ b/docs/pages/kubernetes-access/helm/includes/teleport-cluster-prereqs.mdx @@ -1,6 +1,6 @@ - [Kubernetes](https://kubernetes.io) >= v(=kubernetes.major_version=).(=kubernetes.minor_version=).0 - [Helm](https://helm.sh) >= v(=helm.version=) -Verify that Helm and Kubernetes are installed and up to date. +(!docs/pages/kubernetes-access/helm/includes/teleport-cluster-install.mdx!) -(!docs/pages/includes/permission-warning.mdx!) \ No newline at end of file +(!docs/pages/includes/permission-warning.mdx!) diff --git a/docs/pages/kubernetes-access/register-clusters/iam-joining.mdx b/docs/pages/kubernetes-access/register-clusters/iam-joining.mdx index a530f1c92a8d4..cbbcf628bde4f 100644 --- a/docs/pages/kubernetes-access/register-clusters/iam-joining.mdx +++ b/docs/pages/kubernetes-access/register-clusters/iam-joining.mdx @@ -74,9 +74,9 @@ Then create the IAM policy: $ aws iam create-policy --policy-name --policy-document file://iam-policy.json { "Policy": { - "PolicyName": "kube-iam-policy", + "PolicyName": "", "PolicyId": "ANPAW2Y2Q2Y2Y2Y2Y2Y2Y", - "Arn": "arn:aws:iam::aws:policy/kube-iam-policy", + "Arn": "arn:aws:iam::aws:policy/", "Path": "/", "DefaultVersionId": "v1", "AttachmentCount": 0, @@ -133,10 +133,10 @@ Kubernetes service account. ```code $ kubectl create ns -namespace/teleport-agent created +namespace/ created $ kubectl create sa -n -serviceaccount/teleport-kube-agent-sa created +serviceaccount/ created ``` Then we need to create the IAM role and trust relationship. For that, we need diff --git a/docs/pages/machine-id/getting-started.mdx b/docs/pages/machine-id/getting-started.mdx index 37f002eef4f69..471c4a3df2720 100644 --- a/docs/pages/machine-id/getting-started.mdx +++ b/docs/pages/machine-id/getting-started.mdx @@ -71,7 +71,7 @@ auditor no-login-6566121f-b602-47f1-a118-c9c618ee5aec session:list,r editor user:list,create,read,update,delete,... ``` -Machine ID can join with a token or the [IAM Method](../management/join-services-to-your-cluster/aws-iam.mdx) on AWS. +Machine ID can join with a token or the [IAM Method](../agents/join-services-to-your-cluster/aws-iam.mdx) on AWS. Assuming that you are using the default `access` role, ensure that you use the `--logins` flag when adding your bot to specify the SSH logins that you wish to diff --git a/docs/pages/machine-id/guides/host-certificate.mdx b/docs/pages/machine-id/guides/host-certificate.mdx index f8f0222439cea..3c25b06cf0afc 100644 --- a/docs/pages/machine-id/guides/host-certificate.mdx +++ b/docs/pages/machine-id/guides/host-certificate.mdx @@ -389,7 +389,7 @@ The Machine ID host is now fully configured to accept connections from a `tsh` u To confirm this, enter the following command from your local machine logged into the cluster using `tsh`: ```code -$ tsh ssh root@nodename.my.domain.com:22 +$ tsh ssh -p 22 root@nodename.my.domain.com ``` The connection should successfully complete without the need to manually enter any additional credentials. @@ -402,6 +402,6 @@ to connect to OpenSSH with Teleport, see the following documentation: - [Using Teleport With OpenSSH](../../server-access/guides/openssh.mdx) - [Using SSH Host Certificates](https://goteleport.com/blog/how-to-ssh-properly/) - [Machine ID Configuration Reference](../reference/configuration.mdx) -- [Joining Nodes using the IAM method](../../management/join-services-to-your-cluster/aws-ec2.mdx) +- [Joining Nodes using the IAM method](../../agents/join-services-to-your-cluster/aws-ec2.mdx) [More information about `TELEPORT_ANONYMOUS_TELEMETRY`.](../reference/telemetry.mdx) diff --git a/docs/pages/machine-id/guides/jenkins.mdx b/docs/pages/machine-id/guides/jenkins.mdx index 53ec34d93a0c4..28526225c6e69 100644 --- a/docs/pages/machine-id/guides/jenkins.mdx +++ b/docs/pages/machine-id/guides/jenkins.mdx @@ -17,7 +17,6 @@ You will need the following tools to use Teleport with Jenkins. - `ssh` OpenSSH tool - Jenkins - - (!docs/pages/includes/tctl.mdx!) ## Architecture diff --git a/docs/pages/management/admin/labels.mdx b/docs/pages/management/admin/labels.mdx index b54588ebc3a52..ceb1d7c718472 100644 --- a/docs/pages/management/admin/labels.mdx +++ b/docs/pages/management/admin/labels.mdx @@ -181,7 +181,7 @@ your Node. Run the following command to get the current logins for your user: - + ```code $ tsh status @@ -195,6 +195,21 @@ $ tsh status Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty ``` + + + +```code +$ tsh status +> Profile URL: https://teleport.example.com:443 + Logged in as: myuser + Cluster: teleport.example.com + Roles: access, editor, reviewer + Logins: -teleport-nologin-d4bc1dad-ce49-4bbe-925d-a67f8d2d6afe + Kubernetes: enabled + Valid until: 2022-04-27 22:26:50 -0400 EDT [valid for 11h40m0s] + Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty +``` + @@ -203,7 +218,7 @@ tsh status > Profile URL: https://mytenant.teleport.sh:443 Logged in as: myuser Cluster: mytenant.teleport.sh - Roles: access, editor + Roles: access, editor, reviewer Logins: -teleport-nologin-d4bc1dad-ce49-4bbe-925d-a67f8d2d6afe Kubernetes: enabled Valid until: 2022-04-27 22:26:50 -0400 EDT [valid for 11h40m0s] diff --git a/docs/pages/management/admin/self-signed-certs.mdx b/docs/pages/management/admin/self-signed-certs.mdx index 03904d263c8e3..d833d07968cfd 100644 --- a/docs/pages/management/admin/self-signed-certs.mdx +++ b/docs/pages/management/admin/self-signed-certs.mdx @@ -33,8 +33,8 @@ to the Proxy Service. -- A running Teleport cluster. For details on how to set this up, see one of our - [Getting Started](/docs/getting-started) guides (skip TLS certificate setup). +- A running Teleport cluster. For details on how to set this up, see our + [Getting Started](../../index.mdx) guide (skip TLS certificate setup). - A Teleport Proxy Service which does not have certificates or ACME automatic certificates configured. For example, this Teleport Proxy Service configuration would use self-signed certs: @@ -50,14 +50,14 @@ For example, this Teleport Proxy Service configuration would use self-signed cer - (!docs/pages/includes/tctl-tsh-prerequisite.mdx!) - See [Installation](/docs/installation.mdx) for details. + See [Installation](../../installation.mdx) for details. - A running Teleport cluster. For details on how to set this up, see our Enterprise - [Getting Started](/docs/enterprise/getting-started) guide. + [Getting Started](../../choose-an-edition/teleport-enterprise/introduction.mdx) guide. - A Teleport Proxy Service which does not have certificates or ACME automatic certificates configured. For example, this Teleport Proxy Service configuration would use self-signed certs: @@ -205,7 +205,7 @@ flag](../../connect-your-client/teleport-connect.mdx#skipping-tls-certificate-ve ## Further reading -- [Configuring Teleport TLS Certs](../../get-started.mdx#configure-teleport) +- [Configuring Teleport TLS Certs](../../index.mdx#configure-teleport) - [Run Teleport as a systemd Daemon](./daemon.mdx) - [Teleport Proxy Service](../../architecture/proxy.mdx) - [Teleport Authentication](../../architecture/authentication.mdx) diff --git a/docs/pages/management/admin/trustedclusters.mdx b/docs/pages/management/admin/trustedclusters.mdx index da1d1f990837e..6db59f01a06a1 100644 --- a/docs/pages/management/admin/trustedclusters.mdx +++ b/docs/pages/management/admin/trustedclusters.mdx @@ -27,7 +27,7 @@ A leaf cluster always creates an outbound reverse SSH tunnel to the root cluster Individual nodes and proxies can create reverse tunnels to proxy services without creating a new cluster. You don't need to set up a trusted cluster just to connect a couple of servers, kubernetes clusters or -databases behind a firewall. For more information, see [Adding Nodes to the Cluster](../join-services-to-your-cluster/join-token.mdx). +databases behind a firewall. For more information, see how to [join a service to your cluster](../../agents/join-services-to-your-cluster.mdx). When a user tries to connect to any resource inside the leaf cluster using the root's proxy @@ -45,43 +45,46 @@ This guide will explain how to: - Two running Teleport clusters. For details on how to set up your clusters, see - one of our [Getting Started](/docs/getting-started) guides. + our [Getting Started](../../index.mdx) guide. - (!docs/pages/includes/tctl-tsh-prerequisite.mdx!) - See [Installation](/docs/installation.mdx) for details. + See [Installation](../../installation.mdx) for details. -- A Teleport Node that is joined to one of your clusters. We will refer to this +- A Teleport agent that is joined to one of your clusters. We will refer to this cluster as the **leaf cluster** throughout this guide. - See [Adding Nodes](../join-services-to-your-cluster.mdx) for how to launch a - Teleport Node in your cluster. + See [Join Services to your + Cluster](../../agents/join-services-to-your-cluster.mdx) for how to launch a + Teleport agent in your cluster. - Two running Teleport clusters. For details on how to set up your clusters, see - our Enterprise [Getting Started](/docs/enterprise/getting-started) guide. + our Enterprise [Getting + Started](../../choose-an-edition/teleport-enterprise/introduction.mdx) guide. - (!docs/pages/includes/enterprise/tctl-tsh-prerequisite.mdx!) - A Teleport Node that is joined to one of your clusters. We will refer to this cluster as the **leaf cluster** throughout this guide. - See [Adding Nodes](../join-services-to-your-cluster.mdx) for how to launch a Teleport Node in + See [Join Services to your Cluster](../../agents/join-services-to-your-cluster.mdx) for how to launch a Teleport agent in your cluster. -- A Teleport Cloud account. If you do not have one, visit the - [sign up page](https://goteleport.com/signup/) to begin your free trial. +- A Teleport Enterprise Cloud account. If you do not have one, visit the [sign + up page](https://goteleport.com/signup/) to begin a free trial of Teleport + Team and upgrade to Teleport Enterprise Cloud. - A second Teleport cluster, which will act as the leaf cluster. For details on -how to set up this cluster, see one of our -[Getting Started](/docs/getting-started) guides. +how to set up this cluster, see our +[Getting Started](../../index.mdx) guide. As an alternative, you can set up a second Teleport Cloud account. @@ -90,8 +93,8 @@ how to set up this cluster, see one of our - A Teleport Node that is joined to one of your clusters. We will refer to this cluster as the **leaf cluster** throughout this guide. - See [Adding Nodes](../join-services-to-your-cluster.mdx) for how to launch a - Teleport Node in your cluster. + See [Join Services to your Cluster](../../agents/join-services-to-your-cluster.mdx) for how to launch a + Teleport agent in your cluster. @@ -240,7 +243,7 @@ You can create a join token using the `tctl` tool. First, log out of all clusters and log in to the root cluster. - + ```code $ tsh logout @@ -255,6 +258,22 @@ $ tsh login --user=myuser --proxy=rootcluster.example.com Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty ``` + + + +```code +$ tsh logout +$ tsh login --user=myuser --proxy=rootcluster.example.com +> Profile URL: https://rootcluster.example.com:443 + Logged in as: myuser + Cluster: rootcluster.example.com + Roles: access, auditor, editor, reviewer + Logins: root + Kubernetes: enabled + Valid until: 2022-04-29 03:07:22 -0400 EDT [valid for 12h0m0s] + Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty +``` + @@ -263,7 +282,7 @@ $ tsh login --user=myuser --proxy=myrootclustertenant.teleport.sh > Profile URL: https://rootcluster.teleport.sh:443 Logged in as: myuser Cluster: rootcluster.teleport.sh - Roles: access, auditor, editor + Roles: access, auditor, editor, reviewer Logins: root Kubernetes: enabled Valid until: 2022-04-29 03:07:22 -0400 EDT [valid for 12h0m0s] @@ -276,9 +295,9 @@ Execute the following command on your development machine: ```code # Generates a Trusted Cluster token to allow an inbound connection from a leaf cluster: -$ tctl tokens add --type=trusted_cluster --ttl=15m +$ tctl tokens add --type=trusted_cluster --ttl=5m The cluster invite token: (=presets.tokens.first=) -This token will expire in 15 minutes +This token will expire in 5 minutes Use this token when defining a trusted cluster resource on a remote cluster. ``` @@ -286,6 +305,12 @@ Use this token when defining a trusted cluster resource on a remote cluster. This command generates a Trusted Cluster join token. The token can be used multiple times and has an expiration time of 5 minutes. +
+The `--labels` flag will add labels to the trusted cluster. This lets teams use +the same RBAC controls used on individual resources to approve or deny access +to clusters. +
+ Copy the join token for later use. If you need to display your join token again, run the following command against your root cluster: @@ -751,7 +776,7 @@ certificate authority. A certificate contains four important pieces of data: - Metadata (certificate extensions): additional data protected by the signature above. Teleport uses the metadata to store the list of user roles and SSH options like "permit-agent-forwarding". -- The expiration date. +- The expiration date, or time-to-live (**TTL**). When a user from the root cluster attempts to access a Node in the leaf cluster, the leaf cluster's Auth Service authenticates the user's certificate and reads @@ -762,7 +787,7 @@ these pieces of data from it. It then performs the following actions: cluster with one of the remote user's roles. - Checks if the local role allows the requested identity (Unix login) to have access. -- Checks that the certificate has not expired. +- Checks that the certificate has not expired. The TTL is set by the root cluster.
@@ -786,10 +811,12 @@ these pieces of data from it. It then performs the following actions: type="tip" title="Note" > +Trusted Clusters work only in one direction. In the example above, users from +the leaf cluster cannot see or connect to Nodes in the root cluster. - Trusted Clusters work only in one direction. In the example above, users from - the leaf cluster cannot see or connect to Nodes in the root cluster. - +The Teleport root cluster's Web UI will not populate available OS users for +leaf cluster Nodes. When using the web UI, type in the host user when creating +SSH sessions.
## Step 5/5. Remove trust between your clusters diff --git a/docs/pages/management/admin/users.mdx b/docs/pages/management/admin/users.mdx index 2c6f700c1e626..914687c44e67b 100644 --- a/docs/pages/management/admin/users.mdx +++ b/docs/pages/management/admin/users.mdx @@ -37,9 +37,16 @@ Let's look at this table: Let's add a new user to Teleport using the `tctl` tool: + ```code $ tctl users add joe --logins=joe,root --roles=access,editor ``` + + +```code +$ tctl users add joe --logins=joe,root --roles=access,editor,reviewer +``` + Teleport generates an auto-expiring token (with a TTL of one hour) and prints the token URL, which must be used before the TTL expires. diff --git a/docs/pages/management/dynamic-resources.mdx b/docs/pages/management/dynamic-resources.mdx new file mode 100644 index 0000000000000..ff813489cf200 --- /dev/null +++ b/docs/pages/management/dynamic-resources.mdx @@ -0,0 +1,279 @@ +--- +title: Using Dynamic Resources +description: An introduction to Teleport's dynamic resources, which make it possible to apply settings to remote clusters using infrastructure as code. +tocDepth: 3 +--- + +This section explains how to manage Teleport's **dynamic resources**, which make +it possible to adjust the behavior of your Teleport cluster as your +infrastructure changes. + +## What is a dynamic resource? + +There are two ways to configure a Teleport cluster: + +- **Static configuration file:** At startup, a Teleport process reads a + configuration file from the local filesystem (the default path is + `/etc/teleport.yaml`). Static configuration settings control aspects of a + cluster that are not expected to change frequently, like the ports that + services listen on. +- **Dynamic resources:** Dynamic resources control aspects of your cluster that + are likely to change over time, such as roles, local users, and registered + infrastructure resources. + +This approach makes it possible to incrementally adjust your Teleport +configuration without restarting Teleport instances. + +```mermaid +flowchart LR +subgraph backend["Cluster state backend"] + direction LR + resources["Dynamic resources"] +end + +subgraph cluster[Teleport cluster] + subgraph auth[Auth Service] + conf1["Static config"] + end + subgraph proxy[Proxy Service] + conf2["Static config"] + end +end + +auth-->backend +subgraph clients["API clients"] + terraform["Terraform Provider"] + operator["Kubernetes Operator"] + tctl +end +terraform & operator & tctl-->proxy +proxy-.->auth +``` + +A cluster is composed of different objects (i.e., resources) and there are three +common operations that can be performed on them: `get` , `create` , and `remove` +. + +Every resource in Teleport has three required fields: + +- `kind`: The type of resource +- `name`: A required field in the `metadata` to uniquely identify the resource +- `version`: The version of the resource format + +All other fields are specific to a resource. + +While Teleport Enterprise Cloud and Teleport Team do not expose the static +configuration file to operators, they do use a static configuration file for +certain settings. Read how Teleport [reconciles static and dynamic +resources](#reconciling-the-configuration-file-with-dynamic-resources) to +understand how to see the values of static configuration settings that also +appear in dynamic resources. + +When examining a dynamic resource, note that some of the fields you will see are +used only internally and are not meant to be changed. Others are reserved for +future use. + +## Managing dynamic resources + +Teleport provides three methods for applying dynamic resources: the `tctl` +client tool, Teleport Terraform provider, and Kubernetes Operator. + +All three methods connect to the Teleport Auth Service's gRPC endpoint in order +to manipulate cluster resources stored on the Auth Service backend. The design +of Teleport's configuration interface makes it well suited for +infrastructure-as-code and GitOps approaches. + +### YAML documents with `tctl` + +You can define resources as YAML documents and apply them using the `tctl` +client tool. Here is an example of a `role` resource that allows access to +servers with the label `env:test`: + +```yaml +kind: role +version: v6 +metadata: + name: developer +spec: + allow: + logins: ['ubuntu', 'debian', '{{internal.logins}}'] + node_labels: + 'env': 'test' +``` + +Since `tctl` works from the local filesystem, you can write commands that apply +all configuration documents in a directory tree. See the [CLI +reference](../reference/cli.mdx#tctl) for more information on `tctl`. + +### Teleport Terraform provider + +Teleport's Terraform provider lets you manage your Teleport resources within the +same infrastructure-as-code source as the rest of your infrastructure. There is +a Terraform resource for each Teleport configuration resource. For example: + +```text +resource "teleport_role" "developer" { + metadata = { + name = "developer" + } + + spec = { + allow = { + logins = ["ubuntu", "debian", "{{internal.logins}}"] + + node_labels = { + key = ["env"] + value = ["test"] + } + } + } +} +``` + +- [Get started with the Terraform + provider](./dynamic-configuration/terraform-provider.mdx). +- [Use Teleport's Terraform provider with + Spacelift](./dynamic-configuration/spacelift.mdx). + +### Teleport Kubernetes Operator + +The Teleport Kubernetes Operator lets you apply Teleport resources as Kubernetes +resources so you can manage your Teleport settings alongside the rest of your +Kubernetes infrastructure. Here is an example of a `TeleportRole` resource, +which is equivalent to the two roles shown above: + +```yaml +apiVersion: resources.teleport.dev/v5 +kind: TeleportRole +metadata: + name: developer +spec: + allow: + logins: ['ubuntu', 'debian', '{{internal.logins}}'] + node_labels: + 'env': 'test' +``` + +[Get started with the Kubernetes Operator](dynamic-resources/teleport-operator.mdx). + +## Reconciling the configuration file with dynamic resources + +Some dynamic resources assign the same settings as fields within +Teleport's static configuration file. For these fields, the Teleport Auth +Service reconciles static and dynamic configurations on startup and when you +create or remove a Teleport resource. + +### Configuration resources that apply to static configuration fields + +There are four dynamic resources that share fields with the +static configuration file: + +- `session_recording_config` +- `cluster_auth_preference` +- `cluster_networking_config` +- `ui_config` + +#### `session_recording_config` + +|Dynamic resource field|Static configuration field| +|---|---| +|`spec.mode`|`auth_service.session_recording`| +|`spec.proxy_checks_host_keys`|`auth_service.proxy_checks_host_keys`| + +#### `cluster_auth_preference` + +|Dynamic resource field|Static configuration field| +|---|---| +|`spec.type`|`auth_service.authentication.type`| +|`spec.second_factor`|`auth_service.authentication.second_factor`| +|`spec.connector_name`|`auth_service.authentication.connector_name` +|`spec.u2f`|`auth_service.authentication.u2f`| +|`spec.disconnect_expired_cert`|`auth_service.disconnect_expired_cert`| +|`spec.allow_local_auth`|`auth_service.authentication.local_auth`| +|`spec.message_of_the_day`|`auth_service.message_of_the_day`| +|`spec.locking_mode`|`auth_service.authentication.locking_mode`| +|`spec.webauthn`|`auth_service.authentication.webauthn`| +|`spec.require_session_mfa`|`auth_service.authentication.require_session_mfa`| +|`spec.allow_passwordless`|`auth_service.authentication.passwordless`| +|`spec.device_trust`|`auth_service.authentication.device_trust`| +|`spec.idp`|`proxy_service.idp`| +|`spec.allow_headless`|`auth_service.authentication.headless`| + +#### `cluster_networking_config` + +|Dynamic resource field|Static configuration field| +|---|---| +|`spec.client_idle_timeout`|`auth_service.client_idle_timeout`| +|`spec.keep_alive_interval`|`auth_service.keep_alive_interval`| +|`spec.keep_alive_count_max`|`auth_service.keep_alive_count_max`| +|`spec.session_control_timeout`|`auth_service.session_control_timeout`| +|`spec.idle_timeout_message`|`auth_service.client_idle_timeout_message`| +|`spec.web_idle_timeout`|`auth_service.web_idle_timeout`| +|`spec.proxy_listener_mode`|`auth_service.proxy_listener_mode`| +|`spec.routing_strategy`|`auth_service.routing_strategy`| +|`spec.tunnel_strategy`|`auth_service.tunnel_strategy`| +|`spec.proxy_ping_interval`|`auth_service.proxy_ping_interval`| + +#### `ui_config` + +|Dynamic resource field|Static configuration field| +|---|---| +|`spec.scrollback_lines`|`proxy_service.ui.scrollback_lines`| + +### Origin labels + +The Teleport Auth Service applies the `teleport.dev/origin` label to +configuration resources to indicate whether they originated from the static +configuration file, a dynamic configuration resource, or the default value. + +Here are possible values of the `teleport.dev/origin` label: + +- `defaults` +- `config-file` +- `dynamic` + +When the Auth Service starts up, it looks up the values of static configuration +fields that correspond to fields in dynamic configuration resources. If any of +these have values, it creates the corresponding dynamic configuration resources +and stores them in its backend. + +For any static configuration fields without a value, the Auth Service checks +whether the backend contains the corresponding dynamic configuration resource. +If not, it creates one with default values and the +`teleport.dev/origin=defaults` label. + +If you attempt to create a dynamic configuration resource after the Auth Service +has already loaded the configuration from a static configuration file, the Auth +Service will return an error. + +If you remove a dynamic configuration resource, the Auth Service will restore +its configuration fields to the default values and add the +`teleport.dev/origin=defaults` label. + + + +Cloud-hosted Teleport deployments use configuration files, but these are not +available for operators to modify. Users of Teleport Enterprise Cloud and +Teleport Team may see configuration resources with the +`teleport.dev/origin=config-file` label. + + + +## Further reading + +### Configuration references + +- For a comprehensive reference of Teleport's static configuration options, read + the [Configuration Reference](../reference/config.mdx). +- To see the dynamic configuration resources available to apply, read the + [Configuration Resource Reference](../reference/resources.mdx). There are also + dedicated configuration resource references for + [applications](../application-access/reference.mdx#application-resource) and + [databases](../database-access/reference/configuration.mdx#database-resource). + +### Other ways to use the Teleport API + +The Teleport Kubernetes Operator, Terraform provider, and `tctl` are all clients +of the Teleport Auth Service's gRPC API. To build your own API client to extend +Teleport for your organization's needs, read our [API +guides](../api/introduction.mdx). diff --git a/docs/pages/management/dynamic-resources/spacelift.mdx b/docs/pages/management/dynamic-resources/spacelift.mdx new file mode 100644 index 0000000000000..a7e605f6cc96d --- /dev/null +++ b/docs/pages/management/dynamic-resources/spacelift.mdx @@ -0,0 +1,289 @@ +--- +title: "Manage Dynamic Configuration Resources with Spacelift" +description: "Learn how to set up Spacelift to manage dynamic configuration resources via GitOps and Teleport's Terraform provider." +--- + +You can use Spacelift with Teleport's Terraform provider to manage dynamic +configuration resources via GitOps and infrastructure as code. This gives you an +audit trail of changes to your Teleport configuration and a single source of +truth for operators to examine. + +```mermaid +flowchart TB +subgraph Spacelift + idfile["Teleport Identity File"]-->spacelift["Spacelift Worker"] +end + +repo["GitHub Repo"]--"Configuration Resources (Terraform)"--->spacelift + +spacelift-->proxy["Teleport Proxy Service"] +proxy-- "gRPC API Traffic" -->auth["Teleport Auth Service"] +``` + +This guide will show you how to set up the GitOps platform Spacelift with the +Teleport Terraform provider. While following this guide, you will create a +Teleport user and role with no privileges in order to demonstrate using +Spacelift to create dynamic resources. + +If you are using another GitOps platform, the setup should be similar: + +- Create a Teleport user and role for the GitOps platform with permissions to + manage configuration resources. +- Upload a Teleport identify file to the GitOps platform that it will use to + authenticate as the Teleport user and role you created. +- Configure the GitOps platform to read from a GitHub repository with a + Terraform configuration that tells the Teleport provider where to find your + identity file and Teleport Proxy Service. +- Define Teleport configuration resources as Terraform resources within the + GitHub repository, prompting the GitOps platform to apply your Terraform + configuration. + +## Prerequisites + +(!docs/pages/includes/edition-prereqs-tabs.mdx!) +- A Spacelift account with permissions to create stacks. +- A GitHub repository where you will store your Terraform configuration. For the + purpose of the demo project we show in this guide, the repository should be + empty, though you can use an existing repository connected to Spacelift as + well. +- The GitHub app for Spacelift installed for your GitHub repository. Install + this app by visiting its [page on + GitHub](https://github.com/apps/spacelift-io/). +- (!docs/pages/includes/tctl.mdx!) + + + +For simplicity, the identify file we will export in this guide will have a long +time to live. In a production environment, you will want to provision +short-lived identify files via Machine ID. + +After getting familiar with this guide, read our [Machine ID Getting Started +Guide](../../machine-id/getting-started.mdx) to get started with Machine ID. You +will need to run your own compute workload to upload Teleport identity files to +Spacelift using the `spacectl stack environment mount` command of the +[`spacectl`](https://github.com/spacelift-io/spacectl) CLI (or another method +that takes advantage of Spacelift's GraphQL API). + + + +## Step 1/4. Add a Terraform configuration to your repository + +Clone your GitHub repository. Add the following to a file called `main.tf`, +which configures the Teleport Terraform provider: + +```text +terraform { + required_providers { + teleport = { + source = "terraform.releases.teleport.dev/gravitational/teleport" + version = ">= (=teleport.plugin.version=)" + } + } +} + +provider "teleport" { + addr = "proxy.example.com:443" + identity_file_path = "/mnt/workspace/auth.pem" +} +``` + +Change `proxy.example.com:443` to the host and HTTPS port of your Teleport Proxy +Service. + +Commit the change, merge it to your `main` branch, and push to your remote +repository (or use a pull request). + +## Step 2/4. Create a Spacelift stack + +From the Spacelift web UI, click **Stacks > Add stack**. + +In the **NAME STACK** tab, for "Name", use "Teleport" and click **CONTINUE**. + +In the **INTEGRATE VCS** tab, make sure the **Repository** field points to the +repository you chose for this guide. Select your GitHub repository and the +branch you plan to use as the base branch for pull requests. Click **CONTINUE**. + +In the **CONFIGURE BACKEND** tab, leave all settings at their defaults and click +**CONTINUE**. Do the same with the **DEFINE BEHAVIOR** tab and click **SAVE +STACK**. + +Your new stack should resemble the following: + +![New Spacelift stack](../../../img/management/spacelift/newstack.png) + +## Step 3/4. Grant Teleport permissions to Spacelift + +In this section, you will create a Teleport user and role for Spacelift, plus a +role that can *impersonate* the Spacelift user in order to export an identity +file. You will then export an identity file and upload it to Spacelift. + +Since Teleport manages RBAC permissions via configuration resources, and you +have not set up Spacelift yet, you must create the resources in this section +outside of Spacelift. After that, Spacelift can manage all of your Teleport +configuration resources. + +### Create a Spacelift user and role + +Create a local Teleport user named `spacelift` and a matching role granting the +necessary permissions for Terraform to manage resources in your cluster. + +On your workstation, _outside_ the git repository you connected to Spacelift, +add the following content to a file called `spacelift.yaml`: + +```yaml +kind: role +metadata: + name: spacelift +spec: + allow: + rules: + - resources: + - role + - user + verbs: ['list','create','read','update','delete'] +version: v6 +--- +kind: user +metadata: + name: spacelift +spec: + roles: ['spacelift'] +version: v2 +``` + +This is a minimal version of the configuration you will need to provide to +Spacelift, and is only permitted to manage Teleport roles. + +Create the `spacelift` user and role. + +```code +$ tctl create spacelift.yaml +role 'spacelift' has been created +user "spacelift" has been created +``` + +### Enable impersonation + +The `spacelift` user cannot log in to Teleport to retreive credentials, so +another user must **impersonate** this user in order to request credentials on +`spacelift`'s behalf. + +Create a role that enables your user to impersonate the Terraform user. Paste +the following YAML document into a file called `spacelift-impersonator.yaml`: + +```yaml +kind: role +version: v6 +metadata: + name: spacelift-impersonator +spec: + allow: + impersonate: + users: ['spacelift'] + roles: ['spacelift'] +``` + +Next, create the role: + +```code +$ tctl create spacelift-impersonator.yaml +``` + +(!docs/pages/includes/add-role-to-user.mdx role="spacelift-impersonator"!) + +### Export an identity file + +(!docs/pages/includes/plugins/identity-export.mdx user="spacelift" client="Spacelift"!) + +### Provide an identity file to Spacelift + +In the Spacelift web UI, click **Stacks > Teleport**. Click the **Environment** +tab, then **Edit**. Set the dropdown menu that follows to **Mounted file**, and +the path to `/mnt/workspace/auth.pem`. + +Click **Upload file** and select the file called `auth.pem` that you exported +earlier. + +Make sure you click **Secret** next to the entry for the mounted file: + +![Uploading the identity file](../../../img/management/spacelift/id-file.png) + +## Step 4/4. Declare configuration resources + +In a clone of your GitHub repository, check out a branch from your main branch +and add the following to `main.tf`: + +```text +resource "teleport_role" "terraform_test" { + metadata = { + name = "terraform-test" + description = "Terraform test role" + labels = { + example = "yes" + } + } +} + +resource "teleport_user" "terraform-test" { + metadata = { + name = "terraform-test" + description = "Terraform test user" + + labels = { + test = "true" + } + } + + spec = { + roles = [teleport_role.terraform_test.id] + } +} +``` + +Commit your changes and push the branch to GitHub, then open a pull request +against the `main` branch. (Do not merge it just yet.) + +In the Spacelift UI, click **Stacks > Teleport > PRs**, then click the name of +the PR you opened. + +You should see a Terraform plan that includes the user and role you defined +above: + +![Terraform plan](../../../img/management/spacelift/pr-run.png) + +When running `terraform plan`, Spacelift uses the identity file you mounted +earlier to authenticate to Teleport. + +Merge the PR, then click **Stacks > Teleport > Runs**. Click the status of the +first run, which corresponds to merging your PR, to visit the page for the run. +Click **Confirm** to begin applying your Terraform plan. + +You should see output indicating success: + +![Successful apply](../../../img/management/spacelift/apply-success.png) + +Verify that Spacelift has created the new user and role by running the following +commands, which should return YAML data for each resource: + +```code +$ tctl get roles/terraform-test +$ tctl get users/terraform-test +``` + +## Next steps + +- If you plan to configure Spacelift to manage dynamic configuration resources + besides users and roles, you will need to grant additional permissions to the + Teleport role you assigned to Spacelift. See the [Teleport Role + Reference](../../access-controls/reference.mdx#teleport-resources) for the + resources you can allow access to in a Teleport role. +- Now that you know how to manage Teleport configuration resources with + Terraform and Spacelift, read our [Terraform resource + reference](../../reference/terraform-provider.mdx) so you can flesh out your + configuration. +- The Teleport Terraform provider is an example of a Teleport API client. Other + API clients include Teleport's [Access Request + plugins](../../access-controls/access-request-plugins.mdx) and the [Event + Handler](../export-audit-events.mdx). Learn how to [build your own API + client](../../api/introduction.mdx) so you can manage Teleport configuration + resources via your organization's unique workflows. diff --git a/docs/pages/management/guides/teleport-operator.mdx b/docs/pages/management/dynamic-resources/teleport-operator.mdx similarity index 100% rename from docs/pages/management/guides/teleport-operator.mdx rename to docs/pages/management/dynamic-resources/teleport-operator.mdx diff --git a/docs/pages/management/guides/terraform-provider.mdx b/docs/pages/management/dynamic-resources/terraform-provider.mdx similarity index 98% rename from docs/pages/management/guides/terraform-provider.mdx rename to docs/pages/management/dynamic-resources/terraform-provider.mdx index ba55b9820b330..557bb1377934d 100644 --- a/docs/pages/management/guides/terraform-provider.mdx +++ b/docs/pages/management/dynamic-resources/terraform-provider.mdx @@ -65,15 +65,17 @@ spec: - cluster_auth_preference - cluster_networking_config - db + - device - github + - login_rule - oidc + - okta_import_rule - role - saml - session_recording_config - token - trusted_cluster - user - - login_rule verbs: ['list','create','read','update','delete'] version: v6 --- diff --git a/docs/pages/management/export-audit-events/datadog.mdx b/docs/pages/management/export-audit-events/datadog.mdx index 2b480fec1305a..c7f921631d468 100644 --- a/docs/pages/management/export-audit-events/datadog.mdx +++ b/docs/pages/management/export-audit-events/datadog.mdx @@ -239,7 +239,7 @@ identity = "identity" To start the event handler, run the following command: ```code -$ ./teleport-event-handler start --config teleport-event-handler.toml +$ teleport-event-handler start --config teleport-event-handler.toml ``` @@ -265,7 +265,7 @@ identity = "identity" To start the event handler, run the following command: ```code -$ ./teleport-event-handler start --config teleport-event-handler.toml +$ teleport-event-handler start --config teleport-event-handler.toml ``` @@ -313,7 +313,7 @@ $ helm install teleport-plugin-event-handler teleport/teleport-plugin-event-hand This example will start exporting from `May 5th 2021`: ```code -$ ./teleport-event-handler start --config teleport-event-handler.toml --start-time "2022-02-02T00:00:00Z" +$ teleport-event-handler start --config teleport-event-handler.toml --start-time "2022-02-02T00:00:00Z" ``` The start time can be set only once, on the first run of the tool. diff --git a/docs/pages/management/export-audit-events/fluentd.mdx b/docs/pages/management/export-audit-events/fluentd.mdx index 94747dbfe1110..6254d5d39b1ad 100644 --- a/docs/pages/management/export-audit-events/fluentd.mdx +++ b/docs/pages/management/export-audit-events/fluentd.mdx @@ -257,7 +257,7 @@ identity = "identity" To start the event handler, run the following command: ```code -$ ./teleport-event-handler start --config teleport-event-handler.toml +$ teleport-event-handler start --config teleport-event-handler.toml ``` @@ -283,7 +283,7 @@ identity = "identity" To start the Event Handler, run the following command: ```code -$ ./teleport-event-handler start --config teleport-event-handler.toml +$ teleport-event-handler start --config teleport-event-handler.toml ``` @@ -331,7 +331,7 @@ $ helm install teleport-plugin-event-handler teleport/teleport-plugin-event-hand This example will start exporting from `May 5th 2021`: ```code -$ ./teleport-event-handler start --config teleport-event-handler.toml --start-time "2021-05-05T00:00:00Z" +$ teleport-event-handler start --config teleport-event-handler.toml --start-time "2021-05-05T00:00:00Z" ``` The start time can be set only once, on the first run of the tool. diff --git a/docs/pages/management/guides.mdx b/docs/pages/management/guides.mdx index 47d9c9118275e..66dc8665edf60 100644 --- a/docs/pages/management/guides.mdx +++ b/docs/pages/management/guides.mdx @@ -1,10 +1,15 @@ --- -title: Setup Guides -description: Teleport Installation and Configuration Guides. +title: Integrations +description: Miscellaneous guides for integrating Teleport with third-party tools. layout: tocless-doc --- - - [Kubernetes Operator (Preview)](./guides/teleport-operator.mdx). How to add the Teleport Kubernetes Operator to your Kubernetes cluster. - - [Terraform Provider](./guides/terraform-provider.mdx). How to configure Teleport Cloud, Open Source, and Enterprise with the Terraform Provider for Teleport. - - [EC2 tags as Teleport Nodes](./guides/ec2-tags.mdx). How to set up Teleport Node labels based on EC2 tags. - - [Using Teleport's Certificate Authority with GitHub](./guides/ssh-key-extensions.mdx). Use Teleport's short-lived certificates with GitHub's Certificate Authority. +You can integrate Teleport with third-party tools in order to complete various +tasks in your cluster. These guides describe Teleport integrations that are not +documented elsewhere: + + - [EC2 tags as Teleport Node labels](./guides/ec2-tags.mdx). How to set up + Teleport Node labels based on EC2 tags. + - [Using Teleport's Certificate Authority with + GitHub](./guides/ssh-key-extensions.mdx). Use Teleport's short-lived + certificates with GitHub's Certificate Authority. diff --git a/docs/pages/management/guides/ec2-tags.mdx b/docs/pages/management/guides/ec2-tags.mdx index 94e90b40879bf..3a5da6a11e467 100644 --- a/docs/pages/management/guides/ec2-tags.mdx +++ b/docs/pages/management/guides/ec2-tags.mdx @@ -27,8 +27,8 @@ fakehost.example.com 127.0.0.1:3022 env=example,hostname=ip-172-31-53-70,aws/Nam ## Prerequisites (!docs/pages/includes/edition-prereqs-tabs.mdx!) -- One Teleport Node running on an Amazon EC2 instance. See - [Adding Nodes](../join-services-to-your-cluster.mdx) for how to set up a Teleport Node. +- One Teleport agent running on an Amazon EC2 instance. See + [our guides](../../agents/join-services-to-your-cluster.mdx) for how to set up Teleport agents. ## Enable tags in instance metadata diff --git a/docs/pages/management/introduction.mdx b/docs/pages/management/introduction.mdx index c6cc95f160702..8c53e3ae3244e 100644 --- a/docs/pages/management/introduction.mdx +++ b/docs/pages/management/introduction.mdx @@ -7,14 +7,20 @@ layout: tocless-doc In this section, you can find guides on managing a Teleport cluster after deploying it. -## Join Teleport services to your cluster - -Protect resources in your infrastructure with Teleport by joining Teleport -services to proxy those resources. To do this, start a Teleport process that -runs one or more services. The Teleport process establishes a trust relationship -with your Teleport cluster through a variety of methods. Read [Joining Teleport -Services to a Cluster](./join-services-to-your-cluster.mdx) for a detailed -explanation of each method. +## Use dynamic resources + +In Teleport, **dynamic resources** let you adjust the behavior of your Teleport +cluster as your infrastructure changes. Teleport provides three methods for +applying dynamic resources: the `tctl` client tool, Teleport Terraform provider, +and Kubernetes Operator. Read [Using Dynamic Resources](./dynamic-resources.mdx) +for more information. + +## Configure your cluster + +Get to know the [tools you can use](./dynamic-resources.mdx) to apply +settings to your cluster, all of which work well with infrastructure-as-code +solutions, including the `tctl` client, Terraform provider, and Kubernetes +Operator. ## Admin guides diff --git a/docs/pages/management/operations/ca-rotation.mdx b/docs/pages/management/operations/ca-rotation.mdx index a075c55ac8844..eb52527fc24bb 100644 --- a/docs/pages/management/operations/ca-rotation.mdx +++ b/docs/pages/management/operations/ca-rotation.mdx @@ -14,7 +14,7 @@ description: How to rotate Teleport's certificate authority This section will show you how to rotate Teleport's certificate authority. If you are joining Teleport processes to a cluster via the Teleport Auth Service -using a [join token](../join-services-to-your-cluster/join-token.mdx), each +using a [join token](../../agents/join-services-to-your-cluster/join-token.mdx), each Teleport process will need a CA pin to trust the Auth Service. The CA pin will change after each CA rotation. Make sure you use the *new* CA pin when adding Teleport services after rotation. diff --git a/docs/pages/management/operations/tls-routing.mdx b/docs/pages/management/operations/tls-routing.mdx index 2ab18f62fa656..33b5a83909dec 100644 --- a/docs/pages/management/operations/tls-routing.mdx +++ b/docs/pages/management/operations/tls-routing.mdx @@ -33,9 +33,9 @@ Teleport installation to TLS routing. -Teleport Cloud manages the Proxy Service's networking configuration for you. +Teleport Team manages the Proxy Service's networking configuration for you. Get started with a [free trial](https://goteleport.com/signup?t_source=docs) of -Teleport Cloud. +Teleport Team. To see which ports and networking settings the Proxy Service is configured to use in your Teleport Cloud tenant, run the following command, replacing diff --git a/docs/pages/reference/authentication.mdx b/docs/pages/reference/authentication.mdx index 796c9b0d05908..a246dcac8d963 100644 --- a/docs/pages/reference/authentication.mdx +++ b/docs/pages/reference/authentication.mdx @@ -121,6 +121,50 @@ $ tctl create -f cap.yaml +### Local user login failure rules + +A local user is blocked from attempting logins if, within a 30 minute window, a local user has multiple: + +- failed login attempts or +- failed password resets + +The block lasts 20 minutes. After the block has expired the user may attempt to log in again. + +Overriding a block is available to users with rights to maintain `user` resources, +available in the built-in `editor` role. To turn off a block, update the user entry, +following these steps. + +Retrieve the user entry so you can edit the status: + +```code +$ tctl get users/ > user.yaml +``` + +The file `user.yaml` should resemble the following: + +```yaml +kind: user +metadata: + name: jeff +spec: + roles: + - access + status: + is_locked: true + lock_expires: "2023-04-22T01:55:02.228158166Z" + locked_message: user has exceeded maximum failed login attempts +version: v2 +``` + +Update the `is_locked` field under `status` to `false` and save the file. Now +update the user entry with the command below: + +```code +$ tctl create -f user.yaml +``` + +The user will now be unblocked from login attempts and can attempt to authenticate again. + ## Authentication connectors diff --git a/docs/pages/reference/backends.mdx b/docs/pages/reference/backends.mdx index 5ec35d87bba54..d9eab63aa2b05 100644 --- a/docs/pages/reference/backends.mdx +++ b/docs/pages/reference/backends.mdx @@ -225,12 +225,33 @@ Service reads these parameters to configure its interactions with S3: `s3://bucket/path?region=us-east-1&endpoint=mys3.example.com&insecure=false&disablesse=false&acl=private&use_fips_endpoint=true` - `region=us-east-1` - set the Amazon region to use. + - `endpoint=mys3.example.com` - connect to a custom S3 endpoint. Optional. -- `insecure=true` - set to `true` or `false`. If `true`, TLS will be disabled. Default value is `false`. -- `disablesse=true` - set to `true` or `false`. If `true`, S3 server-side encryption will be disabled. If `false`, aws:kms (Key Management Service) will be used for server-side encryption. Other SSE types are not supported at this time. Setting `insecure=true` implicitly sets `disablesse=true`. -- `sse_kms_key=kms_key_id` - If set to a valid AWS KMS CMK key ID all objects uploaded to S3 will be encrypted with this key. Details can be found below. -- `acl=private` - set the [canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl) to use. Must be one of the predefined ACL values. -- `use_fips_endpoint=true` - [Configure S3 FIPS endpoints](#configuring-aws-fips-endpoints) + +- `insecure=true` - set to `true` or `false`. If `true`, TLS will be disabled. + Default value is `false`. + +- `disablesse=true` - set to `true` or `false`. The Auth Service checks this + value before uploading an object to an S3 bucket. + + If this is `false`, the Auth Service will set the server-side encryption + configuration of the upload to use AWS Key Management Service and, if + `sse_kms_key` is set, configure the upload to use this key. + + If this value is `true`, the Auth Service will not set an explicit server-side + encryption configuration for the object upload, meaning that the upload will + use the bucket-level server-side encryption configuration. + +- `sse_kms_key=kms_key_id` - If set to a valid AWS KMS CMK key ID, all objects + uploaded to S3 will be encrypted with this key (as long as `disablesse` is + `false`). Details can be found below. + +- `acl=private` - set the [canned + ACL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl) + to use. Must be one of the predefined ACL values. + +- `use_fips_endpoint=true` - [Configure S3 FIPS + endpoints](#configuring-aws-fips-endpoints) ### S3 IAM policy @@ -487,11 +508,13 @@ The optional `GET` parameters shown below control how Teleport interacts with a ### DynamoDB autoscaling -When setting up DynamoDB it's important to set up backups. Autoscaling is optional with Teleport, -and it is advised to collect some production usage data before enabling autoscaling. +When setting up DynamoDB it's important to set up backups. Autoscaling is +optional with Teleport, and it is advised to collect some production usage data +before enabling autoscaling. -Autoscaling and backup can be configured on DynamoDB directly. We also make setup simpler by allowing AWS DynamoDB -settings to be set automatically during Teleport startup. The configuration is described below. +Autoscaling and backup can be configured on DynamoDB directly. We also make +setup simpler by allowing AWS DynamoDB settings to be set automatically during +Teleport startup. The configuration is described below. **DynamoDB Continuous Backups** @@ -501,6 +524,16 @@ settings to be set automatically during Teleport startup. The configuration is d - [AWS Docs - Managing Throughput Capacity Automatically with DynamoDB Auto Scaling](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AutoScaling.html) + + +AWS can throttle DynamoDB if more than two processes are reading from the same +stream's shard simultaneously, so you must not deploy more than two Auth Service +instances that read from a DynamoDB backend. For details on DynamoDB Streams, +read the [AWS +documentation](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html). + + + ```yaml # ... teleport: diff --git a/docs/pages/reference/cli.mdx b/docs/pages/reference/cli.mdx index 9372495592225..8e9cdf6232bd2 100644 --- a/docs/pages/reference/cli.mdx +++ b/docs/pages/reference/cli.mdx @@ -331,7 +331,7 @@ $ tsh gcloud [--app] [] | Name | Default Value(s) | Allowed Value(s) | Description | | - | - | - | - | -| `--app` | Currently logged in Google Cloud application | The name of a Google Cloud application as listed via `tsh apps ls`. | The Google Cloud application to run the command against, if logged in to multiple Google Cloud applications. | +| `--app` | Currently logged in Google Cloud application | The name of a Google Cloud application as listed via `tsh apps ls`. | The Google Cloud application to run the command against, if logged in to multiple Google Cloud applications. | #### Global flags @@ -363,7 +363,7 @@ $ tsh gsutil [--app] [] | Name | Default Value(s) | Allowed Value(s) | Description | | - | - | - | - | -| `--app` | Currently logged in Google Cloud application | The name of a Google Cloud application as listed via `tsh apps ls`. | The Google Cloud application to run the command against, if logged in to multiple Google Cloud applications. | +| `--app` | Currently logged in Google Cloud application | The name of a Google Cloud application as listed via `tsh apps ls`. | The Google Cloud application to run the command against, if logged in to multiple Google Cloud applications. | #### Global flags @@ -741,6 +741,7 @@ Access](../application-access/cloud-apis/azure.mdx). This command does not accept any arguments. #### Flags + | Name | Default Value(s) | Allowed Value(s) | Description | | - | - | - | - | | `--app` | none | string | Name of the Teleport application representing Azure (i.e., based on `tsh apps ls`). Use this flag if your Teleport user has access to multiple Azure applications. | @@ -766,9 +767,9 @@ $ tsh proxy aws [] | Name | Default Value(s) | Allowed Value(s) | Description | | - | - | - | - | | `--app` | Currently logged in AWS app | string | Optional name of the AWS application (as shown in `tsh apps ls`) to use if logged in to multiple | -| `-p, --port` | none | port number | Specify the source port for the local proxy | -| ` -e, --endpoint-url` | HTTP Proxy | Endpoint URL | Run the local proxy to serve as an AWS endpoint URL. If not specified, the local proxy serves as an HTTPS proxy. | -| `-f, --format` | unix | `text`, `unix`, `command-prompt`, or `powershell` | Optional format for printing environment variables for the AWS proxy | +| `-p`, `--port` | none | port number | Specify the source port for the local proxy | +| `-e`, `--endpoint-url` | HTTP Proxy | Endpoint URL | Run the local proxy to serve as an AWS endpoint URL. If not specified, the local proxy serves as an HTTPS proxy. | +| `-f`, `--format` | unix | `text`, `unix`, `command-prompt`, or `powershell` | Optional format for printing environment variables for the AWS proxy | #### [Global Flags](#tsh-global-flags) @@ -806,9 +807,9 @@ $ tsh proxy gcloud [] | Name | Default Value(s) | Allowed Value(s) | Description | | - | - | - | - | | `--app` | Currently logged in Google Cloud app | string | Optional name of the Google Cloud application (as shown in `tsh apps ls`) to use if logged in to multiple | -| `-p, --port` | none | port number | Specify the source port for the local proxy | -| `-e, --endpoint-url` | HTTP Proxy | Endpoint URL | Run the local proxy to serve as a Google Cloud endpoint URL. If not specified, the local proxy serves as an HTTPS proxy. | -| `-f, --format` | unix | `text`, `unix`, `command-prompt`, or `powershell` | Optional format for printing environment variables for the Google Cloud proxy | +| `-p`, `--port` | none | port number | Specify the source port for the local proxy | +| `-e`, `--endpoint-url` | HTTP Proxy | Endpoint URL | Run the local proxy to serve as a Google Cloud endpoint URL. If not specified, the local proxy serves as an HTTPS proxy. | +| `-f`, `--format` | unix | `text`, `unix`, `command-prompt`, or `powershell` | Optional format for printing environment variables for the Google Cloud proxy | #### [Global Flags](#tsh-global-flags) @@ -851,7 +852,7 @@ $ tsh scp [] ... #### Global flags -These flags are available for all commands `--login, --proxy, --user, --ttl, --identity, --cert-format, --insecure, --auth, --skip-version, --debug, --jumphost`. +These flags are available for all commands `--login`, `--proxy`, `--user`, `--ttl`, `--identity`, `--cert-format`, `--insecure`, `--auth`, `--skip-version-check`, `--debug`, `--jumphost`. Run `tsh help ` or see the [Global Flags section](#tsh-global-flags). #### Examples @@ -859,6 +860,7 @@ Run `tsh help ` or see the [Global Flags section](#tsh-global-flags) ```code $ tsh --proxy=proxy.example.com scp example.txt user@host:/destination/dir ``` + `tsh scp` will not work from the CLI if the user requires session moderation. You can transfer files in a moderated session by joining the SSH session from the Web UI and requesting the file transfer there. Both the session initiator and moderators must be present in the Web UI in order to approve the file transfer request. @@ -890,7 +892,7 @@ $ tsh ls [] [