diff --git a/.github/pr_labeler.yml b/.github/pr_labeler.yml index c7488950966..5f855fde308 100644 --- a/.github/pr_labeler.yml +++ b/.github/pr_labeler.yml @@ -12,6 +12,8 @@ digitalocean: - plugins/source/digitalocean/**/* datadog: - plugins/source/datadog/**/* +fastly: + - plugins/source/fastly/**/* fuzz: - plugins/source/fuzz/**/* gandi: @@ -36,12 +38,18 @@ terraform: - plugins/source/terraform/**/* vercel: - plugins/source/vercel/**/* +salesforce: + - plugins/source/salesforce/**/* postgresql: - plugins/destination/postgresql/**/* sqlite: - plugins/destination/sqlite/**/* csv: - plugins/destination/csv/**/* +file: + - plugins/destination/file/**/* +gcs: + - plugins/destination/gcs/**/* snowflake: - plugins/destination/snowflake/**/* bigquery: diff --git a/.github/styles/Vocab/Base/accept.txt b/.github/styles/Vocab/Base/accept.txt index 8c2c39383dc..d7aa2ab7da9 100644 --- a/.github/styles/Vocab/Base/accept.txt +++ b/.github/styles/Vocab/Base/accept.txt @@ -127,6 +127,8 @@ SDK serverless Severability skip_tables +snyk +Snyk SRE SREs Steampipe @@ -145,6 +147,7 @@ trojan unbundle unencrypted unmarshalling +upsert upserted uuid UUID diff --git a/.github/workflows/dest_file.yml b/.github/workflows/dest_file.yml new file mode 100644 index 00000000000..ad79e6599ff --- /dev/null +++ b/.github/workflows/dest_file.yml @@ -0,0 +1,81 @@ +name: Destination Plugin File Workflow + +on: + pull_request: + paths: + - "plugins/destination/filetypes/**" + - "plugins/destination/file/**" + - ".github/workflows/dest_file.yml" + push: + branches: + - main + paths: + - "plugins/destination/filetypes/**" + - "plugins/destination/file/**" + - ".github/workflows/dest_file.yml" + +jobs: + plugins-destination-file: + timeout-minutes: 30 + name: "plugins/destination/file" + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./plugins/destination/file + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: Set up Go 1.x + uses: actions/setup-go@v3 + with: + go-version-file: plugins/destination/file/go.mod + cache: true + cache-dependency-path: plugins/destination/file/go.sum + - name: golangci-lint + uses: cloudquery/golangci-lint-action@master + with: + version: v1.50.1 + working-directory: plugins/destination/file + args: "--config ../../.golangci.yml" + - name: Get dependencies + run: go get -t -d ./... + - name: Build + run: go build . + - name: Test file plugin + run: make test + validate-release: + timeout-minutes: 30 + runs-on: ubuntu-latest + env: + CGO_ENABLED: 0 + steps: + - name: Checkout + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: actions/checkout@v3 + - uses: actions/cache@v3 + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-1.19.3-release-cache-${{ hashFiles('plugins/destination/file/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-1.19.3-release-cache-plugins-destination-file + - name: Set up Go + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: actions/setup-go@v3 + with: + go-version-file: plugins/destination/file/go.mod + - name: Install GoReleaser + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: goreleaser/goreleaser-action@v3 + with: + distribution: goreleaser-pro + version: latest + install-only: true + - name: Run GoReleaser Dry-Run + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + run: goreleaser release --snapshot --rm-dist --skip-validate --skip-publish --skip-sign -f ./plugins/destination/file/.goreleaser.yaml + env: + GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} diff --git a/.github/workflows/dest_gcs.yml b/.github/workflows/dest_gcs.yml new file mode 100644 index 00000000000..4fb621cd35b --- /dev/null +++ b/.github/workflows/dest_gcs.yml @@ -0,0 +1,87 @@ +name: Destination Plugin GCS Workflow + +on: + pull_request: + paths: + - "plugins/destination/gcs/**" + - ".github/workflows/dest_gcs.yml" + push: + branches: + - main + paths: + - "plugins/destination/gcs/**" + - ".github/workflows/dest_gcs.yml" + +jobs: + plugins-destination-gcs: + timeout-minutes: 30 + name: "plugins/destination/gcs" + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./plugins/destination/gcs + permissions: + id-token: 'write' # This required for OIDC + contents: 'read' # This is required for actions/checkout@v3 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: Authenticate to Google Cloud + uses: 'google-github-actions/auth@v0' + with: + workload_identity_provider: 'projects/151868820337/locations/global/workloadIdentityPools/integration-test-pool/providers/integration-test-provider' + service_account: 'integration-service-account@cq-integration-tests.iam.gserviceaccount.com' + - name: Set up Go 1.x + uses: actions/setup-go@v3 + with: + go-version-file: plugins/destination/gcs/go.mod + cache: true + cache-dependency-path: plugins/destination/gcs/go.sum + - name: golangci-lint + uses: cloudquery/golangci-lint-action@master + with: + version: v1.50.1 + working-directory: plugins/destination/gcs + args: "--config ../../.golangci.yml" + - name: Get dependencies + run: go get -t -d ./... + - name: Build + run: go build . + - name: Test file plugin + run: make test + validate-release: + timeout-minutes: 30 + runs-on: ubuntu-latest + env: + CGO_ENABLED: 0 + steps: + - name: Checkout + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: actions/checkout@v3 + - uses: actions/cache@v3 + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-1.19.3-release-cache-${{ hashFiles('plugins/destination/gcs/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-1.19.3-release-cache-plugins-destination-gcs + - name: Set up Go + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: actions/setup-go@v3 + with: + go-version-file: plugins/destination/gcs/go.mod + - name: Install GoReleaser + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: goreleaser/goreleaser-action@v3 + with: + distribution: goreleaser-pro + version: latest + install-only: true + - name: Run GoReleaser Dry-Run + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + run: goreleaser release --snapshot --rm-dist --skip-validate --skip-publish --skip-sign -f ./plugins/destination/gcs/.goreleaser.yaml + env: + GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} diff --git a/.github/workflows/source_fastly.yml b/.github/workflows/source_fastly.yml new file mode 100644 index 00000000000..2279d4c8f0b --- /dev/null +++ b/.github/workflows/source_fastly.yml @@ -0,0 +1,85 @@ +name: Source Plugin Fastly Workflow + +on: + pull_request: + paths: + - "plugins/source/fastly/**" + - ".github/workflows/source_fastly.yml" + push: + branches: + - main + paths: + - "plugins/source/fastly/**" + - ".github/workflows/source_fastly.yml" + +jobs: + plugins-source-fastly: + timeout-minutes: 30 + name: "plugins/source/fastly" + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./plugins/source/fastly + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: Set up Go 1.x + uses: actions/setup-go@v3 + with: + go-version-file: plugins/source/fastly/go.mod + cache: true + cache-dependency-path: plugins/source/fastly/go.sum + - name: golangci-lint + uses: cloudquery/golangci-lint-action@master + with: + version: v1.50.1 + working-directory: plugins/source/fastly + args: "--config ../../.golangci.yml" + - name: Get dependencies + run: go get -t -d ./... + - name: Build + run: go build . + - name: Test + run: make test + - name: gen + if: github.event_name == 'pull_request' + run: make gen + - name: Fail if generation updated files + if: github.event_name == 'pull_request' + run: test "$(git status -s | wc -l)" -eq 0 || (git status -s; exit 1) + validate-release: + timeout-minutes: 30 + runs-on: ubuntu-latest + env: + CGO_ENABLED: 0 + steps: + - name: Checkout + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: actions/checkout@v3 + - uses: actions/cache@v3 + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-1.19.3-release-cache-${{ hashFiles('plugins/source/fastly/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-1.19.3-release-cache-plugins-source-fastly + - name: Set up Go + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: actions/setup-go@v3 + with: + go-version-file: plugins/source/fastly/go.mod + - name: Install GoReleaser + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: goreleaser/goreleaser-action@v3 + with: + distribution: goreleaser-pro + version: latest + install-only: true + - name: Run GoReleaser Dry-Run + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + run: goreleaser release --snapshot --rm-dist --skip-validate --skip-publish --skip-sign -f ./plugins/source/fastly/.goreleaser.yaml + env: + GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} diff --git a/.github/workflows/source_snyk.yml b/.github/workflows/source_snyk.yml new file mode 100644 index 00000000000..ec216bdd3e0 --- /dev/null +++ b/.github/workflows/source_snyk.yml @@ -0,0 +1,85 @@ +name: Source Plugin Snyk Workflow + +on: + pull_request: + paths: + - "plugins/source/snyk/**" + - ".github/workflows/source_snyk.yml" + push: + branches: + - main + paths: + - "plugins/source/snyk/**" + - ".github/workflows/source_snyk.yml" + +jobs: + plugins-source-snyk: + timeout-minutes: 30 + name: "plugins/source/snyk" + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./plugins/source/snyk + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: Set up Go 1.x + uses: actions/setup-go@v3 + with: + go-version-file: plugins/source/snyk/go.mod + cache: true + cache-dependency-path: plugins/source/snyk/go.sum + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: v1.50.1 + working-directory: plugins/source/snyk + args: "--config ../../.golangci.yml" + - name: Get dependencies + run: go get -t -d ./... + - name: Build + run: go build . + - name: Test + run: make test + - name: gen + if: github.event_name == 'pull_request' + run: make gen + - name: Fail if generation updated files + if: github.event_name == 'pull_request' + run: test "$(git status -s | wc -l)" -eq 0 || (git status -s; exit 1) + validate-release: + timeout-minutes: 30 + runs-on: ubuntu-latest + env: + CGO_ENABLED: 0 + steps: + - name: Checkout + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: actions/checkout@v3 + - uses: actions/cache@v3 + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-1.19.3-release-cache-${{ hashFiles('plugins/source/snyk/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-1.19.3-release-cache-plugins-source-snyk + - name: Set up Go + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: actions/setup-go@v3 + with: + go-version-file: plugins/source/snyk/go.mod + - name: Install GoReleaser + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + uses: goreleaser/goreleaser-action@v3 + with: + distribution: goreleaser-pro + version: latest + install-only: true + - name: Run GoReleaser Dry-Run + if: startsWith(github.head_ref, 'release-please--branches--main--components') || github.event_name == 'push' + run: goreleaser release --snapshot --rm-dist --skip-validate --skip-publish --skip-sign -f ./plugins/source/snyk/.goreleaser.yaml + env: + GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} diff --git a/.github/workflows/source_tailscale.yml b/.github/workflows/source_tailscale.yml index 4e54565f4f6..b418c2d23a9 100644 --- a/.github/workflows/source_tailscale.yml +++ b/.github/workflows/source_tailscale.yml @@ -45,8 +45,6 @@ jobs: - name: gen if: github.event_name == 'pull_request' run: make gen - - name: Cleanup after build - run: rm ./tailscale - name: Fail if generation updated files if: github.event_name == 'pull_request' run: test "$(git status -s | wc -l)" -eq 0 diff --git a/.github/workflows/wait_for_required_workflows.yml b/.github/workflows/wait_for_required_workflows.yml index 4959d8d8b71..41400921b5d 100644 --- a/.github/workflows/wait_for_required_workflows.yml +++ b/.github/workflows/wait_for_required_workflows.yml @@ -47,6 +47,7 @@ jobs: "plugins/source/crowdstrike", "plugins/source/digitalocean", "plugins/source/datadog", + "plugins/source/fastly", "plugins/source/gandi", "plugins/source/gcp", "plugins/source/github", @@ -56,6 +57,7 @@ jobs: "plugins/source/okta", "plugins/source/slack", "plugins/source/salesforce", + "plugins/source/snyk", "plugins/source/tailscale", "plugins/source/pagerduty", "plugins/source/terraform", @@ -69,6 +71,7 @@ jobs: "plugins/destination/snowflake", "plugins/destination/bigquery", "plugins/destination/mongodb", + "plugins/destination/file", ].filter(action => matchesFile(action)) if (actions.length === 0) { console.log("No actions to wait for") diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2c114853607..8dc9d52b5ae 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,7 +1,7 @@ { - "cli": "2.0.28", + "cli": "2.0.29", "cli+FILLER": "0.0.0", - "plugins/source/aws": "9.0.0", + "plugins/source/aws": "9.0.1", "plugins/source/aws+FILLER": "0.0.0", "plugins/source/azure": "3.0.0", "plugins/source/azure+FILLER": "0.0.0", @@ -9,7 +9,7 @@ "plugins/source/cloudflare+FILLER": "0.0.0", "plugins/source/digitalocean": "4.0.1", "plugins/source/digitalocean+FILLER": "0.0.0", - "plugins/source/gcp": "5.3.0", + "plugins/source/gcp": "5.3.1", "plugins/source/gcp+FILLER": "0.0.0", "plugins/source/github": "1.4.2", "plugins/source/github+FILLER": "0.0.0", @@ -23,21 +23,21 @@ "plugins/source/terraform+FILLER": "0.0.0", "plugins/source/test": "1.3.25", "plugins/source/test+FILLER": "0.0.0", - "plugins/destination/postgresql": "1.10.0", + "plugins/destination/postgresql": "2.0.0", "plugins/destination/postgresql+FILLER": "0.0.0", - "plugins/destination/test": "1.3.8", + "plugins/destination/test": "1.3.11", "plugins/destination/test+FILLER": "0.0.0", - "plugins/destination/csv": "1.2.0", + "plugins/destination/csv": "1.2.2", "plugins/destination/csv+FILLER": "0.0.0", - "plugins/destination/sqlite": "1.1.0", + "plugins/destination/sqlite": "1.1.2", "plugins/destination/sqlite+FILLER": "0.0.0", - "plugins/destination/snowflake": "1.1.0", + "plugins/destination/snowflake": "1.1.2", "plugins/destination/snowflake+FILLER": "0.0.0", "plugins/source/gandi": "1.1.3", "plugins/source/gandi+FILLER": "0.0.0", "plugins/source/datadog": "1.0.4", "plugins/source/datadog+FILLER": "0.0.0", - "plugins/destination/bigquery": "1.3.0", + "plugins/destination/bigquery": "2.0.0", "plugins/destination/bigquery+FILLER": "0.0.0", "plugins/source/tailscale": "1.0.2", "plugins/source/tailscale+FILLER": "0.0.0", @@ -48,8 +48,14 @@ "plugins/source/crowdstrike": "1.0.1", "plugins/source/crowdstrike+FILLER": "0.0.0", "plugins/source/pagerduty": "1.1.1", - "plugins/destination/mongodb": "1.0.0", + "plugins/destination/mongodb": "1.0.2", "plugins/destination/mongodb+FILLTER": "0.0.0", "plugins/source/gitlab": "1.0.1", - "plugins/source/gitlab+FILLER": "0.0.0" + "plugins/source/gitlab+FILLER": "0.0.0", + "plugins/source/azuredevops": "1.0.0", + "plugins/source/azuredevops+FILLER": "0.0.0", + "plugins/source/salesforce": "1.0.0", + "plugins/source/salesforce+FILLER": "0.0.0", + "plugins/source/fastly": "1.0.0", + "plugins/source/fastly+FILLER": "0.0.0" } diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index c388064e228..953f053c14b 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to CloudQuery will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.29](https://github.com/cloudquery/cloudquery/compare/cli-v2.0.28...cli-v2.0.29) (2022-12-29) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.14.0 ([#6025](https://github.com/cloudquery/cloudquery/issues/6025)) ([35b2cfc](https://github.com/cloudquery/cloudquery/commit/35b2cfc7fc7bcdaceb7ee674e3a17f0f5673b366)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.0 ([#6071](https://github.com/cloudquery/cloudquery/issues/6071)) ([684b525](https://github.com/cloudquery/cloudquery/commit/684b525aaa285fcae70dd87af56679c1205adebe)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.1 ([#6079](https://github.com/cloudquery/cloudquery/issues/6079)) ([650659c](https://github.com/cloudquery/cloudquery/commit/650659c3c6766df571868e2ec3a2007cb76696eb)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.16.0 ([#6098](https://github.com/cloudquery/cloudquery/issues/6098)) ([7bacdf3](https://github.com/cloudquery/cloudquery/commit/7bacdf3364716eab08fa1a84ae4047b42edeee7e)) + ## [2.0.28](https://github.com/cloudquery/cloudquery/compare/cli-v2.0.27...cli-v2.0.28) (2022-12-27) diff --git a/cli/cmd/testdata/sync-missing-path-error.yml b/cli/cmd/testdata/sync-missing-path-error.yml index 8f0121e7066..2a8e6ea1293 100644 --- a/cli/cmd/testdata/sync-missing-path-error.yml +++ b/cli/cmd/testdata/sync-missing-path-error.yml @@ -3,9 +3,9 @@ spec: name: "test" path: "cloudquery/test" destinations: [test] - version: "v1.3.24" # latest version of source test plugin + version: "v1.3.25" # latest version of source test plugin --- kind: "destination" spec: name: "test" - version: "v1.3.8" # latest version of destination test plugin + version: "v1.3.11" # latest version of destination test plugin diff --git a/cli/cmd/testdata/sync-success.yml b/cli/cmd/testdata/sync-success.yml index 2f8f04c2c04..d98ae3c8a27 100644 --- a/cli/cmd/testdata/sync-success.yml +++ b/cli/cmd/testdata/sync-success.yml @@ -3,10 +3,10 @@ spec: name: "test" path: "cloudquery/test" destinations: [test] - version: "v1.3.24" # latest version of source test plugin + version: "v1.3.25" # latest version of source test plugin --- kind: "destination" spec: name: "test" path: "cloudquery/test" - version: "v1.3.8" # latest version of destination test plugin + version: "v1.3.11" # latest version of destination test plugin diff --git a/cli/go.mod b/cli/go.mod index e2380bc4193..fdff4cc080d 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/cli go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/getsentry/sentry-go v0.15.0 github.com/google/uuid v1.3.0 github.com/rs/zerolog v1.28.0 diff --git a/cli/go.sum b/cli/go.sum index bc65329f44e..2c90af2191d 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -1,8 +1,8 @@ github.com/avast/retry-go/v4 v4.3.1 h1:Mtg11F9PdAIMkMiio2RKcYauoVHjl2aB3zQJJlzD4cE= github.com/avast/retry-go/v4 v4.3.1/go.mod h1:rg6XFaiuFYII0Xu3RDbZQkxCofFwruZKW8oEF1jpWiU= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= -github.com/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= diff --git a/contributing/adding_a_new_plugin_to_cq_monorepo.md b/contributing/adding_a_new_plugin_to_cq_monorepo.md index dd4ff86287d..19cecac5063 100644 --- a/contributing/adding_a_new_plugin_to_cq_monorepo.md +++ b/contributing/adding_a_new_plugin_to_cq_monorepo.md @@ -4,13 +4,14 @@ This guide relates only when you add a new plugin to the CloudQuery Monorepo. There are number of steps to follow in order to add all the relevant CI and release processes to your plugin. -1. Add it to the [release please configuration file](https://github.com/cloudquery/cloudquery/blob/5c6e5a8eb5b8c6868336967dfe1a375cef5a792f/release-please-config.json#L25). -2. Create a workflow file for it. See example [destination](https://github.com/cloudquery/cloudquery/blob/5c6e5a8eb5b8c6868336967dfe1a375cef5a792f/.github/workflows/dest_test.yml) and [source](https://github.com/cloudquery/cloudquery/blob/812241697c644bdb1ae202bbadcb3baae456f788/.github/workflows/source_gcp.yml) plugins. -3. Add the workflow file job name to the wait for all workflow so it will be enforced, for [example](https://github.com/cloudquery/cloudquery/blob/5c6e5a8eb5b8c6868336967dfe1a375cef5a792f/.github/workflows/wait_for_required_workflows.yml#L51). +1. Add it to the [release please configuration file](../release-please-config.json). +2. Create a workflow file for it. See example [destination](../.github/workflows/dest_test.yml) and [source](../.github/workflows/source_gcp.yml) plugins. +3. Add the workflow file job name to the [wait-for-required-workflows workflow](../.github/workflows/wait_for_required_workflows.yml), so it will be enforced. For [example](https://github.com/cloudquery/cloudquery/blob/5c6e5a8eb5b8c6868336967dfe1a375cef5a792f/.github/workflows/wait_for_required_workflows.yml#L51). 4. Ensure there’s a `Version` var under `resources/plugin/plugin.go` so the version will embedded correctly by Go Releaser, example [here](https://github.com/cloudquery/cloudquery/blob/fb690589a1d2b7ed30f90744d156a6e5b0e57d66/plugins/destination/test/resources/plugin/plugin.go#L5). See also the relevant [Go Releaser configuration file](https://github.com/cloudquery/cloudquery/blob/812241697c644bdb1ae202bbadcb3baae456f788/plugins/.goreleaser.yaml#L12). 5. Add a `.goreleaser.yaml` file - [see example](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/.goreleaser.yaml). -6. If relevant, add it to the Website under [sources](https://github.com/cloudquery/cloudquery/blob/812241697c644bdb1ae202bbadcb3baae456f788/website/pages/docs/plugins/sources/overview.mdx?plain=1#L30) or [destinations](https://github.com/cloudquery/cloudquery/blob/812241697c644bdb1ae202bbadcb3baae456f788/website/pages/docs/plugins/destinations/overview.mdx?plain=1#L21). -7. If relevant add an entry in our [PR labeler](https://github.com/cloudquery/cloudquery/blob/fb690589a1d2b7ed30f90744d156a6e5b0e57d66/.github/pr_labeler.yml#L23). -8. Create a Sentry project for it under https://sentry.io/organizations/cloudquery-v2/projects/ and embed the correct DSN, for example see [here](https://github.com/cloudquery/cloudquery/blob/0e4b8dc53358388f8a1e61cad8ae8a1ab2f52342/plugins/source/azure/main.go#L8). -9. **Only relevant for big source plugins - after the initial PR is merged**, allow the plugin workflow file to access large runners via https://github.com/organizations/cloudquery/settings/actions/runner-groups/6. -10. **After the initial version of the plugin is released** add a “filler` entry for it in [here](https://github.com/cloudquery/cloudquery/blob/fb690589a1d2b7ed30f90744d156a6e5b0e57d66/.release-please-manifest.json#L29). This ensures we don’t get conflicts when creating multiple release PRs. More about this in this [issue](https://github.com/googleapis/release-please/issues/1502). +6. If relevant, add it to the Website under [sources](../website/pages/docs/plugins/sources/overview.mdx) or [destinations](../website/pages/docs/plugins/destinations/overview.mdx). +7. If relevant, add it to the Website [sources _meta.json](../website/pages/docs/plugins/sources/_meta.json) or [destinations _meta.json](../website/pages/docs/plugins/destinations/_meta.json) file so that it displays correctly in the sidebar. +8. If relevant, add an entry in our [PR labeler](../.github/pr_labeler.yml). +9. Create a Sentry project for it under https://sentry.io/organizations/cloudquery-v2/projects/ and embed the correct DSN, for example see [here](https://github.com/cloudquery/cloudquery/blob/0e4b8dc53358388f8a1e61cad8ae8a1ab2f52342/plugins/source/azure/main.go#L8). +10. **Only relevant for big source plugins - after the initial PR is merged**, allow the plugin workflow file to access large runners via https://github.com/organizations/cloudquery/settings/actions/runner-groups/6. +11. **After the initial version of the plugin is released** add a “filler` entry for it in [here](https://github.com/cloudquery/cloudquery/blob/fb690589a1d2b7ed30f90744d156a6e5b0e57d66/.release-please-manifest.json#L29). This ensures we don’t get conflicts when creating multiple release PRs. More about this in this [issue](https://github.com/googleapis/release-please/issues/1502). diff --git a/plugins/destination/bigquery/CHANGELOG.md b/plugins/destination/bigquery/CHANGELOG.md index 77cdb57cc6e..f8b10d75ca8 100644 --- a/plugins/destination/bigquery/CHANGELOG.md +++ b/plugins/destination/bigquery/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## [2.0.0](https://github.com/cloudquery/cloudquery/compare/plugins-destination-bigquery-v1.3.2...plugins-destination-bigquery-v2.0.0) (2022-12-29) + + +### ⚠ BREAKING CHANGES + +* **bigquery-spec:** Move `batch_size` from the plugin spec to the top level spec ([#6092](https://github.com/cloudquery/cloudquery/issues/6092)) + +### Bug Fixes + +* **bigquery-spec:** Move `batch_size` from the plugin spec to the top level spec ([#6092](https://github.com/cloudquery/cloudquery/issues/6092)) ([a1d706e](https://github.com/cloudquery/cloudquery/commit/a1d706e839d3c81d5cb2cbb5971bdbe05a25288e)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.16.0 ([#6098](https://github.com/cloudquery/cloudquery/issues/6098)) ([7bacdf3](https://github.com/cloudquery/cloudquery/commit/7bacdf3364716eab08fa1a84ae4047b42edeee7e)) + +## [1.3.2](https://github.com/cloudquery/cloudquery/compare/plugins-destination-bigquery-v1.3.1...plugins-destination-bigquery-v1.3.2) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.0 ([#6071](https://github.com/cloudquery/cloudquery/issues/6071)) ([684b525](https://github.com/cloudquery/cloudquery/commit/684b525aaa285fcae70dd87af56679c1205adebe)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.1 ([#6079](https://github.com/cloudquery/cloudquery/issues/6079)) ([650659c](https://github.com/cloudquery/cloudquery/commit/650659c3c6766df571868e2ec3a2007cb76696eb)) + +## [1.3.1](https://github.com/cloudquery/cloudquery/compare/plugins-destination-bigquery-v1.3.0...plugins-destination-bigquery-v1.3.1) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.14.0 ([#6025](https://github.com/cloudquery/cloudquery/issues/6025)) ([35b2cfc](https://github.com/cloudquery/cloudquery/commit/35b2cfc7fc7bcdaceb7ee674e3a17f0f5673b366)) + ## [1.3.0](https://github.com/cloudquery/cloudquery/compare/plugins-destination-bigquery-v1.2.1...plugins-destination-bigquery-v1.3.0) (2022-12-23) diff --git a/plugins/destination/bigquery/client/client.go b/plugins/destination/bigquery/client/client.go index 3ff668e3a73..aa561205538 100644 --- a/plugins/destination/bigquery/client/client.go +++ b/plugins/destination/bigquery/client/client.go @@ -17,7 +17,6 @@ type Client struct { logger zerolog.Logger spec specs.Destination metrics destination.Metrics - batchSize int pluginSpec Spec client *bigquery.Client } @@ -41,7 +40,6 @@ func New(ctx context.Context, logger zerolog.Logger, destSpec specs.Destination) } c.pluginSpec = spec - c.batchSize = spec.BatchSize // the context here is used for token refresh so this is workaround as suggested // https://github.com/googleapis/google-cloud-go/issues/946 diff --git a/plugins/destination/bigquery/client/spec.go b/plugins/destination/bigquery/client/spec.go index 029212a68fa..a12842460a6 100644 --- a/plugins/destination/bigquery/client/spec.go +++ b/plugins/destination/bigquery/client/spec.go @@ -34,18 +34,12 @@ type Spec struct { DatasetLocation string `json:"dataset_location"` TimePartitioning TimePartitioningOption `json:"time_partitioning"` ServiceAccountKeyJSON string `json:"service_account_key_json"` - BatchSize int `json:"batch_size,omitempty"` } -const defaultBatchSize = 1000 - func (s *Spec) SetDefaults() { if s.TimePartitioning == "" { s.TimePartitioning = TimePartitioningOptionNone } - if s.BatchSize <= 0 { - s.BatchSize = defaultBatchSize - } } func (s *Spec) Validate() error { diff --git a/plugins/destination/bigquery/client/write.go b/plugins/destination/bigquery/client/write.go index 704687231bf..f07d8964ed4 100644 --- a/plugins/destination/bigquery/client/write.go +++ b/plugins/destination/bigquery/client/write.go @@ -10,7 +10,6 @@ import ( ) const ( - batchSize = 1000 writeTimeout = 5 * time.Minute ) diff --git a/plugins/destination/bigquery/go.mod b/plugins/destination/bigquery/go.mod index c4da8201c97..c4f6828fa1a 100644 --- a/plugins/destination/bigquery/go.mod +++ b/plugins/destination/bigquery/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( cloud.google.com/go/bigquery v1.43.0 - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/rs/zerolog v1.28.0 golang.org/x/sync v0.1.0 google.golang.org/api v0.103.0 diff --git a/plugins/destination/bigquery/go.sum b/plugins/destination/bigquery/go.sum index 1fda0b24ff3..b89718b040c 100644 --- a/plugins/destination/bigquery/go.sum +++ b/plugins/destination/bigquery/go.sum @@ -53,8 +53,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/destination/bigquery/main.go b/plugins/destination/bigquery/main.go index 19d1fdb5826..9b4defb354e 100644 --- a/plugins/destination/bigquery/main.go +++ b/plugins/destination/bigquery/main.go @@ -12,6 +12,6 @@ const ( ) func main() { - p := destination.NewPlugin("bigquery", plugin.Version, client.New, destination.WithManagedWriter()) + p := destination.NewPlugin("bigquery", plugin.Version, client.New, destination.WithManagedWriter(), destination.WithDefaultBatchSize(1000)) serve.Destination(p, serve.WithDestinationSentryDSN(sentryDSN)) } diff --git a/plugins/destination/csv/CHANGELOG.md b/plugins/destination/csv/CHANGELOG.md index 8b61ad901e8..a6a9b786c86 100644 --- a/plugins/destination/csv/CHANGELOG.md +++ b/plugins/destination/csv/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [1.2.2](https://github.com/cloudquery/cloudquery/compare/plugins-destination-csv-v1.2.1...plugins-destination-csv-v1.2.2) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.0 ([#6071](https://github.com/cloudquery/cloudquery/issues/6071)) ([684b525](https://github.com/cloudquery/cloudquery/commit/684b525aaa285fcae70dd87af56679c1205adebe)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.1 ([#6079](https://github.com/cloudquery/cloudquery/issues/6079)) ([650659c](https://github.com/cloudquery/cloudquery/commit/650659c3c6766df571868e2ec3a2007cb76696eb)) + +## [1.2.1](https://github.com/cloudquery/cloudquery/compare/plugins-destination-csv-v1.2.0...plugins-destination-csv-v1.2.1) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.14.0 ([#6025](https://github.com/cloudquery/cloudquery/issues/6025)) ([35b2cfc](https://github.com/cloudquery/cloudquery/commit/35b2cfc7fc7bcdaceb7ee674e3a17f0f5673b366)) + ## [1.2.0](https://github.com/cloudquery/cloudquery/compare/plugins-destination-csv-v1.1.15...plugins-destination-csv-v1.2.0) (2022-12-23) diff --git a/plugins/destination/csv/go.mod b/plugins/destination/csv/go.mod index 2571795dd56..c2da8c21222 100644 --- a/plugins/destination/csv/go.mod +++ b/plugins/destination/csv/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/destination/csv go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/rs/zerolog v1.28.0 ) diff --git a/plugins/destination/csv/go.sum b/plugins/destination/csv/go.sum index 753fe7cdf2d..541e836f71c 100644 --- a/plugins/destination/csv/go.sum +++ b/plugins/destination/csv/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/destination/file/.gitignore b/plugins/destination/file/.gitignore new file mode 100644 index 00000000000..1a010b1c0f0 --- /dev/null +++ b/plugins/destination/file/.gitignore @@ -0,0 +1 @@ +file \ No newline at end of file diff --git a/plugins/destination/file/.goreleaser.yaml b/plugins/destination/file/.goreleaser.yaml new file mode 100644 index 00000000000..9e3d8c587c6 --- /dev/null +++ b/plugins/destination/file/.goreleaser.yaml @@ -0,0 +1,14 @@ +variables: + component: destination/file + binary: file + +project_name: plugins/destination/file + +monorepo: + tag_prefix: plugins-destination-file- + dir: plugins/destination/file + +includes: + - from_file: + # Relative to the directory Go Releaser is run from (which is the root of the repository) + path: ./plugins/.goreleaser.yaml \ No newline at end of file diff --git a/plugins/destination/file/CHANGELOG.md b/plugins/destination/file/CHANGELOG.md new file mode 100644 index 00000000000..4dc68c6ff8e --- /dev/null +++ b/plugins/destination/file/CHANGELOG.md @@ -0,0 +1,2 @@ +# Changelog + diff --git a/plugins/destination/file/Makefile b/plugins/destination/file/Makefile new file mode 100644 index 00000000000..b68c1473fde --- /dev/null +++ b/plugins/destination/file/Makefile @@ -0,0 +1,7 @@ +.PHONY: test +test: + go test -timeout 3m ./... + +.PHONY: lint +lint: + @golangci-lint run --config ../../.golangci.yml diff --git a/plugins/destination/file/README.md b/plugins/destination/file/README.md new file mode 100644 index 00000000000..fa0f29dfb7f --- /dev/null +++ b/plugins/destination/file/README.md @@ -0,0 +1,7 @@ +# CloudQuery File Destination Plugin + +This destination plugin lets you sync data from a CloudQuery source to local files in various formats such as CSV and JSON. + +## Links + +- [User Guide](https://cloudquery.io/docs/plugins/destinations/file/overview) \ No newline at end of file diff --git a/plugins/destination/file/client/client.go b/plugins/destination/file/client/client.go new file mode 100644 index 00000000000..6faad3f0633 --- /dev/null +++ b/plugins/destination/file/client/client.go @@ -0,0 +1,57 @@ +package client + +import ( + "context" + "fmt" + "os" + + "github.com/cloudquery/filetypes/csv" + "github.com/cloudquery/filetypes/json" + "github.com/cloudquery/plugin-sdk/plugins/destination" + "github.com/cloudquery/plugin-sdk/specs" + "github.com/rs/zerolog" +) + +type Client struct { + destination.UnimplementedUnmanagedWriter + logger zerolog.Logger + spec specs.Destination + pluginSpec Spec + + csvTransformer *csv.Transformer + csvReverseTransformer *csv.ReverseTransformer + jsonTransformer *json.Transformer + jsonReverseTransformer *json.ReverseTransformer +} + +func New(ctx context.Context, logger zerolog.Logger, spec specs.Destination) (destination.Client, error) { + if spec.WriteMode != specs.WriteModeAppend { + return nil, fmt.Errorf("file destination only supports append mode") + } + c := &Client{ + logger: logger.With().Str("module", "file").Logger(), + spec: spec, + csvTransformer: &csv.Transformer{}, + jsonTransformer: &json.Transformer{}, + csvReverseTransformer: &csv.ReverseTransformer{}, + jsonReverseTransformer: &json.ReverseTransformer{}, + } + + if err := spec.UnmarshalSpec(&c.pluginSpec); err != nil { + return nil, fmt.Errorf("failed to unmarshal postgresql spec: %w", err) + } + if err := c.pluginSpec.Validate(); err != nil { + return nil, err + } + c.pluginSpec.SetDefaults() + + if err := os.MkdirAll(c.pluginSpec.Directory, 0755); err != nil { + return nil, fmt.Errorf("failed to create directory: %w", err) + } + + return c, nil +} + +func (*Client) Close(ctx context.Context) error { + return nil +} diff --git a/plugins/destination/file/client/client_test.go b/plugins/destination/file/client/client_test.go new file mode 100644 index 00000000000..40225bfba4d --- /dev/null +++ b/plugins/destination/file/client/client_test.go @@ -0,0 +1,39 @@ +package client + +import ( + "testing" + + "github.com/cloudquery/plugin-sdk/plugins/destination" +) + +func TestPluginCSV(t *testing.T) { + p := destination.NewPlugin("file", "development", New, destination.WithManagedWriter()) + + destination.PluginTestSuiteRunner(t, p, + Spec{ + Directory: t.TempDir(), + Format: FormatTypeCSV, + NoRotate: true, + }, + destination.PluginTestSuiteTests{ + SkipOverwrite: true, + SkipDeleteStale: true, + }, + ) +} + +func TestPluginJSON(t *testing.T) { + p := destination.NewPlugin("file", "development", New, destination.WithManagedWriter()) + + destination.PluginTestSuiteRunner(t, p, + Spec{ + Directory: t.TempDir(), + Format: FormatTypeJSON, + NoRotate: true, + }, + destination.PluginTestSuiteTests{ + SkipOverwrite: true, + SkipDeleteStale: true, + }, + ) +} diff --git a/plugins/destination/file/client/deletestale.go b/plugins/destination/file/client/deletestale.go new file mode 100644 index 00000000000..7f1905154db --- /dev/null +++ b/plugins/destination/file/client/deletestale.go @@ -0,0 +1,13 @@ +package client + +import ( + "context" + "fmt" + "time" + + "github.com/cloudquery/plugin-sdk/schema" +) + +func (*Client) DeleteStale(ctx context.Context, tables schema.Tables, sourceName string, syncTime time.Time) error { + return fmt.Errorf("file destination doesn't support overwrite-delete-stale mode. please use append mode") +} diff --git a/plugins/destination/file/client/migrate.go b/plugins/destination/file/client/migrate.go new file mode 100644 index 00000000000..14460ebb19e --- /dev/null +++ b/plugins/destination/file/client/migrate.go @@ -0,0 +1,12 @@ +package client + +import ( + "context" + + "github.com/cloudquery/plugin-sdk/schema" +) + +func (*Client) Migrate(ctx context.Context, tables schema.Tables) error { + // migrate is not needed in migrate mode + return nil +} diff --git a/plugins/destination/file/client/read.go b/plugins/destination/file/client/read.go new file mode 100644 index 00000000000..892eead0d3c --- /dev/null +++ b/plugins/destination/file/client/read.go @@ -0,0 +1,48 @@ +package client + +import ( + "context" + "fmt" + "os" + + "github.com/cloudquery/filetypes/csv" + "github.com/cloudquery/filetypes/json" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/google/uuid" +) + +func (c *Client) ReverseTransformValues(table *schema.Table, values []any) (schema.CQTypes, error) { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvReverseTransformer.ReverseTransformValues(table, values) + case FormatTypeJSON: + return c.jsonReverseTransformer.ReverseTransformValues(table, values) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) Read(ctx context.Context, table *schema.Table, sourceName string, res chan<- []any) error { + name := fmt.Sprintf("%s/%s.%s.%s", c.pluginSpec.Directory, table.Name, c.pluginSpec.Format, uuid.NewString()) + if c.pluginSpec.NoRotate { + name = fmt.Sprintf("%s/%s.%s", c.pluginSpec.Directory, table.Name, c.pluginSpec.Format) + } + f, err := os.Open(name) + if err != nil { + return err + } + defer f.Close() + switch c.pluginSpec.Format { + case FormatTypeCSV: + if err := csv.Read(f, table, sourceName, res); err != nil { + return err + } + case FormatTypeJSON: + if err := json.Read(f, table, sourceName, res); err != nil { + return err + } + default: + panic("unknown format " + c.pluginSpec.Format) + } + return nil +} diff --git a/plugins/destination/file/client/spec.go b/plugins/destination/file/client/spec.go new file mode 100644 index 00000000000..b2542583392 --- /dev/null +++ b/plugins/destination/file/client/spec.go @@ -0,0 +1,31 @@ +package client + +import ( + "fmt" +) + +type FormatType string + +const ( + FormatTypeCSV = "csv" + FormatTypeJSON = "json" +) + +type Spec struct { + Directory string `json:"directory,omitempty"` + Format FormatType `json:"format,omitempty"` + NoRotate bool `json:"no_rotate,omitempty"` +} + +func (*Spec) SetDefaults() {} + +func (s *Spec) Validate() error { + if s.Directory == "" { + return fmt.Errorf("directory is required") + } + if s.Format == "" { + return fmt.Errorf("format is required") + } + + return nil +} diff --git a/plugins/destination/file/client/transformer.go b/plugins/destination/file/client/transformer.go new file mode 100644 index 00000000000..58ab57708a2 --- /dev/null +++ b/plugins/destination/file/client/transformer.go @@ -0,0 +1,190 @@ +package client + +import "github.com/cloudquery/plugin-sdk/schema" + +func (c *Client) TransformBool(v *schema.Bool) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformBool(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformBool(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformBytea(v *schema.Bytea) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformBytea(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformBytea(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformFloat8(v *schema.Float8) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformFloat8(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformFloat8(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformInt8(v *schema.Int8) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformInt8(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformInt8(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformInt8Array(v *schema.Int8Array) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformInt8Array(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformInt8Array(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformJSON(v *schema.JSON) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformJSON(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformJSON(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformText(v *schema.Text) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformText(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformText(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformTextArray(v *schema.TextArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformTextArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformTextArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformTimestamptz(v *schema.Timestamptz) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformTimestamptz(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformTimestamptz(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformUUID(v *schema.UUID) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformUUID(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformUUID(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformUUIDArray(v *schema.UUIDArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformUUIDArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformUUIDArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformCIDR(v *schema.CIDR) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformCIDR(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformCIDR(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformCIDRArray(v *schema.CIDRArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformCIDRArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformCIDRArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformInet(v *schema.Inet) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformInet(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformInet(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformInetArray(v *schema.InetArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformInetArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformInetArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformMacaddr(v *schema.Macaddr) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformMacaddr(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformMacaddr(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformMacaddrArray(v *schema.MacaddrArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformMacaddrArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformMacaddrArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} diff --git a/plugins/destination/file/client/write.go b/plugins/destination/file/client/write.go new file mode 100644 index 00000000000..a4829f813aa --- /dev/null +++ b/plugins/destination/file/client/write.go @@ -0,0 +1,38 @@ +package client + +import ( + "context" + "fmt" + "os" + + "github.com/cloudquery/filetypes/csv" + "github.com/cloudquery/filetypes/json" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/google/uuid" +) + +func (c *Client) WriteTableBatch(ctx context.Context, table *schema.Table, data [][]any) error { + name := fmt.Sprintf("%s/%s.%s.%s", c.pluginSpec.Directory, table.Name, c.pluginSpec.Format, uuid.NewString()) + if c.pluginSpec.NoRotate { + name = fmt.Sprintf("%s/%s.%s", c.pluginSpec.Directory, table.Name, c.pluginSpec.Format) + } + f, err := os.OpenFile(name, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return err + } + defer f.Close() + switch c.pluginSpec.Format { + case FormatTypeCSV: + if err := csv.WriteTableBatch(f, table, data); err != nil { + return err + } + case FormatTypeJSON: + if err := json.WriteTableBatch(f, table, data); err != nil { + return err + } + default: + panic("unknown format " + c.pluginSpec.Format) + } + + return nil +} diff --git a/plugins/destination/file/go.mod b/plugins/destination/file/go.mod new file mode 100644 index 00000000000..fbe1388c1ce --- /dev/null +++ b/plugins/destination/file/go.mod @@ -0,0 +1,33 @@ +module github.com/cloudquery/cloudquery/plugins/destination/file + +go 1.19 + +require ( + github.com/cloudquery/filetypes v1.0.0 + github.com/cloudquery/plugin-sdk v1.15.0 + github.com/google/uuid v1.3.0 + github.com/rs/zerolog v1.28.0 +) + +require ( + github.com/getsentry/sentry-go v0.15.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/thoas/go-funk v0.9.2 // indirect + golang.org/x/net v0.2.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.2.0 // indirect + golang.org/x/text v0.4.0 // indirect + google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e // indirect + google.golang.org/grpc v1.51.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/plugins/destination/file/go.sum b/plugins/destination/file/go.sum new file mode 100644 index 00000000000..7eccedae696 --- /dev/null +++ b/plugins/destination/file/go.sum @@ -0,0 +1,463 @@ +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/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/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= +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/avast/retry-go/v4 v4.3.1 h1:Mtg11F9PdAIMkMiio2RKcYauoVHjl2aB3zQJJlzD4cE= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +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/cloudquery/filetypes v1.0.0 h1:Jg1ays4KCwj2L2qpafvQxbSakLyKQUGuNGvgWxlgcTY= +github.com/cloudquery/filetypes v1.0.0/go.mod h1:EfkcBXPJR9+nEHWHIdG7LYx0dfG+XP+5X8ozbC6EX4s= +github.com/cloudquery/plugin-sdk v1.15.0 h1:N5gAL3YTHiaKZ1lrzbKzg+7qy8836VMATvOREQGXXXc= +github.com/cloudquery/plugin-sdk v1.15.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/getsentry/sentry-go v0.15.0 h1:CP9bmA7pralrVUedYZsmIHWpq/pBtXTSew7xvVpfLaA= +github.com/getsentry/sentry-go v0.15.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2HtRckJk9XVxJ9I= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +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= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/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/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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +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/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 h1:hRcWZ7716+E1tkMSZJ/QeeC2dPGGB1R/4z4m9RsL8Qg= +github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3/go.mod h1:54asssGY3Bohr5FRbew+bjfuQTT2WS9V7hW7gPqmcKM= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2.0.20201002093600-73cf2ae9d891/go.mod h1:GhphxcdlaRyAuBSvo6rV71BvQcvB/vuX8ugCyybuS2k= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= +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/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +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.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= +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.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= +github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/schollz/progressbar/v3 v3.12.1 h1:JAhtIrLWAn6/p7i82SrpSG3fgAwlAxi+Sy12r4AzBvQ= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/thoas/go-funk v0.9.2 h1:oKlNYv0AY5nyf9g+/GhMgS/UO2ces0QRdPKwkhY3VCk= +github.com/thoas/go-funk v0.9.2/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= +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= +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= +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/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/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= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-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-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +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-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/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-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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/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 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +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/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-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-20190828213141-aed303cbaa74/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-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/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/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-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-20200806141610-86f49bd18e98/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-20221111202108-142d8a6fa32e h1:azcyH5lGzGy7pkLCbhPe0KkKxsM7c6UA/FZIXImKE7M= +google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +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.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/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= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.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/plugins/destination/file/main.go b/plugins/destination/file/main.go new file mode 100644 index 00000000000..4d1835c0ca0 --- /dev/null +++ b/plugins/destination/file/main.go @@ -0,0 +1,17 @@ +package main + +import ( + "github.com/cloudquery/cloudquery/plugins/destination/file/client" + "github.com/cloudquery/cloudquery/plugins/destination/file/resources/plugin" + "github.com/cloudquery/plugin-sdk/plugins/destination" + "github.com/cloudquery/plugin-sdk/serve" +) + +const ( + sentryDSN = "https://1e33dfd084aa43f2aa8e686f15a64e45@o1396617.ingest.sentry.io/4504407264526336" +) + +func main() { + p := destination.NewPlugin("file", plugin.Version, client.New, destination.WithManagedWriter()) + serve.Destination(p, serve.WithDestinationSentryDSN(sentryDSN)) +} diff --git a/plugins/destination/file/resources/plugin/plugin.go b/plugins/destination/file/resources/plugin/plugin.go new file mode 100644 index 00000000000..6cdd6b07133 --- /dev/null +++ b/plugins/destination/file/resources/plugin/plugin.go @@ -0,0 +1,6 @@ +package plugin + +var ( + // Don't move this file to a different package, it's used by Go releaser to embed the version in the binary. + Version = "Development" +) diff --git a/plugins/destination/gcs/.gitignore b/plugins/destination/gcs/.gitignore new file mode 100644 index 00000000000..6ca8fec4fd7 --- /dev/null +++ b/plugins/destination/gcs/.gitignore @@ -0,0 +1 @@ +gcs \ No newline at end of file diff --git a/plugins/destination/gcs/.goreleaser.yaml b/plugins/destination/gcs/.goreleaser.yaml new file mode 100644 index 00000000000..c8ec2aaf81e --- /dev/null +++ b/plugins/destination/gcs/.goreleaser.yaml @@ -0,0 +1,14 @@ +variables: + component: destination/gcs + binary: gcs + +project_name: plugins/destination/gcs + +monorepo: + tag_prefix: plugins-destination-gcs- + dir: plugins/destination/gcs + +includes: + - from_file: + # Relative to the directory Go Releaser is run from (which is the root of the repository) + path: ./plugins/.goreleaser.yaml \ No newline at end of file diff --git a/plugins/destination/gcs/CHANGELOG.md b/plugins/destination/gcs/CHANGELOG.md new file mode 100644 index 00000000000..4dc68c6ff8e --- /dev/null +++ b/plugins/destination/gcs/CHANGELOG.md @@ -0,0 +1,2 @@ +# Changelog + diff --git a/plugins/destination/gcs/Makefile b/plugins/destination/gcs/Makefile new file mode 100644 index 00000000000..b68c1473fde --- /dev/null +++ b/plugins/destination/gcs/Makefile @@ -0,0 +1,7 @@ +.PHONY: test +test: + go test -timeout 3m ./... + +.PHONY: lint +lint: + @golangci-lint run --config ../../.golangci.yml diff --git a/plugins/destination/gcs/README.md b/plugins/destination/gcs/README.md new file mode 100644 index 00000000000..0924f905df3 --- /dev/null +++ b/plugins/destination/gcs/README.md @@ -0,0 +1,7 @@ +# CloudQuery GCS (Google Cloud Storage) Destination Plugin + +This destination plugin lets you sync data from a CloudQuery source to remote GCS (Google Cloud Storage) storage in various formats such as CSV and JSON. + +## Links + +- [User Guide](https://cloudquery.io/docs/plugins/destinations/gcs/overview) \ No newline at end of file diff --git a/plugins/destination/gcs/client/client.go b/plugins/destination/gcs/client/client.go new file mode 100644 index 00000000000..fce43fa0a1d --- /dev/null +++ b/plugins/destination/gcs/client/client.go @@ -0,0 +1,73 @@ +package client + +import ( + "context" + "fmt" + + "cloud.google.com/go/storage" + + "github.com/cloudquery/filetypes/csv" + "github.com/cloudquery/filetypes/json" + "github.com/cloudquery/plugin-sdk/plugins/destination" + "github.com/cloudquery/plugin-sdk/specs" + "github.com/google/uuid" + "github.com/rs/zerolog" +) + +type Client struct { + destination.UnimplementedUnmanagedWriter + logger zerolog.Logger + spec specs.Destination + pluginSpec Spec + + gcsClient *storage.Client + bucket *storage.BucketHandle + + csvTransformer *csv.Transformer + csvReverseTransformer *csv.ReverseTransformer + jsonTransformer *json.Transformer + jsonReverseTransformer *json.ReverseTransformer +} + +func New(ctx context.Context, logger zerolog.Logger, spec specs.Destination) (destination.Client, error) { + var err error + if spec.WriteMode != specs.WriteModeAppend { + return nil, fmt.Errorf("destination only supports append mode") + } + c := &Client{ + logger: logger.With().Str("module", "gcs").Logger(), + spec: spec, + csvTransformer: &csv.Transformer{}, + jsonTransformer: &json.Transformer{}, + csvReverseTransformer: &csv.ReverseTransformer{}, + jsonReverseTransformer: &json.ReverseTransformer{}, + } + + if err := spec.UnmarshalSpec(&c.pluginSpec); err != nil { + return nil, fmt.Errorf("failed to unmarshal postgresql spec: %w", err) + } + if err := c.pluginSpec.Validate(); err != nil { + return nil, err + } + c.pluginSpec.SetDefaults() + + c.gcsClient, err = storage.NewClient(ctx) + if err != nil { + return nil, fmt.Errorf("failed to create GCP storage client: %w", err) + } + c.bucket = c.gcsClient.Bucket(c.pluginSpec.Bucket) + // we upload it because we want to fail early if we don't have permissions + gcpWriter := c.bucket.Object("/tmp/.cq-test-file-" + uuid.NewString()).NewWriter(ctx) + if _, err := gcpWriter.Write([]byte("test-string")); err != nil { + return nil, fmt.Errorf("failed to write test file to GCS: %w", err) + } + if err := gcpWriter.Close(); err != nil { + return nil, fmt.Errorf("failed to close GCS writer: %w", err) + } + + return c, nil +} + +func (*Client) Close(ctx context.Context) error { + return nil +} diff --git a/plugins/destination/gcs/client/client_test.go b/plugins/destination/gcs/client/client_test.go new file mode 100644 index 00000000000..d7a63b1e145 --- /dev/null +++ b/plugins/destination/gcs/client/client_test.go @@ -0,0 +1,45 @@ +package client + +import ( + "testing" + + "github.com/cloudquery/plugin-sdk/plugins/destination" +) + +const bucket = "cq-dest-gcs" + +func TestPluginCSV(t *testing.T) { + p := destination.NewPlugin("gcs", "development", New, destination.WithManagedWriter()) + + destination.PluginTestSuiteRunner(t, p, + Spec{ + Bucket: bucket, + Path: t.TempDir(), + Format: FormatTypeCSV, + NoRotate: true, + }, + destination.PluginTestSuiteTests{ + SkipOverwrite: true, + SkipDeleteStale: true, + SkipSecondAppend: true, + }, + ) +} + +func TestPluginJSON(t *testing.T) { + p := destination.NewPlugin("gcs", "development", New, destination.WithManagedWriter()) + + destination.PluginTestSuiteRunner(t, p, + Spec{ + Bucket: bucket, + Path: t.TempDir(), + Format: FormatTypeJSON, + NoRotate: true, + }, + destination.PluginTestSuiteTests{ + SkipOverwrite: true, + SkipDeleteStale: true, + SkipSecondAppend: true, + }, + ) +} diff --git a/plugins/destination/gcs/client/deletestale.go b/plugins/destination/gcs/client/deletestale.go new file mode 100644 index 00000000000..a353f2c27c9 --- /dev/null +++ b/plugins/destination/gcs/client/deletestale.go @@ -0,0 +1,13 @@ +package client + +import ( + "context" + "fmt" + "time" + + "github.com/cloudquery/plugin-sdk/schema" +) + +func (*Client) DeleteStale(ctx context.Context, tables schema.Tables, sourceName string, syncTime time.Time) error { + return fmt.Errorf("destination plugin doesn't support overwrite-delete-stale mode. please use append mode") +} diff --git a/plugins/destination/gcs/client/migrate.go b/plugins/destination/gcs/client/migrate.go new file mode 100644 index 00000000000..14460ebb19e --- /dev/null +++ b/plugins/destination/gcs/client/migrate.go @@ -0,0 +1,12 @@ +package client + +import ( + "context" + + "github.com/cloudquery/plugin-sdk/schema" +) + +func (*Client) Migrate(ctx context.Context, tables schema.Tables) error { + // migrate is not needed in migrate mode + return nil +} diff --git a/plugins/destination/gcs/client/read.go b/plugins/destination/gcs/client/read.go new file mode 100644 index 00000000000..cc4113c653e --- /dev/null +++ b/plugins/destination/gcs/client/read.go @@ -0,0 +1,48 @@ +package client + +import ( + "context" + "fmt" + + "github.com/cloudquery/filetypes/csv" + "github.com/cloudquery/filetypes/json" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/google/uuid" +) + +func (c *Client) ReverseTransformValues(table *schema.Table, values []any) (schema.CQTypes, error) { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvReverseTransformer.ReverseTransformValues(table, values) + case FormatTypeJSON: + return c.jsonReverseTransformer.ReverseTransformValues(table, values) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) Read(ctx context.Context, table *schema.Table, sourceName string, res chan<- []any) error { + name := fmt.Sprintf("%s/%s.%s.%s", c.pluginSpec.Path, table.Name, c.pluginSpec.Format, uuid.NewString()) + if c.pluginSpec.NoRotate { + name = fmt.Sprintf("%s/%s.%s", c.pluginSpec.Path, table.Name, c.pluginSpec.Format) + } + r, err := c.bucket.Object(name).NewReader(ctx) + if err != nil { + return err + } + defer r.Close() + + switch c.pluginSpec.Format { + case FormatTypeCSV: + if err := csv.Read(r, table, sourceName, res); err != nil { + return err + } + case FormatTypeJSON: + if err := json.Read(r, table, sourceName, res); err != nil { + return err + } + default: + panic("unknown format " + c.pluginSpec.Format) + } + return nil +} diff --git a/plugins/destination/gcs/client/spec.go b/plugins/destination/gcs/client/spec.go new file mode 100644 index 00000000000..40058ed95e1 --- /dev/null +++ b/plugins/destination/gcs/client/spec.go @@ -0,0 +1,35 @@ +package client + +import ( + "fmt" +) + +type FormatType string + +const ( + FormatTypeCSV = "csv" + FormatTypeJSON = "json" +) + +type Spec struct { + Bucket string `json:"bucket,omitempty"` + Path string `json:"path,omitempty"` + Format FormatType `json:"format,omitempty"` + NoRotate bool `json:"no_rotate,omitempty"` +} + +func (*Spec) SetDefaults() {} + +func (s *Spec) Validate() error { + if s.Bucket == "" { + return fmt.Errorf("bucket is required") + } + if s.Path == "" { + return fmt.Errorf("path is required") + } + if s.Format == "" { + return fmt.Errorf("format is required") + } + + return nil +} diff --git a/plugins/destination/gcs/client/transformer.go b/plugins/destination/gcs/client/transformer.go new file mode 100644 index 00000000000..58ab57708a2 --- /dev/null +++ b/plugins/destination/gcs/client/transformer.go @@ -0,0 +1,190 @@ +package client + +import "github.com/cloudquery/plugin-sdk/schema" + +func (c *Client) TransformBool(v *schema.Bool) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformBool(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformBool(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformBytea(v *schema.Bytea) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformBytea(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformBytea(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformFloat8(v *schema.Float8) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformFloat8(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformFloat8(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformInt8(v *schema.Int8) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformInt8(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformInt8(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformInt8Array(v *schema.Int8Array) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformInt8Array(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformInt8Array(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformJSON(v *schema.JSON) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformJSON(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformJSON(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformText(v *schema.Text) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformText(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformText(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformTextArray(v *schema.TextArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformTextArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformTextArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformTimestamptz(v *schema.Timestamptz) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformTimestamptz(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformTimestamptz(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformUUID(v *schema.UUID) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformUUID(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformUUID(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformUUIDArray(v *schema.UUIDArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformUUIDArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformUUIDArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformCIDR(v *schema.CIDR) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformCIDR(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformCIDR(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformCIDRArray(v *schema.CIDRArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformCIDRArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformCIDRArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformInet(v *schema.Inet) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformInet(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformInet(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformInetArray(v *schema.InetArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformInetArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformInetArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformMacaddr(v *schema.Macaddr) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformMacaddr(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformMacaddr(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} + +func (c *Client) TransformMacaddrArray(v *schema.MacaddrArray) any { + switch c.pluginSpec.Format { + case FormatTypeCSV: + return c.csvTransformer.TransformMacaddrArray(v) + case FormatTypeJSON: + return c.jsonTransformer.TransformMacaddrArray(v) + default: + panic("unknown format " + c.pluginSpec.Format) + } +} diff --git a/plugins/destination/gcs/client/write.go b/plugins/destination/gcs/client/write.go new file mode 100644 index 00000000000..7c87f6cbc9b --- /dev/null +++ b/plugins/destination/gcs/client/write.go @@ -0,0 +1,34 @@ +package client + +import ( + "context" + "fmt" + + "github.com/cloudquery/filetypes/csv" + "github.com/cloudquery/filetypes/json" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/google/uuid" +) + +func (c *Client) WriteTableBatch(ctx context.Context, table *schema.Table, data [][]any) error { + name := fmt.Sprintf("%s/%s.%s.%s", c.pluginSpec.Path, table.Name, c.pluginSpec.Format, uuid.NewString()) + if c.pluginSpec.NoRotate { + name = fmt.Sprintf("%s/%s.%s", c.pluginSpec.Path, table.Name, c.pluginSpec.Format) + } + w := c.gcsClient.Bucket(c.pluginSpec.Bucket).Object(name).NewWriter(ctx) + defer w.Close() + switch c.pluginSpec.Format { + case FormatTypeCSV: + if err := csv.WriteTableBatch(w, table, data); err != nil { + return err + } + case FormatTypeJSON: + if err := json.WriteTableBatch(w, table, data); err != nil { + return err + } + default: + panic("unknown format " + c.pluginSpec.Format) + } + + return nil +} diff --git a/plugins/destination/gcs/go.mod b/plugins/destination/gcs/go.mod new file mode 100644 index 00000000000..e67c844b367 --- /dev/null +++ b/plugins/destination/gcs/go.mod @@ -0,0 +1,47 @@ +module github.com/cloudquery/cloudquery/plugins/destination/gcs + +go 1.19 + +require ( + cloud.google.com/go/storage v1.27.0 + github.com/cloudquery/filetypes v1.0.0 + github.com/cloudquery/plugin-sdk v1.15.0 + github.com/google/uuid v1.3.0 + github.com/rs/zerolog v1.28.0 +) + +require ( + cloud.google.com/go v0.105.0 // indirect + cloud.google.com/go/compute v1.12.1 // indirect + cloud.google.com/go/compute/metadata v0.2.1 // indirect + cloud.google.com/go/iam v0.7.0 // indirect + github.com/getsentry/sentry-go v0.15.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.6.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/thoas/go-funk v0.9.2 // indirect + go.opencensus.io v0.23.0 // indirect + golang.org/x/net v0.2.0 // indirect + golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.2.0 // indirect + golang.org/x/text v0.4.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.102.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e // indirect + google.golang.org/grpc v1.51.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/plugins/destination/gcs/go.sum b/plugins/destination/gcs/go.sum new file mode 100644 index 00000000000..b844be20717 --- /dev/null +++ b/plugins/destination/gcs/go.sum @@ -0,0 +1,498 @@ +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.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +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.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +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/iam v0.7.0 h1:k4MuwOsS7zGJJ+QfZ5vBK8SgHBAvYN/23BWsiihJ1vs= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +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= +cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +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/avast/retry-go/v4 v4.3.1 h1:Mtg11F9PdAIMkMiio2RKcYauoVHjl2aB3zQJJlzD4cE= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +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/cloudquery/filetypes v1.0.0 h1:Jg1ays4KCwj2L2qpafvQxbSakLyKQUGuNGvgWxlgcTY= +github.com/cloudquery/filetypes v1.0.0/go.mod h1:EfkcBXPJR9+nEHWHIdG7LYx0dfG+XP+5X8ozbC6EX4s= +github.com/cloudquery/plugin-sdk v1.15.0 h1:N5gAL3YTHiaKZ1lrzbKzg+7qy8836VMATvOREQGXXXc= +github.com/cloudquery/plugin-sdk v1.15.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/getsentry/sentry-go v0.15.0 h1:CP9bmA7pralrVUedYZsmIHWpq/pBtXTSew7xvVpfLaA= +github.com/getsentry/sentry-go v0.15.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2HtRckJk9XVxJ9I= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +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 h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +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= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.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/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.3/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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= +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/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 h1:hRcWZ7716+E1tkMSZJ/QeeC2dPGGB1R/4z4m9RsL8Qg= +github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3/go.mod h1:54asssGY3Bohr5FRbew+bjfuQTT2WS9V7hW7gPqmcKM= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2.0.20201002093600-73cf2ae9d891/go.mod h1:GhphxcdlaRyAuBSvo6rV71BvQcvB/vuX8ugCyybuS2k= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= +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/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +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.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= +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.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= +github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/schollz/progressbar/v3 v3.12.1 h1:JAhtIrLWAn6/p7i82SrpSG3fgAwlAxi+Sy12r4AzBvQ= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +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.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/thoas/go-funk v0.9.2 h1:oKlNYv0AY5nyf9g+/GhMgS/UO2ces0QRdPKwkhY3VCk= +github.com/thoas/go-funk v0.9.2/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= +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= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +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/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/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= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +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-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +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.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/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-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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/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 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +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/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-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-20190828213141-aed303cbaa74/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-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/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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +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/api v0.102.0 h1:JxJl2qQ85fRMPNvlZY/enexbxpCjLwGhZUtgfGeQ51I= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +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/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-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-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-20200806141610-86f49bd18e98/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-20221111202108-142d8a6fa32e h1:azcyH5lGzGy7pkLCbhPe0KkKxsM7c6UA/FZIXImKE7M= +google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +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.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/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= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.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/plugins/destination/gcs/main.go b/plugins/destination/gcs/main.go new file mode 100644 index 00000000000..8a58ba4d9c9 --- /dev/null +++ b/plugins/destination/gcs/main.go @@ -0,0 +1,17 @@ +package main + +import ( + "github.com/cloudquery/cloudquery/plugins/destination/gcs/client" + "github.com/cloudquery/cloudquery/plugins/destination/gcs/resources/plugin" + "github.com/cloudquery/plugin-sdk/plugins/destination" + "github.com/cloudquery/plugin-sdk/serve" +) + +const ( + sentryDSN = "https://c808d26943414033b2fb8bb5b5822ab9@o1396617.ingest.sentry.io/4504407917592576" +) + +func main() { + p := destination.NewPlugin("gcs", plugin.Version, client.New, destination.WithManagedWriter()) + serve.Destination(p, serve.WithDestinationSentryDSN(sentryDSN)) +} diff --git a/plugins/destination/gcs/resources/plugin/plugin.go b/plugins/destination/gcs/resources/plugin/plugin.go new file mode 100644 index 00000000000..6cdd6b07133 --- /dev/null +++ b/plugins/destination/gcs/resources/plugin/plugin.go @@ -0,0 +1,6 @@ +package plugin + +var ( + // Don't move this file to a different package, it's used by Go releaser to embed the version in the binary. + Version = "Development" +) diff --git a/plugins/destination/mongodb/CHANGELOG.md b/plugins/destination/mongodb/CHANGELOG.md index bbab8953ffb..d7d726c708a 100644 --- a/plugins/destination/mongodb/CHANGELOG.md +++ b/plugins/destination/mongodb/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [1.0.2](https://github.com/cloudquery/cloudquery/compare/plugins-destination-mongodb-v1.0.1...plugins-destination-mongodb-v1.0.2) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.0 ([#6071](https://github.com/cloudquery/cloudquery/issues/6071)) ([684b525](https://github.com/cloudquery/cloudquery/commit/684b525aaa285fcae70dd87af56679c1205adebe)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.1 ([#6079](https://github.com/cloudquery/cloudquery/issues/6079)) ([650659c](https://github.com/cloudquery/cloudquery/commit/650659c3c6766df571868e2ec3a2007cb76696eb)) + +## [1.0.1](https://github.com/cloudquery/cloudquery/compare/plugins-destination-mongodb-v1.0.0...plugins-destination-mongodb-v1.0.1) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.14.0 ([#6025](https://github.com/cloudquery/cloudquery/issues/6025)) ([35b2cfc](https://github.com/cloudquery/cloudquery/commit/35b2cfc7fc7bcdaceb7ee674e3a17f0f5673b366)) + ## 1.0.0 (2022-12-23) diff --git a/plugins/destination/mongodb/go.mod b/plugins/destination/mongodb/go.mod index 6794babb03d..334d4a2abb3 100644 --- a/plugins/destination/mongodb/go.mod +++ b/plugins/destination/mongodb/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/destination/mongodb go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/rs/zerolog v1.28.0 go.mongodb.org/mongo-driver v1.11.1 ) diff --git a/plugins/destination/mongodb/go.sum b/plugins/destination/mongodb/go.sum index 217207dc846..200e71a1de1 100644 --- a/plugins/destination/mongodb/go.sum +++ b/plugins/destination/mongodb/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/destination/postgresql/CHANGELOG.md b/plugins/destination/postgresql/CHANGELOG.md index f3b15aa9238..b42ff58118c 100644 --- a/plugins/destination/postgresql/CHANGELOG.md +++ b/plugins/destination/postgresql/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## [2.0.0](https://github.com/cloudquery/cloudquery/compare/plugins-destination-postgresql-v1.10.2...plugins-destination-postgresql-v2.0.0) (2022-12-29) + + +### ⚠ BREAKING CHANGES + +* **postgres-spec:** Move `batch_size` from the plugin spec to the top level spec ([#6091](https://github.com/cloudquery/cloudquery/issues/6091)) + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.16.0 ([#6098](https://github.com/cloudquery/cloudquery/issues/6098)) ([7bacdf3](https://github.com/cloudquery/cloudquery/commit/7bacdf3364716eab08fa1a84ae4047b42edeee7e)) +* **postgres-spec:** Move `batch_size` from the plugin spec to the top level spec ([#6091](https://github.com/cloudquery/cloudquery/issues/6091)) ([c504423](https://github.com/cloudquery/cloudquery/commit/c50442397e3e0ded68940f0d3121d00eae22d912)) + +## [1.10.2](https://github.com/cloudquery/cloudquery/compare/plugins-destination-postgresql-v1.10.1...plugins-destination-postgresql-v1.10.2) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.0 ([#6071](https://github.com/cloudquery/cloudquery/issues/6071)) ([684b525](https://github.com/cloudquery/cloudquery/commit/684b525aaa285fcae70dd87af56679c1205adebe)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.1 ([#6079](https://github.com/cloudquery/cloudquery/issues/6079)) ([650659c](https://github.com/cloudquery/cloudquery/commit/650659c3c6766df571868e2ec3a2007cb76696eb)) + +## [1.10.1](https://github.com/cloudquery/cloudquery/compare/plugins-destination-postgresql-v1.10.0...plugins-destination-postgresql-v1.10.1) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.14.0 ([#6025](https://github.com/cloudquery/cloudquery/issues/6025)) ([35b2cfc](https://github.com/cloudquery/cloudquery/commit/35b2cfc7fc7bcdaceb7ee674e3a17f0f5673b366)) + ## [1.10.0](https://github.com/cloudquery/cloudquery/compare/plugins-destination-postgresql-v1.9.0...plugins-destination-postgresql-v1.10.0) (2022-12-23) diff --git a/plugins/destination/postgresql/client/client.go b/plugins/destination/postgresql/client/client.go index d5c912fa5a1..90412e646bc 100644 --- a/plugins/destination/postgresql/client/client.go +++ b/plugins/destination/postgresql/client/client.go @@ -74,7 +74,7 @@ func New(ctx context.Context, logger zerolog.Logger, spec specs.Destination) (de return nil, fmt.Errorf("failed to unmarshal postgresql spec: %w", err) } specPostgreSql.SetDefaults() - c.batchSize = specPostgreSql.BatchSize + c.batchSize = spec.BatchSize logLevel, err := tracelog.LogLevelFromString(specPostgreSql.PgxLogLevel.String()) if err != nil { return nil, fmt.Errorf("failed to parse pgx log level %s: %w", specPostgreSql.PgxLogLevel, err) diff --git a/plugins/destination/postgresql/client/spec.go b/plugins/destination/postgresql/client/spec.go index a00a5d7fcfd..d09db10edb3 100644 --- a/plugins/destination/postgresql/client/spec.go +++ b/plugins/destination/postgresql/client/spec.go @@ -3,13 +3,7 @@ package client type Spec struct { ConnectionString string `json:"connection_string,omitempty"` PgxLogLevel LogLevel `json:"pgx_log_level,omitempty"` - BatchSize int `json:"batch_size,omitempty"` } -const defaultBatchSize = 1000 - -func (s *Spec) SetDefaults() { - if s.BatchSize <= 0 { - s.BatchSize = defaultBatchSize - } +func (*Spec) SetDefaults() { } diff --git a/plugins/destination/postgresql/go.mod b/plugins/destination/postgresql/go.mod index 0a8fff62df1..116cbc8b156 100644 --- a/plugins/destination/postgresql/go.mod +++ b/plugins/destination/postgresql/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/destination/postgresql go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/jackc/pgx-zerolog v0.0.0-20220923130014-7856b90a65ae github.com/jackc/pgx/v5 v5.2.0 github.com/rs/zerolog v1.28.0 diff --git a/plugins/destination/postgresql/go.sum b/plugins/destination/postgresql/go.sum index 389f5e2e61e..3e4b40cab21 100644 --- a/plugins/destination/postgresql/go.sum +++ b/plugins/destination/postgresql/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/destination/postgresql/main.go b/plugins/destination/postgresql/main.go index ebce7619926..f3a86983ec0 100644 --- a/plugins/destination/postgresql/main.go +++ b/plugins/destination/postgresql/main.go @@ -12,6 +12,6 @@ const ( ) func main() { - p := destination.NewPlugin("postgresql", plugin.Version, client.New) + p := destination.NewPlugin("postgresql", plugin.Version, client.New, destination.WithDefaultBatchSize(1000)) serve.Destination(p, serve.WithDestinationSentryDSN(sentryDSN)) } diff --git a/plugins/destination/snowflake/CHANGELOG.md b/plugins/destination/snowflake/CHANGELOG.md index 3dcb1f6b7a8..fd28961fa7c 100644 --- a/plugins/destination/snowflake/CHANGELOG.md +++ b/plugins/destination/snowflake/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [1.1.2](https://github.com/cloudquery/cloudquery/compare/plugins-destination-snowflake-v1.1.1...plugins-destination-snowflake-v1.1.2) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.0 ([#6071](https://github.com/cloudquery/cloudquery/issues/6071)) ([684b525](https://github.com/cloudquery/cloudquery/commit/684b525aaa285fcae70dd87af56679c1205adebe)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.1 ([#6079](https://github.com/cloudquery/cloudquery/issues/6079)) ([650659c](https://github.com/cloudquery/cloudquery/commit/650659c3c6766df571868e2ec3a2007cb76696eb)) + +## [1.1.1](https://github.com/cloudquery/cloudquery/compare/plugins-destination-snowflake-v1.1.0...plugins-destination-snowflake-v1.1.1) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.14.0 ([#6025](https://github.com/cloudquery/cloudquery/issues/6025)) ([35b2cfc](https://github.com/cloudquery/cloudquery/commit/35b2cfc7fc7bcdaceb7ee674e3a17f0f5673b366)) + ## [1.1.0](https://github.com/cloudquery/cloudquery/compare/plugins-destination-snowflake-v1.0.7...plugins-destination-snowflake-v1.1.0) (2022-12-23) diff --git a/plugins/destination/snowflake/go.mod b/plugins/destination/snowflake/go.mod index f84101d6469..856d228b810 100644 --- a/plugins/destination/snowflake/go.mod +++ b/plugins/destination/snowflake/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/destination/snowflake go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/rs/zerolog v1.28.0 github.com/snowflakedb/gosnowflake v1.6.15 ) diff --git a/plugins/destination/snowflake/go.sum b/plugins/destination/snowflake/go.sum index 165e4e39190..64b9b6d0a43 100644 --- a/plugins/destination/snowflake/go.sum +++ b/plugins/destination/snowflake/go.sum @@ -103,8 +103,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= diff --git a/plugins/destination/sqlite/CHANGELOG.md b/plugins/destination/sqlite/CHANGELOG.md index 2cdc0355773..eef877623f6 100644 --- a/plugins/destination/sqlite/CHANGELOG.md +++ b/plugins/destination/sqlite/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [1.1.2](https://github.com/cloudquery/cloudquery/compare/plugins-destination-sqlite-v1.1.1...plugins-destination-sqlite-v1.1.2) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.0 ([#6071](https://github.com/cloudquery/cloudquery/issues/6071)) ([684b525](https://github.com/cloudquery/cloudquery/commit/684b525aaa285fcae70dd87af56679c1205adebe)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.1 ([#6079](https://github.com/cloudquery/cloudquery/issues/6079)) ([650659c](https://github.com/cloudquery/cloudquery/commit/650659c3c6766df571868e2ec3a2007cb76696eb)) + +## [1.1.1](https://github.com/cloudquery/cloudquery/compare/plugins-destination-sqlite-v1.1.0...plugins-destination-sqlite-v1.1.1) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.14.0 ([#6025](https://github.com/cloudquery/cloudquery/issues/6025)) ([35b2cfc](https://github.com/cloudquery/cloudquery/commit/35b2cfc7fc7bcdaceb7ee674e3a17f0f5673b366)) + ## [1.1.0](https://github.com/cloudquery/cloudquery/compare/plugins-destination-sqlite-v1.0.14...plugins-destination-sqlite-v1.1.0) (2022-12-23) diff --git a/plugins/destination/sqlite/go.mod b/plugins/destination/sqlite/go.mod index 15a91c318ae..7a73ea16819 100644 --- a/plugins/destination/sqlite/go.mod +++ b/plugins/destination/sqlite/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/destination/sqlite go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/mattn/go-sqlite3 v1.14.16 github.com/rs/zerolog v1.28.0 ) diff --git a/plugins/destination/sqlite/go.sum b/plugins/destination/sqlite/go.sum index cb721dfe5b5..9e83b8daac0 100644 --- a/plugins/destination/sqlite/go.sum +++ b/plugins/destination/sqlite/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/destination/test/CHANGELOG.md b/plugins/destination/test/CHANGELOG.md index ce2ae3a297d..12f4e95ed21 100644 --- a/plugins/destination/test/CHANGELOG.md +++ b/plugins/destination/test/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## [1.3.11](https://github.com/cloudquery/cloudquery/compare/plugins-destination-test-v1.3.10...plugins-destination-test-v1.3.11) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.0 ([#6071](https://github.com/cloudquery/cloudquery/issues/6071)) ([684b525](https://github.com/cloudquery/cloudquery/commit/684b525aaa285fcae70dd87af56679c1205adebe)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.15.1 ([#6079](https://github.com/cloudquery/cloudquery/issues/6079)) ([650659c](https://github.com/cloudquery/cloudquery/commit/650659c3c6766df571868e2ec3a2007cb76696eb)) + +## [1.3.10](https://github.com/cloudquery/cloudquery/compare/plugins-destination-test-v1.3.9...plugins-destination-test-v1.3.10) (2022-12-28) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.14.0 ([#6025](https://github.com/cloudquery/cloudquery/issues/6025)) ([35b2cfc](https://github.com/cloudquery/cloudquery/commit/35b2cfc7fc7bcdaceb7ee674e3a17f0f5673b366)) + +## [1.3.9](https://github.com/cloudquery/cloudquery/compare/plugins-destination-test-v1.3.8...plugins-destination-test-v1.3.9) (2022-12-27) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.13.1 ([#5897](https://github.com/cloudquery/cloudquery/issues/5897)) ([ad15915](https://github.com/cloudquery/cloudquery/commit/ad15915f2951a75729859f6f1377ed789f8ba115)) + ## [1.3.8](https://github.com/cloudquery/cloudquery/compare/plugins-destination-test-v1.3.7...plugins-destination-test-v1.3.8) (2022-12-20) diff --git a/plugins/destination/test/go.mod b/plugins/destination/test/go.mod index fea9814dd93..6a78aba28a7 100644 --- a/plugins/destination/test/go.mod +++ b/plugins/destination/test/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/destination/test go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/rs/zerolog v1.28.0 ) diff --git a/plugins/destination/test/go.sum b/plugins/destination/test/go.sum index 753fe7cdf2d..541e836f71c 100644 --- a/plugins/destination/test/go.sum +++ b/plugins/destination/test/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/aws/CHANGELOG.md b/plugins/source/aws/CHANGELOG.md index 5e9f0e3bc82..da064e35087 100644 --- a/plugins/source/aws/CHANGELOG.md +++ b/plugins/source/aws/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [9.0.1](https://github.com/cloudquery/cloudquery/compare/plugins-source-aws-v9.0.0...plugins-source-aws-v9.0.1) (2022-12-27) + + +### Bug Fixes + +* **aws_ses_active_receipt_rule_sets:** Don't call DescribeActiveReceiptRuleSet on unsupported regions ([#5997](https://github.com/cloudquery/cloudquery/issues/5997)) ([6a63147](https://github.com/cloudquery/cloudquery/commit/6a631478014ee6cf2d21f3426fe903715e67e3c0)) +* **aws_ses_active_receipt_rule_sets:** Don't sync empty return values from DescribeActiveReceiptRuleSet ([#5992](https://github.com/cloudquery/cloudquery/issues/5992)) ([5837069](https://github.com/cloudquery/cloudquery/commit/58370697f69f10b3ada7c50b5dd6b5ce28cf0f91)) + ## [9.0.0](https://github.com/cloudquery/cloudquery/compare/plugins-source-aws-v8.1.0...plugins-source-aws-v9.0.0) (2022-12-27) diff --git a/plugins/source/aws/codegen/recipes/route53.go b/plugins/source/aws/codegen/recipes/route53.go index dfb6fe35482..fd4768c2dc9 100644 --- a/plugins/source/aws/codegen/recipes/route53.go +++ b/plugins/source/aws/codegen/recipes/route53.go @@ -55,6 +55,10 @@ func Route53Resources() []*Resource { Type: schema.TypeJSON, Resolver: `resolveRoute53DomainTags`, }, + { + Name: "transfer_lock", + Type: schema.TypeBool, + }, }, }, diff --git a/plugins/source/aws/docs/tables/aws_elasticache_clusters.md b/plugins/source/aws/docs/tables/aws_elasticache_clusters.md index 482dcce52dc..4a9de885830 100644 --- a/plugins/source/aws/docs/tables/aws_elasticache_clusters.md +++ b/plugins/source/aws/docs/tables/aws_elasticache_clusters.md @@ -46,4 +46,5 @@ The primary key for this table is **arn**. |security_groups|JSON| |snapshot_retention_limit|Int| |snapshot_window|String| -|transit_encryption_enabled|Bool| \ No newline at end of file +|transit_encryption_enabled|Bool| +|transit_encryption_mode|String| \ No newline at end of file diff --git a/plugins/source/aws/docs/tables/aws_elasticache_replication_groups.md b/plugins/source/aws/docs/tables/aws_elasticache_replication_groups.md index 3817b2f6abd..5a33cba322a 100644 --- a/plugins/source/aws/docs/tables/aws_elasticache_replication_groups.md +++ b/plugins/source/aws/docs/tables/aws_elasticache_replication_groups.md @@ -42,4 +42,5 @@ The primary key for this table is **arn**. |snapshotting_cluster_id|String| |status|String| |transit_encryption_enabled|Bool| +|transit_encryption_mode|String| |user_group_ids|StringArray| \ No newline at end of file diff --git a/plugins/source/aws/docs/tables/aws_rds_engine_versions.md b/plugins/source/aws/docs/tables/aws_rds_engine_versions.md index 4a23cf9a8b5..97466fac7fa 100644 --- a/plugins/source/aws/docs/tables/aws_rds_engine_versions.md +++ b/plugins/source/aws/docs/tables/aws_rds_engine_versions.md @@ -24,6 +24,7 @@ The following tables depend on aws_rds_engine_versions: |create_time|Timestamp| |custom_db_engine_version_manifest|String| |db_engine_description|String| +|db_engine_media_type|String| |db_engine_version_arn|String| |db_engine_version_description|String| |db_parameter_group_family|String| @@ -31,6 +32,7 @@ The following tables depend on aws_rds_engine_versions: |database_installation_files_s3_prefix|String| |default_character_set|JSON| |exportable_log_types|StringArray| +|image|JSON| |kms_key_id|String| |major_engine_version|String| |status|String| diff --git a/plugins/source/aws/docs/tables/aws_route53_domains.md b/plugins/source/aws/docs/tables/aws_route53_domains.md index 8d16286e36a..02efe7f72bd 100644 --- a/plugins/source/aws/docs/tables/aws_route53_domains.md +++ b/plugins/source/aws/docs/tables/aws_route53_domains.md @@ -13,6 +13,7 @@ The composite primary key for this table is (**account_id**, **domain_name**). |account_id (PK)|String| |domain_name (PK)|String| |tags|JSON| +|transfer_lock|Bool| |abuse_contact_email|String| |abuse_contact_phone|String| |admin_contact|JSON| diff --git a/plugins/source/aws/go.mod b/plugins/source/aws/go.mod index 07d6922d279..4b912e136df 100644 --- a/plugins/source/aws/go.mod +++ b/plugins/source/aws/go.mod @@ -40,7 +40,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/ecs v1.22.0 github.com/aws/aws-sdk-go-v2/service/efs v1.18.3 github.com/aws/aws-sdk-go-v2/service/eks v1.26.0 - github.com/aws/aws-sdk-go-v2/service/elasticache v1.24.3 + github.com/aws/aws-sdk-go-v2/service/elasticache v1.25.0 github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.14.22 github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.14.25 github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.18.28 @@ -70,7 +70,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/qldb v1.14.22 github.com/aws/aws-sdk-go-v2/service/quicksight v1.28.3 github.com/aws/aws-sdk-go-v2/service/ram v1.16.26 - github.com/aws/aws-sdk-go-v2/service/rds v1.37.0 + github.com/aws/aws-sdk-go-v2/service/rds v1.38.0 github.com/aws/aws-sdk-go-v2/service/redshift v1.26.18 github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.12.23 github.com/aws/aws-sdk-go-v2/service/route53 v1.25.2 @@ -98,7 +98,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/xray v1.15.3 github.com/aws/smithy-go v1.13.5 github.com/basgys/goxml2json v1.1.0 - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/gocarina/gocsv v0.0.0-20221105105431-c8ef78125b99 github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.5.9 @@ -139,7 +139,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.21 // indirect github.com/aws/aws-sdk-go-v2/service/shield v1.17.13 github.com/aws/aws-sdk-go-v2/service/sso v1.11.28 // indirect - github.com/aws/aws-sdk-go-v2/service/transfer v1.26.0 + github.com/aws/aws-sdk-go-v2/service/transfer v1.27.0 github.com/aws/aws-sdk-go-v2/service/wafregional v1.12.22 github.com/davecgh/go-spew v1.1.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect diff --git a/plugins/source/aws/go.sum b/plugins/source/aws/go.sum index dbcc84888c0..d81cec2ff57 100644 --- a/plugins/source/aws/go.sum +++ b/plugins/source/aws/go.sum @@ -124,8 +124,8 @@ github.com/aws/aws-sdk-go-v2/service/efs v1.18.3 h1:V+qYxQTQObQAegchEMXSP2XXEe3u github.com/aws/aws-sdk-go-v2/service/efs v1.18.3/go.mod h1:5MfwGfNzP7d86CrJKNCk7jawZLgBzO4N+X1q/4eYNN8= github.com/aws/aws-sdk-go-v2/service/eks v1.26.0 h1:YgH4p2ZmNkpsEWOB1xcd4ncvD+JACPhYy7o5EydX0m4= github.com/aws/aws-sdk-go-v2/service/eks v1.26.0/go.mod h1:H/748RFDDxPmaxe03lhX0ufIQHIO2ctqjTfxuX4N7Vg= -github.com/aws/aws-sdk-go-v2/service/elasticache v1.24.3 h1:WOyHP1f5tMqTyrE6bySyxxfVkw7Nyc7ft4MUrQ4R5A8= -github.com/aws/aws-sdk-go-v2/service/elasticache v1.24.3/go.mod h1:gnN6CtMag9be9XGXsMenh084NcSy5pO0hriEYz/TERk= +github.com/aws/aws-sdk-go-v2/service/elasticache v1.25.0 h1:P3YfmNXT2nWjmduq/alZAy/G+BSX/6Kk2G4gS+v8pKk= +github.com/aws/aws-sdk-go-v2/service/elasticache v1.25.0/go.mod h1:gnN6CtMag9be9XGXsMenh084NcSy5pO0hriEYz/TERk= github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.14.22 h1:3PuyV/di5W2n98OZYBUXmEhmytGaoGCU4Qd3K9gQbMk= github.com/aws/aws-sdk-go-v2/service/elasticbeanstalk v1.14.22/go.mod h1:txSsTeuqHfPwicYkpg3PoOXFOpERUL5colZaCaaa8D0= github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.14.25 h1:Iy28SRz2KfiGFtlj/HmLM5QPE+8K9I3bQPFx8Fo59OI= @@ -196,8 +196,8 @@ github.com/aws/aws-sdk-go-v2/service/quicksight v1.28.3 h1:oOITThfr01t8r/v/RzRuH github.com/aws/aws-sdk-go-v2/service/quicksight v1.28.3/go.mod h1:wvJpr20R/imRPZsRJMkxCYV5zquGzJbASqARtCbiKKE= github.com/aws/aws-sdk-go-v2/service/ram v1.16.26 h1:N6sleYzj/LBqeTk53KPGA6+chMQj5m4txIavGZtPmtQ= github.com/aws/aws-sdk-go-v2/service/ram v1.16.26/go.mod h1:hKHJTTpBpOG9+TPPnRjsvXsPytZFmXX0FRDEMiBOcek= -github.com/aws/aws-sdk-go-v2/service/rds v1.37.0 h1:8L3wxX9Iu+Cje65Dc8PNC/bS/PEyhOxdyiVzcOoHMl0= -github.com/aws/aws-sdk-go-v2/service/rds v1.37.0/go.mod h1:Ume9NHqT871hUdxIRojWtWsPFyCswQmSjHHhyGot7v0= +github.com/aws/aws-sdk-go-v2/service/rds v1.38.0 h1:4LyiHO7LPBNQmP8QbK4pa/9wgjpaI16Z4PGZVNJhKTA= +github.com/aws/aws-sdk-go-v2/service/rds v1.38.0/go.mod h1:Ume9NHqT871hUdxIRojWtWsPFyCswQmSjHHhyGot7v0= github.com/aws/aws-sdk-go-v2/service/redshift v1.26.18 h1:a/DqQAS4PqbnEgZj/BDIkc3c31jY3w+M+5/RuSXYKNk= github.com/aws/aws-sdk-go-v2/service/redshift v1.26.18/go.mod h1:cpzzZf+cK9kF7PAbJOU491GGQO/8+oD4jtbawDUG+pc= github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.12.23 h1:DcD2mZOpFmo3HOd4LaXcDuOzPcCYEhumLMSrde/tgFM= @@ -246,8 +246,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.17.7 h1:9Mtq1KM6nD8/+HStvWcvYnixJ5N8 github.com/aws/aws-sdk-go-v2/service/sts v1.17.7/go.mod h1:+lGbb3+1ugwKrNTWcf2RT05Xmp543B06zDFTwiTLp7I= github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.14.8 h1:1FPvcg1m3K7bip7WLscELLF4RKZR0Ys1iUbomhtDYJY= github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.14.8/go.mod h1:CrQFb3Pn8vnj3GDpjKlv9ANunOJx75Km6JkP6pxc2b8= -github.com/aws/aws-sdk-go-v2/service/transfer v1.26.0 h1:hSb2cnr72Fx9hvEan2v1fuZ4VjFOPPXsMZgASZVIXaw= -github.com/aws/aws-sdk-go-v2/service/transfer v1.26.0/go.mod h1:/Sg7CaZ5ua+MkOUGhg0yeVIgnpKc+/ehJcoik7Yikl8= +github.com/aws/aws-sdk-go-v2/service/transfer v1.27.0 h1:E8EpFslyukXM9gQAmmiJC8lvlGWbzPmzZv69FLv9UBg= +github.com/aws/aws-sdk-go-v2/service/transfer v1.27.0/go.mod h1:/Sg7CaZ5ua+MkOUGhg0yeVIgnpKc+/ehJcoik7Yikl8= github.com/aws/aws-sdk-go-v2/service/waf v1.11.21 h1:4g4cMwemkVh0kjgMbg4DLqYBprwzmVh7qI7bmljCcz0= github.com/aws/aws-sdk-go-v2/service/waf v1.11.21/go.mod h1:7/L+ejelv5nOhsD/4pbaVl6jAtCgtYwgud8Pb/SeheE= github.com/aws/aws-sdk-go-v2/service/wafregional v1.12.22 h1:KBjYyYqdS9F4g7NxMZ6yhFkHO/eaZUs03r/pHv9nlQE= @@ -270,8 +270,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/aws/resources/services/elasticache/clusters.go b/plugins/source/aws/resources/services/elasticache/clusters.go index 75af08b1fe1..a49218f9c57 100644 --- a/plugins/source/aws/resources/services/elasticache/clusters.go +++ b/plugins/source/aws/resources/services/elasticache/clusters.go @@ -192,6 +192,11 @@ func Clusters() *schema.Table { Type: schema.TypeBool, Resolver: schema.PathResolver("TransitEncryptionEnabled"), }, + { + Name: "transit_encryption_mode", + Type: schema.TypeString, + Resolver: schema.PathResolver("TransitEncryptionMode"), + }, }, } } diff --git a/plugins/source/aws/resources/services/elasticache/replication_groups.go b/plugins/source/aws/resources/services/elasticache/replication_groups.go index a17aa0ebccf..afa20876631 100644 --- a/plugins/source/aws/resources/services/elasticache/replication_groups.go +++ b/plugins/source/aws/resources/services/elasticache/replication_groups.go @@ -167,6 +167,11 @@ func ReplicationGroups() *schema.Table { Type: schema.TypeBool, Resolver: schema.PathResolver("TransitEncryptionEnabled"), }, + { + Name: "transit_encryption_mode", + Type: schema.TypeString, + Resolver: schema.PathResolver("TransitEncryptionMode"), + }, { Name: "user_group_ids", Type: schema.TypeStringArray, diff --git a/plugins/source/aws/resources/services/rds/engine_versions.go b/plugins/source/aws/resources/services/rds/engine_versions.go index 290a29fc7af..80339282f43 100644 --- a/plugins/source/aws/resources/services/rds/engine_versions.go +++ b/plugins/source/aws/resources/services/rds/engine_versions.go @@ -61,6 +61,11 @@ func EngineVersions() *schema.Table { Type: schema.TypeString, Resolver: schema.PathResolver("DBEngineDescription"), }, + { + Name: "db_engine_media_type", + Type: schema.TypeString, + Resolver: schema.PathResolver("DBEngineMediaType"), + }, { Name: "db_engine_version_arn", Type: schema.TypeString, @@ -96,6 +101,11 @@ func EngineVersions() *schema.Table { Type: schema.TypeStringArray, Resolver: schema.PathResolver("ExportableLogTypes"), }, + { + Name: "image", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Image"), + }, { Name: "kms_key_id", Type: schema.TypeString, diff --git a/plugins/source/aws/resources/services/route53/domains.go b/plugins/source/aws/resources/services/route53/domains.go index 9ee4876e79e..cae2532e8d9 100644 --- a/plugins/source/aws/resources/services/route53/domains.go +++ b/plugins/source/aws/resources/services/route53/domains.go @@ -35,6 +35,10 @@ func Domains() *schema.Table { Resolver: resolveRoute53DomainTags, Description: `A list of tags`, }, + { + Name: "transfer_lock", + Type: schema.TypeBool, + }, { Name: "abuse_contact_email", Type: schema.TypeString, diff --git a/plugins/source/aws/resources/services/route53/domains_fetch.go b/plugins/source/aws/resources/services/route53/domains_fetch.go index 4b5a15029d0..3709e3aab1e 100644 --- a/plugins/source/aws/resources/services/route53/domains_fetch.go +++ b/plugins/source/aws/resources/services/route53/domains_fetch.go @@ -34,7 +34,6 @@ func fetchRoute53Domains(ctx context.Context, meta schema.ClientMeta, parent *sc } return nil } - func getDomain(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource) error { c := meta.(*client.Client) svc := c.Services().Route53domains @@ -46,7 +45,8 @@ func getDomain(ctx context.Context, meta schema.ClientMeta, resource *schema.Res } resource.Item = d - return nil + + return resource.Set("transfer_lock", aws.ToBool(v.TransferLock)) } func resolveRoute53DomainTags(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, col schema.Column) error { diff --git a/plugins/source/aws/resources/services/ses/active_receipt_rule_sets_fetch.go b/plugins/source/aws/resources/services/ses/active_receipt_rule_sets_fetch.go index fe3cdf4aa22..03d46b0efcb 100644 --- a/plugins/source/aws/resources/services/ses/active_receipt_rule_sets_fetch.go +++ b/plugins/source/aws/resources/services/ses/active_receipt_rule_sets_fetch.go @@ -7,12 +7,28 @@ import ( "github.com/cloudquery/plugin-sdk/schema" ) +// Supported regions based on https://docs.aws.amazon.com/ses/latest/dg/regions.html#region-receive-email +// We hard code as there isn't a good way to automatically fetch this list +var supportedRegions = []string{"us-east-1", "us-west-2", "eu-west-1"} + +func isRegionSupported(region string) bool { + for _, r := range supportedRegions { + if r == region { + return true + } + } + return false +} + func fetchSesActiveReceiptRuleSets(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { c := meta.(*client.Client) svc := c.Services().Ses set, err := svc.DescribeActiveReceiptRuleSet(ctx, nil) if err != nil { + if !isRegionSupported(c.Region) && client.IgnoreWithInvalidAction(err) { + return nil + } return err } diff --git a/plugins/source/aws/test/policy_cq_config.yml b/plugins/source/aws/test/policy_cq_config.yml index ec6670c63e5..b1bcb47f6e6 100644 --- a/plugins/source/aws/test/policy_cq_config.yml +++ b/plugins/source/aws/test/policy_cq_config.yml @@ -10,6 +10,6 @@ kind: destination spec: name: postgresql path: cloudquery/postgresql - version: "v1.10.0" # latest version of postgresql plugin + version: "v2.0.0" # latest version of postgresql plugin spec: connection_string: ${CQ_DSN} \ No newline at end of file diff --git a/plugins/source/aws/test/sanity.yml b/plugins/source/aws/test/sanity.yml index 1357df23190..99ec492d238 100644 --- a/plugins/source/aws/test/sanity.yml +++ b/plugins/source/aws/test/sanity.yml @@ -10,4 +10,4 @@ kind: destination spec: name: sqlite path: cloudquery/sqlite - version: "v1.1.0" # latest version of sqlite plugin \ No newline at end of file + version: "v1.1.2" # latest version of sqlite plugin \ No newline at end of file diff --git a/plugins/source/azure/CONTRIBUTING.md b/plugins/source/azure/CONTRIBUTING.md index 37688ff6fee..ede0f39f2dd 100644 --- a/plugins/source/azure/CONTRIBUTING.md +++ b/plugins/source/azure/CONTRIBUTING.md @@ -18,8 +18,7 @@ Process: ### Generating the actual tables -To generate the actual tables take a look at the recipes under `codegen2/recipes/*` and add your own based on other recipes. - +To generate the actual tables take a look at the recipes under `codegen2/recipes/*` and add your own based on other recipes. Recipes for resources that can't be generated by `codegen0` and `codegen1` should be added to recipes with `_e.go` ending. Then you can run `make gen`. ## General Tips diff --git a/plugins/source/azure/codegen2/recipes/costmanagement.go b/plugins/source/azure/codegen2/recipes/costmanagement_e.go similarity index 51% rename from plugins/source/azure/codegen2/recipes/costmanagement.go rename to plugins/source/azure/codegen2/recipes/costmanagement_e.go index bfdac72b7db..73950b24731 100644 --- a/plugins/source/azure/codegen2/recipes/costmanagement.go +++ b/plugins/source/azure/codegen2/recipes/costmanagement_e.go @@ -1,4 +1,3 @@ -// Code generated by codegen1; DO NOT EDIT. package recipes import "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement" @@ -11,11 +10,27 @@ func init() { Struct: &armcostmanagement.View{}, ResponseStruct: &armcostmanagement.ViewsClientListResponse{}, Client: &armcostmanagement.ViewsClient{}, - ListFunc: (&armcostmanagement.ViewsClient{}).NewListPager, + ListFunc: (&armcostmanagement.ViewsClient{}).NewListByScopePager, NewFunc: armcostmanagement.NewViewsClient, URL: "/providers/Microsoft.CostManagement/views", Multiplex: `client.SubscriptionMultiplexRegisteredNamespace(client.Namespacemicrosoft_costmanagement)`, ExtraColumns: DefaultExtraColumns, + SkipFetch: true, + SkipMock: true, + Relations: []*Table{ + { + Service: "armcostmanagement", + Name: "view_queries", + Struct: &armcostmanagement.QueryResult{}, + ResponseStruct: &armcostmanagement.QueryClientUsageResponse{}, + Client: &armcostmanagement.QueryClient{}, + ListFunc: (&armcostmanagement.QueryClient{}).Usage, + NewFunc: armcostmanagement.NewQueryClient, + URL: "/providers/Microsoft.CostManagement/query", + SkipFetch: true, + SkipMock: true, + }, + }, }, } Tables = append(Tables, tables...) diff --git a/plugins/source/azure/codegen2/recipes/security_e.go b/plugins/source/azure/codegen2/recipes/security_e.go new file mode 100644 index 00000000000..4ecf8bd923f --- /dev/null +++ b/plugins/source/azure/codegen2/recipes/security_e.go @@ -0,0 +1,23 @@ +// Code generated by codegen1; DO NOT EDIT. +package recipes + +import "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/security/armsecurity" + +func init() { + tables := []Table{ + { + Service: "armsecurity", + Name: "pricings", + Struct: &armsecurity.Pricing{}, + ResponseStruct: &armsecurity.PricingsClientListResponse{}, + Client: &armsecurity.PricingsClient{}, + ListFunc: (&armsecurity.PricingsClient{}).List, + NewFunc: armsecurity.NewPricingsClient, + URL: "/subscriptions/{subscriptionId}/providers/Microsoft.Security/pricings", + Multiplex: `client.SubscriptionMultiplexRegisteredNamespace(client.Namespacemicrosoft_security)`, + ExtraColumns: DefaultExtraColumns, + SkipFetch: true, + }, + } + Tables = append(Tables, tables...) +} diff --git a/plugins/source/azure/docs/tables/README.md b/plugins/source/azure/docs/tables/README.md index f8151aee02e..2389d58b1df 100644 --- a/plugins/source/azure/docs/tables/README.md +++ b/plugins/source/azure/docs/tables/README.md @@ -74,6 +74,7 @@ - [azure_cosmos_mongo_db_databases](azure_cosmos_mongo_db_databases.md) - [azure_cosmos_sql_databases](azure_cosmos_sql_databases.md) - [azure_costmanagement_views](azure_costmanagement_views.md) + - [azure_costmanagement_view_queries](azure_costmanagement_view_queries.md) - [azure_customerinsights_hubs](azure_customerinsights_hubs.md) - [azure_dashboard_grafana](azure_dashboard_grafana.md) - [azure_databox_jobs](azure_databox_jobs.md) @@ -210,6 +211,7 @@ - [azure_security_tasks](azure_security_tasks.md) - [azure_security_topology](azure_security_topology.md) - [azure_security_workspace_settings](azure_security_workspace_settings.md) +- [azure_security_pricings](azure_security_pricings.md) - [azure_servicebus_namespaces](azure_servicebus_namespaces.md) - [azure_sql_instance_pools](azure_sql_instance_pools.md) - [azure_sql_managed_instances](azure_sql_managed_instances.md) diff --git a/plugins/source/azure/docs/tables/azure_costmanagement_view_queries.md b/plugins/source/azure/docs/tables/azure_costmanagement_view_queries.md new file mode 100644 index 00000000000..989adbf9fa4 --- /dev/null +++ b/plugins/source/azure/docs/tables/azure_costmanagement_view_queries.md @@ -0,0 +1,24 @@ +# Table: azure_costmanagement_view_queries + +The primary key for this table is **id**. + +## Relations + +This table depends on [azure_costmanagement_views](azure_costmanagement_views.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|properties|JSON| +|etag|String| +|id (PK)|String| +|location|String| +|name|String| +|sku|String| +|tags|JSON| +|type|String| \ No newline at end of file diff --git a/plugins/source/azure/docs/tables/azure_costmanagement_views.md b/plugins/source/azure/docs/tables/azure_costmanagement_views.md index ac9a2f72076..7d15ab8f589 100644 --- a/plugins/source/azure/docs/tables/azure_costmanagement_views.md +++ b/plugins/source/azure/docs/tables/azure_costmanagement_views.md @@ -2,6 +2,11 @@ The primary key for this table is **id**. +## Relations + +The following tables depend on azure_costmanagement_views: + - [azure_costmanagement_view_queries](azure_costmanagement_view_queries.md) + ## Columns | Name | Type | diff --git a/plugins/source/azure/docs/tables/azure_security_pricings.md b/plugins/source/azure/docs/tables/azure_security_pricings.md new file mode 100644 index 00000000000..3fc8233271b --- /dev/null +++ b/plugins/source/azure/docs/tables/azure_security_pricings.md @@ -0,0 +1,17 @@ +# Table: azure_security_pricings + +The primary key for this table is **id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|subscription_id|String| +|properties|JSON| +|id (PK)|String| +|name|String| +|type|String| \ No newline at end of file diff --git a/plugins/source/azure/go.mod b/plugins/source/azure/go.mod index 71fda70d6c2..f945b5cb040 100644 --- a/plugins/source/azure/go.mod +++ b/plugins/source/azure/go.mod @@ -108,7 +108,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/windowsesu/armwindowsesu v0.5.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/windowsiot/armwindowsiot v1.0.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/workloads/armworkloads v0.2.0 - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/gorilla/mux v1.8.0 github.com/iancoleman/strcase v0.2.0 github.com/rs/zerolog v1.28.0 diff --git a/plugins/source/azure/go.sum b/plugins/source/azure/go.sum index f5293910c01..20233916eef 100644 --- a/plugins/source/azure/go.sum +++ b/plugins/source/azure/go.sum @@ -255,8 +255,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/azure/resources/plugin/tables.go b/plugins/source/azure/resources/plugin/tables.go index 5695742f340..9926f390f9b 100644 --- a/plugins/source/azure/resources/plugin/tables.go +++ b/plugins/source/azure/resources/plugin/tables.go @@ -297,6 +297,7 @@ func generatedTables() []*schema.Table { security.Tasks(), security.Topology(), security.WorkspaceSettings(), + security.Pricings(), servicebus.Namespaces(), sql.InstancePools(), sql.ManagedInstances(), diff --git a/plugins/source/azure/resources/services/costmanagement/view_queries.go b/plugins/source/azure/resources/services/costmanagement/view_queries.go new file mode 100644 index 00000000000..8bae496254f --- /dev/null +++ b/plugins/source/azure/resources/services/costmanagement/view_queries.go @@ -0,0 +1,58 @@ +// Code generated by codegen2; DO NOT EDIT. +package costmanagement + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func view_queries() *schema.Table { + return &schema.Table{ + Name: "azure_costmanagement_view_queries", + Resolver: fetchViewQueries, + Columns: []schema.Column{ + { + Name: "properties", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Properties"), + }, + { + Name: "etag", + Type: schema.TypeString, + Resolver: schema.PathResolver("ETag"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location", + Type: schema.TypeString, + Resolver: schema.PathResolver("Location"), + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + }, + { + Name: "sku", + Type: schema.TypeString, + Resolver: schema.PathResolver("SKU"), + }, + { + Name: "tags", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Tags"), + }, + { + Name: "type", + Type: schema.TypeString, + Resolver: schema.PathResolver("Type"), + }, + }, + } +} diff --git a/plugins/source/azure/resources/services/costmanagement/view_queries_fetch.go b/plugins/source/azure/resources/services/costmanagement/view_queries_fetch.go new file mode 100644 index 00000000000..f98d64236f2 --- /dev/null +++ b/plugins/source/azure/resources/services/costmanagement/view_queries_fetch.go @@ -0,0 +1,40 @@ +package costmanagement + +import ( + "context" + "encoding/json" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement" + "github.com/cloudquery/cloudquery/plugins/source/azure/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchViewQueries(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + cl := meta.(*client.Client) + item := parent.Item.(*armcostmanagement.View) + if item.Properties == nil { + return nil + } + + svc, err := armcostmanagement.NewQueryClient(cl.Creds, cl.Options) + if err != nil { + return err + } + + b, err := json.Marshal(item.Properties.Query) + if err != nil { + return err + } + var qd armcostmanagement.QueryDefinition + if err := json.Unmarshal(b, &qd); err != nil { + return err + } + + data, err := svc.Usage(ctx, *item.Properties.Scope, qd, nil) + if err != nil { + return err + } + + res <- data + return nil +} diff --git a/plugins/source/azure/resources/services/costmanagement/view_queries_mock_test.go b/plugins/source/azure/resources/services/costmanagement/view_queries_mock_test.go new file mode 100644 index 00000000000..8497c070639 --- /dev/null +++ b/plugins/source/azure/resources/services/costmanagement/view_queries_mock_test.go @@ -0,0 +1,30 @@ +package costmanagement + +import ( + "encoding/json" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/gorilla/mux" +) + +func createViewQueries(router *mux.Router) error { + var item armcostmanagement.QueryClientUsageResponse + if err := faker.FakeObject(&item); err != nil { + return err + } + + router.HandleFunc("/{scope}/providers/Microsoft.CostManagement/query", func(w http.ResponseWriter, r *http.Request) { + b, err := json.Marshal(&item) + if err != nil { + http.Error(w, "unable to marshal request: "+err.Error(), http.StatusBadRequest) + return + } + if _, err := w.Write(b); err != nil { + http.Error(w, "failed to write", http.StatusBadRequest) + return + } + }) + return nil +} diff --git a/plugins/source/azure/resources/services/costmanagement/views.go b/plugins/source/azure/resources/services/costmanagement/views.go index f176252ce98..84989fdfde5 100644 --- a/plugins/source/azure/resources/services/costmanagement/views.go +++ b/plugins/source/azure/resources/services/costmanagement/views.go @@ -2,8 +2,6 @@ package costmanagement import ( - "context" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement" "github.com/cloudquery/cloudquery/plugins/source/azure/client" "github.com/cloudquery/plugin-sdk/schema" ) @@ -48,22 +46,9 @@ func Views() *schema.Table { Resolver: schema.PathResolver("Type"), }, }, - } -} -func fetchViews(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { - cl := meta.(*client.Client) - svc, err := armcostmanagement.NewViewsClient(cl.Creds, cl.Options) - if err != nil { - return err - } - pager := svc.NewListPager(nil) - for pager.More() { - p, err := pager.NextPage(ctx) - if err != nil { - return err - } - res <- p.Value + Relations: []*schema.Table{ + view_queries(), + }, } - return nil } diff --git a/plugins/source/azure/resources/services/costmanagement/views_fetch.go b/plugins/source/azure/resources/services/costmanagement/views_fetch.go new file mode 100644 index 00000000000..48eaa899880 --- /dev/null +++ b/plugins/source/azure/resources/services/costmanagement/views_fetch.go @@ -0,0 +1,26 @@ +package costmanagement + +import ( + "context" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement" + "github.com/cloudquery/cloudquery/plugins/source/azure/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchViews(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + cl := meta.(*client.Client) + svc, err := armcostmanagement.NewViewsClient(cl.Creds, cl.Options) + if err != nil { + return err + } + pager := svc.NewListByScopePager("subscriptions/"+cl.SubscriptionId, nil) + for pager.More() { + p, err := pager.NextPage(ctx) + if err != nil { + return err + } + res <- p.Value + } + return nil +} diff --git a/plugins/source/azure/resources/services/costmanagement/views_mock_test.go b/plugins/source/azure/resources/services/costmanagement/views_mock_test.go index f15446dd0ec..bb3470dafd7 100644 --- a/plugins/source/azure/resources/services/costmanagement/views_mock_test.go +++ b/plugins/source/azure/resources/services/costmanagement/views_mock_test.go @@ -1,12 +1,12 @@ -// Code generated by codegen2; DO NOT EDIT. package costmanagement import ( "encoding/json" - "github.com/cloudquery/cloudquery/plugins/source/azure/client" "net/http" "testing" + "github.com/cloudquery/cloudquery/plugins/source/azure/client" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement" "github.com/cloudquery/plugin-sdk/faker" "github.com/gorilla/mux" @@ -21,7 +21,7 @@ func createViews(router *mux.Router) error { emptyStr := "" item.NextLink = &emptyStr - router.HandleFunc("/providers/Microsoft.CostManagement/views", func(w http.ResponseWriter, r *http.Request) { + router.HandleFunc("/subscriptions/{subscriptionId}/providers/Microsoft.CostManagement/views", func(w http.ResponseWriter, r *http.Request) { b, err := json.Marshal(&item) if err != nil { http.Error(w, "unable to marshal request: "+err.Error(), http.StatusBadRequest) @@ -32,7 +32,7 @@ func createViews(router *mux.Router) error { return } }) - return nil + return createViewQueries(router) } func TestViews(t *testing.T) { diff --git a/plugins/source/azure/resources/services/security/pricings.go b/plugins/source/azure/resources/services/security/pricings.go new file mode 100644 index 00000000000..591f6a8bad3 --- /dev/null +++ b/plugins/source/azure/resources/services/security/pricings.go @@ -0,0 +1,45 @@ +// Code generated by codegen2; DO NOT EDIT. +package security + +import ( + "github.com/cloudquery/cloudquery/plugins/source/azure/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Pricings() *schema.Table { + return &schema.Table{ + Name: "azure_security_pricings", + Resolver: fetchPricings, + Multiplex: client.SubscriptionMultiplexRegisteredNamespace(client.Namespacemicrosoft_security), + Columns: []schema.Column{ + { + Name: "subscription_id", + Type: schema.TypeString, + Resolver: client.ResolveAzureSubscription, + }, + { + Name: "properties", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Properties"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + }, + { + Name: "type", + Type: schema.TypeString, + Resolver: schema.PathResolver("Type"), + }, + }, + } +} diff --git a/plugins/source/azure/resources/services/security/pricings_fetch.go b/plugins/source/azure/resources/services/security/pricings_fetch.go new file mode 100644 index 00000000000..19dc855bee9 --- /dev/null +++ b/plugins/source/azure/resources/services/security/pricings_fetch.go @@ -0,0 +1,22 @@ +package security + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/security/armsecurity" + "github.com/cloudquery/cloudquery/plugins/source/azure/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchPricings(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + cl := meta.(*client.Client) + svc, err := armsecurity.NewPricingsClient(cl.SubscriptionId, cl.Creds, cl.Options) + if err != nil { + return err + } + result, err := svc.List(ctx, nil) + if err != nil { + return err + } + res <- result.Value + return nil +} diff --git a/plugins/source/azure/resources/services/security/pricings_mock_test.go b/plugins/source/azure/resources/services/security/pricings_mock_test.go new file mode 100644 index 00000000000..f52ef0d74bf --- /dev/null +++ b/plugins/source/azure/resources/services/security/pricings_mock_test.go @@ -0,0 +1,37 @@ +// Code generated by codegen2; DO NOT EDIT. +package security + +import ( + "encoding/json" + "github.com/cloudquery/cloudquery/plugins/source/azure/client" + "net/http" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/security/armsecurity" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/gorilla/mux" +) + +func createPricings(router *mux.Router) error { + var item armsecurity.PricingsClientListResponse + if err := faker.FakeObject(&item); err != nil { + return err + } + + router.HandleFunc("/subscriptions/{subscriptionId}/providers/Microsoft.Security/pricings", func(w http.ResponseWriter, r *http.Request) { + b, err := json.Marshal(&item) + if err != nil { + http.Error(w, "unable to marshal request: "+err.Error(), http.StatusBadRequest) + return + } + if _, err := w.Write(b); err != nil { + http.Error(w, "failed to write", http.StatusBadRequest) + return + } + }) + return nil +} + +func TestPricings(t *testing.T) { + client.MockTestHelper(t, Pricings(), createPricings) +} diff --git a/plugins/source/azure/test/policy_cq_config.yml b/plugins/source/azure/test/policy_cq_config.yml index 6a7d2c4db44..ab00139a062 100644 --- a/plugins/source/azure/test/policy_cq_config.yml +++ b/plugins/source/azure/test/policy_cq_config.yml @@ -10,6 +10,6 @@ kind: destination spec: name: postgresql path: cloudquery/postgresql - version: "v1.10.0" # latest version of postgresql plugin + version: "v2.0.0" # latest version of postgresql plugin spec: connection_string: ${CQ_DSN} \ No newline at end of file diff --git a/plugins/source/azure/views/resource.sql b/plugins/source/azure/views/resource.sql index 12b655859a8..ce5c0e41f5c 100644 --- a/plugins/source/azure/views/resource.sql +++ b/plugins/source/azure/views/resource.sql @@ -23,7 +23,7 @@ LOOP -- we use the double reverse here because split_part with negative indexes is not available in PostgreSQL < 14; https://pgpedia.info/postgresql-versions/postgresql-14.html#system_function_changes strSQL = strSQL || format(' SELECT _cq_id, _cq_source_name, _cq_sync_time, %L as _cq_table, subscription_id, reverse(split_part(reverse(id), ''/''::TEXT, 1)) as id, - %s as name, %s as kind, %s as location + %s as name, %s as kind, %s as location, id AS full_id FROM %s', tbl, CASE WHEN EXISTS (SELECT 1 FROM information_schema.columns WHERE column_name='name' AND table_name=tbl) THEN 'name' ELSE 'NULL' END, diff --git a/plugins/source/azuredevops/CHANGELOG.md b/plugins/source/azuredevops/CHANGELOG.md new file mode 100644 index 00000000000..69789e649e4 --- /dev/null +++ b/plugins/source/azuredevops/CHANGELOG.md @@ -0,0 +1,19 @@ +# Changelog + +## 1.0.0 (2022-12-27) + + +### Features + +* Add codegen ([#5618](https://github.com/cloudquery/cloudquery/issues/5618)) ([1a964ac](https://github.com/cloudquery/cloudquery/commit/1a964ac280c18113bb2abc9c616dd86163d058d8)) +* **azuredevops:** Create client, fetch project ids ([#5611](https://github.com/cloudquery/cloudquery/issues/5611)) ([285b9cd](https://github.com/cloudquery/cloudquery/commit/285b9cde83d43f794a907ae23eb97304af30c706)) + + +### Bug Fixes + +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.12.3 ([#5639](https://github.com/cloudquery/cloudquery/issues/5639)) ([6452d0e](https://github.com/cloudquery/cloudquery/commit/6452d0ed5a44abad9d7530af6e79cde6504d0c4c)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.12.4 ([#5649](https://github.com/cloudquery/cloudquery/issues/5649)) ([b4aa889](https://github.com/cloudquery/cloudquery/commit/b4aa889e396db3b0887d1684e4bc07da6050af43)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.12.5 ([#5661](https://github.com/cloudquery/cloudquery/issues/5661)) ([b354b8a](https://github.com/cloudquery/cloudquery/commit/b354b8a3683fa2bc918c1002afac487427d65a5f)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.12.6 ([#5790](https://github.com/cloudquery/cloudquery/issues/5790)) ([8e2663c](https://github.com/cloudquery/cloudquery/commit/8e2663c17c3347afd5e53f665462adc3e709c96c)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.12.7 ([#5797](https://github.com/cloudquery/cloudquery/issues/5797)) ([15da529](https://github.com/cloudquery/cloudquery/commit/15da5294786fa2656228ca5bbc48ef1fc44e486b)) +* **deps:** Update module github.com/cloudquery/plugin-sdk to v1.13.1 ([#5897](https://github.com/cloudquery/cloudquery/issues/5897)) ([ad15915](https://github.com/cloudquery/cloudquery/commit/ad15915f2951a75729859f6f1377ed789f8ba115)) diff --git a/plugins/source/azuredevops/go.mod b/plugins/source/azuredevops/go.mod index b6525bfa901..b5731ce93f6 100644 --- a/plugins/source/azuredevops/go.mod +++ b/plugins/source/azuredevops/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/azuredevops go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/google/uuid v1.3.0 github.com/iancoleman/strcase v0.2.0 github.com/microsoft/azure-devops-go-api/azuredevops/v6 v6.0.1 diff --git a/plugins/source/azuredevops/go.sum b/plugins/source/azuredevops/go.sum index 357fa7d0345..eedfcb2334e 100644 --- a/plugins/source/azuredevops/go.sum +++ b/plugins/source/azuredevops/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/cloudflare/go.mod b/plugins/source/cloudflare/go.mod index 85996259149..b9a113f7aea 100644 --- a/plugins/source/cloudflare/go.mod +++ b/plugins/source/cloudflare/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/cloudflare/cloudflare-go v0.55.0 - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/gertd/go-pluralize v0.2.1 github.com/golang/mock v1.6.0 github.com/rs/zerolog v1.28.0 diff --git a/plugins/source/cloudflare/go.sum b/plugins/source/cloudflare/go.sum index 56764d9b103..d43d890cd72 100644 --- a/plugins/source/cloudflare/go.sum +++ b/plugins/source/cloudflare/go.sum @@ -42,8 +42,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.55.0 h1:r/+AC9WX7+/G3K7DH5l58Mmnc8dIF5kyQsKW7NmNlX8= github.com/cloudflare/cloudflare-go v0.55.0/go.mod h1:2N8L4vv3eobUgkB41tSiIJWRK4u/jJsK3IQz3EgFS+8= -github.com/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/crowdstrike/go.mod b/plugins/source/crowdstrike/go.mod index c149f8222a7..342917a2a20 100644 --- a/plugins/source/crowdstrike/go.mod +++ b/plugins/source/crowdstrike/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/crowdstrike go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/crowdstrike/gofalcon v0.2.30 github.com/go-openapi/runtime v0.24.2 github.com/golang/mock v1.6.0 diff --git a/plugins/source/crowdstrike/go.sum b/plugins/source/crowdstrike/go.sum index 6507c925943..237bd7ee29b 100644 --- a/plugins/source/crowdstrike/go.sum +++ b/plugins/source/crowdstrike/go.sum @@ -76,8 +76,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= diff --git a/plugins/source/datadog/go.mod b/plugins/source/datadog/go.mod index 06c483134ec..4e40324331e 100644 --- a/plugins/source/datadog/go.mod +++ b/plugins/source/datadog/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/DataDog/datadog-api-client-go/v2 v2.5.0 - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/golang/mock v1.6.0 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.28.0 diff --git a/plugins/source/datadog/go.sum b/plugins/source/datadog/go.sum index 8da2f8a280e..c93ab2ac2f6 100644 --- a/plugins/source/datadog/go.sum +++ b/plugins/source/datadog/go.sum @@ -44,8 +44,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/digitalocean/go.mod b/plugins/source/digitalocean/go.mod index 9492fb0ef39..d06b43d026a 100644 --- a/plugins/source/digitalocean/go.mod +++ b/plugins/source/digitalocean/go.mod @@ -8,7 +8,7 @@ require ( github.com/aws/aws-sdk-go-v2/config v1.18.7 github.com/aws/aws-sdk-go-v2/service/s3 v1.29.6 github.com/aws/smithy-go v1.13.5 - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/digitalocean/godo v1.91.1 github.com/gertd/go-pluralize v0.2.1 github.com/golang/mock v1.6.0 diff --git a/plugins/source/digitalocean/go.sum b/plugins/source/digitalocean/go.sum index 5bcd492b456..b92fc0e1366 100644 --- a/plugins/source/digitalocean/go.sum +++ b/plugins/source/digitalocean/go.sum @@ -77,8 +77,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/fastly/.gitignore b/plugins/source/fastly/.gitignore new file mode 100644 index 00000000000..f1ba15f0f66 --- /dev/null +++ b/plugins/source/fastly/.gitignore @@ -0,0 +1,3 @@ +test +dist +fastly \ No newline at end of file diff --git a/plugins/source/fastly/.goreleaser.yaml b/plugins/source/fastly/.goreleaser.yaml new file mode 100644 index 00000000000..112ace433b4 --- /dev/null +++ b/plugins/source/fastly/.goreleaser.yaml @@ -0,0 +1,14 @@ +variables: + component: source/fastly + binary: fastly + +project_name: plugins/source/fastly + +monorepo: + tag_prefix: plugins-source-fastly- + dir: plugins/source/fastly + +includes: + - from_file: + # Relative to the directory Go Releaser is run from (which is the root of the repository) + path: ./plugins/.goreleaser.yaml diff --git a/plugins/source/fastly/CHANGELOG.md b/plugins/source/fastly/CHANGELOG.md new file mode 100644 index 00000000000..61f4277197c --- /dev/null +++ b/plugins/source/fastly/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## 1.0.0 (2022-12-29) + + +### Features + +* Fastly Source Plugin ([#5945](https://github.com/cloudquery/cloudquery/issues/5945)) ([d9980e6](https://github.com/cloudquery/cloudquery/commit/d9980e600a0c9d879965db2c74b1da60e159d0a9)) + diff --git a/plugins/source/fastly/CONTRIBUTING.md b/plugins/source/fastly/CONTRIBUTING.md new file mode 100644 index 00000000000..2a1be70318d --- /dev/null +++ b/plugins/source/fastly/CONTRIBUTING.md @@ -0,0 +1,96 @@ +# Fastly Source Plugin Contribution Guide + +Thanks for contributing to CloudQuery! You are awesome. This document serves as a guide for adding new services and resources to the Fastly source plugin. + +There are two main steps to adding a new resource: + +1. [Add a code generation recipe](#1-add-a-code-generation-recipe) +2. [Write the resolver function to fetch the resource using the AWS SDK](#2-setting-up-the-resource) + +## 1. Add a Code Generation Recipe + +Every supported Fastly service has a recipe file under [codegen/recipes](codegen/recipes). For example, all service API resources are listed in [codegen/recipes/services.go](codegen/recipes/services.go). + +In the following examples, we will use the fictional `MyService` service with `MyResource` resource as an example. We recommend taking a look at a few examples in [codegen/recipes](codegen/recipes) first, as these steps will make more sense with some examples to reference. + +If you are adding a service that needs a new recipe, see [Add a New Recipe File](#add-a-new-recipe-file). Otherwise, if the service is already supported but is missing resource(s), you may skip to [Add a Resource to a Recipe](#add-a-resource-to-a-recipe). + +### Add a New Recipe File + +The process to follow for adding a new recipe is: + +1. Add a new file under [codegen/recipes](codegen/recipes) called `myservice.go`. +2. Inside the new file, add a function called `MyServiceResources()` that returns `[]*Resource`. +3. Call the function from [codegen/main.go](codegen/main.go) by adding + `resources = append(resources, recipes.MyServiceResources()...)` +4. Define the list of resources to be generated and return it inside this function. See + [Add a Resource to a Recipe](#add-a-resource-to-a-recipe) for more details. + +### Add a Resource to a Recipe + +`MyServiceResources()` should return a slice of `*Resource` instances. Each resource should, at a minimum, have the following fields defined: + + 1. `Service`: This will be the directory name under [resources/services](resources/services) where the resource will be generated, and the first part of the table name, by default. + 2. `DataStruct`: This should be a pointer to the struct that will be synced to the destination. CloudQuery's plugin-sdk code generation will read the fields of this struct and convert it to a `Table` instance with appropriate column types. If `TableName` is omitted, the name of the struct will be used to infer the table name. + 3. `Description`: A link to the API documentation for the resource, as well as (optionally) any other relevant information about the table. + +#### All Available Resource Fields + +All available Resource fields can be seen in [base.go](codegen/recipes/base.go). These closely map to the `Table` fields [defined by the plugin-sdk](https://github.com/cloudquery/plugin-sdk/blob/main/schema/table.go), which you may use as a further reference about what each field does. + +#### Common Fields + +If all the resources share the same value for a field (as is often the case for `Service`), our convention is to reduce boilerplate by setting these properties in a loop after defining the resources slice, e.g. + +```go +// set default values +for _, r := range resources { + r.Service = "myservice" +} +``` + +### Run Code Generation + +With the recipe file added and some resources defined, you are ready to run code generation. Run: + +```shell +make gen +``` + +This will update all resources and generate a new directory for your service under [resources/services](resources/services). + +## 2. Setting up the resource + +By following the steps outlined above, you should now have generated a `myservice` directory under `resources/services`, containing a file called `myresource.go` (these names are examples, your actual filenames will differ). We will now set up the resource. This involves two steps: refining the `codegen` recipe, and writing one or more resolver functions. + +1. Open the generated `myservice/myresource.go` and inspect the `schema.Table` that is being returned. Does it contain the appropriate columns for the resource? Does it have a primary key? If something looks off, return to the recipe for this resource (under [codegen/recipes](codegen/recipes)) and make adjustments. Then re-run code generation as described in [Run Code Generation](#run-code-generation). Repeat this process until the Table looks right. +2. Your generated `Table` will reference a `Resolver` function that needs to be implemented. The generated file should never be edited directly, so create a new file called `myresource_fetch.go` and add a resolver function with the following signature: + ```go + func fetchMyResource(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- interface{}) error { + // TODO: implement this + } + ``` + You may use a type assertion on `meta` to obtain a reference to your interface functions, e.g.: + ```go + c := meta.(*client.Client) + ``` + With this in hand, complete the resolver function to fetch all resources. After resources are retrieved, send them to the `res` channel for the SDK to deliver to all destinations. +3. Implement a mock test in `myresource_mock_test.go`. We will not describe this in detail here; look at a few examples for similar resources to get you started. + +We recommend looking at other resources similar to yours to get an idea of what needs to be done in this step. + +### Implementing Resolver Functions + +A few important things to note when adding functions that call the Fastly API: + +- If possible, always use an API call that allows you to fetch many resources at once +- Take pagination into account. Use `Paginator`s if the Fastly service supports it. Ensure you fetch **all** the resources. +- Columns may also have their own resolver functions (not covered in this guide). This may be used for simple transformations or when additional calls can help add further context to the table. + +## General Tips + +- Keep transformations to a minimum. As far as possible, we aim to deliver an accurate reflection of what the API provides. +- We generally only unroll structs one level deep. Nested structs should be transformed into JSON columns. +- Primary keys are used to upsert rows. Make sure the primary key uniquely defines an entry, otherwise some rows may be overwritten by accident. +- Before submitting a pull request, run `make gen` to generate code and documentation for the table. Include these generated files in the pull request. +- If you get stuck or need help, feel free to reach out on [Discord](https://www.cloudquery.io/discord). We are a friendly community and would love to help! diff --git a/plugins/source/fastly/Makefile b/plugins/source/fastly/Makefile new file mode 100644 index 00000000000..7a6c6f9e5a9 --- /dev/null +++ b/plugins/source/fastly/Makefile @@ -0,0 +1,38 @@ +# Test unit +.PHONY: test +test: + go test -timeout 3m ./... + +# Install tools +.PHONY: install-tools +install-tools: + @echo Installing tools from tools/tool.go + @cat tools/tool.go | grep _ | awk -F'"' '{print $$2}' | xargs -tI % go install % + +.PHONY: lint +lint: + golangci-lint run --config ../../.golangci.yml + +.PHONY: lint-fix +lint-fix: + golangci-lint run --fix --config ../../.golangci.yml + +.PHONY: gen-code +gen-code: + grep -rl '// Code generated by codegen; DO NOT EDIT.' resources/services/* | xargs rm + go run codegen/main.go + +.PHONY: gen-mocks +gen-mocks: install-tools + rm -rf ./client/mocks/* + go generate ./client/... + +.PHONY: gen-docs +gen-docs: + rm -rf ./docs/tables/* + go run main.go doc ./docs/tables + sed 's_(\(.*\))_(https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/\1)_' docs/tables/README.md > ../../../website/pages/docs/plugins/sources/fastly/tables.md + +# All gen targets +.PHONY: gen +gen: gen-mocks gen-code gen-docs diff --git a/plugins/source/fastly/README.md b/plugins/source/fastly/README.md new file mode 100644 index 00000000000..6705bddca98 --- /dev/null +++ b/plugins/source/fastly/README.md @@ -0,0 +1,7 @@ +# Fastly Source Plugin + +The Fastly Source plugin for CloudQuery extracts configuration from a variety of Fastly APIs and loads it into any supported CloudQuery destination (e.g. PostgreSQL). + +## Links + +- [User Guide](https://www.cloudquery.io/docs/plugins/sources/fastly/overview) \ No newline at end of file diff --git a/plugins/source/fastly/client/client.go b/plugins/source/fastly/client/client.go new file mode 100644 index 00000000000..f002183c6a2 --- /dev/null +++ b/plugins/source/fastly/client/client.go @@ -0,0 +1,116 @@ +package client + +import ( + "context" + "fmt" + "time" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/services" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugin-sdk/specs" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/rs/zerolog" + "github.com/thoas/go-funk" +) + +const ( + defaultMaxRetries = 5 + defaultBackoff = 10 * time.Second +) + +type Client struct { + logger zerolog.Logger + spec specs.Source + Fastly services.FastlyClient + Spec Spec + + // used for service-region multiplexing + Service *fastly.Service + Region string + services []*fastly.Service + regions []string + + maxRetries int + backoff time.Duration // backoff duration between retries (jitter will be added) +} + +func (c *Client) Logger() *zerolog.Logger { + return &c.logger +} + +func (c *Client) ID() string { + return c.spec.Name +} + +func (c *Client) withServiceAndRegion(service *fastly.Service, region string) schema.ClientMeta { + return &Client{ + logger: c.logger.With().Str("service_id", service.ID).Str("Region", region).Logger(), + spec: c.spec, + Fastly: c.Fastly, + maxRetries: c.maxRetries, + backoff: c.backoff, + Service: service, + Region: region, + services: c.services, + regions: c.regions, + } +} + +func Configure(ctx context.Context, logger zerolog.Logger, sourceSpec specs.Source) (schema.ClientMeta, error) { + var config Spec + err := sourceSpec.UnmarshalSpec(&config) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal spec: %w", err) + } + client, err := fastly.NewClient(config.FastlyAPIKey) + if err != nil { + return nil, fmt.Errorf("failed to create fastly client: %w", err) + } + + fastlyServices, err := listServices(client, config) + if err != nil { + return nil, fmt.Errorf("failed to list services: %w", err) + } + regions, err := listRegions(client) + if err != nil { + return nil, fmt.Errorf("failed to list regions: %w", err) + } + + return &Client{ + logger: logger, + spec: sourceSpec, + Fastly: client, + maxRetries: defaultMaxRetries, + backoff: defaultBackoff, + services: fastlyServices, + regions: regions, + }, nil +} + +func listServices(client services.FastlyClient, cfg Spec) ([]*fastly.Service, error) { + var fastlyServices []*fastly.Service + p := client.NewListServicesPaginator(&fastly.ListServicesInput{ + PerPage: 100, + }) + if p.HasNext() { + s, err := p.GetNext() + if err != nil { + return nil, err + } + for _, service := range s { + if len(cfg.Services) > 0 && !funk.ContainsString(cfg.Services, service.ID) { + continue + } + fastlyServices = append(fastlyServices, service) + } + } + return fastlyServices, nil +} + +func listRegions(client services.FastlyClient) ([]string, error) { + r, err := client.GetRegions() + if err != nil { + return nil, err + } + return r.Data, nil +} diff --git a/plugins/source/fastly/client/errors.go b/plugins/source/fastly/client/errors.go new file mode 100644 index 00000000000..44ff9b81233 --- /dev/null +++ b/plugins/source/fastly/client/errors.go @@ -0,0 +1,34 @@ +package client + +import ( + "context" + "math/rand" + "time" + + "github.com/fastly/go-fastly/v7/fastly" +) + +// RetryOnError will run the given resolver function and retry on rate limit exceeded errors +// or other retryable errors (like internal server errors) after waiting some amount of time. +func (c *Client) RetryOnError(ctx context.Context, tableName string, f func() error) error { + retries := 0 + for err := f(); err != nil; err = f() { + if ferr, ok := err.(*fastly.HTTPError); ok && isRetryable(ferr) { + retryAfter := time.Duration(rand.Float64() * float64(c.backoff)) + retries++ + c.logger.Info().Str("table", tableName).Msgf("Got retryable error (%v), retrying in %.2fs (%d/%d)", err, retryAfter.Seconds(), retries, c.maxRetries) + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(retryAfter): + continue + } + } + return err + } + return nil +} + +func isRetryable(err *fastly.HTTPError) bool { + return err.StatusCode >= 500 || err.StatusCode == 429 +} diff --git a/plugins/source/fastly/client/errors_test.go b/plugins/source/fastly/client/errors_test.go new file mode 100644 index 00000000000..34ed9787d00 --- /dev/null +++ b/plugins/source/fastly/client/errors_test.go @@ -0,0 +1,84 @@ +package client + +import ( + "context" + "errors" + "net/http" + "os" + "testing" + "time" + + "github.com/fastly/go-fastly/v7/fastly" + "github.com/rs/zerolog" +) + +func TestRetryOnRateLimitError(t *testing.T) { + logger := zerolog.New(zerolog.NewTestWriter(t)).Output( + zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.StampMicro}, + ).Level(zerolog.DebugLevel).With().Timestamp().Logger() + c := Client{ + logger: logger, + maxRetries: 1, + backoff: 1 * time.Microsecond, + } + ctx := context.Background() + t.Run("no_error", func(t *testing.T) { + got := c.RetryOnError(ctx, "table_name", func() error { + return nil + }) + if got != nil { + t.Errorf("RetryOnError returned error: %v, want nil", got) + } + }) + + t.Run("with_error", func(t *testing.T) { + got := c.RetryOnError(ctx, "table_name", func() error { + return errors.New("test error") + }) + if got == nil || got.Error() != "test error" { + t.Errorf("RetryOnError returned error: %v, want %v", got, "test error") + } + }) + + t.Run("with_too_many_requests_error", func(t *testing.T) { + calls := 0 + got := c.RetryOnError(ctx, "table_name", func() error { + if calls == 0 { + calls++ + return &fastly.HTTPError{ + StatusCode: http.StatusTooManyRequests, + } + } + return nil + }) + if got != nil { + t.Errorf("RetryOnError returned error: %v, want nil", got) + } + }) + + t.Run("with_internal_server_error", func(t *testing.T) { + calls := 0 + got := c.RetryOnError(ctx, "table_name", func() error { + if calls == 0 { + calls++ + return &fastly.HTTPError{ + StatusCode: http.StatusInternalServerError, + } + } + return nil + }) + if got != nil { + t.Errorf("RetryOnError returned error: %v, want nil", got) + } + }) + + t.Run("retryable_error_that_never_succeeds", func(t *testing.T) { + err := errors.New("slack server error: 500 Internal Server Error") + got := c.RetryOnError(ctx, "table_name", func() error { + return err + }) + if got != err { + t.Errorf("RetryOnError returned error: %v, want %v", got, err) + } + }) +} diff --git a/plugins/source/fastly/client/mocks/fastly.go b/plugins/source/fastly/client/mocks/fastly.go new file mode 100644 index 00000000000..cc07f8753cf --- /dev/null +++ b/plugins/source/fastly/client/mocks/fastly.go @@ -0,0 +1,2429 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: fastly.go + +// Package mocks is a generated GoMock package. +package mocks + +import ( + http "net/http" + reflect "reflect" + + fastly "github.com/fastly/go-fastly/v7/fastly" + gomock "github.com/golang/mock/gomock" +) + +// MockFastlyClient is a mock of FastlyClient interface. +type MockFastlyClient struct { + ctrl *gomock.Controller + recorder *MockFastlyClientMockRecorder +} + +// MockFastlyClientMockRecorder is the mock recorder for MockFastlyClient. +type MockFastlyClientMockRecorder struct { + mock *MockFastlyClient +} + +// NewMockFastlyClient creates a new mock instance. +func NewMockFastlyClient(ctrl *gomock.Controller) *MockFastlyClient { + mock := &MockFastlyClient{ctrl: ctrl} + mock.recorder = &MockFastlyClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFastlyClient) EXPECT() *MockFastlyClientMockRecorder { + return m.recorder +} + +// Get mocks base method. +func (m *MockFastlyClient) Get(arg0 string, arg1 *fastly.RequestOptions) (*http.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1) + ret0, _ := ret[0].(*http.Response) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockFastlyClientMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockFastlyClient)(nil).Get), arg0, arg1) +} + +// GetACL mocks base method. +func (m *MockFastlyClient) GetACL(arg0 *fastly.GetACLInput) (*fastly.ACL, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetACL", arg0) + ret0, _ := ret[0].(*fastly.ACL) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetACL indicates an expected call of GetACL. +func (mr *MockFastlyClientMockRecorder) GetACL(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetACL", reflect.TypeOf((*MockFastlyClient)(nil).GetACL), arg0) +} + +// GetACLEntry mocks base method. +func (m *MockFastlyClient) GetACLEntry(arg0 *fastly.GetACLEntryInput) (*fastly.ACLEntry, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetACLEntry", arg0) + ret0, _ := ret[0].(*fastly.ACLEntry) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetACLEntry indicates an expected call of GetACLEntry. +func (mr *MockFastlyClientMockRecorder) GetACLEntry(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetACLEntry", reflect.TypeOf((*MockFastlyClient)(nil).GetACLEntry), arg0) +} + +// GetAPIEvent mocks base method. +func (m *MockFastlyClient) GetAPIEvent(arg0 *fastly.GetAPIEventInput) (*fastly.Event, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAPIEvent", arg0) + ret0, _ := ret[0].(*fastly.Event) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAPIEvent indicates an expected call of GetAPIEvent. +func (mr *MockFastlyClientMockRecorder) GetAPIEvent(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAPIEvent", reflect.TypeOf((*MockFastlyClient)(nil).GetAPIEvent), arg0) +} + +// GetAPIEvents mocks base method. +func (m *MockFastlyClient) GetAPIEvents(arg0 *fastly.GetAPIEventsFilterInput) (fastly.GetAPIEventsResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAPIEvents", arg0) + ret0, _ := ret[0].(fastly.GetAPIEventsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAPIEvents indicates an expected call of GetAPIEvents. +func (mr *MockFastlyClientMockRecorder) GetAPIEvents(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAPIEvents", reflect.TypeOf((*MockFastlyClient)(nil).GetAPIEvents), arg0) +} + +// GetBackend mocks base method. +func (m *MockFastlyClient) GetBackend(arg0 *fastly.GetBackendInput) (*fastly.Backend, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBackend", arg0) + ret0, _ := ret[0].(*fastly.Backend) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBackend indicates an expected call of GetBackend. +func (mr *MockFastlyClientMockRecorder) GetBackend(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBackend", reflect.TypeOf((*MockFastlyClient)(nil).GetBackend), arg0) +} + +// GetBigQuery mocks base method. +func (m *MockFastlyClient) GetBigQuery(arg0 *fastly.GetBigQueryInput) (*fastly.BigQuery, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBigQuery", arg0) + ret0, _ := ret[0].(*fastly.BigQuery) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBigQuery indicates an expected call of GetBigQuery. +func (mr *MockFastlyClientMockRecorder) GetBigQuery(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBigQuery", reflect.TypeOf((*MockFastlyClient)(nil).GetBigQuery), arg0) +} + +// GetBilling mocks base method. +func (m *MockFastlyClient) GetBilling(arg0 *fastly.GetBillingInput) (*fastly.Billing, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBilling", arg0) + ret0, _ := ret[0].(*fastly.Billing) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBilling indicates an expected call of GetBilling. +func (mr *MockFastlyClientMockRecorder) GetBilling(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBilling", reflect.TypeOf((*MockFastlyClient)(nil).GetBilling), arg0) +} + +// GetBlobStorage mocks base method. +func (m *MockFastlyClient) GetBlobStorage(arg0 *fastly.GetBlobStorageInput) (*fastly.BlobStorage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlobStorage", arg0) + ret0, _ := ret[0].(*fastly.BlobStorage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlobStorage indicates an expected call of GetBlobStorage. +func (mr *MockFastlyClientMockRecorder) GetBlobStorage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlobStorage", reflect.TypeOf((*MockFastlyClient)(nil).GetBlobStorage), arg0) +} + +// GetBulkCertificate mocks base method. +func (m *MockFastlyClient) GetBulkCertificate(arg0 *fastly.GetBulkCertificateInput) (*fastly.BulkCertificate, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBulkCertificate", arg0) + ret0, _ := ret[0].(*fastly.BulkCertificate) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBulkCertificate indicates an expected call of GetBulkCertificate. +func (mr *MockFastlyClientMockRecorder) GetBulkCertificate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBulkCertificate", reflect.TypeOf((*MockFastlyClient)(nil).GetBulkCertificate), arg0) +} + +// GetCacheSetting mocks base method. +func (m *MockFastlyClient) GetCacheSetting(arg0 *fastly.GetCacheSettingInput) (*fastly.CacheSetting, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCacheSetting", arg0) + ret0, _ := ret[0].(*fastly.CacheSetting) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCacheSetting indicates an expected call of GetCacheSetting. +func (mr *MockFastlyClientMockRecorder) GetCacheSetting(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCacheSetting", reflect.TypeOf((*MockFastlyClient)(nil).GetCacheSetting), arg0) +} + +// GetCloudfiles mocks base method. +func (m *MockFastlyClient) GetCloudfiles(arg0 *fastly.GetCloudfilesInput) (*fastly.Cloudfiles, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCloudfiles", arg0) + ret0, _ := ret[0].(*fastly.Cloudfiles) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCloudfiles indicates an expected call of GetCloudfiles. +func (mr *MockFastlyClientMockRecorder) GetCloudfiles(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCloudfiles", reflect.TypeOf((*MockFastlyClient)(nil).GetCloudfiles), arg0) +} + +// GetCondition mocks base method. +func (m *MockFastlyClient) GetCondition(arg0 *fastly.GetConditionInput) (*fastly.Condition, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCondition", arg0) + ret0, _ := ret[0].(*fastly.Condition) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCondition indicates an expected call of GetCondition. +func (mr *MockFastlyClientMockRecorder) GetCondition(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCondition", reflect.TypeOf((*MockFastlyClient)(nil).GetCondition), arg0) +} + +// GetCurrentUser mocks base method. +func (m *MockFastlyClient) GetCurrentUser() (*fastly.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentUser") + ret0, _ := ret[0].(*fastly.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentUser indicates an expected call of GetCurrentUser. +func (mr *MockFastlyClientMockRecorder) GetCurrentUser() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentUser", reflect.TypeOf((*MockFastlyClient)(nil).GetCurrentUser)) +} + +// GetCustomTLSCertificate mocks base method. +func (m *MockFastlyClient) GetCustomTLSCertificate(arg0 *fastly.GetCustomTLSCertificateInput) (*fastly.CustomTLSCertificate, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCustomTLSCertificate", arg0) + ret0, _ := ret[0].(*fastly.CustomTLSCertificate) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCustomTLSCertificate indicates an expected call of GetCustomTLSCertificate. +func (mr *MockFastlyClientMockRecorder) GetCustomTLSCertificate(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCustomTLSCertificate", reflect.TypeOf((*MockFastlyClient)(nil).GetCustomTLSCertificate), arg0) +} + +// GetCustomTLSConfiguration mocks base method. +func (m *MockFastlyClient) GetCustomTLSConfiguration(arg0 *fastly.GetCustomTLSConfigurationInput) (*fastly.CustomTLSConfiguration, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCustomTLSConfiguration", arg0) + ret0, _ := ret[0].(*fastly.CustomTLSConfiguration) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCustomTLSConfiguration indicates an expected call of GetCustomTLSConfiguration. +func (mr *MockFastlyClientMockRecorder) GetCustomTLSConfiguration(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCustomTLSConfiguration", reflect.TypeOf((*MockFastlyClient)(nil).GetCustomTLSConfiguration), arg0) +} + +// GetDatadog mocks base method. +func (m *MockFastlyClient) GetDatadog(arg0 *fastly.GetDatadogInput) (*fastly.Datadog, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDatadog", arg0) + ret0, _ := ret[0].(*fastly.Datadog) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDatadog indicates an expected call of GetDatadog. +func (mr *MockFastlyClientMockRecorder) GetDatadog(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDatadog", reflect.TypeOf((*MockFastlyClient)(nil).GetDatadog), arg0) +} + +// GetDictionary mocks base method. +func (m *MockFastlyClient) GetDictionary(arg0 *fastly.GetDictionaryInput) (*fastly.Dictionary, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDictionary", arg0) + ret0, _ := ret[0].(*fastly.Dictionary) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDictionary indicates an expected call of GetDictionary. +func (mr *MockFastlyClientMockRecorder) GetDictionary(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDictionary", reflect.TypeOf((*MockFastlyClient)(nil).GetDictionary), arg0) +} + +// GetDictionaryInfo mocks base method. +func (m *MockFastlyClient) GetDictionaryInfo(arg0 *fastly.GetDictionaryInfoInput) (*fastly.DictionaryInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDictionaryInfo", arg0) + ret0, _ := ret[0].(*fastly.DictionaryInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDictionaryInfo indicates an expected call of GetDictionaryInfo. +func (mr *MockFastlyClientMockRecorder) GetDictionaryInfo(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDictionaryInfo", reflect.TypeOf((*MockFastlyClient)(nil).GetDictionaryInfo), arg0) +} + +// GetDictionaryItem mocks base method. +func (m *MockFastlyClient) GetDictionaryItem(arg0 *fastly.GetDictionaryItemInput) (*fastly.DictionaryItem, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDictionaryItem", arg0) + ret0, _ := ret[0].(*fastly.DictionaryItem) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDictionaryItem indicates an expected call of GetDictionaryItem. +func (mr *MockFastlyClientMockRecorder) GetDictionaryItem(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDictionaryItem", reflect.TypeOf((*MockFastlyClient)(nil).GetDictionaryItem), arg0) +} + +// GetDiff mocks base method. +func (m *MockFastlyClient) GetDiff(arg0 *fastly.GetDiffInput) (*fastly.Diff, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDiff", arg0) + ret0, _ := ret[0].(*fastly.Diff) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDiff indicates an expected call of GetDiff. +func (mr *MockFastlyClientMockRecorder) GetDiff(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDiff", reflect.TypeOf((*MockFastlyClient)(nil).GetDiff), arg0) +} + +// GetDigitalOcean mocks base method. +func (m *MockFastlyClient) GetDigitalOcean(arg0 *fastly.GetDigitalOceanInput) (*fastly.DigitalOcean, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDigitalOcean", arg0) + ret0, _ := ret[0].(*fastly.DigitalOcean) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDigitalOcean indicates an expected call of GetDigitalOcean. +func (mr *MockFastlyClientMockRecorder) GetDigitalOcean(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDigitalOcean", reflect.TypeOf((*MockFastlyClient)(nil).GetDigitalOcean), arg0) +} + +// GetDirector mocks base method. +func (m *MockFastlyClient) GetDirector(arg0 *fastly.GetDirectorInput) (*fastly.Director, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDirector", arg0) + ret0, _ := ret[0].(*fastly.Director) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDirector indicates an expected call of GetDirector. +func (mr *MockFastlyClientMockRecorder) GetDirector(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDirector", reflect.TypeOf((*MockFastlyClient)(nil).GetDirector), arg0) +} + +// GetDirectorBackend mocks base method. +func (m *MockFastlyClient) GetDirectorBackend(arg0 *fastly.GetDirectorBackendInput) (*fastly.DirectorBackend, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDirectorBackend", arg0) + ret0, _ := ret[0].(*fastly.DirectorBackend) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDirectorBackend indicates an expected call of GetDirectorBackend. +func (mr *MockFastlyClientMockRecorder) GetDirectorBackend(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDirectorBackend", reflect.TypeOf((*MockFastlyClient)(nil).GetDirectorBackend), arg0) +} + +// GetDomain mocks base method. +func (m *MockFastlyClient) GetDomain(arg0 *fastly.GetDomainInput) (*fastly.Domain, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDomain", arg0) + ret0, _ := ret[0].(*fastly.Domain) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDomain indicates an expected call of GetDomain. +func (mr *MockFastlyClientMockRecorder) GetDomain(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDomain", reflect.TypeOf((*MockFastlyClient)(nil).GetDomain), arg0) +} + +// GetDynamicSnippet mocks base method. +func (m *MockFastlyClient) GetDynamicSnippet(arg0 *fastly.GetDynamicSnippetInput) (*fastly.DynamicSnippet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDynamicSnippet", arg0) + ret0, _ := ret[0].(*fastly.DynamicSnippet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDynamicSnippet indicates an expected call of GetDynamicSnippet. +func (mr *MockFastlyClientMockRecorder) GetDynamicSnippet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDynamicSnippet", reflect.TypeOf((*MockFastlyClient)(nil).GetDynamicSnippet), arg0) +} + +// GetERL mocks base method. +func (m *MockFastlyClient) GetERL(arg0 *fastly.GetERLInput) (*fastly.ERL, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetERL", arg0) + ret0, _ := ret[0].(*fastly.ERL) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetERL indicates an expected call of GetERL. +func (mr *MockFastlyClientMockRecorder) GetERL(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetERL", reflect.TypeOf((*MockFastlyClient)(nil).GetERL), arg0) +} + +// GetElasticsearch mocks base method. +func (m *MockFastlyClient) GetElasticsearch(arg0 *fastly.GetElasticsearchInput) (*fastly.Elasticsearch, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetElasticsearch", arg0) + ret0, _ := ret[0].(*fastly.Elasticsearch) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetElasticsearch indicates an expected call of GetElasticsearch. +func (mr *MockFastlyClientMockRecorder) GetElasticsearch(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetElasticsearch", reflect.TypeOf((*MockFastlyClient)(nil).GetElasticsearch), arg0) +} + +// GetFTP mocks base method. +func (m *MockFastlyClient) GetFTP(arg0 *fastly.GetFTPInput) (*fastly.FTP, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFTP", arg0) + ret0, _ := ret[0].(*fastly.FTP) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFTP indicates an expected call of GetFTP. +func (mr *MockFastlyClientMockRecorder) GetFTP(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFTP", reflect.TypeOf((*MockFastlyClient)(nil).GetFTP), arg0) +} + +// GetGCS mocks base method. +func (m *MockFastlyClient) GetGCS(arg0 *fastly.GetGCSInput) (*fastly.GCS, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetGCS", arg0) + ret0, _ := ret[0].(*fastly.GCS) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetGCS indicates an expected call of GetGCS. +func (mr *MockFastlyClientMockRecorder) GetGCS(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGCS", reflect.TypeOf((*MockFastlyClient)(nil).GetGCS), arg0) +} + +// GetGeneratedVCL mocks base method. +func (m *MockFastlyClient) GetGeneratedVCL(arg0 *fastly.GetGeneratedVCLInput) (*fastly.VCL, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetGeneratedVCL", arg0) + ret0, _ := ret[0].(*fastly.VCL) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetGeneratedVCL indicates an expected call of GetGeneratedVCL. +func (mr *MockFastlyClientMockRecorder) GetGeneratedVCL(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGeneratedVCL", reflect.TypeOf((*MockFastlyClient)(nil).GetGeneratedVCL), arg0) +} + +// GetGzip mocks base method. +func (m *MockFastlyClient) GetGzip(arg0 *fastly.GetGzipInput) (*fastly.Gzip, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetGzip", arg0) + ret0, _ := ret[0].(*fastly.Gzip) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetGzip indicates an expected call of GetGzip. +func (mr *MockFastlyClientMockRecorder) GetGzip(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGzip", reflect.TypeOf((*MockFastlyClient)(nil).GetGzip), arg0) +} + +// GetHTTPS mocks base method. +func (m *MockFastlyClient) GetHTTPS(arg0 *fastly.GetHTTPSInput) (*fastly.HTTPS, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetHTTPS", arg0) + ret0, _ := ret[0].(*fastly.HTTPS) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetHTTPS indicates an expected call of GetHTTPS. +func (mr *MockFastlyClientMockRecorder) GetHTTPS(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHTTPS", reflect.TypeOf((*MockFastlyClient)(nil).GetHTTPS), arg0) +} + +// GetHeader mocks base method. +func (m *MockFastlyClient) GetHeader(arg0 *fastly.GetHeaderInput) (*fastly.Header, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetHeader", arg0) + ret0, _ := ret[0].(*fastly.Header) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetHeader indicates an expected call of GetHeader. +func (mr *MockFastlyClientMockRecorder) GetHeader(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHeader", reflect.TypeOf((*MockFastlyClient)(nil).GetHeader), arg0) +} + +// GetHealthCheck mocks base method. +func (m *MockFastlyClient) GetHealthCheck(arg0 *fastly.GetHealthCheckInput) (*fastly.HealthCheck, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetHealthCheck", arg0) + ret0, _ := ret[0].(*fastly.HealthCheck) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetHealthCheck indicates an expected call of GetHealthCheck. +func (mr *MockFastlyClientMockRecorder) GetHealthCheck(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthCheck", reflect.TypeOf((*MockFastlyClient)(nil).GetHealthCheck), arg0) +} + +// GetHeroku mocks base method. +func (m *MockFastlyClient) GetHeroku(arg0 *fastly.GetHerokuInput) (*fastly.Heroku, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetHeroku", arg0) + ret0, _ := ret[0].(*fastly.Heroku) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetHeroku indicates an expected call of GetHeroku. +func (mr *MockFastlyClientMockRecorder) GetHeroku(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHeroku", reflect.TypeOf((*MockFastlyClient)(nil).GetHeroku), arg0) +} + +// GetHoneycomb mocks base method. +func (m *MockFastlyClient) GetHoneycomb(arg0 *fastly.GetHoneycombInput) (*fastly.Honeycomb, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetHoneycomb", arg0) + ret0, _ := ret[0].(*fastly.Honeycomb) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetHoneycomb indicates an expected call of GetHoneycomb. +func (mr *MockFastlyClientMockRecorder) GetHoneycomb(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHoneycomb", reflect.TypeOf((*MockFastlyClient)(nil).GetHoneycomb), arg0) +} + +// GetKafka mocks base method. +func (m *MockFastlyClient) GetKafka(arg0 *fastly.GetKafkaInput) (*fastly.Kafka, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetKafka", arg0) + ret0, _ := ret[0].(*fastly.Kafka) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetKafka indicates an expected call of GetKafka. +func (mr *MockFastlyClientMockRecorder) GetKafka(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKafka", reflect.TypeOf((*MockFastlyClient)(nil).GetKafka), arg0) +} + +// GetKinesis mocks base method. +func (m *MockFastlyClient) GetKinesis(arg0 *fastly.GetKinesisInput) (*fastly.Kinesis, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetKinesis", arg0) + ret0, _ := ret[0].(*fastly.Kinesis) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetKinesis indicates an expected call of GetKinesis. +func (mr *MockFastlyClientMockRecorder) GetKinesis(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKinesis", reflect.TypeOf((*MockFastlyClient)(nil).GetKinesis), arg0) +} + +// GetLogentries mocks base method. +func (m *MockFastlyClient) GetLogentries(arg0 *fastly.GetLogentriesInput) (*fastly.Logentries, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLogentries", arg0) + ret0, _ := ret[0].(*fastly.Logentries) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLogentries indicates an expected call of GetLogentries. +func (mr *MockFastlyClientMockRecorder) GetLogentries(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogentries", reflect.TypeOf((*MockFastlyClient)(nil).GetLogentries), arg0) +} + +// GetLoggly mocks base method. +func (m *MockFastlyClient) GetLoggly(arg0 *fastly.GetLogglyInput) (*fastly.Loggly, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLoggly", arg0) + ret0, _ := ret[0].(*fastly.Loggly) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLoggly indicates an expected call of GetLoggly. +func (mr *MockFastlyClientMockRecorder) GetLoggly(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLoggly", reflect.TypeOf((*MockFastlyClient)(nil).GetLoggly), arg0) +} + +// GetLogshuttle mocks base method. +func (m *MockFastlyClient) GetLogshuttle(arg0 *fastly.GetLogshuttleInput) (*fastly.Logshuttle, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLogshuttle", arg0) + ret0, _ := ret[0].(*fastly.Logshuttle) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLogshuttle indicates an expected call of GetLogshuttle. +func (mr *MockFastlyClientMockRecorder) GetLogshuttle(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogshuttle", reflect.TypeOf((*MockFastlyClient)(nil).GetLogshuttle), arg0) +} + +// GetNewRelic mocks base method. +func (m *MockFastlyClient) GetNewRelic(arg0 *fastly.GetNewRelicInput) (*fastly.NewRelic, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNewRelic", arg0) + ret0, _ := ret[0].(*fastly.NewRelic) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetNewRelic indicates an expected call of GetNewRelic. +func (mr *MockFastlyClientMockRecorder) GetNewRelic(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNewRelic", reflect.TypeOf((*MockFastlyClient)(nil).GetNewRelic), arg0) +} + +// GetObjectStore mocks base method. +func (m *MockFastlyClient) GetObjectStore(arg0 *fastly.GetObjectStoreInput) (*fastly.ObjectStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectStore", arg0) + ret0, _ := ret[0].(*fastly.ObjectStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectStore indicates an expected call of GetObjectStore. +func (mr *MockFastlyClientMockRecorder) GetObjectStore(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectStore", reflect.TypeOf((*MockFastlyClient)(nil).GetObjectStore), arg0) +} + +// GetObjectStoreKey mocks base method. +func (m *MockFastlyClient) GetObjectStoreKey(arg0 *fastly.GetObjectStoreKeyInput) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetObjectStoreKey", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetObjectStoreKey indicates an expected call of GetObjectStoreKey. +func (mr *MockFastlyClientMockRecorder) GetObjectStoreKey(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectStoreKey", reflect.TypeOf((*MockFastlyClient)(nil).GetObjectStoreKey), arg0) +} + +// GetOpenstack mocks base method. +func (m *MockFastlyClient) GetOpenstack(arg0 *fastly.GetOpenstackInput) (*fastly.Openstack, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOpenstack", arg0) + ret0, _ := ret[0].(*fastly.Openstack) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOpenstack indicates an expected call of GetOpenstack. +func (mr *MockFastlyClientMockRecorder) GetOpenstack(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOpenstack", reflect.TypeOf((*MockFastlyClient)(nil).GetOpenstack), arg0) +} + +// GetOriginMetricsForService mocks base method. +func (m *MockFastlyClient) GetOriginMetricsForService(arg0 *fastly.GetOriginMetricsInput) (*fastly.OriginInspector, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOriginMetricsForService", arg0) + ret0, _ := ret[0].(*fastly.OriginInspector) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOriginMetricsForService indicates an expected call of GetOriginMetricsForService. +func (mr *MockFastlyClientMockRecorder) GetOriginMetricsForService(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOriginMetricsForService", reflect.TypeOf((*MockFastlyClient)(nil).GetOriginMetricsForService), arg0) +} + +// GetOriginMetricsForServiceJSON mocks base method. +func (m *MockFastlyClient) GetOriginMetricsForServiceJSON(arg0 *fastly.GetOriginMetricsInput, arg1 interface{}) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOriginMetricsForServiceJSON", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetOriginMetricsForServiceJSON indicates an expected call of GetOriginMetricsForServiceJSON. +func (mr *MockFastlyClientMockRecorder) GetOriginMetricsForServiceJSON(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOriginMetricsForServiceJSON", reflect.TypeOf((*MockFastlyClient)(nil).GetOriginMetricsForServiceJSON), arg0, arg1) +} + +// GetPackage mocks base method. +func (m *MockFastlyClient) GetPackage(arg0 *fastly.GetPackageInput) (*fastly.Package, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPackage", arg0) + ret0, _ := ret[0].(*fastly.Package) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPackage indicates an expected call of GetPackage. +func (mr *MockFastlyClientMockRecorder) GetPackage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPackage", reflect.TypeOf((*MockFastlyClient)(nil).GetPackage), arg0) +} + +// GetPapertrail mocks base method. +func (m *MockFastlyClient) GetPapertrail(arg0 *fastly.GetPapertrailInput) (*fastly.Papertrail, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPapertrail", arg0) + ret0, _ := ret[0].(*fastly.Papertrail) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPapertrail indicates an expected call of GetPapertrail. +func (mr *MockFastlyClientMockRecorder) GetPapertrail(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPapertrail", reflect.TypeOf((*MockFastlyClient)(nil).GetPapertrail), arg0) +} + +// GetPool mocks base method. +func (m *MockFastlyClient) GetPool(arg0 *fastly.GetPoolInput) (*fastly.Pool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPool", arg0) + ret0, _ := ret[0].(*fastly.Pool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPool indicates an expected call of GetPool. +func (mr *MockFastlyClientMockRecorder) GetPool(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPool", reflect.TypeOf((*MockFastlyClient)(nil).GetPool), arg0) +} + +// GetPrivateKey mocks base method. +func (m *MockFastlyClient) GetPrivateKey(arg0 *fastly.GetPrivateKeyInput) (*fastly.PrivateKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPrivateKey", arg0) + ret0, _ := ret[0].(*fastly.PrivateKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPrivateKey indicates an expected call of GetPrivateKey. +func (mr *MockFastlyClientMockRecorder) GetPrivateKey(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrivateKey", reflect.TypeOf((*MockFastlyClient)(nil).GetPrivateKey), arg0) +} + +// GetPubsub mocks base method. +func (m *MockFastlyClient) GetPubsub(arg0 *fastly.GetPubsubInput) (*fastly.Pubsub, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPubsub", arg0) + ret0, _ := ret[0].(*fastly.Pubsub) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPubsub indicates an expected call of GetPubsub. +func (mr *MockFastlyClientMockRecorder) GetPubsub(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPubsub", reflect.TypeOf((*MockFastlyClient)(nil).GetPubsub), arg0) +} + +// GetRegions mocks base method. +func (m *MockFastlyClient) GetRegions() (*fastly.RegionsResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRegions") + ret0, _ := ret[0].(*fastly.RegionsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRegions indicates an expected call of GetRegions. +func (mr *MockFastlyClientMockRecorder) GetRegions() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRegions", reflect.TypeOf((*MockFastlyClient)(nil).GetRegions)) +} + +// GetRequestSetting mocks base method. +func (m *MockFastlyClient) GetRequestSetting(arg0 *fastly.GetRequestSettingInput) (*fastly.RequestSetting, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRequestSetting", arg0) + ret0, _ := ret[0].(*fastly.RequestSetting) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRequestSetting indicates an expected call of GetRequestSetting. +func (mr *MockFastlyClientMockRecorder) GetRequestSetting(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRequestSetting", reflect.TypeOf((*MockFastlyClient)(nil).GetRequestSetting), arg0) +} + +// GetResponseObject mocks base method. +func (m *MockFastlyClient) GetResponseObject(arg0 *fastly.GetResponseObjectInput) (*fastly.ResponseObject, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetResponseObject", arg0) + ret0, _ := ret[0].(*fastly.ResponseObject) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetResponseObject indicates an expected call of GetResponseObject. +func (mr *MockFastlyClientMockRecorder) GetResponseObject(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResponseObject", reflect.TypeOf((*MockFastlyClient)(nil).GetResponseObject), arg0) +} + +// GetS3 mocks base method. +func (m *MockFastlyClient) GetS3(arg0 *fastly.GetS3Input) (*fastly.S3, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetS3", arg0) + ret0, _ := ret[0].(*fastly.S3) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetS3 indicates an expected call of GetS3. +func (mr *MockFastlyClientMockRecorder) GetS3(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetS3", reflect.TypeOf((*MockFastlyClient)(nil).GetS3), arg0) +} + +// GetSFTP mocks base method. +func (m *MockFastlyClient) GetSFTP(arg0 *fastly.GetSFTPInput) (*fastly.SFTP, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSFTP", arg0) + ret0, _ := ret[0].(*fastly.SFTP) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSFTP indicates an expected call of GetSFTP. +func (mr *MockFastlyClientMockRecorder) GetSFTP(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSFTP", reflect.TypeOf((*MockFastlyClient)(nil).GetSFTP), arg0) +} + +// GetScalyr mocks base method. +func (m *MockFastlyClient) GetScalyr(arg0 *fastly.GetScalyrInput) (*fastly.Scalyr, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetScalyr", arg0) + ret0, _ := ret[0].(*fastly.Scalyr) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetScalyr indicates an expected call of GetScalyr. +func (mr *MockFastlyClientMockRecorder) GetScalyr(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetScalyr", reflect.TypeOf((*MockFastlyClient)(nil).GetScalyr), arg0) +} + +// GetSecret mocks base method. +func (m *MockFastlyClient) GetSecret(arg0 *fastly.GetSecretInput) (*fastly.Secret, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSecret", arg0) + ret0, _ := ret[0].(*fastly.Secret) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSecret indicates an expected call of GetSecret. +func (mr *MockFastlyClientMockRecorder) GetSecret(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSecret", reflect.TypeOf((*MockFastlyClient)(nil).GetSecret), arg0) +} + +// GetSecretStore mocks base method. +func (m *MockFastlyClient) GetSecretStore(arg0 *fastly.GetSecretStoreInput) (*fastly.SecretStore, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSecretStore", arg0) + ret0, _ := ret[0].(*fastly.SecretStore) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSecretStore indicates an expected call of GetSecretStore. +func (mr *MockFastlyClientMockRecorder) GetSecretStore(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSecretStore", reflect.TypeOf((*MockFastlyClient)(nil).GetSecretStore), arg0) +} + +// GetServer mocks base method. +func (m *MockFastlyClient) GetServer(arg0 *fastly.GetServerInput) (*fastly.Server, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetServer", arg0) + ret0, _ := ret[0].(*fastly.Server) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetServer indicates an expected call of GetServer. +func (mr *MockFastlyClientMockRecorder) GetServer(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetServer", reflect.TypeOf((*MockFastlyClient)(nil).GetServer), arg0) +} + +// GetService mocks base method. +func (m *MockFastlyClient) GetService(arg0 *fastly.GetServiceInput) (*fastly.Service, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetService", arg0) + ret0, _ := ret[0].(*fastly.Service) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetService indicates an expected call of GetService. +func (mr *MockFastlyClientMockRecorder) GetService(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetService", reflect.TypeOf((*MockFastlyClient)(nil).GetService), arg0) +} + +// GetServiceAuthorization mocks base method. +func (m *MockFastlyClient) GetServiceAuthorization(arg0 *fastly.GetServiceAuthorizationInput) (*fastly.ServiceAuthorization, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetServiceAuthorization", arg0) + ret0, _ := ret[0].(*fastly.ServiceAuthorization) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetServiceAuthorization indicates an expected call of GetServiceAuthorization. +func (mr *MockFastlyClientMockRecorder) GetServiceAuthorization(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetServiceAuthorization", reflect.TypeOf((*MockFastlyClient)(nil).GetServiceAuthorization), arg0) +} + +// GetServiceDetails mocks base method. +func (m *MockFastlyClient) GetServiceDetails(arg0 *fastly.GetServiceInput) (*fastly.ServiceDetail, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetServiceDetails", arg0) + ret0, _ := ret[0].(*fastly.ServiceDetail) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetServiceDetails indicates an expected call of GetServiceDetails. +func (mr *MockFastlyClientMockRecorder) GetServiceDetails(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetServiceDetails", reflect.TypeOf((*MockFastlyClient)(nil).GetServiceDetails), arg0) +} + +// GetSettings mocks base method. +func (m *MockFastlyClient) GetSettings(arg0 *fastly.GetSettingsInput) (*fastly.Settings, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSettings", arg0) + ret0, _ := ret[0].(*fastly.Settings) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSettings indicates an expected call of GetSettings. +func (mr *MockFastlyClientMockRecorder) GetSettings(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSettings", reflect.TypeOf((*MockFastlyClient)(nil).GetSettings), arg0) +} + +// GetSnippet mocks base method. +func (m *MockFastlyClient) GetSnippet(arg0 *fastly.GetSnippetInput) (*fastly.Snippet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSnippet", arg0) + ret0, _ := ret[0].(*fastly.Snippet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSnippet indicates an expected call of GetSnippet. +func (mr *MockFastlyClientMockRecorder) GetSnippet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSnippet", reflect.TypeOf((*MockFastlyClient)(nil).GetSnippet), arg0) +} + +// GetSplunk mocks base method. +func (m *MockFastlyClient) GetSplunk(arg0 *fastly.GetSplunkInput) (*fastly.Splunk, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSplunk", arg0) + ret0, _ := ret[0].(*fastly.Splunk) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSplunk indicates an expected call of GetSplunk. +func (mr *MockFastlyClientMockRecorder) GetSplunk(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSplunk", reflect.TypeOf((*MockFastlyClient)(nil).GetSplunk), arg0) +} + +// GetStats mocks base method. +func (m *MockFastlyClient) GetStats(arg0 *fastly.GetStatsInput) (*fastly.StatsResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStats", arg0) + ret0, _ := ret[0].(*fastly.StatsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStats indicates an expected call of GetStats. +func (mr *MockFastlyClientMockRecorder) GetStats(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStats", reflect.TypeOf((*MockFastlyClient)(nil).GetStats), arg0) +} + +// GetStatsField mocks base method. +func (m *MockFastlyClient) GetStatsField(arg0 *fastly.GetStatsInput) (*fastly.StatsFieldResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStatsField", arg0) + ret0, _ := ret[0].(*fastly.StatsFieldResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStatsField indicates an expected call of GetStatsField. +func (mr *MockFastlyClientMockRecorder) GetStatsField(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatsField", reflect.TypeOf((*MockFastlyClient)(nil).GetStatsField), arg0) +} + +// GetStatsJSON mocks base method. +func (m *MockFastlyClient) GetStatsJSON(arg0 *fastly.GetStatsInput, arg1 interface{}) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStatsJSON", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetStatsJSON indicates an expected call of GetStatsJSON. +func (mr *MockFastlyClientMockRecorder) GetStatsJSON(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatsJSON", reflect.TypeOf((*MockFastlyClient)(nil).GetStatsJSON), arg0, arg1) +} + +// GetSumologic mocks base method. +func (m *MockFastlyClient) GetSumologic(arg0 *fastly.GetSumologicInput) (*fastly.Sumologic, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSumologic", arg0) + ret0, _ := ret[0].(*fastly.Sumologic) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSumologic indicates an expected call of GetSumologic. +func (mr *MockFastlyClientMockRecorder) GetSumologic(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSumologic", reflect.TypeOf((*MockFastlyClient)(nil).GetSumologic), arg0) +} + +// GetSyslog mocks base method. +func (m *MockFastlyClient) GetSyslog(arg0 *fastly.GetSyslogInput) (*fastly.Syslog, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSyslog", arg0) + ret0, _ := ret[0].(*fastly.Syslog) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSyslog indicates an expected call of GetSyslog. +func (mr *MockFastlyClientMockRecorder) GetSyslog(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSyslog", reflect.TypeOf((*MockFastlyClient)(nil).GetSyslog), arg0) +} + +// GetTLSActivation mocks base method. +func (m *MockFastlyClient) GetTLSActivation(arg0 *fastly.GetTLSActivationInput) (*fastly.TLSActivation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTLSActivation", arg0) + ret0, _ := ret[0].(*fastly.TLSActivation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTLSActivation indicates an expected call of GetTLSActivation. +func (mr *MockFastlyClientMockRecorder) GetTLSActivation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTLSActivation", reflect.TypeOf((*MockFastlyClient)(nil).GetTLSActivation), arg0) +} + +// GetTLSSubscription mocks base method. +func (m *MockFastlyClient) GetTLSSubscription(arg0 *fastly.GetTLSSubscriptionInput) (*fastly.TLSSubscription, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTLSSubscription", arg0) + ret0, _ := ret[0].(*fastly.TLSSubscription) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTLSSubscription indicates an expected call of GetTLSSubscription. +func (mr *MockFastlyClientMockRecorder) GetTLSSubscription(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTLSSubscription", reflect.TypeOf((*MockFastlyClient)(nil).GetTLSSubscription), arg0) +} + +// GetTokenSelf mocks base method. +func (m *MockFastlyClient) GetTokenSelf() (*fastly.Token, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTokenSelf") + ret0, _ := ret[0].(*fastly.Token) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTokenSelf indicates an expected call of GetTokenSelf. +func (mr *MockFastlyClientMockRecorder) GetTokenSelf() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTokenSelf", reflect.TypeOf((*MockFastlyClient)(nil).GetTokenSelf)) +} + +// GetUsage mocks base method. +func (m *MockFastlyClient) GetUsage(arg0 *fastly.GetUsageInput) (*fastly.UsageResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUsage", arg0) + ret0, _ := ret[0].(*fastly.UsageResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUsage indicates an expected call of GetUsage. +func (mr *MockFastlyClientMockRecorder) GetUsage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUsage", reflect.TypeOf((*MockFastlyClient)(nil).GetUsage), arg0) +} + +// GetUsageByService mocks base method. +func (m *MockFastlyClient) GetUsageByService(arg0 *fastly.GetUsageInput) (*fastly.UsageByServiceResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUsageByService", arg0) + ret0, _ := ret[0].(*fastly.UsageByServiceResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUsageByService indicates an expected call of GetUsageByService. +func (mr *MockFastlyClientMockRecorder) GetUsageByService(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUsageByService", reflect.TypeOf((*MockFastlyClient)(nil).GetUsageByService), arg0) +} + +// GetUser mocks base method. +func (m *MockFastlyClient) GetUser(arg0 *fastly.GetUserInput) (*fastly.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUser", arg0) + ret0, _ := ret[0].(*fastly.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUser indicates an expected call of GetUser. +func (mr *MockFastlyClientMockRecorder) GetUser(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUser", reflect.TypeOf((*MockFastlyClient)(nil).GetUser), arg0) +} + +// GetVCL mocks base method. +func (m *MockFastlyClient) GetVCL(arg0 *fastly.GetVCLInput) (*fastly.VCL, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetVCL", arg0) + ret0, _ := ret[0].(*fastly.VCL) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetVCL indicates an expected call of GetVCL. +func (mr *MockFastlyClientMockRecorder) GetVCL(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVCL", reflect.TypeOf((*MockFastlyClient)(nil).GetVCL), arg0) +} + +// GetVersion mocks base method. +func (m *MockFastlyClient) GetVersion(arg0 *fastly.GetVersionInput) (*fastly.Version, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetVersion", arg0) + ret0, _ := ret[0].(*fastly.Version) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetVersion indicates an expected call of GetVersion. +func (mr *MockFastlyClientMockRecorder) GetVersion(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVersion", reflect.TypeOf((*MockFastlyClient)(nil).GetVersion), arg0) +} + +// GetWAF mocks base method. +func (m *MockFastlyClient) GetWAF(arg0 *fastly.GetWAFInput) (*fastly.WAF, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetWAF", arg0) + ret0, _ := ret[0].(*fastly.WAF) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetWAF indicates an expected call of GetWAF. +func (mr *MockFastlyClientMockRecorder) GetWAF(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWAF", reflect.TypeOf((*MockFastlyClient)(nil).GetWAF), arg0) +} + +// GetWAFVersion mocks base method. +func (m *MockFastlyClient) GetWAFVersion(arg0 *fastly.GetWAFVersionInput) (*fastly.WAFVersion, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetWAFVersion", arg0) + ret0, _ := ret[0].(*fastly.WAFVersion) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetWAFVersion indicates an expected call of GetWAFVersion. +func (mr *MockFastlyClientMockRecorder) GetWAFVersion(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWAFVersion", reflect.TypeOf((*MockFastlyClient)(nil).GetWAFVersion), arg0) +} + +// ListACLEntries mocks base method. +func (m *MockFastlyClient) ListACLEntries(arg0 *fastly.ListACLEntriesInput) ([]*fastly.ACLEntry, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListACLEntries", arg0) + ret0, _ := ret[0].([]*fastly.ACLEntry) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListACLEntries indicates an expected call of ListACLEntries. +func (mr *MockFastlyClientMockRecorder) ListACLEntries(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListACLEntries", reflect.TypeOf((*MockFastlyClient)(nil).ListACLEntries), arg0) +} + +// ListACLs mocks base method. +func (m *MockFastlyClient) ListACLs(arg0 *fastly.ListACLsInput) ([]*fastly.ACL, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListACLs", arg0) + ret0, _ := ret[0].([]*fastly.ACL) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListACLs indicates an expected call of ListACLs. +func (mr *MockFastlyClientMockRecorder) ListACLs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListACLs", reflect.TypeOf((*MockFastlyClient)(nil).ListACLs), arg0) +} + +// ListAllWAFActiveRules mocks base method. +func (m *MockFastlyClient) ListAllWAFActiveRules(arg0 *fastly.ListAllWAFActiveRulesInput) (*fastly.WAFActiveRuleResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListAllWAFActiveRules", arg0) + ret0, _ := ret[0].(*fastly.WAFActiveRuleResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListAllWAFActiveRules indicates an expected call of ListAllWAFActiveRules. +func (mr *MockFastlyClientMockRecorder) ListAllWAFActiveRules(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAllWAFActiveRules", reflect.TypeOf((*MockFastlyClient)(nil).ListAllWAFActiveRules), arg0) +} + +// ListAllWAFRuleExclusions mocks base method. +func (m *MockFastlyClient) ListAllWAFRuleExclusions(arg0 *fastly.ListAllWAFRuleExclusionsInput) (*fastly.WAFRuleExclusionResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListAllWAFRuleExclusions", arg0) + ret0, _ := ret[0].(*fastly.WAFRuleExclusionResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListAllWAFRuleExclusions indicates an expected call of ListAllWAFRuleExclusions. +func (mr *MockFastlyClientMockRecorder) ListAllWAFRuleExclusions(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAllWAFRuleExclusions", reflect.TypeOf((*MockFastlyClient)(nil).ListAllWAFRuleExclusions), arg0) +} + +// ListAllWAFRules mocks base method. +func (m *MockFastlyClient) ListAllWAFRules(arg0 *fastly.ListAllWAFRulesInput) (*fastly.WAFRuleResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListAllWAFRules", arg0) + ret0, _ := ret[0].(*fastly.WAFRuleResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListAllWAFRules indicates an expected call of ListAllWAFRules. +func (mr *MockFastlyClientMockRecorder) ListAllWAFRules(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAllWAFRules", reflect.TypeOf((*MockFastlyClient)(nil).ListAllWAFRules), arg0) +} + +// ListAllWAFVersions mocks base method. +func (m *MockFastlyClient) ListAllWAFVersions(arg0 *fastly.ListAllWAFVersionsInput) (*fastly.WAFVersionResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListAllWAFVersions", arg0) + ret0, _ := ret[0].(*fastly.WAFVersionResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListAllWAFVersions indicates an expected call of ListAllWAFVersions. +func (mr *MockFastlyClientMockRecorder) ListAllWAFVersions(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAllWAFVersions", reflect.TypeOf((*MockFastlyClient)(nil).ListAllWAFVersions), arg0) +} + +// ListBackends mocks base method. +func (m *MockFastlyClient) ListBackends(arg0 *fastly.ListBackendsInput) ([]*fastly.Backend, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBackends", arg0) + ret0, _ := ret[0].([]*fastly.Backend) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBackends indicates an expected call of ListBackends. +func (mr *MockFastlyClientMockRecorder) ListBackends(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBackends", reflect.TypeOf((*MockFastlyClient)(nil).ListBackends), arg0) +} + +// ListBigQueries mocks base method. +func (m *MockFastlyClient) ListBigQueries(arg0 *fastly.ListBigQueriesInput) ([]*fastly.BigQuery, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBigQueries", arg0) + ret0, _ := ret[0].([]*fastly.BigQuery) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBigQueries indicates an expected call of ListBigQueries. +func (mr *MockFastlyClientMockRecorder) ListBigQueries(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBigQueries", reflect.TypeOf((*MockFastlyClient)(nil).ListBigQueries), arg0) +} + +// ListBlobStorages mocks base method. +func (m *MockFastlyClient) ListBlobStorages(arg0 *fastly.ListBlobStoragesInput) ([]*fastly.BlobStorage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBlobStorages", arg0) + ret0, _ := ret[0].([]*fastly.BlobStorage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBlobStorages indicates an expected call of ListBlobStorages. +func (mr *MockFastlyClientMockRecorder) ListBlobStorages(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBlobStorages", reflect.TypeOf((*MockFastlyClient)(nil).ListBlobStorages), arg0) +} + +// ListBulkCertificates mocks base method. +func (m *MockFastlyClient) ListBulkCertificates(arg0 *fastly.ListBulkCertificatesInput) ([]*fastly.BulkCertificate, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListBulkCertificates", arg0) + ret0, _ := ret[0].([]*fastly.BulkCertificate) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListBulkCertificates indicates an expected call of ListBulkCertificates. +func (mr *MockFastlyClientMockRecorder) ListBulkCertificates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBulkCertificates", reflect.TypeOf((*MockFastlyClient)(nil).ListBulkCertificates), arg0) +} + +// ListCacheSettings mocks base method. +func (m *MockFastlyClient) ListCacheSettings(arg0 *fastly.ListCacheSettingsInput) ([]*fastly.CacheSetting, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListCacheSettings", arg0) + ret0, _ := ret[0].([]*fastly.CacheSetting) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListCacheSettings indicates an expected call of ListCacheSettings. +func (mr *MockFastlyClientMockRecorder) ListCacheSettings(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCacheSettings", reflect.TypeOf((*MockFastlyClient)(nil).ListCacheSettings), arg0) +} + +// ListCloudfiles mocks base method. +func (m *MockFastlyClient) ListCloudfiles(arg0 *fastly.ListCloudfilesInput) ([]*fastly.Cloudfiles, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListCloudfiles", arg0) + ret0, _ := ret[0].([]*fastly.Cloudfiles) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListCloudfiles indicates an expected call of ListCloudfiles. +func (mr *MockFastlyClientMockRecorder) ListCloudfiles(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCloudfiles", reflect.TypeOf((*MockFastlyClient)(nil).ListCloudfiles), arg0) +} + +// ListConditions mocks base method. +func (m *MockFastlyClient) ListConditions(arg0 *fastly.ListConditionsInput) ([]*fastly.Condition, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListConditions", arg0) + ret0, _ := ret[0].([]*fastly.Condition) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListConditions indicates an expected call of ListConditions. +func (mr *MockFastlyClientMockRecorder) ListConditions(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListConditions", reflect.TypeOf((*MockFastlyClient)(nil).ListConditions), arg0) +} + +// ListCustomTLSCertificates mocks base method. +func (m *MockFastlyClient) ListCustomTLSCertificates(arg0 *fastly.ListCustomTLSCertificatesInput) ([]*fastly.CustomTLSCertificate, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListCustomTLSCertificates", arg0) + ret0, _ := ret[0].([]*fastly.CustomTLSCertificate) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListCustomTLSCertificates indicates an expected call of ListCustomTLSCertificates. +func (mr *MockFastlyClientMockRecorder) ListCustomTLSCertificates(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCustomTLSCertificates", reflect.TypeOf((*MockFastlyClient)(nil).ListCustomTLSCertificates), arg0) +} + +// ListCustomTLSConfigurations mocks base method. +func (m *MockFastlyClient) ListCustomTLSConfigurations(arg0 *fastly.ListCustomTLSConfigurationsInput) ([]*fastly.CustomTLSConfiguration, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListCustomTLSConfigurations", arg0) + ret0, _ := ret[0].([]*fastly.CustomTLSConfiguration) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListCustomTLSConfigurations indicates an expected call of ListCustomTLSConfigurations. +func (mr *MockFastlyClientMockRecorder) ListCustomTLSConfigurations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCustomTLSConfigurations", reflect.TypeOf((*MockFastlyClient)(nil).ListCustomTLSConfigurations), arg0) +} + +// ListCustomerTokens mocks base method. +func (m *MockFastlyClient) ListCustomerTokens(arg0 *fastly.ListCustomerTokensInput) ([]*fastly.Token, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListCustomerTokens", arg0) + ret0, _ := ret[0].([]*fastly.Token) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListCustomerTokens indicates an expected call of ListCustomerTokens. +func (mr *MockFastlyClientMockRecorder) ListCustomerTokens(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCustomerTokens", reflect.TypeOf((*MockFastlyClient)(nil).ListCustomerTokens), arg0) +} + +// ListCustomerUsers mocks base method. +func (m *MockFastlyClient) ListCustomerUsers(arg0 *fastly.ListCustomerUsersInput) ([]*fastly.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListCustomerUsers", arg0) + ret0, _ := ret[0].([]*fastly.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListCustomerUsers indicates an expected call of ListCustomerUsers. +func (mr *MockFastlyClientMockRecorder) ListCustomerUsers(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCustomerUsers", reflect.TypeOf((*MockFastlyClient)(nil).ListCustomerUsers), arg0) +} + +// ListDatadog mocks base method. +func (m *MockFastlyClient) ListDatadog(arg0 *fastly.ListDatadogInput) ([]*fastly.Datadog, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListDatadog", arg0) + ret0, _ := ret[0].([]*fastly.Datadog) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListDatadog indicates an expected call of ListDatadog. +func (mr *MockFastlyClientMockRecorder) ListDatadog(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDatadog", reflect.TypeOf((*MockFastlyClient)(nil).ListDatadog), arg0) +} + +// ListDictionaries mocks base method. +func (m *MockFastlyClient) ListDictionaries(arg0 *fastly.ListDictionariesInput) ([]*fastly.Dictionary, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListDictionaries", arg0) + ret0, _ := ret[0].([]*fastly.Dictionary) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListDictionaries indicates an expected call of ListDictionaries. +func (mr *MockFastlyClientMockRecorder) ListDictionaries(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDictionaries", reflect.TypeOf((*MockFastlyClient)(nil).ListDictionaries), arg0) +} + +// ListDictionaryItems mocks base method. +func (m *MockFastlyClient) ListDictionaryItems(arg0 *fastly.ListDictionaryItemsInput) ([]*fastly.DictionaryItem, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListDictionaryItems", arg0) + ret0, _ := ret[0].([]*fastly.DictionaryItem) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListDictionaryItems indicates an expected call of ListDictionaryItems. +func (mr *MockFastlyClientMockRecorder) ListDictionaryItems(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDictionaryItems", reflect.TypeOf((*MockFastlyClient)(nil).ListDictionaryItems), arg0) +} + +// ListDigitalOceans mocks base method. +func (m *MockFastlyClient) ListDigitalOceans(arg0 *fastly.ListDigitalOceansInput) ([]*fastly.DigitalOcean, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListDigitalOceans", arg0) + ret0, _ := ret[0].([]*fastly.DigitalOcean) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListDigitalOceans indicates an expected call of ListDigitalOceans. +func (mr *MockFastlyClientMockRecorder) ListDigitalOceans(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDigitalOceans", reflect.TypeOf((*MockFastlyClient)(nil).ListDigitalOceans), arg0) +} + +// ListDirectors mocks base method. +func (m *MockFastlyClient) ListDirectors(arg0 *fastly.ListDirectorsInput) ([]*fastly.Director, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListDirectors", arg0) + ret0, _ := ret[0].([]*fastly.Director) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListDirectors indicates an expected call of ListDirectors. +func (mr *MockFastlyClientMockRecorder) ListDirectors(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDirectors", reflect.TypeOf((*MockFastlyClient)(nil).ListDirectors), arg0) +} + +// ListDomains mocks base method. +func (m *MockFastlyClient) ListDomains(arg0 *fastly.ListDomainsInput) ([]*fastly.Domain, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListDomains", arg0) + ret0, _ := ret[0].([]*fastly.Domain) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListDomains indicates an expected call of ListDomains. +func (mr *MockFastlyClientMockRecorder) ListDomains(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDomains", reflect.TypeOf((*MockFastlyClient)(nil).ListDomains), arg0) +} + +// ListERLs mocks base method. +func (m *MockFastlyClient) ListERLs(arg0 *fastly.ListERLsInput) ([]*fastly.ERL, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListERLs", arg0) + ret0, _ := ret[0].([]*fastly.ERL) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListERLs indicates an expected call of ListERLs. +func (mr *MockFastlyClientMockRecorder) ListERLs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListERLs", reflect.TypeOf((*MockFastlyClient)(nil).ListERLs), arg0) +} + +// ListElasticsearch mocks base method. +func (m *MockFastlyClient) ListElasticsearch(arg0 *fastly.ListElasticsearchInput) ([]*fastly.Elasticsearch, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListElasticsearch", arg0) + ret0, _ := ret[0].([]*fastly.Elasticsearch) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListElasticsearch indicates an expected call of ListElasticsearch. +func (mr *MockFastlyClientMockRecorder) ListElasticsearch(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListElasticsearch", reflect.TypeOf((*MockFastlyClient)(nil).ListElasticsearch), arg0) +} + +// ListFTPs mocks base method. +func (m *MockFastlyClient) ListFTPs(arg0 *fastly.ListFTPsInput) ([]*fastly.FTP, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListFTPs", arg0) + ret0, _ := ret[0].([]*fastly.FTP) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListFTPs indicates an expected call of ListFTPs. +func (mr *MockFastlyClientMockRecorder) ListFTPs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListFTPs", reflect.TypeOf((*MockFastlyClient)(nil).ListFTPs), arg0) +} + +// ListGCSs mocks base method. +func (m *MockFastlyClient) ListGCSs(arg0 *fastly.ListGCSsInput) ([]*fastly.GCS, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListGCSs", arg0) + ret0, _ := ret[0].([]*fastly.GCS) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListGCSs indicates an expected call of ListGCSs. +func (mr *MockFastlyClientMockRecorder) ListGCSs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGCSs", reflect.TypeOf((*MockFastlyClient)(nil).ListGCSs), arg0) +} + +// ListGzips mocks base method. +func (m *MockFastlyClient) ListGzips(arg0 *fastly.ListGzipsInput) ([]*fastly.Gzip, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListGzips", arg0) + ret0, _ := ret[0].([]*fastly.Gzip) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListGzips indicates an expected call of ListGzips. +func (mr *MockFastlyClientMockRecorder) ListGzips(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGzips", reflect.TypeOf((*MockFastlyClient)(nil).ListGzips), arg0) +} + +// ListHTTPS mocks base method. +func (m *MockFastlyClient) ListHTTPS(arg0 *fastly.ListHTTPSInput) ([]*fastly.HTTPS, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListHTTPS", arg0) + ret0, _ := ret[0].([]*fastly.HTTPS) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListHTTPS indicates an expected call of ListHTTPS. +func (mr *MockFastlyClientMockRecorder) ListHTTPS(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListHTTPS", reflect.TypeOf((*MockFastlyClient)(nil).ListHTTPS), arg0) +} + +// ListHeaders mocks base method. +func (m *MockFastlyClient) ListHeaders(arg0 *fastly.ListHeadersInput) ([]*fastly.Header, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListHeaders", arg0) + ret0, _ := ret[0].([]*fastly.Header) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListHeaders indicates an expected call of ListHeaders. +func (mr *MockFastlyClientMockRecorder) ListHeaders(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListHeaders", reflect.TypeOf((*MockFastlyClient)(nil).ListHeaders), arg0) +} + +// ListHealthChecks mocks base method. +func (m *MockFastlyClient) ListHealthChecks(arg0 *fastly.ListHealthChecksInput) ([]*fastly.HealthCheck, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListHealthChecks", arg0) + ret0, _ := ret[0].([]*fastly.HealthCheck) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListHealthChecks indicates an expected call of ListHealthChecks. +func (mr *MockFastlyClientMockRecorder) ListHealthChecks(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListHealthChecks", reflect.TypeOf((*MockFastlyClient)(nil).ListHealthChecks), arg0) +} + +// ListHerokus mocks base method. +func (m *MockFastlyClient) ListHerokus(arg0 *fastly.ListHerokusInput) ([]*fastly.Heroku, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListHerokus", arg0) + ret0, _ := ret[0].([]*fastly.Heroku) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListHerokus indicates an expected call of ListHerokus. +func (mr *MockFastlyClientMockRecorder) ListHerokus(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListHerokus", reflect.TypeOf((*MockFastlyClient)(nil).ListHerokus), arg0) +} + +// ListHoneycombs mocks base method. +func (m *MockFastlyClient) ListHoneycombs(arg0 *fastly.ListHoneycombsInput) ([]*fastly.Honeycomb, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListHoneycombs", arg0) + ret0, _ := ret[0].([]*fastly.Honeycomb) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListHoneycombs indicates an expected call of ListHoneycombs. +func (mr *MockFastlyClientMockRecorder) ListHoneycombs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListHoneycombs", reflect.TypeOf((*MockFastlyClient)(nil).ListHoneycombs), arg0) +} + +// ListKafkas mocks base method. +func (m *MockFastlyClient) ListKafkas(arg0 *fastly.ListKafkasInput) ([]*fastly.Kafka, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListKafkas", arg0) + ret0, _ := ret[0].([]*fastly.Kafka) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListKafkas indicates an expected call of ListKafkas. +func (mr *MockFastlyClientMockRecorder) ListKafkas(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListKafkas", reflect.TypeOf((*MockFastlyClient)(nil).ListKafkas), arg0) +} + +// ListKinesis mocks base method. +func (m *MockFastlyClient) ListKinesis(arg0 *fastly.ListKinesisInput) ([]*fastly.Kinesis, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListKinesis", arg0) + ret0, _ := ret[0].([]*fastly.Kinesis) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListKinesis indicates an expected call of ListKinesis. +func (mr *MockFastlyClientMockRecorder) ListKinesis(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListKinesis", reflect.TypeOf((*MockFastlyClient)(nil).ListKinesis), arg0) +} + +// ListLogentries mocks base method. +func (m *MockFastlyClient) ListLogentries(arg0 *fastly.ListLogentriesInput) ([]*fastly.Logentries, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListLogentries", arg0) + ret0, _ := ret[0].([]*fastly.Logentries) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListLogentries indicates an expected call of ListLogentries. +func (mr *MockFastlyClientMockRecorder) ListLogentries(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogentries", reflect.TypeOf((*MockFastlyClient)(nil).ListLogentries), arg0) +} + +// ListLoggly mocks base method. +func (m *MockFastlyClient) ListLoggly(arg0 *fastly.ListLogglyInput) ([]*fastly.Loggly, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListLoggly", arg0) + ret0, _ := ret[0].([]*fastly.Loggly) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListLoggly indicates an expected call of ListLoggly. +func (mr *MockFastlyClientMockRecorder) ListLoggly(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLoggly", reflect.TypeOf((*MockFastlyClient)(nil).ListLoggly), arg0) +} + +// ListLogshuttles mocks base method. +func (m *MockFastlyClient) ListLogshuttles(arg0 *fastly.ListLogshuttlesInput) ([]*fastly.Logshuttle, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListLogshuttles", arg0) + ret0, _ := ret[0].([]*fastly.Logshuttle) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListLogshuttles indicates an expected call of ListLogshuttles. +func (mr *MockFastlyClientMockRecorder) ListLogshuttles(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogshuttles", reflect.TypeOf((*MockFastlyClient)(nil).ListLogshuttles), arg0) +} + +// ListNewRelic mocks base method. +func (m *MockFastlyClient) ListNewRelic(arg0 *fastly.ListNewRelicInput) ([]*fastly.NewRelic, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListNewRelic", arg0) + ret0, _ := ret[0].([]*fastly.NewRelic) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListNewRelic indicates an expected call of ListNewRelic. +func (mr *MockFastlyClientMockRecorder) ListNewRelic(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListNewRelic", reflect.TypeOf((*MockFastlyClient)(nil).ListNewRelic), arg0) +} + +// ListObjectStoreKeys mocks base method. +func (m *MockFastlyClient) ListObjectStoreKeys(arg0 *fastly.ListObjectStoreKeysInput) (*fastly.ListObjectStoreKeysResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectStoreKeys", arg0) + ret0, _ := ret[0].(*fastly.ListObjectStoreKeysResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListObjectStoreKeys indicates an expected call of ListObjectStoreKeys. +func (mr *MockFastlyClientMockRecorder) ListObjectStoreKeys(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectStoreKeys", reflect.TypeOf((*MockFastlyClient)(nil).ListObjectStoreKeys), arg0) +} + +// ListObjectStores mocks base method. +func (m *MockFastlyClient) ListObjectStores(arg0 *fastly.ListObjectStoresInput) (*fastly.ListObjectStoresResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListObjectStores", arg0) + ret0, _ := ret[0].(*fastly.ListObjectStoresResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListObjectStores indicates an expected call of ListObjectStores. +func (mr *MockFastlyClientMockRecorder) ListObjectStores(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectStores", reflect.TypeOf((*MockFastlyClient)(nil).ListObjectStores), arg0) +} + +// ListOpenstack mocks base method. +func (m *MockFastlyClient) ListOpenstack(arg0 *fastly.ListOpenstackInput) ([]*fastly.Openstack, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListOpenstack", arg0) + ret0, _ := ret[0].([]*fastly.Openstack) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListOpenstack indicates an expected call of ListOpenstack. +func (mr *MockFastlyClientMockRecorder) ListOpenstack(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListOpenstack", reflect.TypeOf((*MockFastlyClient)(nil).ListOpenstack), arg0) +} + +// ListPapertrails mocks base method. +func (m *MockFastlyClient) ListPapertrails(arg0 *fastly.ListPapertrailsInput) ([]*fastly.Papertrail, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListPapertrails", arg0) + ret0, _ := ret[0].([]*fastly.Papertrail) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListPapertrails indicates an expected call of ListPapertrails. +func (mr *MockFastlyClientMockRecorder) ListPapertrails(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPapertrails", reflect.TypeOf((*MockFastlyClient)(nil).ListPapertrails), arg0) +} + +// ListPools mocks base method. +func (m *MockFastlyClient) ListPools(arg0 *fastly.ListPoolsInput) ([]*fastly.Pool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListPools", arg0) + ret0, _ := ret[0].([]*fastly.Pool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListPools indicates an expected call of ListPools. +func (mr *MockFastlyClientMockRecorder) ListPools(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPools", reflect.TypeOf((*MockFastlyClient)(nil).ListPools), arg0) +} + +// ListPrivateKeys mocks base method. +func (m *MockFastlyClient) ListPrivateKeys(arg0 *fastly.ListPrivateKeysInput) ([]*fastly.PrivateKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListPrivateKeys", arg0) + ret0, _ := ret[0].([]*fastly.PrivateKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListPrivateKeys indicates an expected call of ListPrivateKeys. +func (mr *MockFastlyClientMockRecorder) ListPrivateKeys(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPrivateKeys", reflect.TypeOf((*MockFastlyClient)(nil).ListPrivateKeys), arg0) +} + +// ListPubsubs mocks base method. +func (m *MockFastlyClient) ListPubsubs(arg0 *fastly.ListPubsubsInput) ([]*fastly.Pubsub, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListPubsubs", arg0) + ret0, _ := ret[0].([]*fastly.Pubsub) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListPubsubs indicates an expected call of ListPubsubs. +func (mr *MockFastlyClientMockRecorder) ListPubsubs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPubsubs", reflect.TypeOf((*MockFastlyClient)(nil).ListPubsubs), arg0) +} + +// ListRequestSettings mocks base method. +func (m *MockFastlyClient) ListRequestSettings(arg0 *fastly.ListRequestSettingsInput) ([]*fastly.RequestSetting, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListRequestSettings", arg0) + ret0, _ := ret[0].([]*fastly.RequestSetting) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListRequestSettings indicates an expected call of ListRequestSettings. +func (mr *MockFastlyClientMockRecorder) ListRequestSettings(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListRequestSettings", reflect.TypeOf((*MockFastlyClient)(nil).ListRequestSettings), arg0) +} + +// ListResponseObjects mocks base method. +func (m *MockFastlyClient) ListResponseObjects(arg0 *fastly.ListResponseObjectsInput) ([]*fastly.ResponseObject, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListResponseObjects", arg0) + ret0, _ := ret[0].([]*fastly.ResponseObject) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListResponseObjects indicates an expected call of ListResponseObjects. +func (mr *MockFastlyClientMockRecorder) ListResponseObjects(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResponseObjects", reflect.TypeOf((*MockFastlyClient)(nil).ListResponseObjects), arg0) +} + +// ListS3s mocks base method. +func (m *MockFastlyClient) ListS3s(arg0 *fastly.ListS3sInput) ([]*fastly.S3, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListS3s", arg0) + ret0, _ := ret[0].([]*fastly.S3) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListS3s indicates an expected call of ListS3s. +func (mr *MockFastlyClientMockRecorder) ListS3s(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListS3s", reflect.TypeOf((*MockFastlyClient)(nil).ListS3s), arg0) +} + +// ListSFTPs mocks base method. +func (m *MockFastlyClient) ListSFTPs(arg0 *fastly.ListSFTPsInput) ([]*fastly.SFTP, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListSFTPs", arg0) + ret0, _ := ret[0].([]*fastly.SFTP) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListSFTPs indicates an expected call of ListSFTPs. +func (mr *MockFastlyClientMockRecorder) ListSFTPs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSFTPs", reflect.TypeOf((*MockFastlyClient)(nil).ListSFTPs), arg0) +} + +// ListScalyrs mocks base method. +func (m *MockFastlyClient) ListScalyrs(arg0 *fastly.ListScalyrsInput) ([]*fastly.Scalyr, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListScalyrs", arg0) + ret0, _ := ret[0].([]*fastly.Scalyr) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListScalyrs indicates an expected call of ListScalyrs. +func (mr *MockFastlyClientMockRecorder) ListScalyrs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListScalyrs", reflect.TypeOf((*MockFastlyClient)(nil).ListScalyrs), arg0) +} + +// ListSecretStores mocks base method. +func (m *MockFastlyClient) ListSecretStores(arg0 *fastly.ListSecretStoresInput) (*fastly.SecretStores, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListSecretStores", arg0) + ret0, _ := ret[0].(*fastly.SecretStores) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListSecretStores indicates an expected call of ListSecretStores. +func (mr *MockFastlyClientMockRecorder) ListSecretStores(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSecretStores", reflect.TypeOf((*MockFastlyClient)(nil).ListSecretStores), arg0) +} + +// ListSecrets mocks base method. +func (m *MockFastlyClient) ListSecrets(arg0 *fastly.ListSecretsInput) (*fastly.Secrets, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListSecrets", arg0) + ret0, _ := ret[0].(*fastly.Secrets) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListSecrets indicates an expected call of ListSecrets. +func (mr *MockFastlyClientMockRecorder) ListSecrets(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSecrets", reflect.TypeOf((*MockFastlyClient)(nil).ListSecrets), arg0) +} + +// ListServers mocks base method. +func (m *MockFastlyClient) ListServers(arg0 *fastly.ListServersInput) ([]*fastly.Server, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListServers", arg0) + ret0, _ := ret[0].([]*fastly.Server) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListServers indicates an expected call of ListServers. +func (mr *MockFastlyClientMockRecorder) ListServers(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListServers", reflect.TypeOf((*MockFastlyClient)(nil).ListServers), arg0) +} + +// ListServiceAuthorizations mocks base method. +func (m *MockFastlyClient) ListServiceAuthorizations(arg0 *fastly.ListServiceAuthorizationsInput) (*fastly.ServiceAuthorizations, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListServiceAuthorizations", arg0) + ret0, _ := ret[0].(*fastly.ServiceAuthorizations) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListServiceAuthorizations indicates an expected call of ListServiceAuthorizations. +func (mr *MockFastlyClientMockRecorder) ListServiceAuthorizations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListServiceAuthorizations", reflect.TypeOf((*MockFastlyClient)(nil).ListServiceAuthorizations), arg0) +} + +// ListServiceDomains mocks base method. +func (m *MockFastlyClient) ListServiceDomains(arg0 *fastly.ListServiceDomainInput) (fastly.ServiceDomainsList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListServiceDomains", arg0) + ret0, _ := ret[0].(fastly.ServiceDomainsList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListServiceDomains indicates an expected call of ListServiceDomains. +func (mr *MockFastlyClientMockRecorder) ListServiceDomains(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListServiceDomains", reflect.TypeOf((*MockFastlyClient)(nil).ListServiceDomains), arg0) +} + +// ListServices mocks base method. +func (m *MockFastlyClient) ListServices(arg0 *fastly.ListServicesInput) ([]*fastly.Service, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListServices", arg0) + ret0, _ := ret[0].([]*fastly.Service) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListServices indicates an expected call of ListServices. +func (mr *MockFastlyClientMockRecorder) ListServices(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListServices", reflect.TypeOf((*MockFastlyClient)(nil).ListServices), arg0) +} + +// ListSnippets mocks base method. +func (m *MockFastlyClient) ListSnippets(arg0 *fastly.ListSnippetsInput) ([]*fastly.Snippet, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListSnippets", arg0) + ret0, _ := ret[0].([]*fastly.Snippet) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListSnippets indicates an expected call of ListSnippets. +func (mr *MockFastlyClientMockRecorder) ListSnippets(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSnippets", reflect.TypeOf((*MockFastlyClient)(nil).ListSnippets), arg0) +} + +// ListSplunks mocks base method. +func (m *MockFastlyClient) ListSplunks(arg0 *fastly.ListSplunksInput) ([]*fastly.Splunk, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListSplunks", arg0) + ret0, _ := ret[0].([]*fastly.Splunk) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListSplunks indicates an expected call of ListSplunks. +func (mr *MockFastlyClientMockRecorder) ListSplunks(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSplunks", reflect.TypeOf((*MockFastlyClient)(nil).ListSplunks), arg0) +} + +// ListSumologics mocks base method. +func (m *MockFastlyClient) ListSumologics(arg0 *fastly.ListSumologicsInput) ([]*fastly.Sumologic, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListSumologics", arg0) + ret0, _ := ret[0].([]*fastly.Sumologic) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListSumologics indicates an expected call of ListSumologics. +func (mr *MockFastlyClientMockRecorder) ListSumologics(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSumologics", reflect.TypeOf((*MockFastlyClient)(nil).ListSumologics), arg0) +} + +// ListSyslogs mocks base method. +func (m *MockFastlyClient) ListSyslogs(arg0 *fastly.ListSyslogsInput) ([]*fastly.Syslog, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListSyslogs", arg0) + ret0, _ := ret[0].([]*fastly.Syslog) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListSyslogs indicates an expected call of ListSyslogs. +func (mr *MockFastlyClientMockRecorder) ListSyslogs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSyslogs", reflect.TypeOf((*MockFastlyClient)(nil).ListSyslogs), arg0) +} + +// ListTLSActivations mocks base method. +func (m *MockFastlyClient) ListTLSActivations(arg0 *fastly.ListTLSActivationsInput) ([]*fastly.TLSActivation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTLSActivations", arg0) + ret0, _ := ret[0].([]*fastly.TLSActivation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTLSActivations indicates an expected call of ListTLSActivations. +func (mr *MockFastlyClientMockRecorder) ListTLSActivations(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTLSActivations", reflect.TypeOf((*MockFastlyClient)(nil).ListTLSActivations), arg0) +} + +// ListTLSDomains mocks base method. +func (m *MockFastlyClient) ListTLSDomains(arg0 *fastly.ListTLSDomainsInput) ([]*fastly.TLSDomain, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTLSDomains", arg0) + ret0, _ := ret[0].([]*fastly.TLSDomain) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTLSDomains indicates an expected call of ListTLSDomains. +func (mr *MockFastlyClientMockRecorder) ListTLSDomains(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTLSDomains", reflect.TypeOf((*MockFastlyClient)(nil).ListTLSDomains), arg0) +} + +// ListTLSSubscriptions mocks base method. +func (m *MockFastlyClient) ListTLSSubscriptions(arg0 *fastly.ListTLSSubscriptionsInput) ([]*fastly.TLSSubscription, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTLSSubscriptions", arg0) + ret0, _ := ret[0].([]*fastly.TLSSubscription) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTLSSubscriptions indicates an expected call of ListTLSSubscriptions. +func (mr *MockFastlyClientMockRecorder) ListTLSSubscriptions(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTLSSubscriptions", reflect.TypeOf((*MockFastlyClient)(nil).ListTLSSubscriptions), arg0) +} + +// ListTokens mocks base method. +func (m *MockFastlyClient) ListTokens() ([]*fastly.Token, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListTokens") + ret0, _ := ret[0].([]*fastly.Token) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListTokens indicates an expected call of ListTokens. +func (mr *MockFastlyClientMockRecorder) ListTokens() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTokens", reflect.TypeOf((*MockFastlyClient)(nil).ListTokens)) +} + +// ListVCLs mocks base method. +func (m *MockFastlyClient) ListVCLs(arg0 *fastly.ListVCLsInput) ([]*fastly.VCL, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListVCLs", arg0) + ret0, _ := ret[0].([]*fastly.VCL) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListVCLs indicates an expected call of ListVCLs. +func (mr *MockFastlyClientMockRecorder) ListVCLs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListVCLs", reflect.TypeOf((*MockFastlyClient)(nil).ListVCLs), arg0) +} + +// ListVersions mocks base method. +func (m *MockFastlyClient) ListVersions(arg0 *fastly.ListVersionsInput) ([]*fastly.Version, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListVersions", arg0) + ret0, _ := ret[0].([]*fastly.Version) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListVersions indicates an expected call of ListVersions. +func (mr *MockFastlyClientMockRecorder) ListVersions(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListVersions", reflect.TypeOf((*MockFastlyClient)(nil).ListVersions), arg0) +} + +// ListWAFActiveRules mocks base method. +func (m *MockFastlyClient) ListWAFActiveRules(arg0 *fastly.ListWAFActiveRulesInput) (*fastly.WAFActiveRuleResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListWAFActiveRules", arg0) + ret0, _ := ret[0].(*fastly.WAFActiveRuleResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListWAFActiveRules indicates an expected call of ListWAFActiveRules. +func (mr *MockFastlyClientMockRecorder) ListWAFActiveRules(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListWAFActiveRules", reflect.TypeOf((*MockFastlyClient)(nil).ListWAFActiveRules), arg0) +} + +// ListWAFRuleExclusions mocks base method. +func (m *MockFastlyClient) ListWAFRuleExclusions(arg0 *fastly.ListWAFRuleExclusionsInput) (*fastly.WAFRuleExclusionResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListWAFRuleExclusions", arg0) + ret0, _ := ret[0].(*fastly.WAFRuleExclusionResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListWAFRuleExclusions indicates an expected call of ListWAFRuleExclusions. +func (mr *MockFastlyClientMockRecorder) ListWAFRuleExclusions(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListWAFRuleExclusions", reflect.TypeOf((*MockFastlyClient)(nil).ListWAFRuleExclusions), arg0) +} + +// ListWAFRules mocks base method. +func (m *MockFastlyClient) ListWAFRules(arg0 *fastly.ListWAFRulesInput) (*fastly.WAFRuleResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListWAFRules", arg0) + ret0, _ := ret[0].(*fastly.WAFRuleResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListWAFRules indicates an expected call of ListWAFRules. +func (mr *MockFastlyClientMockRecorder) ListWAFRules(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListWAFRules", reflect.TypeOf((*MockFastlyClient)(nil).ListWAFRules), arg0) +} + +// ListWAFVersions mocks base method. +func (m *MockFastlyClient) ListWAFVersions(arg0 *fastly.ListWAFVersionsInput) (*fastly.WAFVersionResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListWAFVersions", arg0) + ret0, _ := ret[0].(*fastly.WAFVersionResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListWAFVersions indicates an expected call of ListWAFVersions. +func (mr *MockFastlyClientMockRecorder) ListWAFVersions(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListWAFVersions", reflect.TypeOf((*MockFastlyClient)(nil).ListWAFVersions), arg0) +} + +// ListWAFs mocks base method. +func (m *MockFastlyClient) ListWAFs(arg0 *fastly.ListWAFsInput) (*fastly.WAFResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListWAFs", arg0) + ret0, _ := ret[0].(*fastly.WAFResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListWAFs indicates an expected call of ListWAFs. +func (mr *MockFastlyClientMockRecorder) ListWAFs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListWAFs", reflect.TypeOf((*MockFastlyClient)(nil).ListWAFs), arg0) +} + +// NewListACLEntriesPaginator mocks base method. +func (m *MockFastlyClient) NewListACLEntriesPaginator(arg0 *fastly.ListACLEntriesInput) fastly.PaginatorACLEntries { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewListACLEntriesPaginator", arg0) + ret0, _ := ret[0].(fastly.PaginatorACLEntries) + return ret0 +} + +// NewListACLEntriesPaginator indicates an expected call of NewListACLEntriesPaginator. +func (mr *MockFastlyClientMockRecorder) NewListACLEntriesPaginator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListACLEntriesPaginator", reflect.TypeOf((*MockFastlyClient)(nil).NewListACLEntriesPaginator), arg0) +} + +// NewListDictionaryItemsPaginator mocks base method. +func (m *MockFastlyClient) NewListDictionaryItemsPaginator(arg0 *fastly.ListDictionaryItemsInput) fastly.PaginatorDictionaryItems { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewListDictionaryItemsPaginator", arg0) + ret0, _ := ret[0].(fastly.PaginatorDictionaryItems) + return ret0 +} + +// NewListDictionaryItemsPaginator indicates an expected call of NewListDictionaryItemsPaginator. +func (mr *MockFastlyClientMockRecorder) NewListDictionaryItemsPaginator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListDictionaryItemsPaginator", reflect.TypeOf((*MockFastlyClient)(nil).NewListDictionaryItemsPaginator), arg0) +} + +// NewListObjectStoreKeysPaginator mocks base method. +func (m *MockFastlyClient) NewListObjectStoreKeysPaginator(arg0 *fastly.ListObjectStoreKeysInput) *fastly.ListObjectStoreKeysPaginator { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewListObjectStoreKeysPaginator", arg0) + ret0, _ := ret[0].(*fastly.ListObjectStoreKeysPaginator) + return ret0 +} + +// NewListObjectStoreKeysPaginator indicates an expected call of NewListObjectStoreKeysPaginator. +func (mr *MockFastlyClientMockRecorder) NewListObjectStoreKeysPaginator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListObjectStoreKeysPaginator", reflect.TypeOf((*MockFastlyClient)(nil).NewListObjectStoreKeysPaginator), arg0) +} + +// NewListObjectStoresPaginator mocks base method. +func (m *MockFastlyClient) NewListObjectStoresPaginator(arg0 *fastly.ListObjectStoresInput) *fastly.ListObjectStoresPaginator { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewListObjectStoresPaginator", arg0) + ret0, _ := ret[0].(*fastly.ListObjectStoresPaginator) + return ret0 +} + +// NewListObjectStoresPaginator indicates an expected call of NewListObjectStoresPaginator. +func (mr *MockFastlyClientMockRecorder) NewListObjectStoresPaginator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListObjectStoresPaginator", reflect.TypeOf((*MockFastlyClient)(nil).NewListObjectStoresPaginator), arg0) +} + +// NewListServicesPaginator mocks base method. +func (m *MockFastlyClient) NewListServicesPaginator(arg0 *fastly.ListServicesInput) fastly.PaginatorServices { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewListServicesPaginator", arg0) + ret0, _ := ret[0].(fastly.PaginatorServices) + return ret0 +} + +// NewListServicesPaginator indicates an expected call of NewListServicesPaginator. +func (mr *MockFastlyClientMockRecorder) NewListServicesPaginator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListServicesPaginator", reflect.TypeOf((*MockFastlyClient)(nil).NewListServicesPaginator), arg0) +} diff --git a/plugins/source/fastly/client/multiplexers.go b/plugins/source/fastly/client/multiplexers.go new file mode 100644 index 00000000000..8eb9f6a3755 --- /dev/null +++ b/plugins/source/fastly/client/multiplexers.go @@ -0,0 +1,16 @@ +package client + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func ServiceRegionMultiplex(meta schema.ClientMeta) []schema.ClientMeta { + client := meta.(*Client) + clients := make([]schema.ClientMeta, 0, len(client.services)*len(client.regions)) + for _, serviceID := range client.services { + for _, region := range client.regions { + clients = append(clients, client.withServiceAndRegion(serviceID, region)) + } + } + return clients +} diff --git a/plugins/source/fastly/client/resolvers.go b/plugins/source/fastly/client/resolvers.go new file mode 100644 index 00000000000..db43760fd8d --- /dev/null +++ b/plugins/source/fastly/client/resolvers.go @@ -0,0 +1,24 @@ +package client + +import ( + "context" + "time" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/thoas/go-funk" +) + +func UnixTimeResolver(fieldName string) schema.ColumnResolver { + return func(_ context.Context, meta schema.ClientMeta, r *schema.Resource, col schema.Column) error { + t := funk.Get(r.Item, fieldName, funk.WithAllowZero()) + switch v := t.(type) { + case int64: + return r.Set(col.Name, time.Unix(v, 0)) + case int: + return r.Set(col.Name, time.Unix(int64(v), 0)) + case uint64: + return r.Set(col.Name, time.Unix(int64(v), 0)) + } + panic("unknown type for UnixTimeResolver") + } +} diff --git a/plugins/source/fastly/client/services/fastly.go b/plugins/source/fastly/client/services/fastly.go new file mode 100644 index 00000000000..3896279eac4 --- /dev/null +++ b/plugins/source/fastly/client/services/fastly.go @@ -0,0 +1,171 @@ +// Code generated by codegen; DO NOT EDIT. +package services + +import ( + "github.com/fastly/go-fastly/v7/fastly" + "net/http" +) + +//go:generate mockgen -package=mocks -destination=../mocks/fastly.go -source=fastly.go FastlyClient +type FastlyClient interface { + Get(string, *fastly.RequestOptions) (*http.Response, error) + GetACL(*fastly.GetACLInput) (*fastly.ACL, error) + GetACLEntry(*fastly.GetACLEntryInput) (*fastly.ACLEntry, error) + GetAPIEvent(*fastly.GetAPIEventInput) (*fastly.Event, error) + GetAPIEvents(*fastly.GetAPIEventsFilterInput) (fastly.GetAPIEventsResponse, error) + GetBackend(*fastly.GetBackendInput) (*fastly.Backend, error) + GetBigQuery(*fastly.GetBigQueryInput) (*fastly.BigQuery, error) + GetBilling(*fastly.GetBillingInput) (*fastly.Billing, error) + GetBlobStorage(*fastly.GetBlobStorageInput) (*fastly.BlobStorage, error) + GetBulkCertificate(*fastly.GetBulkCertificateInput) (*fastly.BulkCertificate, error) + GetCacheSetting(*fastly.GetCacheSettingInput) (*fastly.CacheSetting, error) + GetCloudfiles(*fastly.GetCloudfilesInput) (*fastly.Cloudfiles, error) + GetCondition(*fastly.GetConditionInput) (*fastly.Condition, error) + GetCurrentUser() (*fastly.User, error) + GetCustomTLSCertificate(*fastly.GetCustomTLSCertificateInput) (*fastly.CustomTLSCertificate, error) + GetCustomTLSConfiguration(*fastly.GetCustomTLSConfigurationInput) (*fastly.CustomTLSConfiguration, error) + GetDatadog(*fastly.GetDatadogInput) (*fastly.Datadog, error) + GetDictionary(*fastly.GetDictionaryInput) (*fastly.Dictionary, error) + GetDictionaryInfo(*fastly.GetDictionaryInfoInput) (*fastly.DictionaryInfo, error) + GetDictionaryItem(*fastly.GetDictionaryItemInput) (*fastly.DictionaryItem, error) + GetDiff(*fastly.GetDiffInput) (*fastly.Diff, error) + GetDigitalOcean(*fastly.GetDigitalOceanInput) (*fastly.DigitalOcean, error) + GetDirector(*fastly.GetDirectorInput) (*fastly.Director, error) + GetDirectorBackend(*fastly.GetDirectorBackendInput) (*fastly.DirectorBackend, error) + GetDomain(*fastly.GetDomainInput) (*fastly.Domain, error) + GetDynamicSnippet(*fastly.GetDynamicSnippetInput) (*fastly.DynamicSnippet, error) + GetERL(*fastly.GetERLInput) (*fastly.ERL, error) + GetElasticsearch(*fastly.GetElasticsearchInput) (*fastly.Elasticsearch, error) + GetFTP(*fastly.GetFTPInput) (*fastly.FTP, error) + GetGCS(*fastly.GetGCSInput) (*fastly.GCS, error) + GetGeneratedVCL(*fastly.GetGeneratedVCLInput) (*fastly.VCL, error) + GetGzip(*fastly.GetGzipInput) (*fastly.Gzip, error) + GetHTTPS(*fastly.GetHTTPSInput) (*fastly.HTTPS, error) + GetHeader(*fastly.GetHeaderInput) (*fastly.Header, error) + GetHealthCheck(*fastly.GetHealthCheckInput) (*fastly.HealthCheck, error) + GetHeroku(*fastly.GetHerokuInput) (*fastly.Heroku, error) + GetHoneycomb(*fastly.GetHoneycombInput) (*fastly.Honeycomb, error) + GetKafka(*fastly.GetKafkaInput) (*fastly.Kafka, error) + GetKinesis(*fastly.GetKinesisInput) (*fastly.Kinesis, error) + GetLogentries(*fastly.GetLogentriesInput) (*fastly.Logentries, error) + GetLoggly(*fastly.GetLogglyInput) (*fastly.Loggly, error) + GetLogshuttle(*fastly.GetLogshuttleInput) (*fastly.Logshuttle, error) + GetNewRelic(*fastly.GetNewRelicInput) (*fastly.NewRelic, error) + GetObjectStore(*fastly.GetObjectStoreInput) (*fastly.ObjectStore, error) + GetObjectStoreKey(*fastly.GetObjectStoreKeyInput) (string, error) + GetOpenstack(*fastly.GetOpenstackInput) (*fastly.Openstack, error) + GetOriginMetricsForService(*fastly.GetOriginMetricsInput) (*fastly.OriginInspector, error) + GetOriginMetricsForServiceJSON(*fastly.GetOriginMetricsInput, interface{}) error + GetPackage(*fastly.GetPackageInput) (*fastly.Package, error) + GetPapertrail(*fastly.GetPapertrailInput) (*fastly.Papertrail, error) + GetPool(*fastly.GetPoolInput) (*fastly.Pool, error) + GetPrivateKey(*fastly.GetPrivateKeyInput) (*fastly.PrivateKey, error) + GetPubsub(*fastly.GetPubsubInput) (*fastly.Pubsub, error) + GetRegions() (*fastly.RegionsResponse, error) + GetRequestSetting(*fastly.GetRequestSettingInput) (*fastly.RequestSetting, error) + GetResponseObject(*fastly.GetResponseObjectInput) (*fastly.ResponseObject, error) + GetS3(*fastly.GetS3Input) (*fastly.S3, error) + GetSFTP(*fastly.GetSFTPInput) (*fastly.SFTP, error) + GetScalyr(*fastly.GetScalyrInput) (*fastly.Scalyr, error) + GetSecret(*fastly.GetSecretInput) (*fastly.Secret, error) + GetSecretStore(*fastly.GetSecretStoreInput) (*fastly.SecretStore, error) + GetServer(*fastly.GetServerInput) (*fastly.Server, error) + GetService(*fastly.GetServiceInput) (*fastly.Service, error) + GetServiceAuthorization(*fastly.GetServiceAuthorizationInput) (*fastly.ServiceAuthorization, error) + GetServiceDetails(*fastly.GetServiceInput) (*fastly.ServiceDetail, error) + GetSettings(*fastly.GetSettingsInput) (*fastly.Settings, error) + GetSnippet(*fastly.GetSnippetInput) (*fastly.Snippet, error) + GetSplunk(*fastly.GetSplunkInput) (*fastly.Splunk, error) + GetStats(*fastly.GetStatsInput) (*fastly.StatsResponse, error) + GetStatsField(*fastly.GetStatsInput) (*fastly.StatsFieldResponse, error) + GetStatsJSON(*fastly.GetStatsInput, interface{}) error + GetSumologic(*fastly.GetSumologicInput) (*fastly.Sumologic, error) + GetSyslog(*fastly.GetSyslogInput) (*fastly.Syslog, error) + GetTLSActivation(*fastly.GetTLSActivationInput) (*fastly.TLSActivation, error) + GetTLSSubscription(*fastly.GetTLSSubscriptionInput) (*fastly.TLSSubscription, error) + GetTokenSelf() (*fastly.Token, error) + GetUsage(*fastly.GetUsageInput) (*fastly.UsageResponse, error) + GetUsageByService(*fastly.GetUsageInput) (*fastly.UsageByServiceResponse, error) + GetUser(*fastly.GetUserInput) (*fastly.User, error) + GetVCL(*fastly.GetVCLInput) (*fastly.VCL, error) + GetVersion(*fastly.GetVersionInput) (*fastly.Version, error) + GetWAF(*fastly.GetWAFInput) (*fastly.WAF, error) + GetWAFVersion(*fastly.GetWAFVersionInput) (*fastly.WAFVersion, error) + ListACLEntries(*fastly.ListACLEntriesInput) ([]*fastly.ACLEntry, error) + ListACLs(*fastly.ListACLsInput) ([]*fastly.ACL, error) + ListAllWAFActiveRules(*fastly.ListAllWAFActiveRulesInput) (*fastly.WAFActiveRuleResponse, error) + ListAllWAFRuleExclusions(*fastly.ListAllWAFRuleExclusionsInput) (*fastly.WAFRuleExclusionResponse, error) + ListAllWAFRules(*fastly.ListAllWAFRulesInput) (*fastly.WAFRuleResponse, error) + ListAllWAFVersions(*fastly.ListAllWAFVersionsInput) (*fastly.WAFVersionResponse, error) + ListBackends(*fastly.ListBackendsInput) ([]*fastly.Backend, error) + ListBigQueries(*fastly.ListBigQueriesInput) ([]*fastly.BigQuery, error) + ListBlobStorages(*fastly.ListBlobStoragesInput) ([]*fastly.BlobStorage, error) + ListBulkCertificates(*fastly.ListBulkCertificatesInput) ([]*fastly.BulkCertificate, error) + ListCacheSettings(*fastly.ListCacheSettingsInput) ([]*fastly.CacheSetting, error) + ListCloudfiles(*fastly.ListCloudfilesInput) ([]*fastly.Cloudfiles, error) + ListConditions(*fastly.ListConditionsInput) ([]*fastly.Condition, error) + ListCustomTLSCertificates(*fastly.ListCustomTLSCertificatesInput) ([]*fastly.CustomTLSCertificate, error) + ListCustomTLSConfigurations(*fastly.ListCustomTLSConfigurationsInput) ([]*fastly.CustomTLSConfiguration, error) + ListCustomerTokens(*fastly.ListCustomerTokensInput) ([]*fastly.Token, error) + ListCustomerUsers(*fastly.ListCustomerUsersInput) ([]*fastly.User, error) + ListDatadog(*fastly.ListDatadogInput) ([]*fastly.Datadog, error) + ListDictionaries(*fastly.ListDictionariesInput) ([]*fastly.Dictionary, error) + ListDictionaryItems(*fastly.ListDictionaryItemsInput) ([]*fastly.DictionaryItem, error) + ListDigitalOceans(*fastly.ListDigitalOceansInput) ([]*fastly.DigitalOcean, error) + ListDirectors(*fastly.ListDirectorsInput) ([]*fastly.Director, error) + ListDomains(*fastly.ListDomainsInput) ([]*fastly.Domain, error) + ListERLs(*fastly.ListERLsInput) ([]*fastly.ERL, error) + ListElasticsearch(*fastly.ListElasticsearchInput) ([]*fastly.Elasticsearch, error) + ListFTPs(*fastly.ListFTPsInput) ([]*fastly.FTP, error) + ListGCSs(*fastly.ListGCSsInput) ([]*fastly.GCS, error) + ListGzips(*fastly.ListGzipsInput) ([]*fastly.Gzip, error) + ListHTTPS(*fastly.ListHTTPSInput) ([]*fastly.HTTPS, error) + ListHeaders(*fastly.ListHeadersInput) ([]*fastly.Header, error) + ListHealthChecks(*fastly.ListHealthChecksInput) ([]*fastly.HealthCheck, error) + ListHerokus(*fastly.ListHerokusInput) ([]*fastly.Heroku, error) + ListHoneycombs(*fastly.ListHoneycombsInput) ([]*fastly.Honeycomb, error) + ListKafkas(*fastly.ListKafkasInput) ([]*fastly.Kafka, error) + ListKinesis(*fastly.ListKinesisInput) ([]*fastly.Kinesis, error) + ListLogentries(*fastly.ListLogentriesInput) ([]*fastly.Logentries, error) + ListLoggly(*fastly.ListLogglyInput) ([]*fastly.Loggly, error) + ListLogshuttles(*fastly.ListLogshuttlesInput) ([]*fastly.Logshuttle, error) + ListNewRelic(*fastly.ListNewRelicInput) ([]*fastly.NewRelic, error) + ListObjectStoreKeys(*fastly.ListObjectStoreKeysInput) (*fastly.ListObjectStoreKeysResponse, error) + ListObjectStores(*fastly.ListObjectStoresInput) (*fastly.ListObjectStoresResponse, error) + ListOpenstack(*fastly.ListOpenstackInput) ([]*fastly.Openstack, error) + ListPapertrails(*fastly.ListPapertrailsInput) ([]*fastly.Papertrail, error) + ListPools(*fastly.ListPoolsInput) ([]*fastly.Pool, error) + ListPrivateKeys(*fastly.ListPrivateKeysInput) ([]*fastly.PrivateKey, error) + ListPubsubs(*fastly.ListPubsubsInput) ([]*fastly.Pubsub, error) + ListRequestSettings(*fastly.ListRequestSettingsInput) ([]*fastly.RequestSetting, error) + ListResponseObjects(*fastly.ListResponseObjectsInput) ([]*fastly.ResponseObject, error) + ListS3s(*fastly.ListS3sInput) ([]*fastly.S3, error) + ListSFTPs(*fastly.ListSFTPsInput) ([]*fastly.SFTP, error) + ListScalyrs(*fastly.ListScalyrsInput) ([]*fastly.Scalyr, error) + ListSecretStores(*fastly.ListSecretStoresInput) (*fastly.SecretStores, error) + ListSecrets(*fastly.ListSecretsInput) (*fastly.Secrets, error) + ListServers(*fastly.ListServersInput) ([]*fastly.Server, error) + ListServiceAuthorizations(*fastly.ListServiceAuthorizationsInput) (*fastly.ServiceAuthorizations, error) + ListServiceDomains(*fastly.ListServiceDomainInput) (fastly.ServiceDomainsList, error) + ListServices(*fastly.ListServicesInput) ([]*fastly.Service, error) + ListSnippets(*fastly.ListSnippetsInput) ([]*fastly.Snippet, error) + ListSplunks(*fastly.ListSplunksInput) ([]*fastly.Splunk, error) + ListSumologics(*fastly.ListSumologicsInput) ([]*fastly.Sumologic, error) + ListSyslogs(*fastly.ListSyslogsInput) ([]*fastly.Syslog, error) + ListTLSActivations(*fastly.ListTLSActivationsInput) ([]*fastly.TLSActivation, error) + ListTLSDomains(*fastly.ListTLSDomainsInput) ([]*fastly.TLSDomain, error) + ListTLSSubscriptions(*fastly.ListTLSSubscriptionsInput) ([]*fastly.TLSSubscription, error) + ListTokens() ([]*fastly.Token, error) + ListVCLs(*fastly.ListVCLsInput) ([]*fastly.VCL, error) + ListVersions(*fastly.ListVersionsInput) ([]*fastly.Version, error) + ListWAFActiveRules(*fastly.ListWAFActiveRulesInput) (*fastly.WAFActiveRuleResponse, error) + ListWAFRuleExclusions(*fastly.ListWAFRuleExclusionsInput) (*fastly.WAFRuleExclusionResponse, error) + ListWAFRules(*fastly.ListWAFRulesInput) (*fastly.WAFRuleResponse, error) + ListWAFVersions(*fastly.ListWAFVersionsInput) (*fastly.WAFVersionResponse, error) + ListWAFs(*fastly.ListWAFsInput) (*fastly.WAFResponse, error) + NewListACLEntriesPaginator(*fastly.ListACLEntriesInput) fastly.PaginatorACLEntries + NewListDictionaryItemsPaginator(*fastly.ListDictionaryItemsInput) fastly.PaginatorDictionaryItems + NewListObjectStoreKeysPaginator(*fastly.ListObjectStoreKeysInput) *fastly.ListObjectStoreKeysPaginator + NewListObjectStoresPaginator(*fastly.ListObjectStoresInput) *fastly.ListObjectStoresPaginator + NewListServicesPaginator(*fastly.ListServicesInput) fastly.PaginatorServices +} diff --git a/plugins/source/fastly/client/spec.go b/plugins/source/fastly/client/spec.go new file mode 100644 index 00000000000..84b8a61c341 --- /dev/null +++ b/plugins/source/fastly/client/spec.go @@ -0,0 +1,6 @@ +package client + +type Spec struct { + FastlyAPIKey string `json:"fastly_api_key"` + Services []string `json:"services"` +} diff --git a/plugins/source/fastly/client/testing.go b/plugins/source/fastly/client/testing.go new file mode 100644 index 00000000000..6caea2d045b --- /dev/null +++ b/plugins/source/fastly/client/testing.go @@ -0,0 +1,62 @@ +package client + +import ( + "context" + "os" + "testing" + "time" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/services" + "github.com/cloudquery/plugin-sdk/plugins/source" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugin-sdk/specs" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" + "github.com/rs/zerolog" +) + +type TestOptions struct { + Service *fastly.Service + Region string +} + +func MockTestHelper(t *testing.T, table *schema.Table, builder func(*testing.T, *gomock.Controller) services.FastlyClient, opts TestOptions) { + version := "vDev" + table.IgnoreInTests = false + t.Helper() + ctrl := gomock.NewController(t) + l := zerolog.New(zerolog.NewTestWriter(t)).Output( + zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.StampMicro}, + ).Level(zerolog.DebugLevel).With().Timestamp().Logger() + newTestExecutionClient := func(ctx context.Context, logger zerolog.Logger, spec specs.Source) (schema.ClientMeta, error) { + var s []*fastly.Service + if opts.Service != nil { + s = []*fastly.Service{opts.Service} + } + var regions []string + if opts.Region != "" { + regions = []string{opts.Region} + } + return &Client{ + logger: l, + Fastly: builder(t, ctrl), + services: s, + regions: regions, + }, nil + } + p := source.NewPlugin( + table.Name, + version, + []*schema.Table{ + table, + }, + newTestExecutionClient) + p.SetLogger(l) + source.TestPluginSync(t, p, specs.Source{ + Name: "dev", + Path: "cloudquery/dev", + Version: version, + Tables: []string{table.Name}, + Destinations: []string{"mock-destination"}, + }) +} diff --git a/plugins/source/fastly/codegen/main.go b/plugins/source/fastly/codegen/main.go new file mode 100644 index 00000000000..fa0a0837fde --- /dev/null +++ b/plugins/source/fastly/codegen/main.go @@ -0,0 +1,119 @@ +package main + +import ( + "bytes" + "embed" + "fmt" + "go/format" + "log" + "os" + "path" + "runtime" + "strings" + "text/template" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/codegen/recipes" + "github.com/cloudquery/cloudquery/plugins/source/fastly/codegen/services" + "github.com/cloudquery/cloudquery/plugins/source/fastly/codegen/tables" + "github.com/cloudquery/plugin-sdk/codegen" +) + +//go:embed templates/*.go.tpl +var templatesFS embed.FS + +func main() { + err := services.Generate() + if err != nil { + log.Fatal(err) + } + + var resources []*recipes.Resource + resources = append(resources, recipes.AccountResources()...) + resources = append(resources, recipes.AuthResources()...) + resources = append(resources, recipes.ServiceResources()...) + resources = append(resources, recipes.StatsResources()...) + + for _, r := range resources { + r.Infer() + } + for _, r := range resources { + r.GenerateNames() + + _, filename, _, ok := runtime.Caller(0) + if !ok { + log.Fatal("Failed to get caller information") + } + codegenDir := path.Join(path.Dir(filename), "..", "resources", "services") + + generateTable(codegenDir, *r) + } + + err = tables.Generate(resources) + if err != nil { + log.Fatal(err) + } +} + +func generateTable(basedir string, r recipes.Resource) { + var err error + + r.TableName = "fastly_" + r.TableName + + log.Println("Generating table", r.TableName) + opts := []codegen.TableOption{ + codegen.WithSkipFields(r.SkipFields), + codegen.WithExtraColumns(r.ExtraColumns), + codegen.WithPKColumns(r.PKColumns...), + } + if r.UnwrapEmbeddedStructs { + opts = append(opts, codegen.WithUnwrapAllEmbeddedStructs()) + } + r.Table, err = codegen.NewTableFromStruct(r.TableName, r.DataStruct, opts...) + + if err != nil { + log.Fatal(err) + } + + r.Table.Description = r.Description + r.Table.Resolver = r.ResolverFuncName + r.Table.Multiplex = r.Multiplex + r.ImportClient = strings.HasPrefix(r.Multiplex, "client.") + r.Table.Relations = r.Relations + r.Table.PreResourceResolver = r.PreResourceResolver + r.Table.PostResourceResolver = r.PostResourceResolver + + for _, c := range r.Table.Columns { + if strings.HasPrefix(c.Resolver, "client.") { + r.ImportClient = true + } + } + + mainTemplate := r.Template + ".go.tpl" + tpl, err := template.New(mainTemplate).ParseFS(templatesFS, "templates/"+mainTemplate) + if err != nil { + log.Fatal(fmt.Errorf("failed to parse fastly templates: %w", err)) + } + tpl, err = tpl.ParseFS(codegen.TemplatesFS, "templates/*.go.tpl") + if err != nil { + log.Fatal(fmt.Errorf("failed to parse recipes template: %w", err)) + } + var buff bytes.Buffer + if err := tpl.Execute(&buff, r); err != nil { + log.Fatal(fmt.Errorf("failed to execute template: %w", err)) + } + + pkgPath := path.Join(basedir, r.Service) + if err := os.Mkdir(pkgPath, 0o755); err != nil && !os.IsExist(err) { + log.Fatal(err) + } + + filePath := path.Join(pkgPath, r.Filename) + content, err := format.Source(buff.Bytes()) + if err != nil { + fmt.Println(buff.String()) + log.Fatal(fmt.Errorf("failed to format code for %s: %w", filePath, err)) + } + if err := os.WriteFile(filePath, content, 0644); err != nil { + log.Fatal(fmt.Errorf("failed to write file %s: %w", filePath, err)) + } +} diff --git a/plugins/source/fastly/codegen/recipes/account.go b/plugins/source/fastly/codegen/recipes/account.go new file mode 100644 index 00000000000..98357fe4d5a --- /dev/null +++ b/plugins/source/fastly/codegen/recipes/account.go @@ -0,0 +1,26 @@ +package recipes + +import ( + "github.com/fastly/go-fastly/v7/fastly" +) + +func AccountResources() []*Resource { + resources := []*Resource{ + { + TableName: "account_users", + DataStruct: &fastly.User{}, + Description: "https://developer.fastly.com/reference/api/account/user/", + PKColumns: []string{"id"}, + }, + { + TableName: "account_events", + DataStruct: &fastly.Event{}, + Description: "https://developer.fastly.com/reference/api/account/events/", + PKColumns: []string{"id"}, + }, + } + for _, r := range resources { + r.Service = "account" + } + return resources +} diff --git a/plugins/source/fastly/codegen/recipes/auth.go b/plugins/source/fastly/codegen/recipes/auth.go new file mode 100644 index 00000000000..71bcebf333f --- /dev/null +++ b/plugins/source/fastly/codegen/recipes/auth.go @@ -0,0 +1,20 @@ +package recipes + +import ( + "github.com/fastly/go-fastly/v7/fastly" +) + +func AuthResources() []*Resource { + resources := []*Resource{ + { + TableName: "auth_tokens", + DataStruct: &fastly.Token{}, + Description: "https://developer.fastly.com/reference/api/auth-tokens/", + PKColumns: []string{"id"}, + }, + } + for _, r := range resources { + r.Service = "auth" + } + return resources +} diff --git a/plugins/source/fastly/codegen/recipes/recipes.go b/plugins/source/fastly/codegen/recipes/recipes.go new file mode 100644 index 00000000000..d340c5b304c --- /dev/null +++ b/plugins/source/fastly/codegen/recipes/recipes.go @@ -0,0 +1,105 @@ +package recipes + +import ( + "log" + "reflect" + "strings" + + "github.com/cloudquery/plugin-sdk/caser" + "github.com/cloudquery/plugin-sdk/codegen" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/gertd/go-pluralize" +) + +type Resource struct { + Service string + Description string + // Table is the table definition that will be used to generate the cloudquery table + Table *codegen.TableDefinition + // DataStruct that will be used to generate the cloudquery table + DataStruct any + // SkipFields fields in go struct to skip when generating the table from the go struct + SkipFields []string + Template string + Multiplex string + + ExtraColumns []codegen.ColumnDefinition + PKColumns []string + + PreResourceResolver string + PostResourceResolver string + Relations []string + UnwrapEmbeddedStructs bool + + // These are inferred with reflection but can be overridden + SubService string // Inferred from DataStruct name, singular + TableName string // singular Service + plural SubService + + // These are auto calculated + ImportClient bool // true if the resource/column resolvers use the client package + Filename string // Calculated from TableName + TableFuncName string // Calculated from TableName + ResolverFuncName string // Calculated from TableFuncName + + //used for generating better table names + parent *Resource + children []*Resource +} + +var ( + TeamIDColumn = codegen.ColumnDefinition{ + Name: "team_id", + Type: schema.TypeString, + Resolver: "client.ResolveTeamID", + } + + pluralizeClient *pluralize.Client + csr *caser.Caser +) + +func init() { + pluralizeClient = pluralize.NewClient() + csr = caser.New() +} + +func (r *Resource) Infer() { + // Set defaults and/or infer fields + if r.Template == "" { + r.Template = "resource" + } + + ds := reflect.TypeOf(r.DataStruct) + if ds.Kind() == reflect.Ptr { + ds = ds.Elem() + } + if r.SubService == "" { + r.SubService = csr.ToSnake(pluralizeClient.Singular(ds.Name())) + } +} + +func (r *Resource) GenerateNames() { + if r.TableName == "" { + r.TableName = tableNameForResource(r) + } + + r.Filename = csr.ToSnake(r.TableName) + ".go" + r.TableFuncName = csr.ToPascal(r.TableName) + r.ResolverFuncName = "fetch" + r.TableFuncName +} + +func tableNameForResource(r *Resource) string { + var nParts []string + p := r.parent + for p != nil { + nParts = append(nParts, pluralizeClient.Singular(p.SubService)) + p = p.parent + } + nParts = append(nParts, pluralizeClient.Plural(r.SubService)) + switch len(nParts) { + case 1: + nParts[0] = pluralizeClient.Plural(nParts[0]) + case 0: + log.Fatalf("Could not generate table name for %s.%s", r.Service, r.SubService) + } + return strings.Join(nParts, "_") +} diff --git a/plugins/source/fastly/codegen/recipes/services.go b/plugins/source/fastly/codegen/recipes/services.go new file mode 100644 index 00000000000..6f7a33bbcfb --- /dev/null +++ b/plugins/source/fastly/codegen/recipes/services.go @@ -0,0 +1,51 @@ +package recipes + +import ( + "github.com/fastly/go-fastly/v7/fastly" +) + +func ServiceResources() []*Resource { + resources := []*Resource{ + { + DataStruct: &fastly.Service{}, + Description: "https://developer.fastly.com/reference/api/services/service/", + PKColumns: []string{"id"}, + Relations: []string{ + "ServiceVersions()", + }, + }, + { + TableName: "service_versions", + DataStruct: &fastly.Version{}, + Description: "https://developer.fastly.com/reference/api/services/version/", + PKColumns: []string{"service_id", "number"}, + Relations: []string{ + "ServiceHealthChecks()", + "ServiceDomains()", + "ServiceBackends()", + }, + }, + { + TableName: "service_backends", + DataStruct: &fastly.Backend{}, + Description: "https://developer.fastly.com/reference/api/services/backend/", + PKColumns: []string{"service_id", "service_version", "name"}, + }, + { + TableName: "service_health_checks", + DataStruct: &fastly.HealthCheck{}, + Description: "https://developer.fastly.com/reference/api/services/healthcheck/", + PKColumns: []string{"service_id", "service_version", "name"}, + }, + { + TableName: "service_domains", + DataStruct: &fastly.Domain{}, + Description: "https://developer.fastly.com/reference/api/services/domain/", + PKColumns: []string{"service_id", "service_version", "name"}, + }, + } + for _, r := range resources { + r.Service = "services" + } + return resources +} diff --git a/plugins/source/fastly/codegen/recipes/stats.go b/plugins/source/fastly/codegen/recipes/stats.go new file mode 100644 index 00000000000..fd39cf2e8e2 --- /dev/null +++ b/plugins/source/fastly/codegen/recipes/stats.go @@ -0,0 +1,48 @@ +package recipes + +import ( + "github.com/cloudquery/cloudquery/plugins/source/fastly/resources/services/stats/models" + "github.com/cloudquery/plugin-sdk/codegen" + "github.com/cloudquery/plugin-sdk/schema" +) + +func StatsResources() []*Resource { + resources := []*Resource{ + { + TableName: "stats_regions", + DataStruct: &struct{}{}, + Description: "https://developer.fastly.com/reference/api/metrics-stats/historical-stats/#get-regions", + PKColumns: []string{"name"}, + ExtraColumns: []codegen.ColumnDefinition{ + { + Name: "name", + Type: schema.TypeString, + Resolver: `setRegionName`, + }, + }, + }, + { + TableName: "stats_services", + DataStruct: &models.StatsWrapper{}, + Description: "https://developer.fastly.com/reference/api/metrics-stats/historical-stats/", + PKColumns: []string{"service_id", "region", "start_time", "by"}, + Multiplex: `client.ServiceRegionMultiplex`, + SkipFields: []string{ + "StartTime", // custom column resolver + "MissHistogram", // decoding issues + }, + UnwrapEmbeddedStructs: true, + ExtraColumns: []codegen.ColumnDefinition{ + { + Name: "start_time", + Type: schema.TypeTimestamp, + Resolver: `client.UnixTimeResolver("StartTime")`, + }, + }, + }, + } + for _, r := range resources { + r.Service = "stats" + } + return resources +} diff --git a/plugins/source/fastly/codegen/services/generate.go b/plugins/source/fastly/codegen/services/generate.go new file mode 100644 index 00000000000..d23db1f37c9 --- /dev/null +++ b/plugins/source/fastly/codegen/services/generate.go @@ -0,0 +1,175 @@ +package services + +import ( + "bytes" + "embed" + "fmt" + "go/format" + "os" + "path" + "reflect" + "runtime" + "strings" + "text/template" + + "github.com/cloudquery/plugin-sdk/caser" + "github.com/fastly/go-fastly/v7/fastly" +) + +//go:embed templates/*.go.tpl +var templatesFS embed.FS + +// these clients will be used to generate interfaces +var clients = []any{ + &fastly.Client{}, +} + +// these method name prefixes will be part of the generated client interface +var acceptedPrefixes = []string{ + "List", "NewList", "Get", "NewGet", +} + +// these methods will be included despite not starting with an accepted prefix +var exceptions = []string{} + +// Adapted from https://stackoverflow.com/a/54129236 +func signature(name string, f any) string { + t := reflect.TypeOf(f) + if t.Kind() != reflect.Func { + return "" + } + + buf := strings.Builder{} + buf.WriteString(name + "(") + for i := 0; i < t.NumIn(); i++ { + if i > 0 { + buf.WriteString(", ") + } + if t.IsVariadic() && i == t.NumIn()-1 { + buf.WriteString("..." + strings.TrimPrefix(t.In(i).String(), "[]")) + } else { + buf.WriteString(t.In(i).String()) + } + } + buf.WriteString(")") + if numOut := t.NumOut(); numOut > 0 { + if numOut > 1 { + buf.WriteString(" (") + } else { + buf.WriteString(" ") + } + for i := 0; i < t.NumOut(); i++ { + if i > 0 { + buf.WriteString(", ") + } + buf.WriteString(t.Out(i).String()) + } + if numOut > 1 { + buf.WriteString(")") + } + } + + return buf.String() +} + +func shouldInclude(name string) bool { + if hasPrefix(name) { + return true + } + for _, e := range exceptions { + if name == e { + return true + } + } + return false +} + +func hasPrefix(name string) bool { + for _, t := range acceptedPrefixes { + if strings.HasPrefix(name, t) { + return true + } + } + return false +} + +type serviceInfo struct { + Import string + Name string + PackageName string + ClientName string + Signatures []string +} + +func getServiceInfo(client any) serviceInfo { + v := reflect.ValueOf(client) + t := v.Type() + pkgPath := t.Elem().PkgPath() + parts := strings.Split(pkgPath, "/") + pkgName := parts[len(parts)-1] + csr := caser.New() + name := csr.ToPascal(pkgName) + clientName := name + "Client" + signatures := make([]string, 0) + for i := 0; i < t.NumMethod(); i++ { + method := t.Method(i) + if shouldInclude(method.Name) { + sig := signature(method.Name, v.Method(i).Interface()) + signatures = append(signatures, sig) + } + } + return serviceInfo{ + Import: pkgPath, + Name: name, + PackageName: pkgName, + ClientName: clientName, + Signatures: signatures, + } +} + +// Generate generates a services.go file and individual service files from the clients defined in clients.go +func Generate() error { + services := make([]serviceInfo, 0) + for _, client := range clients { + services = append(services, getServiceInfo(client)) + } + + _, filename, _, ok := runtime.Caller(0) + if !ok { + return fmt.Errorf("failed to get caller information") + } + + // write individual service files + serviceTpl, err := template.New("service.go.tpl").ParseFS(templatesFS, "templates/service.go.tpl") + if err != nil { + return err + } + + for _, service := range services { + buff := bytes.Buffer{} + if err := serviceTpl.Execute(&buff, service); err != nil { + return fmt.Errorf("failed to execute template: %w", err) + } + filePath := path.Join(path.Dir(filename), fmt.Sprintf("../../client/services/%s.go", service.PackageName)) + err := formatAndWriteFile(filePath, buff) + if err != nil { + return fmt.Errorf("failed to format and write file for service %v: %w", service.Name, err) + } + } + + return nil +} + +func formatAndWriteFile(filePath string, buff bytes.Buffer) error { + content := buff.Bytes() + formattedContent, err := format.Source(buff.Bytes()) + if err != nil { + fmt.Printf("failed to format source: %s: %v\n", filePath, err) + } else { + content = formattedContent + } + if err := os.WriteFile(filePath, content, 0644); err != nil { + return fmt.Errorf("failed to write file %s: %w", filePath, err) + } + return nil +} diff --git a/plugins/source/fastly/codegen/services/templates/service.go.tpl b/plugins/source/fastly/codegen/services/templates/service.go.tpl new file mode 100644 index 00000000000..4664b8fd6c2 --- /dev/null +++ b/plugins/source/fastly/codegen/services/templates/service.go.tpl @@ -0,0 +1,14 @@ +// Code generated by codegen; DO NOT EDIT. +package services + +import ( + "net/http" + "{{ .Import }}" +) + +//go:generate mockgen -package=mocks -destination=../mocks/{{.PackageName}}.go -source={{.PackageName}}.go {{.ClientName}} +type {{.ClientName}} interface { + {{- range $sig := .Signatures }} + {{ $sig }} + {{- end }} +} \ No newline at end of file diff --git a/plugins/source/fastly/codegen/tables/generate.go b/plugins/source/fastly/codegen/tables/generate.go new file mode 100644 index 00000000000..4f08e4f9e5b --- /dev/null +++ b/plugins/source/fastly/codegen/tables/generate.go @@ -0,0 +1,68 @@ +package tables + +import ( + "bytes" + "embed" + "fmt" + "go/format" + "os" + "path" + "runtime" + "strings" + "text/template" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/codegen/recipes" +) + +//go:embed templates/*.go.tpl +var templatesFS embed.FS + +func Generate(resources []*recipes.Resource) error { + tpl, err := template.New("tables.go.tpl").ParseFS(templatesFS, "templates/tables.go.tpl") + if err != nil { + return err + } + + resources = removeChildResources(resources) + var buff bytes.Buffer + if err := tpl.Execute(&buff, resources); err != nil { + return fmt.Errorf("failed to execute template: %w", err) + } + + _, filename, _, ok := runtime.Caller(0) + if !ok { + return fmt.Errorf("failed to get caller information") + } + + filePath := path.Join(path.Dir(filename), "../../resources/plugin/tables.go") + content := buff.Bytes() + formattedContent, err := format.Source(buff.Bytes()) + if err != nil { + fmt.Printf("failed to format source: %s: %v\n", filePath, err) + } else { + content = formattedContent + } + if err := os.WriteFile(filePath, content, 0644); err != nil { + return fmt.Errorf("failed to write file %s: %w", filePath, err) + } + + return nil +} + +func removeChildResources(resources []*recipes.Resource) []*recipes.Resource { + filtered := make([]*recipes.Resource, 0) + relations := map[string]bool{} + for _, r := range resources { + for _, rel := range r.Relations { + relations[r.Service+"."+strings.TrimSuffix(rel, "()")] = true + } + } + for _, r := range resources { + funcName := r.Service + "." + r.TableFuncName + if relations[funcName] { + continue + } + filtered = append(filtered, r) + } + return filtered +} diff --git a/plugins/source/fastly/codegen/tables/templates/tables.go.tpl b/plugins/source/fastly/codegen/tables/templates/tables.go.tpl new file mode 100644 index 00000000000..d92703a25b9 --- /dev/null +++ b/plugins/source/fastly/codegen/tables/templates/tables.go.tpl @@ -0,0 +1,18 @@ +// Code generated by codegen; DO NOT EDIT. + +package plugin + +import ( + "github.com/cloudquery/plugin-sdk/schema" +{{- range $resource := . }} + "github.com/cloudquery/cloudquery/plugins/source/fastly/resources/services/{{ $resource.Service }}" +{{- end }} +) + +func tables() []*schema.Table { + return []*schema.Table{ + {{- range $resource := . }} + {{ $resource.Service }}.{{ $resource.TableFuncName }}(), + {{- end }} + } +} diff --git a/plugins/source/fastly/codegen/templates/resource.go.tpl b/plugins/source/fastly/codegen/templates/resource.go.tpl new file mode 100644 index 00000000000..e31bae4ef32 --- /dev/null +++ b/plugins/source/fastly/codegen/templates/resource.go.tpl @@ -0,0 +1,14 @@ +// Code generated by codegen; DO NOT EDIT. + +package {{.Service}} + +import ( + "github.com/cloudquery/plugin-sdk/schema" + {{- if .ImportClient }} + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + {{- end }} +) + +func {{.TableFuncName}}() *schema.Table { + return &schema.Table{{template "table.go.tpl" .Table}} +} \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/README.md b/plugins/source/fastly/docs/tables/README.md new file mode 100644 index 00000000000..55ecea167dc --- /dev/null +++ b/plugins/source/fastly/docs/tables/README.md @@ -0,0 +1,14 @@ +# Source Plugin: fastly + +## Tables + +- [fastly_account_users](fastly_account_users.md) +- [fastly_account_events](fastly_account_events.md) +- [fastly_auth_tokens](fastly_auth_tokens.md) +- [fastly_services](fastly_services.md) + - [fastly_service_versions](fastly_service_versions.md) + - [fastly_service_health_checks](fastly_service_health_checks.md) + - [fastly_service_domains](fastly_service_domains.md) + - [fastly_service_backends](fastly_service_backends.md) +- [fastly_stats_regions](fastly_stats_regions.md) +- [fastly_stats_services](fastly_stats_services.md) \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_account_events.md b/plugins/source/fastly/docs/tables/fastly_account_events.md new file mode 100644 index 00000000000..2cc2d222e02 --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_account_events.md @@ -0,0 +1,24 @@ +# Table: fastly_account_events + +https://developer.fastly.com/reference/api/account/events/ + +The primary key for this table is **id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|admin|Bool| +|created_at|Timestamp| +|customer_id|String| +|description|String| +|event_type|String| +|id (PK)|String| +|ip|String| +|metadata|JSON| +|service_id|String| +|user_id|String| \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_account_users.md b/plugins/source/fastly/docs/tables/fastly_account_users.md new file mode 100644 index 00000000000..4d6ca7099c1 --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_account_users.md @@ -0,0 +1,28 @@ +# Table: fastly_account_users + +https://developer.fastly.com/reference/api/account/user/ + +The primary key for this table is **id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|created_at|Timestamp| +|customer_id|String| +|deleted_at|Timestamp| +|email_hash|String| +|id (PK)|String| +|limit_services|Bool| +|locked|Bool| +|login|String| +|name|String| +|require_new_password|Bool| +|role|String| +|two_factor_auth_enabled|Bool| +|two_factor_setup_required|Bool| +|updated_at|Timestamp| \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_auth_tokens.md b/plugins/source/fastly/docs/tables/fastly_auth_tokens.md new file mode 100644 index 00000000000..1326e521033 --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_auth_tokens.md @@ -0,0 +1,24 @@ +# Table: fastly_auth_tokens + +https://developer.fastly.com/reference/api/auth-tokens/ + +The primary key for this table is **id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|access_token|String| +|created_at|Timestamp| +|expires_at|Timestamp| +|id (PK)|String| +|ip|String| +|last_used_at|Timestamp| +|name|String| +|scope|String| +|services|StringArray| +|user_id|String| \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_service_backends.md b/plugins/source/fastly/docs/tables/fastly_service_backends.md new file mode 100644 index 00000000000..d0ada204be9 --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_service_backends.md @@ -0,0 +1,50 @@ +# Table: fastly_service_backends + +https://developer.fastly.com/reference/api/services/backend/ + +The composite primary key for this table is (**name**, **service_id**, **service_version**). + +## Relations + +This table depends on [fastly_service_versions](fastly_service_versions.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|address|String| +|auto_loadbalance|Bool| +|between_bytes_timeout|Int| +|comment|String| +|connect_timeout|Int| +|created_at|Timestamp| +|deleted_at|Timestamp| +|error_threshold|Int| +|first_byte_timeout|Int| +|health_check|String| +|hostname|String| +|max_conn|Int| +|max_tls_version|String| +|min_tls_version|String| +|name (PK)|String| +|override_host|String| +|port|Int| +|request_condition|String| +|sslca_cert|String| +|ssl_cert_hostname|String| +|ssl_check_cert|Bool| +|ssl_ciphers|String| +|ssl_client_cert|String| +|ssl_client_key|String| +|ssl_hostname|String| +|sslsni_hostname|String| +|service_id (PK)|String| +|service_version (PK)|Int| +|shield|String| +|updated_at|Timestamp| +|use_ssl|Bool| +|weight|Int| \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_service_domains.md b/plugins/source/fastly/docs/tables/fastly_service_domains.md new file mode 100644 index 00000000000..03b4356a9ec --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_service_domains.md @@ -0,0 +1,25 @@ +# Table: fastly_service_domains + +https://developer.fastly.com/reference/api/services/domain/ + +The composite primary key for this table is (**name**, **service_id**, **service_version**). + +## Relations + +This table depends on [fastly_service_versions](fastly_service_versions.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|comment|String| +|created_at|Timestamp| +|deleted_at|Timestamp| +|name (PK)|String| +|service_id (PK)|String| +|service_version (PK)|Int| +|updated_at|Timestamp| \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_service_health_checks.md b/plugins/source/fastly/docs/tables/fastly_service_health_checks.md new file mode 100644 index 00000000000..4bb79e024dd --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_service_health_checks.md @@ -0,0 +1,36 @@ +# Table: fastly_service_health_checks + +https://developer.fastly.com/reference/api/services/healthcheck/ + +The composite primary key for this table is (**name**, **service_id**, **service_version**). + +## Relations + +This table depends on [fastly_service_versions](fastly_service_versions.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|check_interval|Int| +|comment|String| +|created_at|Timestamp| +|deleted_at|Timestamp| +|expected_response|Int| +|http_version|String| +|headers|StringArray| +|host|String| +|initial|Int| +|method|String| +|name (PK)|String| +|path|String| +|service_id (PK)|String| +|service_version (PK)|Int| +|threshold|Int| +|timeout|Int| +|updated_at|Timestamp| +|window|Int| \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_service_versions.md b/plugins/source/fastly/docs/tables/fastly_service_versions.md new file mode 100644 index 00000000000..64f5231d642 --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_service_versions.md @@ -0,0 +1,34 @@ +# Table: fastly_service_versions + +https://developer.fastly.com/reference/api/services/version/ + +The composite primary key for this table is (**number**, **service_id**). + +## Relations + +This table depends on [fastly_services](fastly_services.md). + +The following tables depend on fastly_service_versions: + - [fastly_service_health_checks](fastly_service_health_checks.md) + - [fastly_service_domains](fastly_service_domains.md) + - [fastly_service_backends](fastly_service_backends.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|active|Bool| +|comment|String| +|created_at|Timestamp| +|deleted_at|Timestamp| +|deployed|Bool| +|locked|Bool| +|number (PK)|Int| +|service_id (PK)|String| +|staging|Bool| +|testing|Bool| +|updated_at|Timestamp| \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_services.md b/plugins/source/fastly/docs/tables/fastly_services.md new file mode 100644 index 00000000000..fc453212385 --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_services.md @@ -0,0 +1,29 @@ +# Table: fastly_services + +https://developer.fastly.com/reference/api/services/service/ + +The primary key for this table is **id**. + +## Relations + +The following tables depend on fastly_services: + - [fastly_service_versions](fastly_service_versions.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|active_version|Int| +|comment|String| +|created_at|Timestamp| +|customer_id|String| +|deleted_at|Timestamp| +|id (PK)|String| +|name|String| +|type|String| +|updated_at|Timestamp| +|versions|JSON| \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_stats_regions.md b/plugins/source/fastly/docs/tables/fastly_stats_regions.md new file mode 100644 index 00000000000..ce6656d6ce7 --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_stats_regions.md @@ -0,0 +1,15 @@ +# Table: fastly_stats_regions + +https://developer.fastly.com/reference/api/metrics-stats/historical-stats/#get-regions + +The primary key for this table is **name**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|name (PK)|String| \ No newline at end of file diff --git a/plugins/source/fastly/docs/tables/fastly_stats_services.md b/plugins/source/fastly/docs/tables/fastly_stats_services.md new file mode 100644 index 00000000000..9ee291d18ca --- /dev/null +++ b/plugins/source/fastly/docs/tables/fastly_stats_services.md @@ -0,0 +1,143 @@ +# Table: fastly_stats_services + +https://developer.fastly.com/reference/api/metrics-stats/historical-stats/ + +The composite primary key for this table is (**start_time**, **service_id**, **region**, **by**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|start_time (PK)|Timestamp| +|service_id (PK)|String| +|region (PK)|String| +|by (PK)|String| +|attack_req_header_bytes|Int| +|attack_req_body_bytes|Int| +|attack_resp_synth_bytes|Int| +|bereq_body_bytes|Int| +|bereq_header_bytes|Int| +|bandwidth|Int| +|billed_body_bytes|Int| +|billed_header_bytes|Int| +|errors|Int| +|http2|Int| +|hit_ratio|Float| +|hits|Int| +|hits_time|Float| +|ipv6|Int| +|imgopto|Int| +|log|Int| +|miss|Int| +|miss_time|Float| +|otfp|Int| +|object_size_100k|Int| +|object_size_100m|Int| +|object_size_10k|Int| +|object_size_10m|Int| +|object_size_1g|Int| +|object_size_1k|Int| +|object_size_1m|Int| +|pci|Int| +|pass|Int| +|pass_time|Float| +|pipe|Int| +|req_body_bytes|Int| +|req_header_bytes|Int| +|requests|Int| +|resp_body_bytes|Int| +|resp_header_bytes|Int| +|restarts|Int| +|shield|Int| +|shield_resp_body_bytes|Int| +|shield_resp_header_bytes|Int| +|status_1xx|Int| +|status_200|Int| +|status_204|Int| +|status_206|Int| +|status_2xx|Int| +|status_301|Int| +|status_302|Int| +|status_304|Int| +|status_3xx|Int| +|status_400|Int| +|status_401|Int| +|status_403|Int| +|status_404|Int| +|status_416|Int| +|status_4xx|Int| +|status_500|Int| +|status_501|Int| +|status_502|Int| +|status_503|Int| +|status_504|Int| +|status_505|Int| +|status_5xx|Int| +|synth|Int| +|tls|Int| +|tls_v10|Int| +|tls_v11|Int| +|tls_v12|Int| +|tls_v13|Int| +|uncachable|Int| +|video|Int| +|waf_blocked|Int| +|waf_logged|Int| +|waf_passed|Int| +|compute_bereq_body_bytes|Int| +|compute_bereq_errors|Int| +|compute_bereq_header_bytes|Int| +|compute_bereqs|Int| +|compute_beresp_body_bytes|Int| +|compute_beresp_header_bytes|Int| +|compute_execution_time_ms|Int| +|compute_globals_limit_exceeded|Int| +|compute_guest_errors|Int| +|compute_heap_limit_exceeded|Int| +|compute_ram_used|Int| +|compute_req_body_bytes|Int| +|compute_req_header_bytes|Int| +|compute_request_time_ms|Int| +|compute_requests|Int| +|compute_resource_limit_exceeded|Int| +|compute_resp_body_bytes|Int| +|compute_resp_header_bytes|Int| +|compute_resp_status_1xx|Int| +|compute_resp_status_2xx|Int| +|compute_resp_status_3xx|Int| +|compute_resp_status_4xx|Int| +|compute_resp_status_5xx|Int| +|compute_runtime_errors|Int| +|compute_stack_limit_exceeded|Int| +|edge_hit_requests|Int| +|edge_hit_resp_body_bytes|Int| +|edge_hit_resp_header_bytes|Int| +|edge_miss_requests|Int| +|edge_miss_resp_body_bytes|Int| +|edge_miss_resp_header_bytes|Int| +|edge_requests|Int| +|edge_resp_body_bytes|Int| +|edge_resp_header_bytes|Int| +|origin_cache_fetch_resp_body_bytes|Int| +|origin_cache_fetch_resp_header_bytes|Int| +|origin_cache_fetches|Int| +|origin_fetch_body_bytes|Int| +|origin_fetch_header_bytes|Int| +|origin_fetch_resp_body_bytes|Int| +|origin_fetch_resp_header_bytes|Int| +|origin_fetches|Int| +|fanout_bereq_body_bytes|Int| +|fanout_bereq_header_bytes|Int| +|fanout_beresp_body_bytes|Int| +|fanout_beresp_header_bytes|Int| +|fanout_conn_time_ms|Int| +|fanout_recv_publishes|Int| +|fanout_req_body_bytes|Int| +|fanout_req_header_bytes|Int| +|fanout_resp_body_bytes|Int| +|fanout_resp_header_bytes|Int| +|fanout_send_publishes|Int| \ No newline at end of file diff --git a/plugins/source/fastly/go.mod b/plugins/source/fastly/go.mod new file mode 100644 index 00000000000..d63f79992e4 --- /dev/null +++ b/plugins/source/fastly/go.mod @@ -0,0 +1,43 @@ +module github.com/cloudquery/cloudquery/plugins/source/fastly + +go 1.19 + +require ( + github.com/cloudquery/plugin-sdk v1.12.7 + github.com/fastly/go-fastly/v7 v7.0.0 + github.com/gertd/go-pluralize v0.2.1 + github.com/golang/mock v1.6.0 + github.com/rs/zerolog v1.28.0 + github.com/thoas/go-funk v0.9.2 +) + +require ( + github.com/getsentry/sentry-go v0.15.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/jsonapi v1.0.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/peterhellberg/link v1.1.0 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 // indirect + golang.org/x/mod v0.6.0 // indirect + golang.org/x/net v0.2.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.2.0 // indirect + golang.org/x/text v0.4.0 // indirect + golang.org/x/tools v0.2.0 // indirect + google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e // indirect + google.golang.org/grpc v1.51.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/plugins/source/fastly/go.sum b/plugins/source/fastly/go.sum new file mode 100644 index 00000000000..344d99d9ec1 --- /dev/null +++ b/plugins/source/fastly/go.sum @@ -0,0 +1,508 @@ +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/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/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= +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/avast/retry-go/v4 v4.3.1 h1:Mtg11F9PdAIMkMiio2RKcYauoVHjl2aB3zQJJlzD4cE= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +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/cloudquery/plugin-sdk v1.12.7 h1:hg84meEkASUPLnAuBxvgFpyjWUP2iWjxZulkxVcnxTY= +github.com/cloudquery/plugin-sdk v1.12.7/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fastly/go-fastly/v7 v7.0.0 h1:Qz6AHosQtSbp8u3aQyGruXNFF/yAqvvjaUCNvTM1XS4= +github.com/fastly/go-fastly/v7 v7.0.0/go.mod h1:WdssHSSIe41/a5juIJagw8MCTA9m7xQ1TVLRcBQQuS8= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlLgiA= +github.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk= +github.com/getsentry/sentry-go v0.15.0 h1:CP9bmA7pralrVUedYZsmIHWpq/pBtXTSew7xvVpfLaA= +github.com/getsentry/sentry-go v0.15.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2HtRckJk9XVxJ9I= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +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/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/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/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.2/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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +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/jsonapi v1.0.0 h1:qIGgO5Smu3yJmSs+QlvhQnrscdZfFhiV6S8ryJAglqU= +github.com/google/jsonapi v1.0.0/go.mod h1:YYHiRPJT8ARXGER8In9VuLv4qvLfDmA9ULQqptbLE4s= +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/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 h1:hRcWZ7716+E1tkMSZJ/QeeC2dPGGB1R/4z4m9RsL8Qg= +github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3/go.mod h1:54asssGY3Bohr5FRbew+bjfuQTT2WS9V7hW7gPqmcKM= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2.0.20201002093600-73cf2ae9d891/go.mod h1:GhphxcdlaRyAuBSvo6rV71BvQcvB/vuX8ugCyybuS2k= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= +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= +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/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +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.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +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= +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.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/peterhellberg/link v1.1.0 h1:s2+RH8EGuI/mI4QwrWGSYQCRz7uNgip9BaM04HKu5kc= +github.com/peterhellberg/link v1.1.0/go.mod h1:gtSlOT4jmkY8P47hbTc8PTgiDDWpdPbFYl75keYyBB8= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= +github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/schollz/progressbar/v3 v3.12.1 h1:JAhtIrLWAn6/p7i82SrpSG3fgAwlAxi+Sy12r4AzBvQ= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/thoas/go-funk v0.9.2 h1:oKlNYv0AY5nyf9g+/GhMgS/UO2ces0QRdPKwkhY3VCk= +github.com/thoas/go-funk v0.9.2/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +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= +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/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/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +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-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +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-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/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-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-20210119212857-b64e53b001e4/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/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 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.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 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +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/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-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-20190828213141-aed303cbaa74/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-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.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +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/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-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-20200806141610-86f49bd18e98/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-20221111202108-142d8a6fa32e h1:azcyH5lGzGy7pkLCbhPe0KkKxsM7c6UA/FZIXImKE7M= +google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +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.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/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= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.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= +honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= +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/plugins/source/fastly/main.go b/plugins/source/fastly/main.go new file mode 100644 index 00000000000..549a15a1436 --- /dev/null +++ b/plugins/source/fastly/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/cloudquery/cloudquery/plugins/source/fastly/resources/plugin" + "github.com/cloudquery/plugin-sdk/serve" +) + +const sentryDSN = "https://c4e711b87a8846de90e5ba2c785fb901@o1396617.ingest.sentry.io/4504379395604480" + +func main() { + serve.Source(plugin.Plugin(), serve.WithSourceSentryDSN(sentryDSN)) +} diff --git a/plugins/source/fastly/resources/plugin/plugin.go b/plugins/source/fastly/resources/plugin/plugin.go new file mode 100644 index 00000000000..17164da1ed6 --- /dev/null +++ b/plugins/source/fastly/resources/plugin/plugin.go @@ -0,0 +1,19 @@ +package plugin + +import ( + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/plugins/source" +) + +var ( + Version = "development" +) + +func Plugin() *source.Plugin { + return source.NewPlugin( + "fastly", + Version, + tables(), + client.Configure, + ) +} diff --git a/plugins/source/fastly/resources/plugin/tables.go b/plugins/source/fastly/resources/plugin/tables.go new file mode 100644 index 00000000000..626cd4c97c6 --- /dev/null +++ b/plugins/source/fastly/resources/plugin/tables.go @@ -0,0 +1,22 @@ +// Code generated by codegen; DO NOT EDIT. + +package plugin + +import ( + "github.com/cloudquery/cloudquery/plugins/source/fastly/resources/services/account" + "github.com/cloudquery/cloudquery/plugins/source/fastly/resources/services/auth" + "github.com/cloudquery/cloudquery/plugins/source/fastly/resources/services/services" + "github.com/cloudquery/cloudquery/plugins/source/fastly/resources/services/stats" + "github.com/cloudquery/plugin-sdk/schema" +) + +func tables() []*schema.Table { + return []*schema.Table{ + account.AccountUsers(), + account.AccountEvents(), + auth.AuthTokens(), + services.Services(), + stats.StatsRegions(), + stats.StatsServices(), + } +} diff --git a/plugins/source/fastly/resources/services/account/account_events.go b/plugins/source/fastly/resources/services/account/account_events.go new file mode 100644 index 00000000000..3c06866c61e --- /dev/null +++ b/plugins/source/fastly/resources/services/account/account_events.go @@ -0,0 +1,70 @@ +// Code generated by codegen; DO NOT EDIT. + +package account + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func AccountEvents() *schema.Table { + return &schema.Table{ + Name: "fastly_account_events", + Description: `https://developer.fastly.com/reference/api/account/events/`, + Resolver: fetchAccountEvents, + Columns: []schema.Column{ + { + Name: "admin", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Admin"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "customer_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("CustomerID"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "event_type", + Type: schema.TypeString, + Resolver: schema.PathResolver("EventType"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "ip", + Type: schema.TypeString, + Resolver: schema.PathResolver("IP"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + { + Name: "service_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceID"), + }, + { + Name: "user_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("UserID"), + }, + }, + } +} diff --git a/plugins/source/fastly/resources/services/account/account_events_fetch.go b/plugins/source/fastly/resources/services/account/account_events_fetch.go new file mode 100644 index 00000000000..7a204c9e215 --- /dev/null +++ b/plugins/source/fastly/resources/services/account/account_events_fetch.go @@ -0,0 +1,32 @@ +package account + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/fastly/go-fastly/v7/fastly" +) + +func fetchAccountEvents(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + input := &fastly.GetAPIEventsFilterInput{ + MaxResults: 100, + PageNumber: 1, + } + for { + r, err := c.Fastly.GetAPIEvents(input) + if err != nil { + return err + } + res <- r.Events + if r.Links.Next == "" { + break + } + input.PageNumber++ + } + return nil + } + return c.RetryOnError(ctx, "fastly_account_events", f) +} diff --git a/plugins/source/fastly/resources/services/account/account_events_mock_test.go b/plugins/source/fastly/resources/services/account/account_events_mock_test.go new file mode 100644 index 00000000000..2675c0b7a40 --- /dev/null +++ b/plugins/source/fastly/resources/services/account/account_events_mock_test.go @@ -0,0 +1,28 @@ +package account + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/services" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +func buildAccountEventsMock(t *testing.T, ctrl *gomock.Controller) services.FastlyClient { + m := mocks.NewMockFastlyClient(ctrl) + f := fastly.GetAPIEventsResponse{} + err := faker.FakeObject(&f) + if err != nil { + t.Fatal(err) + } + f.Links.Next = "" + m.EXPECT().GetAPIEvents(gomock.Any()).Return(f, nil) + return m +} + +func TestStatsRegions(t *testing.T) { + client.MockTestHelper(t, AccountEvents(), buildAccountEventsMock, client.TestOptions{}) +} diff --git a/plugins/source/fastly/resources/services/account/account_users.go b/plugins/source/fastly/resources/services/account/account_users.go new file mode 100644 index 00000000000..22a3fa240af --- /dev/null +++ b/plugins/source/fastly/resources/services/account/account_users.go @@ -0,0 +1,90 @@ +// Code generated by codegen; DO NOT EDIT. + +package account + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func AccountUsers() *schema.Table { + return &schema.Table{ + Name: "fastly_account_users", + Description: `https://developer.fastly.com/reference/api/account/user/`, + Resolver: fetchAccountUsers, + Columns: []schema.Column{ + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "customer_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("CustomerID"), + }, + { + Name: "deleted_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("DeletedAt"), + }, + { + Name: "email_hash", + Type: schema.TypeString, + Resolver: schema.PathResolver("EmailHash"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "limit_services", + Type: schema.TypeBool, + Resolver: schema.PathResolver("LimitServices"), + }, + { + Name: "locked", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Locked"), + }, + { + Name: "login", + Type: schema.TypeString, + Resolver: schema.PathResolver("Login"), + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + }, + { + Name: "require_new_password", + Type: schema.TypeBool, + Resolver: schema.PathResolver("RequireNewPassword"), + }, + { + Name: "role", + Type: schema.TypeString, + Resolver: schema.PathResolver("Role"), + }, + { + Name: "two_factor_auth_enabled", + Type: schema.TypeBool, + Resolver: schema.PathResolver("TwoFactorAuthEnabled"), + }, + { + Name: "two_factor_setup_required", + Type: schema.TypeBool, + Resolver: schema.PathResolver("TwoFactorSetupRequired"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + }, + } +} diff --git a/plugins/source/fastly/resources/services/account/account_users_fetch.go b/plugins/source/fastly/resources/services/account/account_users_fetch.go new file mode 100644 index 00000000000..f11b6ad90a0 --- /dev/null +++ b/plugins/source/fastly/resources/services/account/account_users_fetch.go @@ -0,0 +1,29 @@ +package account + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/fastly/go-fastly/v7/fastly" +) + +func fetchAccountUsers(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + currentUser, err := c.Fastly.GetCurrentUser() + if err != nil { + return err + } + input := &fastly.ListCustomerUsersInput{ + CustomerID: currentUser.CustomerID, + } + r, err := c.Fastly.ListCustomerUsers(input) + if err != nil { + return err + } + res <- r + return nil + } + return c.RetryOnError(ctx, "fastly_account_users", f) +} diff --git a/plugins/source/fastly/resources/services/account/account_users_mock_test.go b/plugins/source/fastly/resources/services/account/account_users_mock_test.go new file mode 100644 index 00000000000..70af53c2480 --- /dev/null +++ b/plugins/source/fastly/resources/services/account/account_users_mock_test.go @@ -0,0 +1,28 @@ +package account + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/services" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +func buildAccountUsersMock(t *testing.T, ctrl *gomock.Controller) services.FastlyClient { + m := mocks.NewMockFastlyClient(ctrl) + f := make([]*fastly.User, 0, 1) + err := faker.FakeObject(&f) + if err != nil { + t.Fatal(err) + } + m.EXPECT().GetCurrentUser().Return(f[0], nil) + m.EXPECT().ListCustomerUsers(gomock.Any()).Return(f, nil) + return m +} + +func TestAccountUsers(t *testing.T) { + client.MockTestHelper(t, AccountUsers(), buildAccountUsersMock, client.TestOptions{}) +} diff --git a/plugins/source/fastly/resources/services/auth/auth_tokens.go b/plugins/source/fastly/resources/services/auth/auth_tokens.go new file mode 100644 index 00000000000..ae8e84455f0 --- /dev/null +++ b/plugins/source/fastly/resources/services/auth/auth_tokens.go @@ -0,0 +1,70 @@ +// Code generated by codegen; DO NOT EDIT. + +package auth + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func AuthTokens() *schema.Table { + return &schema.Table{ + Name: "fastly_auth_tokens", + Description: `https://developer.fastly.com/reference/api/auth-tokens/`, + Resolver: fetchAuthTokens, + Columns: []schema.Column{ + { + Name: "access_token", + Type: schema.TypeString, + Resolver: schema.PathResolver("AccessToken"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "expires_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("ExpiresAt"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "ip", + Type: schema.TypeString, + Resolver: schema.PathResolver("IP"), + }, + { + Name: "last_used_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("LastUsedAt"), + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + }, + { + Name: "scope", + Type: schema.TypeString, + Resolver: schema.PathResolver("Scope"), + }, + { + Name: "services", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("Services"), + }, + { + Name: "user_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("UserID"), + }, + }, + } +} diff --git a/plugins/source/fastly/resources/services/auth/auth_tokens_fetch.go b/plugins/source/fastly/resources/services/auth/auth_tokens_fetch.go new file mode 100644 index 00000000000..0ba65da0217 --- /dev/null +++ b/plugins/source/fastly/resources/services/auth/auth_tokens_fetch.go @@ -0,0 +1,21 @@ +package auth + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchAuthTokens(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + r, err := c.Fastly.ListTokens() + if err != nil { + return err + } + res <- r + return nil + } + return c.RetryOnError(ctx, "fastly_auth_tokens", f) +} diff --git a/plugins/source/fastly/resources/services/auth/auth_tokens_mock_test.go b/plugins/source/fastly/resources/services/auth/auth_tokens_mock_test.go new file mode 100644 index 00000000000..ac902072563 --- /dev/null +++ b/plugins/source/fastly/resources/services/auth/auth_tokens_mock_test.go @@ -0,0 +1,27 @@ +package auth + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/services" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +func buildAuthTokensMock(t *testing.T, ctrl *gomock.Controller) services.FastlyClient { + m := mocks.NewMockFastlyClient(ctrl) + f := make([]*fastly.Token, 0, 1) + err := faker.FakeObject(&f) + if err != nil { + t.Fatal(err) + } + m.EXPECT().ListTokens().Return(f, nil) + return m +} + +func TestAuthTokens(t *testing.T) { + client.MockTestHelper(t, AuthTokens(), buildAuthTokensMock, client.TestOptions{}) +} diff --git a/plugins/source/fastly/resources/services/services/service_backends.go b/plugins/source/fastly/resources/services/services/service_backends.go new file mode 100644 index 00000000000..87a5d271bf8 --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_backends.go @@ -0,0 +1,186 @@ +// Code generated by codegen; DO NOT EDIT. + +package services + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func ServiceBackends() *schema.Table { + return &schema.Table{ + Name: "fastly_service_backends", + Description: `https://developer.fastly.com/reference/api/services/backend/`, + Resolver: fetchServiceBackends, + Columns: []schema.Column{ + { + Name: "address", + Type: schema.TypeString, + Resolver: schema.PathResolver("Address"), + }, + { + Name: "auto_loadbalance", + Type: schema.TypeBool, + Resolver: schema.PathResolver("AutoLoadbalance"), + }, + { + Name: "between_bytes_timeout", + Type: schema.TypeInt, + Resolver: schema.PathResolver("BetweenBytesTimeout"), + }, + { + Name: "comment", + Type: schema.TypeString, + Resolver: schema.PathResolver("Comment"), + }, + { + Name: "connect_timeout", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ConnectTimeout"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "deleted_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("DeletedAt"), + }, + { + Name: "error_threshold", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ErrorThreshold"), + }, + { + Name: "first_byte_timeout", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FirstByteTimeout"), + }, + { + Name: "health_check", + Type: schema.TypeString, + Resolver: schema.PathResolver("HealthCheck"), + }, + { + Name: "hostname", + Type: schema.TypeString, + Resolver: schema.PathResolver("Hostname"), + }, + { + Name: "max_conn", + Type: schema.TypeInt, + Resolver: schema.PathResolver("MaxConn"), + }, + { + Name: "max_tls_version", + Type: schema.TypeString, + Resolver: schema.PathResolver("MaxTLSVersion"), + }, + { + Name: "min_tls_version", + Type: schema.TypeString, + Resolver: schema.PathResolver("MinTLSVersion"), + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "override_host", + Type: schema.TypeString, + Resolver: schema.PathResolver("OverrideHost"), + }, + { + Name: "port", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Port"), + }, + { + Name: "request_condition", + Type: schema.TypeString, + Resolver: schema.PathResolver("RequestCondition"), + }, + { + Name: "sslca_cert", + Type: schema.TypeString, + Resolver: schema.PathResolver("SSLCACert"), + }, + { + Name: "ssl_cert_hostname", + Type: schema.TypeString, + Resolver: schema.PathResolver("SSLCertHostname"), + }, + { + Name: "ssl_check_cert", + Type: schema.TypeBool, + Resolver: schema.PathResolver("SSLCheckCert"), + }, + { + Name: "ssl_ciphers", + Type: schema.TypeString, + Resolver: schema.PathResolver("SSLCiphers"), + }, + { + Name: "ssl_client_cert", + Type: schema.TypeString, + Resolver: schema.PathResolver("SSLClientCert"), + }, + { + Name: "ssl_client_key", + Type: schema.TypeString, + Resolver: schema.PathResolver("SSLClientKey"), + }, + { + Name: "ssl_hostname", + Type: schema.TypeString, + Resolver: schema.PathResolver("SSLHostname"), + }, + { + Name: "sslsni_hostname", + Type: schema.TypeString, + Resolver: schema.PathResolver("SSLSNIHostname"), + }, + { + Name: "service_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "service_version", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ServiceVersion"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "shield", + Type: schema.TypeString, + Resolver: schema.PathResolver("Shield"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + { + Name: "use_ssl", + Type: schema.TypeBool, + Resolver: schema.PathResolver("UseSSL"), + }, + { + Name: "weight", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Weight"), + }, + }, + } +} diff --git a/plugins/source/fastly/resources/services/services/service_backends_fetch.go b/plugins/source/fastly/resources/services/services/service_backends_fetch.go new file mode 100644 index 00000000000..46c59ce85ab --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_backends_fetch.go @@ -0,0 +1,27 @@ +package services + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/fastly/go-fastly/v7/fastly" +) + +func fetchServiceBackends(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + v := parent.Item.(*fastly.Version) + + backend, err := c.Fastly.ListBackends(&fastly.ListBackendsInput{ + ServiceID: v.ServiceID, + ServiceVersion: v.Number, + }) + if err != nil { + return err + } + res <- backend + return nil + } + return c.RetryOnError(ctx, "fastly_service_backends", f) +} diff --git a/plugins/source/fastly/resources/services/services/service_backends_mock_test.go b/plugins/source/fastly/resources/services/services/service_backends_mock_test.go new file mode 100644 index 00000000000..4196ba60e1a --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_backends_mock_test.go @@ -0,0 +1,19 @@ +package services + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +func buildServiceBackendsMock(t *testing.T, m *mocks.MockFastlyClient) { + d := make([]*fastly.Backend, 0, 1) + err := faker.FakeObject(&d) + if err != nil { + t.Fatal(err) + } + m.EXPECT().ListBackends(gomock.Any()).Return(d, nil) +} diff --git a/plugins/source/fastly/resources/services/services/service_domains.go b/plugins/source/fastly/resources/services/services/service_domains.go new file mode 100644 index 00000000000..65f99d67beb --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_domains.go @@ -0,0 +1,61 @@ +// Code generated by codegen; DO NOT EDIT. + +package services + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func ServiceDomains() *schema.Table { + return &schema.Table{ + Name: "fastly_service_domains", + Description: `https://developer.fastly.com/reference/api/services/domain/`, + Resolver: fetchServiceDomains, + Columns: []schema.Column{ + { + Name: "comment", + Type: schema.TypeString, + Resolver: schema.PathResolver("Comment"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "deleted_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("DeletedAt"), + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "service_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "service_version", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ServiceVersion"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + }, + } +} diff --git a/plugins/source/fastly/resources/services/services/service_domains_fetch.go b/plugins/source/fastly/resources/services/services/service_domains_fetch.go new file mode 100644 index 00000000000..5bc339add15 --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_domains_fetch.go @@ -0,0 +1,26 @@ +package services + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/fastly/go-fastly/v7/fastly" +) + +func fetchServiceDomains(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + v := parent.Item.(*fastly.Version) + domains, err := c.Fastly.ListDomains(&fastly.ListDomainsInput{ + ServiceID: v.ServiceID, + ServiceVersion: v.Number, + }) + if err != nil { + return err + } + res <- domains + return nil + } + return c.RetryOnError(ctx, "fastly_service_domains", f) +} diff --git a/plugins/source/fastly/resources/services/services/service_domains_mock_test.go b/plugins/source/fastly/resources/services/services/service_domains_mock_test.go new file mode 100644 index 00000000000..ad5b8a137e7 --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_domains_mock_test.go @@ -0,0 +1,19 @@ +package services + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +func buildServiceDomainsMock(t *testing.T, m *mocks.MockFastlyClient) { + d := make([]*fastly.Domain, 0, 1) + err := faker.FakeObject(&d) + if err != nil { + t.Fatal(err) + } + m.EXPECT().ListDomains(gomock.Any()).Return(d, nil) +} diff --git a/plugins/source/fastly/resources/services/services/service_health_checks.go b/plugins/source/fastly/resources/services/services/service_health_checks.go new file mode 100644 index 00000000000..5bd0bee65d2 --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_health_checks.go @@ -0,0 +1,116 @@ +// Code generated by codegen; DO NOT EDIT. + +package services + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func ServiceHealthChecks() *schema.Table { + return &schema.Table{ + Name: "fastly_service_health_checks", + Description: `https://developer.fastly.com/reference/api/services/healthcheck/`, + Resolver: fetchServiceHealthChecks, + Columns: []schema.Column{ + { + Name: "check_interval", + Type: schema.TypeInt, + Resolver: schema.PathResolver("CheckInterval"), + }, + { + Name: "comment", + Type: schema.TypeString, + Resolver: schema.PathResolver("Comment"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "deleted_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("DeletedAt"), + }, + { + Name: "expected_response", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ExpectedResponse"), + }, + { + Name: "http_version", + Type: schema.TypeString, + Resolver: schema.PathResolver("HTTPVersion"), + }, + { + Name: "headers", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("Headers"), + }, + { + Name: "host", + Type: schema.TypeString, + Resolver: schema.PathResolver("Host"), + }, + { + Name: "initial", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Initial"), + }, + { + Name: "method", + Type: schema.TypeString, + Resolver: schema.PathResolver("Method"), + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "path", + Type: schema.TypeString, + Resolver: schema.PathResolver("Path"), + }, + { + Name: "service_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "service_version", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ServiceVersion"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "threshold", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Threshold"), + }, + { + Name: "timeout", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Timeout"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + { + Name: "window", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Window"), + }, + }, + } +} diff --git a/plugins/source/fastly/resources/services/services/service_health_checks_fetch.go b/plugins/source/fastly/resources/services/services/service_health_checks_fetch.go new file mode 100644 index 00000000000..c6801db324b --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_health_checks_fetch.go @@ -0,0 +1,27 @@ +package services + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/fastly/go-fastly/v7/fastly" +) + +func fetchServiceHealthChecks(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + v := parent.Item.(*fastly.Version) + healthChecks, err := c.Fastly.ListHealthChecks(&fastly.ListHealthChecksInput{ + ServiceID: v.ServiceID, + ServiceVersion: v.Number, + }) + if err != nil { + return err + } + res <- healthChecks + + return nil + } + return c.RetryOnError(ctx, "fastly_service_health_checks", f) +} diff --git a/plugins/source/fastly/resources/services/services/service_health_checks_mock_test.go b/plugins/source/fastly/resources/services/services/service_health_checks_mock_test.go new file mode 100644 index 00000000000..f7ce94bae92 --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_health_checks_mock_test.go @@ -0,0 +1,19 @@ +package services + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +func buildServiceHealthChecksMock(t *testing.T, m *mocks.MockFastlyClient) { + d := make([]*fastly.HealthCheck, 0, 1) + err := faker.FakeObject(&d) + if err != nil { + t.Fatal(err) + } + m.EXPECT().ListHealthChecks(gomock.Any()).Return(d, nil) +} diff --git a/plugins/source/fastly/resources/services/services/service_versions.go b/plugins/source/fastly/resources/services/services/service_versions.go new file mode 100644 index 00000000000..87ffa213aca --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_versions.go @@ -0,0 +1,84 @@ +// Code generated by codegen; DO NOT EDIT. + +package services + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func ServiceVersions() *schema.Table { + return &schema.Table{ + Name: "fastly_service_versions", + Description: `https://developer.fastly.com/reference/api/services/version/`, + Resolver: fetchServiceVersions, + Columns: []schema.Column{ + { + Name: "active", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Active"), + }, + { + Name: "comment", + Type: schema.TypeString, + Resolver: schema.PathResolver("Comment"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "deleted_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("DeletedAt"), + }, + { + Name: "deployed", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Deployed"), + }, + { + Name: "locked", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Locked"), + }, + { + Name: "number", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Number"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "service_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "staging", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Staging"), + }, + { + Name: "testing", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Testing"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + }, + + Relations: []*schema.Table{ + ServiceHealthChecks(), + ServiceDomains(), + ServiceBackends(), + }, + } +} diff --git a/plugins/source/fastly/resources/services/services/service_versions_fetch.go b/plugins/source/fastly/resources/services/services/service_versions_fetch.go new file mode 100644 index 00000000000..d3f7c8c11bc --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_versions_fetch.go @@ -0,0 +1,25 @@ +package services + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/fastly/go-fastly/v7/fastly" +) + +func fetchServiceVersions(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + s := parent.Item.(*fastly.Service) + versions, err := c.Fastly.ListVersions(&fastly.ListVersionsInput{ + ServiceID: s.ID, + }) + if err != nil { + return err + } + res <- versions + return nil + } + return c.RetryOnError(ctx, "fastly_service_versions", f) +} diff --git a/plugins/source/fastly/resources/services/services/service_versions_mock_test.go b/plugins/source/fastly/resources/services/services/service_versions_mock_test.go new file mode 100644 index 00000000000..f34eea4d03a --- /dev/null +++ b/plugins/source/fastly/resources/services/services/service_versions_mock_test.go @@ -0,0 +1,19 @@ +package services + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +func buildServiceVersionsMock(t *testing.T, m *mocks.MockFastlyClient) { + d := make([]*fastly.Version, 0, 1) + err := faker.FakeObject(&d) + if err != nil { + t.Fatal(err) + } + m.EXPECT().ListVersions(gomock.Any()).Return(d, nil) +} diff --git a/plugins/source/fastly/resources/services/services/services.go b/plugins/source/fastly/resources/services/services/services.go new file mode 100644 index 00000000000..59bb7a3c9f7 --- /dev/null +++ b/plugins/source/fastly/resources/services/services/services.go @@ -0,0 +1,74 @@ +// Code generated by codegen; DO NOT EDIT. + +package services + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func Services() *schema.Table { + return &schema.Table{ + Name: "fastly_services", + Description: `https://developer.fastly.com/reference/api/services/service/`, + Resolver: fetchServices, + Columns: []schema.Column{ + { + Name: "active_version", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ActiveVersion"), + }, + { + Name: "comment", + Type: schema.TypeString, + Resolver: schema.PathResolver("Comment"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "customer_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("CustomerID"), + }, + { + Name: "deleted_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("DeletedAt"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + }, + { + Name: "type", + Type: schema.TypeString, + Resolver: schema.PathResolver("Type"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + { + Name: "versions", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Versions"), + }, + }, + + Relations: []*schema.Table{ + ServiceVersions(), + }, + } +} diff --git a/plugins/source/fastly/resources/services/services/services_fetch.go b/plugins/source/fastly/resources/services/services/services_fetch.go new file mode 100644 index 00000000000..8a174380eab --- /dev/null +++ b/plugins/source/fastly/resources/services/services/services_fetch.go @@ -0,0 +1,34 @@ +package services + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/thoas/go-funk" +) + +func fetchServices(ctx context.Context, meta schema.ClientMeta, _ *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + p := c.Fastly.NewListServicesPaginator(&fastly.ListServicesInput{ + PerPage: 100, + }) + cfg := c.Spec + if p.HasNext() { + services, err := p.GetNext() + if err != nil { + return err + } + for _, s := range services { + if len(cfg.Services) > 0 && !funk.ContainsString(cfg.Services, s.ID) { + continue + } + res <- s + } + } + return nil + } + return c.RetryOnError(ctx, "fastly_services", f) +} diff --git a/plugins/source/fastly/resources/services/services/services_mock_test.go b/plugins/source/fastly/resources/services/services/services_mock_test.go new file mode 100644 index 00000000000..a9396f289b0 --- /dev/null +++ b/plugins/source/fastly/resources/services/services/services_mock_test.go @@ -0,0 +1,57 @@ +package services + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/services" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +type mockListServicesPaginator struct { + items []*fastly.Service + pages int + currentPage int +} + +func (m *mockListServicesPaginator) Remaining() int { + return m.pages - m.currentPage +} + +func (m *mockListServicesPaginator) GetNext() ([]*fastly.Service, error) { + m.currentPage++ + return m.items[m.currentPage-2 : m.currentPage-1], nil +} + +func (m *mockListServicesPaginator) HasNext() bool { + return m.currentPage <= m.pages +} + +func buildServicesMock(t *testing.T, ctrl *gomock.Controller) services.FastlyClient { + m := mocks.NewMockFastlyClient(ctrl) + + buildServiceVersionsMock(t, m) + buildServiceBackendsMock(t, m) + buildServiceDomainsMock(t, m) + buildServiceHealthChecksMock(t, m) + + d := make([]*fastly.Service, 0, 1) + err := faker.FakeObject(&d) + if err != nil { + t.Fatal(err) + } + p := &mockListServicesPaginator{ + items: d, + pages: 1, + currentPage: 1, + } + m.EXPECT().NewListServicesPaginator(gomock.Any()).Return(p) + return m +} + +func TestServices(t *testing.T) { + client.MockTestHelper(t, Services(), buildServicesMock, client.TestOptions{}) +} diff --git a/plugins/source/fastly/resources/services/stats/models/stats.go b/plugins/source/fastly/resources/services/stats/models/stats.go new file mode 100644 index 00000000000..48fb7bd780f --- /dev/null +++ b/plugins/source/fastly/resources/services/stats/models/stats.go @@ -0,0 +1,138 @@ +package models + +type StatsWrapper struct { + ServiceID string `json:"service_id"` + Region string `json:"region"` + StartTime uint64 `json:"start_time"` // unix timestamp + By string `json:"by"` // e.g. "hour" + + // Stats + AttackRequestHeaderBytes uint64 `json:"attack_req_header_bytes"` + AttackRequestBodyBytes uint64 `json:"attack_req_body_bytes"` + AttackResponseSynthBytes uint64 `json:"attack_resp_synth_bytes"` + BERequestBodyBytes uint64 `json:"bereq_body_bytes"` + BERequestHeaderbytes uint64 `json:"bereq_header_bytes"` + Bandwidth uint64 `json:"bandwidth"` + BilledBodyBytes uint64 `json:"billed_body_bytes"` + BilledHeaderBytes uint64 `json:"billed_header_bytes"` + Errors uint64 `json:"errors"` + HTTP2 uint64 `json:"http2"` + HitRatio float64 `json:"hit_ratio"` + Hits uint64 `json:"hits"` + HitsTime float64 `json:"hits_time"` + IPv6 uint64 `json:"ipv6"` + ImageOptimizer uint64 `json:"imgopto"` + Log uint64 `json:"log"` + Miss uint64 `json:"miss"` + MissHistogram map[int]int `json:"miss_histogram"` + MissTime float64 `json:"miss_time"` + OTFP uint64 `json:"otfp"` + ObjectSize100k uint64 `json:"object_size_100k"` + ObjectSize100m uint64 `json:"object_size_100m"` + ObjectSize10k uint64 `json:"object_size_10k"` + ObjectSize10m uint64 `json:"object_size_10m"` + ObjectSize1g uint64 `json:"object_size_1g"` + ObjectSize1k uint64 `json:"object_size_1k"` + ObjectSize1m uint64 `json:"object_size_1m"` + PCI uint64 `json:"pci"` + Pass uint64 `json:"pass"` + PassTime float64 `json:"pass_time"` + Pipe uint64 `json:"pipe"` + RequestBodyBytes uint64 `json:"req_body_bytes"` + RequestHeaderBytes uint64 `json:"req_header_bytes"` + Requests uint64 `json:"requests"` + ResponseBodyBytes uint64 `json:"resp_body_bytes"` + ResponseHeaderBytes uint64 `json:"resp_header_bytes"` + Restarts uint64 `json:"restarts"` + Shield uint64 `json:"shield"` + ShieldResponseBodyBytes uint64 `json:"shield_resp_body_bytes"` + ShieldResponseHeaderBytes uint64 `json:"shield_resp_header_bytes"` + Status1xx uint64 `json:"status_1xx"` + Status200 uint64 `json:"status_200"` + Status204 uint64 `json:"status_204"` + Status206 uint64 `json:"status_206"` + Status2xx uint64 `json:"status_2xx"` + Status301 uint64 `json:"status_301"` + Status302 uint64 `json:"status_302"` + Status304 uint64 `json:"status_304"` + Status3xx uint64 `json:"status_3xx"` + Status400 uint64 `json:"status_400"` + Status401 uint64 `json:"status_401"` + Status403 uint64 `json:"status_403"` + Status404 uint64 `json:"status_404"` + Status416 uint64 `json:"status_416"` + Status4xx uint64 `json:"status_4xx"` + Status500 uint64 `json:"status_500"` + Status501 uint64 `json:"status_501"` + Status502 uint64 `json:"status_502"` + Status503 uint64 `json:"status_503"` + Status504 uint64 `json:"status_504"` + Status505 uint64 `json:"status_505"` + Status5xx uint64 `json:"status_5xx"` + Synth uint64 `json:"synth"` + TLS uint64 `json:"tls"` + TLSv10 uint64 `json:"tls_v10"` + TLSv11 uint64 `json:"tls_v11"` + TLSv12 uint64 `json:"tls_v12"` + TLSv13 uint64 `json:"tls_v13"` + Uncachable uint64 `json:"uncachable"` + Video uint64 `json:"video"` + WAFBlocked uint64 `json:"waf_blocked"` + WAFLogged uint64 `json:"waf_logged"` + WAFPassed uint64 `json:"waf_passed"` + + // Not currently present in fastly-go SDK: + ComputeBereqBodyBytes uint64 `json:"compute_bereq_body_bytes"` + ComputeBereqErrors uint64 `json:"compute_bereq_errors"` + ComputeBereqHeaderBytes uint64 `json:"compute_bereq_header_bytes"` + ComputeBereqs uint64 `json:"compute_bereqs"` + ComputeBerespBodyBytes uint64 `json:"compute_beresp_body_bytes"` + ComputeBerespHeaderBytes uint64 `json:"compute_beresp_header_bytes"` + ComputeExecutionTimeMs uint64 `json:"compute_execution_time_ms"` + ComputeGlobalsLimitExceeded uint64 `json:"compute_globals_limit_exceeded"` + ComputeGuestErrors uint64 `json:"compute_guest_errors"` + ComputeHeapLimitExceeded uint64 `json:"compute_heap_limit_exceeded"` + ComputeRamUsed uint64 `json:"compute_ram_used"` + ComputeReqBodyBytes uint64 `json:"compute_req_body_bytes"` + ComputeReqHeaderBytes uint64 `json:"compute_req_header_bytes"` + ComputeRequestTimeMs uint64 `json:"compute_request_time_ms"` + ComputeRequests uint64 `json:"compute_requests"` + ComputeResourceLimitExceeded uint64 `json:"compute_resource_limit_exceeded"` + ComputeRespBodyBytes uint64 `json:"compute_resp_body_bytes"` + ComputeRespHeaderBytes uint64 `json:"compute_resp_header_bytes"` + ComputeRespStatus1xx uint64 `json:"compute_resp_status_1xx"` + ComputeRespStatus2xx uint64 `json:"compute_resp_status_2xx"` + ComputeRespStatus3xx uint64 `json:"compute_resp_status_3xx"` + ComputeRespStatus4xx uint64 `json:"compute_resp_status_4xx"` + ComputeRespStatus5xx uint64 `json:"compute_resp_status_5xx"` + ComputeRuntimeErrors uint64 `json:"compute_runtime_errors"` + ComputeStackLimitExceeded uint64 `json:"compute_stack_limit_exceeded"` + EdgeHitRequests uint64 `json:"edge_hit_requests"` + EdgeHitRespBodyBytes uint64 `json:"edge_hit_resp_body_bytes"` + EdgeHitRespHeaderBytes uint64 `json:"edge_hit_resp_header_bytes"` + EdgeMissRequests uint64 `json:"edge_miss_requests"` + EdgeMissRespBodyBytes uint64 `json:"edge_miss_resp_body_bytes"` + EdgeMissRespHeaderBytes uint64 `json:"edge_miss_resp_header_bytes"` + EdgeRequests uint64 `json:"edge_requests"` + EdgeRespBodyBytes uint64 `json:"edge_resp_body_bytes"` + EdgeRespHeaderBytes uint64 `json:"edge_resp_header_bytes"` + OriginCacheFetchRespBodyBytes uint64 `json:"origin_cache_fetch_resp_body_bytes"` + OriginCacheFetchRespHeaderBytes uint64 `json:"origin_cache_fetch_resp_header_bytes"` + OriginCacheFetches uint64 `json:"origin_cache_fetches"` + OriginFetchBodyBytes uint64 `json:"origin_fetch_body_bytes"` + OriginFetchHeaderBytes uint64 `json:"origin_fetch_header_bytes"` + OriginFetchRespBodyBytes uint64 `json:"origin_fetch_resp_body_bytes"` + OriginFetchRespHeaderBytes uint64 `json:"origin_fetch_resp_header_bytes"` + OriginFetches uint64 `json:"origin_fetches"` + FanoutBereqBodyBytes uint64 `json:"fanout_bereq_body_bytes"` + FanoutBereqHeaderBytes uint64 `json:"fanout_bereq_header_bytes"` + FanoutBerespBodyBytes uint64 `json:"fanout_beresp_body_bytes"` + FanoutBerespHeaderBytes uint64 `json:"fanout_beresp_header_bytes"` + FanoutConnTimeMs uint64 `json:"fanout_conn_time_ms"` + FanoutRecvPublishes uint64 `json:"fanout_recv_publishes"` + FanoutReqBodyBytes uint64 `json:"fanout_req_body_bytes"` + FanoutReqHeaderBytes uint64 `json:"fanout_req_header_bytes"` + FanoutRespBodyBytes uint64 `json:"fanout_resp_body_bytes"` + FanoutRespHeaderBytes uint64 `json:"fanout_resp_header_bytes"` + FanoutSendPublishes uint64 `json:"fanout_send_publishes"` +} diff --git a/plugins/source/fastly/resources/services/stats/stats_regions.go b/plugins/source/fastly/resources/services/stats/stats_regions.go new file mode 100644 index 00000000000..824b77c7919 --- /dev/null +++ b/plugins/source/fastly/resources/services/stats/stats_regions.go @@ -0,0 +1,25 @@ +// Code generated by codegen; DO NOT EDIT. + +package stats + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func StatsRegions() *schema.Table { + return &schema.Table{ + Name: "fastly_stats_regions", + Description: `https://developer.fastly.com/reference/api/metrics-stats/historical-stats/#get-regions`, + Resolver: fetchStatsRegions, + Columns: []schema.Column{ + { + Name: "name", + Type: schema.TypeString, + Resolver: setRegionName, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + }, + } +} diff --git a/plugins/source/fastly/resources/services/stats/stats_regions_fetch.go b/plugins/source/fastly/resources/services/stats/stats_regions_fetch.go new file mode 100644 index 00000000000..6f7766d423c --- /dev/null +++ b/plugins/source/fastly/resources/services/stats/stats_regions_fetch.go @@ -0,0 +1,25 @@ +package stats + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchStatsRegions(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + r, err := c.Fastly.GetRegions() + if err != nil { + return err + } + res <- r.Data + return nil + } + return c.RetryOnError(ctx, "fastly_stats_regions", f) +} + +func setRegionName(_ context.Context, _ schema.ClientMeta, resource *schema.Resource, c schema.Column) error { + return resource.Set(c.Name, resource.Item.(string)) +} diff --git a/plugins/source/fastly/resources/services/stats/stats_regions_fetch_test.go b/plugins/source/fastly/resources/services/stats/stats_regions_fetch_test.go new file mode 100644 index 00000000000..df82548b14d --- /dev/null +++ b/plugins/source/fastly/resources/services/stats/stats_regions_fetch_test.go @@ -0,0 +1,27 @@ +package stats + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/services" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +func buildRegionsMock(t *testing.T, ctrl *gomock.Controller) services.FastlyClient { + m := mocks.NewMockFastlyClient(ctrl) + f := &fastly.RegionsResponse{} + err := faker.FakeObject(&f) + if err != nil { + t.Fatal(err) + } + m.EXPECT().GetRegions().Return(f, nil) + return m +} + +func TestStatsRegions(t *testing.T) { + client.MockTestHelper(t, StatsRegions(), buildRegionsMock, client.TestOptions{}) +} diff --git a/plugins/source/fastly/resources/services/stats/stats_services.go b/plugins/source/fastly/resources/services/stats/stats_services.go new file mode 100644 index 00000000000..ddb01f40526 --- /dev/null +++ b/plugins/source/fastly/resources/services/stats/stats_services.go @@ -0,0 +1,676 @@ +// Code generated by codegen; DO NOT EDIT. + +package stats + +import ( + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func StatsServices() *schema.Table { + return &schema.Table{ + Name: "fastly_stats_services", + Description: `https://developer.fastly.com/reference/api/metrics-stats/historical-stats/`, + Resolver: fetchStatsServices, + Multiplex: client.ServiceRegionMultiplex, + Columns: []schema.Column{ + { + Name: "start_time", + Type: schema.TypeTimestamp, + Resolver: client.UnixTimeResolver("StartTime"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "service_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "region", + Type: schema.TypeString, + Resolver: schema.PathResolver("Region"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "by", + Type: schema.TypeString, + Resolver: schema.PathResolver("By"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "attack_req_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("AttackRequestHeaderBytes"), + }, + { + Name: "attack_req_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("AttackRequestBodyBytes"), + }, + { + Name: "attack_resp_synth_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("AttackResponseSynthBytes"), + }, + { + Name: "bereq_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("BERequestBodyBytes"), + }, + { + Name: "bereq_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("BERequestHeaderbytes"), + }, + { + Name: "bandwidth", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Bandwidth"), + }, + { + Name: "billed_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("BilledBodyBytes"), + }, + { + Name: "billed_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("BilledHeaderBytes"), + }, + { + Name: "errors", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Errors"), + }, + { + Name: "http2", + Type: schema.TypeInt, + Resolver: schema.PathResolver("HTTP2"), + }, + { + Name: "hit_ratio", + Type: schema.TypeFloat, + Resolver: schema.PathResolver("HitRatio"), + }, + { + Name: "hits", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Hits"), + }, + { + Name: "hits_time", + Type: schema.TypeFloat, + Resolver: schema.PathResolver("HitsTime"), + }, + { + Name: "ipv6", + Type: schema.TypeInt, + Resolver: schema.PathResolver("IPv6"), + }, + { + Name: "imgopto", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ImageOptimizer"), + }, + { + Name: "log", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Log"), + }, + { + Name: "miss", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Miss"), + }, + { + Name: "miss_time", + Type: schema.TypeFloat, + Resolver: schema.PathResolver("MissTime"), + }, + { + Name: "otfp", + Type: schema.TypeInt, + Resolver: schema.PathResolver("OTFP"), + }, + { + Name: "object_size_100k", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ObjectSize100k"), + }, + { + Name: "object_size_100m", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ObjectSize100m"), + }, + { + Name: "object_size_10k", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ObjectSize10k"), + }, + { + Name: "object_size_10m", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ObjectSize10m"), + }, + { + Name: "object_size_1g", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ObjectSize1g"), + }, + { + Name: "object_size_1k", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ObjectSize1k"), + }, + { + Name: "object_size_1m", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ObjectSize1m"), + }, + { + Name: "pci", + Type: schema.TypeInt, + Resolver: schema.PathResolver("PCI"), + }, + { + Name: "pass", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Pass"), + }, + { + Name: "pass_time", + Type: schema.TypeFloat, + Resolver: schema.PathResolver("PassTime"), + }, + { + Name: "pipe", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Pipe"), + }, + { + Name: "req_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("RequestBodyBytes"), + }, + { + Name: "req_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("RequestHeaderBytes"), + }, + { + Name: "requests", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Requests"), + }, + { + Name: "resp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ResponseBodyBytes"), + }, + { + Name: "resp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ResponseHeaderBytes"), + }, + { + Name: "restarts", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Restarts"), + }, + { + Name: "shield", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Shield"), + }, + { + Name: "shield_resp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ShieldResponseBodyBytes"), + }, + { + Name: "shield_resp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ShieldResponseHeaderBytes"), + }, + { + Name: "status_1xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status1xx"), + }, + { + Name: "status_200", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status200"), + }, + { + Name: "status_204", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status204"), + }, + { + Name: "status_206", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status206"), + }, + { + Name: "status_2xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status2xx"), + }, + { + Name: "status_301", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status301"), + }, + { + Name: "status_302", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status302"), + }, + { + Name: "status_304", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status304"), + }, + { + Name: "status_3xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status3xx"), + }, + { + Name: "status_400", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status400"), + }, + { + Name: "status_401", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status401"), + }, + { + Name: "status_403", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status403"), + }, + { + Name: "status_404", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status404"), + }, + { + Name: "status_416", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status416"), + }, + { + Name: "status_4xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status4xx"), + }, + { + Name: "status_500", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status500"), + }, + { + Name: "status_501", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status501"), + }, + { + Name: "status_502", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status502"), + }, + { + Name: "status_503", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status503"), + }, + { + Name: "status_504", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status504"), + }, + { + Name: "status_505", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status505"), + }, + { + Name: "status_5xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Status5xx"), + }, + { + Name: "synth", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Synth"), + }, + { + Name: "tls", + Type: schema.TypeInt, + Resolver: schema.PathResolver("TLS"), + }, + { + Name: "tls_v10", + Type: schema.TypeInt, + Resolver: schema.PathResolver("TLSv10"), + }, + { + Name: "tls_v11", + Type: schema.TypeInt, + Resolver: schema.PathResolver("TLSv11"), + }, + { + Name: "tls_v12", + Type: schema.TypeInt, + Resolver: schema.PathResolver("TLSv12"), + }, + { + Name: "tls_v13", + Type: schema.TypeInt, + Resolver: schema.PathResolver("TLSv13"), + }, + { + Name: "uncachable", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Uncachable"), + }, + { + Name: "video", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Video"), + }, + { + Name: "waf_blocked", + Type: schema.TypeInt, + Resolver: schema.PathResolver("WAFBlocked"), + }, + { + Name: "waf_logged", + Type: schema.TypeInt, + Resolver: schema.PathResolver("WAFLogged"), + }, + { + Name: "waf_passed", + Type: schema.TypeInt, + Resolver: schema.PathResolver("WAFPassed"), + }, + { + Name: "compute_bereq_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeBereqBodyBytes"), + }, + { + Name: "compute_bereq_errors", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeBereqErrors"), + }, + { + Name: "compute_bereq_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeBereqHeaderBytes"), + }, + { + Name: "compute_bereqs", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeBereqs"), + }, + { + Name: "compute_beresp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeBerespBodyBytes"), + }, + { + Name: "compute_beresp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeBerespHeaderBytes"), + }, + { + Name: "compute_execution_time_ms", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeExecutionTimeMs"), + }, + { + Name: "compute_globals_limit_exceeded", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeGlobalsLimitExceeded"), + }, + { + Name: "compute_guest_errors", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeGuestErrors"), + }, + { + Name: "compute_heap_limit_exceeded", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeHeapLimitExceeded"), + }, + { + Name: "compute_ram_used", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRamUsed"), + }, + { + Name: "compute_req_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeReqBodyBytes"), + }, + { + Name: "compute_req_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeReqHeaderBytes"), + }, + { + Name: "compute_request_time_ms", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRequestTimeMs"), + }, + { + Name: "compute_requests", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRequests"), + }, + { + Name: "compute_resource_limit_exceeded", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeResourceLimitExceeded"), + }, + { + Name: "compute_resp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRespBodyBytes"), + }, + { + Name: "compute_resp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRespHeaderBytes"), + }, + { + Name: "compute_resp_status_1xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRespStatus1xx"), + }, + { + Name: "compute_resp_status_2xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRespStatus2xx"), + }, + { + Name: "compute_resp_status_3xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRespStatus3xx"), + }, + { + Name: "compute_resp_status_4xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRespStatus4xx"), + }, + { + Name: "compute_resp_status_5xx", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRespStatus5xx"), + }, + { + Name: "compute_runtime_errors", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeRuntimeErrors"), + }, + { + Name: "compute_stack_limit_exceeded", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ComputeStackLimitExceeded"), + }, + { + Name: "edge_hit_requests", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EdgeHitRequests"), + }, + { + Name: "edge_hit_resp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EdgeHitRespBodyBytes"), + }, + { + Name: "edge_hit_resp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EdgeHitRespHeaderBytes"), + }, + { + Name: "edge_miss_requests", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EdgeMissRequests"), + }, + { + Name: "edge_miss_resp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EdgeMissRespBodyBytes"), + }, + { + Name: "edge_miss_resp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EdgeMissRespHeaderBytes"), + }, + { + Name: "edge_requests", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EdgeRequests"), + }, + { + Name: "edge_resp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EdgeRespBodyBytes"), + }, + { + Name: "edge_resp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EdgeRespHeaderBytes"), + }, + { + Name: "origin_cache_fetch_resp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("OriginCacheFetchRespBodyBytes"), + }, + { + Name: "origin_cache_fetch_resp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("OriginCacheFetchRespHeaderBytes"), + }, + { + Name: "origin_cache_fetches", + Type: schema.TypeInt, + Resolver: schema.PathResolver("OriginCacheFetches"), + }, + { + Name: "origin_fetch_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("OriginFetchBodyBytes"), + }, + { + Name: "origin_fetch_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("OriginFetchHeaderBytes"), + }, + { + Name: "origin_fetch_resp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("OriginFetchRespBodyBytes"), + }, + { + Name: "origin_fetch_resp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("OriginFetchRespHeaderBytes"), + }, + { + Name: "origin_fetches", + Type: schema.TypeInt, + Resolver: schema.PathResolver("OriginFetches"), + }, + { + Name: "fanout_bereq_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutBereqBodyBytes"), + }, + { + Name: "fanout_bereq_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutBereqHeaderBytes"), + }, + { + Name: "fanout_beresp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutBerespBodyBytes"), + }, + { + Name: "fanout_beresp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutBerespHeaderBytes"), + }, + { + Name: "fanout_conn_time_ms", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutConnTimeMs"), + }, + { + Name: "fanout_recv_publishes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutRecvPublishes"), + }, + { + Name: "fanout_req_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutReqBodyBytes"), + }, + { + Name: "fanout_req_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutReqHeaderBytes"), + }, + { + Name: "fanout_resp_body_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutRespBodyBytes"), + }, + { + Name: "fanout_resp_header_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutRespHeaderBytes"), + }, + { + Name: "fanout_send_publishes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("FanoutSendPublishes"), + }, + }, + } +} diff --git a/plugins/source/fastly/resources/services/stats/stats_services_fetch.go b/plugins/source/fastly/resources/services/stats/stats_services_fetch.go new file mode 100644 index 00000000000..d6d8b914cc5 --- /dev/null +++ b/plugins/source/fastly/resources/services/stats/stats_services_fetch.go @@ -0,0 +1,54 @@ +package stats + +import ( + "context" + "fmt" + "time" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/cloudquery/plugins/source/fastly/resources/services/stats/models" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/fastly/go-fastly/v7/fastly" +) + +type statsResponse struct { + Data []*models.StatsWrapper `mapstructure:"data"` + Message string `mapstructure:"msg"` + Meta map[string]string `mapstructure:"meta"` + Status string `mapstructure:"status"` +} + +func fetchStatsServices(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + f := func() error { + startTime := *c.Service.CreatedAt + startTime = startTime.Truncate(time.Hour) + endTime := time.Now().Add(-5 * time.Minute).Truncate(time.Hour) // avoid storing incomplete data + + // read 60 days of hourly data at a time + duration := 60 * 24 * time.Hour + for startTime.Before(endTime) { + var resp statsResponse + err := c.Fastly.GetStatsJSON(&fastly.GetStatsInput{ + Service: c.Service.ID, + Region: c.Region, + // We only support hourly stats right now. + // Please raise a ticket if you need stats at minutely or daily granularity: + // https://github.com/cloudquery/cloudquery/issues + By: "hour", + From: fmt.Sprintf("%d", startTime.Unix()), + To: fmt.Sprintf("%d", startTime.Add(duration).Unix()), + }, &resp) + if err != nil { + return err + } + for _, stat := range resp.Data { + stat.By = "hour" + } + res <- resp.Data + startTime = startTime.Add(duration) + } + return nil + } + return c.RetryOnError(ctx, "fastly_stats_services", f) +} diff --git a/plugins/source/fastly/resources/services/stats/stats_services_mock_test.go b/plugins/source/fastly/resources/services/stats/stats_services_mock_test.go new file mode 100644 index 00000000000..59a63b27b88 --- /dev/null +++ b/plugins/source/fastly/resources/services/stats/stats_services_mock_test.go @@ -0,0 +1,36 @@ +package stats + +import ( + "encoding/json" + "os" + "testing" + "time" + + "github.com/cloudquery/cloudquery/plugins/source/fastly/client" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/mocks" + "github.com/cloudquery/cloudquery/plugins/source/fastly/client/services" + "github.com/fastly/go-fastly/v7/fastly" + "github.com/golang/mock/gomock" +) + +func buildServiceStatsMock(t *testing.T, ctrl *gomock.Controller) services.FastlyClient { + m := mocks.NewMockFastlyClient(ctrl) + m.EXPECT().GetStatsJSON(gomock.Any(), gomock.Any()).DoAndReturn(func(a, resp any) error { + b, err := os.ReadFile("testdata/stats.json") + if err != nil { + return err + } + return json.Unmarshal(b, resp) + }) + return m +} + +func TestStatsServices(t *testing.T) { + createdAt := time.Now().Add(-time.Hour * 24 * 20) + client.MockTestHelper(t, StatsServices(), buildServiceStatsMock, client.TestOptions{ + Service: &fastly.Service{ + CreatedAt: &createdAt, + }, + Region: "test-region", + }) +} diff --git a/plugins/source/fastly/resources/services/stats/testdata/stats.json b/plugins/source/fastly/resources/services/stats/testdata/stats.json new file mode 100644 index 00000000000..48d1cbf0960 --- /dev/null +++ b/plugins/source/fastly/resources/services/stats/testdata/stats.json @@ -0,0 +1,110 @@ +{ + "status": "success", + "meta": { + "to": "Thu May 16 20:39:09 UTC 2020", + "from": "Tue May 14 20:39:09 UTC 2020", + "by": "day", + "region": "all" + }, + "msg": null, + "data": [ + { + "requests": 21, + "miss_time": 0, + "start_time": 1368734160, + "service_id": "1jlmtMz1ncwA0KC3TBGD0X", + "bandwidth": 160238, + "hits": 0, + "hits_time": 0, + "miss": 0, + "body_size": 150948, + "pass": 19, + "header_size": 9290, + "req_header_bytes": 2905859973, + "req_body_bytes": 390017958, + "resp_header_bytes": 9290, + "resp_body_bytes": 150948, + "bereq_header_bytes": 1870557109, + "bereq_body_bytes": 389234083, + "status_200": 14, + "status_204": 0, + "status_301": 2, + "status_302": 0, + "status_304": 0, + "errors": 0, + "hit_ratio": null, + "status_1xx": 0, + "status_2xx": 14, + "status_3xx": 2, + "status_4xx": 5, + "status_503": 0, + "pipe": 0, + "status_5xx": 0, + "uncacheable": 0, + "tls": 2804069, + "shield": 208055, + "ipv6": 14156, + "otfp": 12006, + "video": 306053, + "pci": 3041, + "logging": 2088120, + "http2": 251589, + "waf_logged": 508, + "waf_blocked": 360, + "waf_passed": 0, + "attack_req_body_bytes": 1274842, + "attack_req_header_bytes": 892196, + "attack_resp_synth_bytes": 0, + "img_opto": 1404 + }, + { + "requests": 20, + "miss_time": 0, + "start_time": 1368734220, + "service_id": "1jlmtMz1ncwA0KC3TBGD0X", + "bandwidth": 156504, + "hits": 0, + "hits_time": 0, + "miss": 0, + "body_size": 147806, + "pass": 17, + "header_size": 8698, + "req_header_bytes": 2905859973, + "req_body_bytes": 390017958, + "resp_header_bytes": 8698, + "resp_body_bytes": 147806, + "bereq_header_bytes": 1870557109, + "bereq_body_bytes": 389234083, + "status_200": 12, + "status_204": 0, + "status_301": 3, + "status_302": 0, + "status_304": 0, + "errors": 0, + "hit_ratio": null, + "status_1xx": 0, + "status_2xx": 12, + "status_3xx": 3, + "status_4xx": 5, + "status_503": 0, + "pipe": 0, + "status_5xx": 0, + "uncacheable": 0, + "tls": 2804069, + "shield": 208055, + "ipv6": 14156, + "otfp": 12006, + "video": 306053, + "pci": 3041, + "logging": 2088120, + "http2": 251589, + "waf_logged": 508, + "waf_blocked": 360, + "waf_passed": 0, + "attack_req_body_bytes": 1274842, + "attack_req_header_bytes": 892196, + "attack_resp_synth_bytes": 0, + "img_opto": 1404 + } + ] +} \ No newline at end of file diff --git a/plugins/source/fastly/tools/tool.go b/plugins/source/fastly/tools/tool.go new file mode 100644 index 00000000000..e66c9256724 --- /dev/null +++ b/plugins/source/fastly/tools/tool.go @@ -0,0 +1,7 @@ +//go:build tools + +package tools + +import ( + _ "github.com/golang/mock/mockgen" +) diff --git a/plugins/source/gandi/go.mod b/plugins/source/gandi/go.mod index ea67bdb11ac..64161f6523a 100644 --- a/plugins/source/gandi/go.mod +++ b/plugins/source/gandi/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/gandi go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/gertd/go-pluralize v0.2.1 github.com/go-gandi/go-gandi v0.5.1-0.20221118201059-f69b292fa399 github.com/golang/mock v1.6.0 diff --git a/plugins/source/gandi/go.sum b/plugins/source/gandi/go.sum index d269a65445e..1f4d447e8ef 100644 --- a/plugins/source/gandi/go.sum +++ b/plugins/source/gandi/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/gcp/CHANGELOG.md b/plugins/source/gcp/CHANGELOG.md index 64f170fa608..d6b5a2075bd 100644 --- a/plugins/source/gcp/CHANGELOG.md +++ b/plugins/source/gcp/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this provider will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [5.3.1](https://github.com/cloudquery/cloudquery/compare/plugins-source-gcp-v5.3.0...plugins-source-gcp-v5.3.1) (2022-12-27) + + +### Bug Fixes + +* **gcp_run_locations:** Use correct description link ([#6009](https://github.com/cloudquery/cloudquery/issues/6009)) ([916f659](https://github.com/cloudquery/cloudquery/commit/916f659716a22b8c15d101b6d2dffabcf785e93e)) + ## [5.3.0](https://github.com/cloudquery/cloudquery/compare/plugins-source-gcp-v5.2.0...plugins-source-gcp-v5.3.0) (2022-12-27) diff --git a/plugins/source/gcp/client/services.go b/plugins/source/gcp/client/services.go index 3db91febadb..63ed15a05ee 100644 --- a/plugins/source/gcp/client/services.go +++ b/plugins/source/gcp/client/services.go @@ -1,10 +1,12 @@ package client var GcpServices = map[string]bool{ + "aiplatform.googleapis.com": true, "apikeys.googleapis.com": true, "apigateway.googleapis.com": true, "appengine.googleapis.com": true, "artifactregistry.googleapis.com": true, + "baremetalsolution.googleapis.com": true, "bigquery.googleapis.com": true, "bigquerydatatransfer.googleapis.com": true, "bigquerymigration.googleapis.com": true, diff --git a/plugins/source/gcp/codegen/main.go b/plugins/source/gcp/codegen/main.go index 177dd02e4c9..9a7b44f3c39 100644 --- a/plugins/source/gcp/codegen/main.go +++ b/plugins/source/gcp/codegen/main.go @@ -70,6 +70,83 @@ func needsProjectIDColumn(r recipes.Resource) bool { return r.Multiplex != &recipes.OrgMultiplex } +func InferListFunction(r *recipes.Resource) { + // We can infer the List function by matching a list function that return the same struct as r.Struct + server := reflect.TypeOf(r.RegisterServer).In(1) + for i := 0; i < server.NumMethod(); i++ { + method := server.Method(i) + if strings.HasPrefix(method.Name, "List") { + response := method.Type.Out(0).Elem() + for j := 0; j < response.NumField(); j++ { + field := response.Field(j) + kind := field.Type.Kind() + if kind != reflect.Slice { + continue + } + if field.Type.Elem() == reflect.TypeOf(r.Struct) { + r.ListFunctionName = method.Name + r.RequestStructName = method.Type.In(1).Elem().Name() + r.ResponseStructName = method.Type.Out(0).Elem().Name() + return + } + } + } + } +} + +func getColumn(columns codegen.ColumnDefinitions, name string) *codegen.ColumnDefinition { + for i := range columns { + if columns[i].Name == name { + return &columns[i] + } + } + return nil +} + +func listMethodSignature(method reflect.Method) string { + t := method.Type + buf := strings.Builder{} + buf.WriteString(method.Name + "(") + buf.WriteString(t.In(0).String()) + buf.WriteString(", ") + buf.WriteString(t.In(1).String()) + buf.WriteString(")") + buf.WriteString(" (") + buf.WriteString(t.Out(0).String()) + buf.WriteString(", ") + buf.WriteString(t.Out(1).String()) + buf.WriteString(")") + return buf.String() +} + +func isValidListMethod(method reflect.Method) bool { + if !strings.HasPrefix(method.Name, "List") { + return false + } + + _, responseHasNextPage := method.Type.Out(0).Elem().FieldByName("NextPageToken") + return responseHasNextPage +} + +func generateMockTestData(r *recipes.Resource) { + registerServerPath := runtime.FuncForPC(reflect.ValueOf(r.RelationsTestData.RegisterServer).Pointer()).Name() + serverName := strings.Split(registerServerPath, "/")[4] + pbName := strings.Split(serverName, ".")[0] + pbPath := strings.Split(registerServerPath, pbName)[0] + r.RelationsTestData.ProtobufImport = fmt.Sprintf("%s%s", pbPath, pbName) + r.RelationsTestData.RegisterServerName = serverName + r.RelationsTestData.UnimplementedServerName = strings.Replace(serverName, "Register", "Unimplemented", 1) + server := reflect.TypeOf(r.RelationsTestData.RegisterServer).In(1) + for i := 0; i < server.NumMethod(); i++ { + method := server.Method(i) + if isValidListMethod(method) { + sig := listMethodSignature(method) + responseType := method.Type.Out(0).Elem().String() + r.RelationsTestData.ListFunctions = append(r.RelationsTestData.ListFunctions, recipes.ListFunctions{Signature: sig, ResponseStructName: responseType}) + } + } +} + func generateResource(r recipes.Resource, mock bool) { var err error _, filename, _, ok := runtime.Caller(0) @@ -82,10 +159,12 @@ func generateResource(r recipes.Resource, mock bool) { path := strings.Split(runtime.FuncForPC(reflect.ValueOf(r.NewFunction).Pointer()).Name(), ".") r.NewFunctionName = path[len(path)-1] } + if r.RegisterServer != nil { path := strings.Split(runtime.FuncForPC(reflect.ValueOf(r.RegisterServer).Pointer()).Name(), ".") r.RegisterServerName = path[len(path)-1] r.UnimplementedServerName = strings.Replace(r.RegisterServerName, "Register", "Unimplemented", 1) + } if r.ClientName == "" && r.NewFunctionName != "" { @@ -97,25 +176,32 @@ func generateResource(r recipes.Resource, mock bool) { r.StructName = reflect.TypeOf(r.Struct).Elem().Name() } - if r.ListFunction != nil && !r.SkipFetch { - path := strings.Split(runtime.FuncForPC(reflect.ValueOf(r.ListFunction).Pointer()).Name(), ".") - r.ListFunctionName = path[len(path)-1] - // https://stackoverflow.com/questions/32925344/why-is-there-a-fm-suffix-when-getting-a-functions-name-in-go - r.ListFunctionName = strings.Split(r.ListFunctionName, "-")[0] - r.RequestStructName = reflect.TypeOf(r.ListFunction).In(1).Elem().Name() - - switch { - case r.RegisterServer != nil: - server := reflect.TypeOf(r.RegisterServer).In(1) - method, _ := server.MethodByName(r.ListFunctionName) - r.ResponseStructName = method.Type.Out(0).Elem().Name() - case r.ListFunctionName == "Get": - r.ResponseStructName = r.StructName - default: - r.ResponseStructName = r.StructName + r.ListFunctionName + if !r.SkipFetch { + if r.ListFunction == nil { + InferListFunction(&r) + } else { + path := strings.Split(runtime.FuncForPC(reflect.ValueOf(r.ListFunction).Pointer()).Name(), ".") + r.ListFunctionName = path[len(path)-1] + // https://stackoverflow.com/questions/32925344/why-is-there-a-fm-suffix-when-getting-a-functions-name-in-go + r.ListFunctionName = strings.Split(r.ListFunctionName, "-")[0] + r.RequestStructName = reflect.TypeOf(r.ListFunction).In(1).Elem().Name() + switch { + case r.RegisterServer != nil: + server := reflect.TypeOf(r.RegisterServer).In(1) + method, _ := server.MethodByName(r.ListFunctionName) + r.ResponseStructName = method.Type.Out(0).Elem().Name() + case r.ListFunctionName == "Get": + r.ResponseStructName = r.StructName + default: + r.ResponseStructName = r.StructName + r.ListFunctionName + } } } + if mock && r.RelationsTestData.RegisterServer != nil { + generateMockTestData(&r) + } + if r.ResponseStruct != nil { r.ResponseStructName = reflect.TypeOf(r.ResponseStruct).Elem().Name() } @@ -179,6 +265,9 @@ func generateResource(r recipes.Resource, mock bool) { log.Fatal(fmt.Errorf("failed to create table for %s: %w", r.StructName, err)) } if r.Multiplex == nil { + if r.ServiceDNS == "" { + r.ServiceDNS = r.Service + ".googleapis.com" + } if _, ok := client.GcpServices[r.ServiceDNS]; !ok { panic("unknown service DNS: " + r.ServiceDNS) } @@ -188,10 +277,16 @@ func generateResource(r recipes.Resource, mock bool) { } for _, f := range r.PrimaryKeys { - for i := range r.Table.Columns { - if r.Table.Columns[i].Name == f { - r.Table.Columns[i].Options.PrimaryKey = true - } + column := getColumn(r.Table.Columns, f) + if column != nil { + column.Options.PrimaryKey = true + } + } + + for _, f := range r.IgnoreInTestsColumns { + column := getColumn(r.Table.Columns, f) + if column != nil { + column.IgnoreInTests = true } } diff --git a/plugins/source/gcp/codegen/recipes/aiplatform.go b/plugins/source/gcp/codegen/recipes/aiplatform.go new file mode 100644 index 00000000000..2be0610545b --- /dev/null +++ b/plugins/source/gcp/codegen/recipes/aiplatform.go @@ -0,0 +1,231 @@ +package recipes + +import ( + "reflect" + "runtime" + "strings" + + aiplatform "cloud.google.com/go/aiplatform/apiv1" + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb" + locationpb "google.golang.org/genproto/googleapis/cloud/location" + "google.golang.org/protobuf/types/known/structpb" +) + +func getLocationsServiceName(f interface{}) string { + fName := strings.Split(runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name(), "apiv1.") + return strings.ToLower(strings.TrimSuffix(strings.TrimPrefix(fName[1], "New"), "Client")) +} + +func isFieldMockable(field reflect.StructField) bool { + nonMockables := []any{&structpb.Value{}, &structpb.Struct{}, &pb.Model{}, &pb.PipelineJob_RuntimeConfig{}} + for _, nonMockable := range nonMockables { + if field.Type == reflect.TypeOf(nonMockable) { + return false + } + } + + return true +} + +func init() { + resources := []*Resource{ + { + SubService: "batch_prediction_jobs", + Struct: &pb.BatchPredictionJob{}, + NewFunction: aiplatform.NewJobClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.batchPredictionJobs#BatchPredictionJob", + RegisterServer: pb.RegisterJobServiceServer, + }, + { + SubService: "custom_jobs", + Struct: &pb.CustomJob{}, + NewFunction: aiplatform.NewJobClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.customJobs#CustomJob", + RegisterServer: pb.RegisterJobServiceServer, + }, + { + SubService: "data_labeling_jobs", + Struct: &pb.DataLabelingJob{}, + NewFunction: aiplatform.NewJobClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.dataLabelingJobs#DataLabelingJob", + RegisterServer: pb.RegisterJobServiceServer, + }, + { + SubService: "datasets", + Struct: &pb.Dataset{}, + NewFunction: aiplatform.NewDatasetClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.datasets#Dataset", + RegisterServer: pb.RegisterDatasetServiceServer, + }, + { + SubService: "endpoints", + Struct: &pb.Endpoint{}, + NewFunction: aiplatform.NewEndpointClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.endpoints#Endpoint", + RegisterServer: pb.RegisterEndpointServiceServer, + }, + { + SubService: "featurestores", + Struct: &pb.Featurestore{}, + NewFunction: aiplatform.NewFeaturestoreClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.featurestores#Featurestore", + RegisterServer: pb.RegisterFeaturestoreServiceServer, + }, + { + SubService: "hyperparameter_tuning_jobs", + Struct: &pb.HyperparameterTuningJob{}, + NewFunction: aiplatform.NewJobClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.hyperparameterTuningJobs#HyperparameterTuningJob", + RegisterServer: pb.RegisterJobServiceServer, + }, + { + SubService: "index_endpoints", + Struct: &pb.IndexEndpoint{}, + NewFunction: aiplatform.NewIndexEndpointClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.indexEndpoints#IndexEndpoint", + RegisterServer: pb.RegisterIndexEndpointServiceServer, + ParentFilterFunc: "filterIndexesLocations", + }, + { + SubService: "indexes", + Struct: &pb.Index{}, + NewFunction: aiplatform.NewIndexClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.indexes#Index", + RegisterServer: pb.RegisterIndexServiceServer, + ParentFilterFunc: "filterIndexesLocations", + }, + { + SubService: "metadata_stores", + Struct: &pb.MetadataStore{}, + NewFunction: aiplatform.NewMetadataClient, + ListFunction: (&aiplatform.MetadataClient{}).ListMetadataStores, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.metadataStores#MetadataStore", + RegisterServer: pb.RegisterMetadataServiceServer, + }, + { + SubService: "model_deployment_monitoring_jobs", + Struct: &pb.ModelDeploymentMonitoringJob{}, + NewFunction: aiplatform.NewJobClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.modelDeploymentMonitoringJobs#ModelDeploymentMonitoringJob", + RegisterServer: pb.RegisterJobServiceServer, + }, + { + SubService: "models", + Struct: &pb.Model{}, + NewFunction: aiplatform.NewModelClient, + ListFunction: (&aiplatform.ModelClient{}).ListModels, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.models#Model", + RegisterServer: pb.RegisterModelServiceServer, + }, + + { + SubService: "pipeline_jobs", + Struct: &pb.PipelineJob{}, + NewFunction: aiplatform.NewPipelineClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.pipelineJobs#PipelineJob", + RegisterServer: pb.RegisterPipelineServiceServer, + }, + { + SubService: "specialist_pools", + Struct: &pb.SpecialistPool{}, + NewFunction: aiplatform.NewSpecialistPoolClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.specialistPools#SpecialistPool", + RegisterServer: pb.RegisterSpecialistPoolServiceServer, + }, + { + SubService: "studies", + Struct: &pb.Study{}, + NewFunction: aiplatform.NewVizierClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.studies#Study", + RegisterServer: pb.RegisterVizierServiceServer, + ParentFilterFunc: "filterStudiesLocation", + }, + { + SubService: "tensorboards", + Struct: &pb.Tensorboard{}, + NewFunction: aiplatform.NewTensorboardClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.tensorboards#Tensorboard", + RegisterServer: pb.RegisterTensorboardServiceServer, + }, + { + SubService: "training_pipelines", + Struct: &pb.TrainingPipeline{}, + NewFunction: aiplatform.NewPipelineClient, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.trainingPipelines#TrainingPipeline", + RegisterServer: pb.RegisterPipelineServiceServer, + IgnoreInTestsColumns: []string{"model_to_upload"}, + }, + } + + locationsMap := map[string]*Resource{} + locationResources := []*Resource{} + for _, resource := range resources { + resource.ProtobufImport = "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + resource.ChildTable = true + resource.RequestStructFields = `Parent: parent.Item.(*location.Location).Name,` + resource.MockImports = []string{"google.golang.org/api/option", "google.golang.org/genproto/googleapis/cloud/location"} + resource.ClientOptions = []string{`option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")`} + if resource.ParentFilterFunc == "" { + resource.ParentFilterFunc = "filterLocation" + } + resource.SkipMock = true + + locationSubService := getLocationsServiceName(resource.NewFunction) + "_locations" + locationResource := locationsMap[locationSubService] + if locationResource == nil { + locationResource = &Resource{} + locationResource.SubService = locationSubService + locationResource.Struct = &locationpb.Location{} + locationResource.PrimaryKeys = []string{ProjectIdColumn.Name, "name"} + locationResource.NewFunction = resource.NewFunction + locationResource.RequestStructFields = `Name: "projects/" + c.ProjectId,` + locationResource.Description = "https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location" + locationResource.RegisterServer = locationpb.RegisterLocationsServer + locationResource.ProtobufImport = "google.golang.org/genproto/googleapis/cloud/location" + locationResource.ClientOptions = []string{`option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")`} + locationResource.MockImports = []string{"google.golang.org/api/option"} + locationResource.RelationsTestData = RelationsTestData{ + RegisterServer: resource.RegisterServer, + } + + locationsMap[locationSubService] = locationResource + locationResources = append(locationResources, locationResource) + } + locationResource.Relations = append(locationResource.Relations, Caser.ToPascal(resource.SubService)+"()") + } + + operationsResource := &Resource{ + SubService: "operations", + Struct: &longrunningpb.Operation{}, + NewFunction: aiplatform.NewPipelineClient, + RequestStructFields: `Name: "projects/" + c.ProjectId + "/locations/-",`, + Description: "https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.operations#Operation", + RegisterServer: longrunningpb.RegisterOperationsServer, + ProtobufImport: "cloud.google.com/go/longrunning/autogen/longrunningpb", + ClientOptions: []string{`option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")`}, + MockImports: []string{"google.golang.org/api/option"}, + } + + allResources := append(resources, locationResources...) + allResources = append(allResources, operationsResource) + + for _, resource := range allResources { + resource.PrimaryKeys = []string{ProjectIdColumn.Name, "name"} + resource.Service = "aiplatform" + resource.Template = "newapi_list" + resource.MockTemplate = "newapi_list_grpc_mock" + resource.MockImports = append(resource.MockImports, "cloud.google.com/go/aiplatform/apiv1") + + structElem := reflect.TypeOf(resource.Struct).Elem() + for i := 0; i < structElem.NumField(); i++ { + field := structElem.Field(i) + if isFieldMockable(field) { + continue + } + resource.IgnoreInTestsColumns = append(resource.IgnoreInTestsColumns, Caser.ToSnake(field.Name)) + } + } + + Resources = append(Resources, allResources...) +} diff --git a/plugins/source/gcp/codegen/recipes/apigateway.go b/plugins/source/gcp/codegen/recipes/apigateway.go index 691fb1c775d..881ae1907c4 100644 --- a/plugins/source/gcp/codegen/recipes/apigateway.go +++ b/plugins/source/gcp/codegen/recipes/apigateway.go @@ -11,7 +11,6 @@ func init() { SubService: "apis", Struct: &pb.Api{}, PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, - ListFunction: (&apigateway.Client{}).ListApis, RequestStructFields: `Parent: "projects/" + c.ProjectId + "/locations/-",`, Description: "https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations.apis#Api", }, @@ -19,7 +18,6 @@ func init() { SubService: "gateways", Struct: &pb.Gateway{}, PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, - ListFunction: (&apigateway.Client{}).ListGateways, RequestStructFields: `Parent: "projects/" + c.ProjectId + "/locations/-",`, Description: "https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations.gateways#Gateway", }, @@ -33,7 +31,6 @@ func init() { resource.MockImports = []string{"cloud.google.com/go/apigateway/apiv1"} resource.NewFunction = apigateway.NewClient resource.RegisterServer = pb.RegisterApiGatewayServiceServer - resource.ServiceDNS = "apigateway.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/apikeys.go b/plugins/source/gcp/codegen/recipes/apikeys.go index 9033309ab32..4b1158ae4c7 100644 --- a/plugins/source/gcp/codegen/recipes/apikeys.go +++ b/plugins/source/gcp/codegen/recipes/apikeys.go @@ -11,7 +11,6 @@ func init() { SubService: "keys", Struct: &pb.Key{}, PrimaryKeys: []string{ProjectIdColumn.Name, "uid"}, - ListFunction: (&apikeys.Client{}).ListKeys, RequestStructFields: `Parent: "projects/" + c.ProjectId + "/locations/global",`, Description: "https://cloud.google.com/api-keys/docs/reference/rest/v2/projects.locations.keys#Key", }, @@ -26,7 +25,6 @@ func init() { resource.MockImports = []string{"cloud.google.com/go/apikeys/apiv2"} resource.NewFunction = apikeys.NewClient resource.RegisterServer = pb.RegisterApiKeysServer - resource.ServiceDNS = "apikeys.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/appengine.go b/plugins/source/gcp/codegen/recipes/appengine.go new file mode 100644 index 00000000000..6184c96fa16 --- /dev/null +++ b/plugins/source/gcp/codegen/recipes/appengine.go @@ -0,0 +1,103 @@ +package recipes + +import ( + appengine "cloud.google.com/go/appengine/apiv1" + pb "cloud.google.com/go/appengine/apiv1/appenginepb" +) + +func init() { + resources := []*Resource{ + { + SubService: "apps", + Struct: &pb.Application{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + NewFunction: appengine.NewApplicationsClient, + ListFunction: (&appengine.ApplicationsClient{}).GetApplication, + RegisterServer: pb.RegisterApplicationsServer, + RequestStructFields: `Parent: "apps/" + c.ProjectId,`, + Description: "https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps#Application", + SkipFetch: true, + SkipMock: true, + }, + { + SubService: "services", + Struct: &pb.Service{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + NewFunction: appengine.NewServicesClient, + RegisterServer: pb.RegisterServicesServer, + RequestStructFields: `Parent: "apps/" + c.ProjectId,`, + Description: "https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services#Service", + Relations: []string{"Versions()"}, + SkipMock: true, + }, + { + SubService: "versions", + Struct: &pb.Version{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + NewFunction: appengine.NewVersionsClient, + RegisterServer: pb.RegisterVersionsServer, + RequestStructFields: `Parent: parent.Item.(*pb.Service).Name,`, + Description: "https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions#Version", + ChildTable: true, + Relations: []string{"Instances()"}, + SkipMock: true, + }, + { + SubService: "instances", + Struct: &pb.Instance{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + NewFunction: appengine.NewInstancesClient, + RegisterServer: pb.RegisterInstancesServer, + RequestStructFields: `Parent: parent.Item.(*pb.Version).Name,`, + ChildTable: true, + Description: "https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions.instances#Instance", + SkipMock: true, + }, + { + SubService: "authorized_certificates", + Struct: &pb.AuthorizedCertificate{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + NewFunction: appengine.NewAuthorizedCertificatesClient, + RegisterServer: pb.RegisterAuthorizedCertificatesServer, + RequestStructFields: `Parent: "apps/" + c.ProjectId,`, + Description: "https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.authorizedCertificates#AuthorizedCertificate", + }, + { + SubService: "authorized_domains", + Struct: &pb.AuthorizedDomain{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + NewFunction: appengine.NewAuthorizedDomainsClient, + RegisterServer: pb.RegisterAuthorizedDomainsServer, + RequestStructFields: `Parent: "apps/" + c.ProjectId,`, + Description: "https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.authorizedDomains#AuthorizedDomain", + }, + { + SubService: "domain_mappings", + Struct: &pb.DomainMapping{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + NewFunction: appengine.NewDomainMappingsClient, + RegisterServer: pb.RegisterDomainMappingsServer, + RequestStructFields: `Parent: "apps/" + c.ProjectId,`, + Description: "https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.domainMappings#DomainMapping", + }, + { + SubService: "firewall_ingress_rules", + Struct: &pb.FirewallRule{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + NewFunction: appengine.NewFirewallClient, + RegisterServer: pb.RegisterFirewallServer, + RequestStructFields: `Parent: "apps/" + c.ProjectId,`, + Description: "https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.firewall.ingressRules#FirewallRule", + }, + } + + for _, resource := range resources { + resource.Service = "appengine" + resource.Template = "newapi_list" + resource.MockTemplate = "newapi_list_grpc_mock" + resource.ProtobufImport = "cloud.google.com/go/appengine/apiv1/appenginepb" + resource.MockImports = []string{"cloud.google.com/go/appengine/apiv1"} + } + + Resources = append(Resources, resources...) +} diff --git a/plugins/source/gcp/codegen/recipes/artifactregistry.go b/plugins/source/gcp/codegen/recipes/artifactregistry.go new file mode 100644 index 00000000000..bc6a7a2ee12 --- /dev/null +++ b/plugins/source/gcp/codegen/recipes/artifactregistry.go @@ -0,0 +1,91 @@ +package recipes + +import ( + artifactregistry "cloud.google.com/go/artifactregistry/apiv1" + pb "cloud.google.com/go/artifactregistry/apiv1/artifactregistrypb" + registerV1 "google.golang.org/api/artifactregistry/v1" +) + +func init() { + resources := []*Resource{ + { + SubService: "locations", + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + Struct: ®isterV1.Location{}, + SkipFetch: true, + SkipMock: true, + Description: "https://cloud.google.com/artifact-registry/docs/reference/rest/Shared.Types/ListLocationsResponse#Location", + Relations: []string{"Repositories()"}, + }, + { + SubService: "repositories", + Struct: &pb.Repository{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + Description: "https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories#Repository", + ChildTable: true, + SkipFetch: true, + SkipMock: true, + Relations: []string{"DockerImages()", "Files()", "Packages()"}, + }, + { + SubService: "docker_images", + Struct: &pb.DockerImage{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: parent.Item.(*pb.Repository).Name,`, + Description: "https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.dockerImages#DockerImage", + ChildTable: true, + SkipMock: true, + }, + { + SubService: "files", + Struct: &pb.File{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: parent.Item.(*pb.Repository).Name,`, + Description: "https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.files#File", + ChildTable: true, + SkipMock: true, + }, + { + SubService: "packages", + Struct: &pb.Package{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: parent.Item.(*pb.Repository).Name,`, + Description: "https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.packages#Package", + ChildTable: true, + SkipMock: true, + Relations: []string{"Tags()", "Versions()"}, + }, + { + SubService: "tags", + Struct: &pb.Tag{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: parent.Item.(*pb.Package).Name,`, + Description: "https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.packages.tags#Tag", + ChildTable: true, + SkipMock: true, + }, + { + SubService: "versions", + Struct: &pb.Version{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: parent.Item.(*pb.Package).Name,`, + Description: "https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.packages.versions#Version", + ChildTable: true, + SkipMock: true, + }, + } + + for _, resource := range resources { + resource.Service = "artifactregistry" + resource.Template = "newapi_list" + resource.MockTemplate = "newapi_list_grpc_mock" + if resource.ProtobufImport == "" { + resource.ProtobufImport = "cloud.google.com/go/artifactregistry/apiv1/artifactregistrypb" + } + resource.MockImports = []string{"cloud.google.com/go/artifactregistry/apiv1"} + resource.NewFunction = artifactregistry.NewClient + resource.RegisterServer = pb.RegisterArtifactRegistryServer + } + + Resources = append(Resources, resources...) +} diff --git a/plugins/source/gcp/codegen/recipes/baremetalsolution.go b/plugins/source/gcp/codegen/recipes/baremetalsolution.go new file mode 100644 index 00000000000..736f81b121e --- /dev/null +++ b/plugins/source/gcp/codegen/recipes/baremetalsolution.go @@ -0,0 +1,62 @@ +package recipes + +import ( + baremetalsolution "cloud.google.com/go/baremetalsolution/apiv2" + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" +) + +func init() { + resources := []*Resource{ + { + SubService: "instances", + Struct: &pb.Instance{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: "projects/" + c.ProjectId + "/locations/-",`, + Description: "https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.instances#Instance", + }, + { + SubService: "networks", + Struct: &pb.Network{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: "projects/" + c.ProjectId + "/locations/-",`, + Description: "https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.networks#Network", + }, + { + SubService: "nfs_shares", + Struct: &pb.NfsShare{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: "projects/" + c.ProjectId + "/locations/-",`, + Description: "https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.nfsShares#NfsShare", + }, + { + SubService: "volumes", + Struct: &pb.Volume{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: "projects/" + c.ProjectId + "/locations/-",`, + Description: "https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.volumes#Volume", + Relations: []string{"VolumeLuns()"}, + SkipMock: true, + }, + { + SubService: "volume_luns", + Struct: &pb.Lun{}, + PrimaryKeys: []string{ProjectIdColumn.Name, "name"}, + RequestStructFields: `Parent: parent.Item.(*pb.Volume).Name,`, + Description: "https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.volumes.luns#Lun", + ChildTable: true, + SkipMock: true, + }, + } + + for _, resource := range resources { + resource.Service = "baremetalsolution" + resource.Template = "newapi_list" + resource.MockTemplate = "newapi_list_grpc_mock" + resource.ProtobufImport = "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" + resource.MockImports = []string{"cloud.google.com/go/baremetalsolution/apiv2"} + resource.NewFunction = baremetalsolution.NewClient + resource.RegisterServer = pb.RegisterBareMetalSolutionServer + } + + Resources = append(Resources, resources...) +} diff --git a/plugins/source/gcp/codegen/recipes/base.go b/plugins/source/gcp/codegen/recipes/base.go index dd45caa5c62..272dc72c598 100644 --- a/plugins/source/gcp/codegen/recipes/base.go +++ b/plugins/source/gcp/codegen/recipes/base.go @@ -4,12 +4,26 @@ import ( "reflect" "strings" + "github.com/cloudquery/plugin-sdk/caser" "github.com/cloudquery/plugin-sdk/codegen" "github.com/cloudquery/plugin-sdk/schema" ) var Resources []*Resource +type ListFunctions struct { + ResponseStructName string + Signature string +} + +type RelationsTestData struct { + RegisterServer any + RegisterServerName string + UnimplementedServerName string + ListFunctions []ListFunctions + ProtobufImport string +} + type Resource struct { Description string // PackageName name is the packgename in the source plugin this resource is located @@ -50,6 +64,8 @@ type Resource struct { RegisterServer any // RegisterServerName is the name of the above function via Reflection RegisterServerName string + // RelationsTestData has relations data used for creating tests + RelationsTestData RelationsTestData // UnimplementedServerName is the name of the above function via Reflection UnimplementedServerName string // OutputField is field where the result is located in the output struct @@ -84,6 +100,11 @@ type Resource struct { ExtraColumns []codegen.ColumnDefinition // NameTransformer custom name transformer for resource NameTransformer func(field reflect.StructField) (string, error) + // ClientOptions is a list of options to pass to the client + ClientOptions []string + // IgnoreInTestsColumns is a list of columns to ignore in tests + IgnoreInTestsColumns []string + ParentFilterFunc string } var ProjectIdColumn = codegen.ColumnDefinition{ @@ -92,6 +113,8 @@ var ProjectIdColumn = codegen.ColumnDefinition{ Resolver: "client.ResolveProject", } +var Caser = caser.New() + func CreateReplaceTransformer(replace map[string]string) func(field reflect.StructField) (string, error) { return func(field reflect.StructField) (string, error) { name, err := codegen.DefaultNameTransformer(field) diff --git a/plugins/source/gcp/codegen/recipes/bigquery.go b/plugins/source/gcp/codegen/recipes/bigquery.go index 0403cecf622..eb5fb8bc8de 100644 --- a/plugins/source/gcp/codegen/recipes/bigquery.go +++ b/plugins/source/gcp/codegen/recipes/bigquery.go @@ -29,7 +29,6 @@ func init() { for _, resource := range resources { resource.Service = "bigquery" - resource.ServiceDNS = "bigquery.googleapis.com" resource.Template = "newapi_list" } diff --git a/plugins/source/gcp/codegen/recipes/billing.go b/plugins/source/gcp/codegen/recipes/billing.go index 10b5355f5cc..03281e0af18 100644 --- a/plugins/source/gcp/codegen/recipes/billing.go +++ b/plugins/source/gcp/codegen/recipes/billing.go @@ -13,7 +13,6 @@ func init() { SubService: "billing_accounts", Struct: &pb.BillingAccount{}, NewFunction: billing.NewCloudBillingClient, - ListFunction: (&billing.CloudBillingClient{}).ListBillingAccounts, RegisterServer: pb.RegisterCloudBillingServer, PrimaryKeys: []string{"name"}, Description: "https://cloud.google.com/billing/docs/reference/rest/v1/billingAccounts#BillingAccount", @@ -23,7 +22,6 @@ func init() { Struct: &pb.Service{}, NewFunction: billing.NewCloudCatalogClient, ResponseStruct: &pb.ListServicesResponse{}, - ListFunction: (&billing.CloudCatalogClient{}).ListServices, RegisterServer: pb.RegisterCloudCatalogServer, PrimaryKeys: []string{"name"}, Description: "https://cloud.google.com/billing/docs/reference/rest/v1/services/list#Service", diff --git a/plugins/source/gcp/codegen/recipes/compute.go b/plugins/source/gcp/codegen/recipes/compute.go index d37dde4eb58..9e5b6e60741 100644 --- a/plugins/source/gcp/codegen/recipes/compute.go +++ b/plugins/source/gcp/codegen/recipes/compute.go @@ -200,7 +200,6 @@ func init() { if resource.PrimaryKeys == nil { resource.PrimaryKeys = []string{"self_link"} } - resource.ServiceDNS = "compute.googleapis.com" } diff --git a/plugins/source/gcp/codegen/recipes/container.go b/plugins/source/gcp/codegen/recipes/container.go index 256889d8e40..7889ad09c17 100644 --- a/plugins/source/gcp/codegen/recipes/container.go +++ b/plugins/source/gcp/codegen/recipes/container.go @@ -23,7 +23,6 @@ func init() { resource.ProtobufImport = "google.golang.org/genproto/googleapis/container/v1" resource.Template = "newapi_list" resource.MockTemplate = "newapi_list_grpc_mock" - resource.ServiceDNS = "container.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/containeranalysis.go b/plugins/source/gcp/codegen/recipes/containeranalysis.go index e1a63e25d0b..66d9ed7b74b 100644 --- a/plugins/source/gcp/codegen/recipes/containeranalysis.go +++ b/plugins/source/gcp/codegen/recipes/containeranalysis.go @@ -27,7 +27,6 @@ func init() { resource.MockTemplate = "newapi_list_grpc_mock" resource.RegisterServer = grafeaspb.RegisterGrafeasV1Beta1Server - resource.ServiceDNS = "containeranalysis.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/dns.go b/plugins/source/gcp/codegen/recipes/dns.go index 6758fc692b8..e34a6740469 100644 --- a/plugins/source/gcp/codegen/recipes/dns.go +++ b/plugins/source/gcp/codegen/recipes/dns.go @@ -8,20 +8,18 @@ import ( func init() { resources := []*Resource{ { - SubService: "policies", - Struct: &dns.Policy{}, - NewFunction: dns.NewService, - ListFunction: (&dns.PoliciesService{}).List, - PrimaryKeys: []string{"id"}, - Description: "https://cloud.google.com/dns/docs/reference/v1/policies#resource", + SubService: "policies", + Struct: &dns.Policy{}, + NewFunction: dns.NewService, + PrimaryKeys: []string{"id"}, + Description: "https://cloud.google.com/dns/docs/reference/v1/policies#resource", }, { - SubService: "managed_zones", - Struct: &dns.ManagedZone{}, - NewFunction: dns.NewManagedZoneOperationsService, - ListFunction: (&dns.ManagedZonesService{}).List, - PrimaryKeys: []string{"id"}, - Description: "https://cloud.google.com/dns/docs/reference/v1/managedZones#resource", + SubService: "managed_zones", + Struct: &dns.ManagedZone{}, + NewFunction: dns.NewManagedZoneOperationsService, + PrimaryKeys: []string{"id"}, + Description: "https://cloud.google.com/dns/docs/reference/v1/managedZones#resource", }, } @@ -32,7 +30,6 @@ func init() { resource.Template = "newapi_list" resource.MockTemplate = "resource_list_mock" resource.OutputField = strcase.ToCamel(resource.SubService) - resource.ServiceDNS = "dns.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/domains.go b/plugins/source/gcp/codegen/recipes/domains.go index 45ea9af7041..0a587b55775 100644 --- a/plugins/source/gcp/codegen/recipes/domains.go +++ b/plugins/source/gcp/codegen/recipes/domains.go @@ -12,7 +12,6 @@ func init() { Struct: &pb.Registration{}, NewFunction: domains.NewClient, RegisterServer: pb.RegisterDomainsServer, - ListFunction: (&pb.UnimplementedDomainsServer{}).ListRegistrations, RequestStructFields: `Parent: fmt.Sprintf("projects/%s/locations/-", c.ProjectId),`, Imports: []string{"fmt"}, Description: "https://cloud.google.com/domains/docs/reference/rest/v1beta1/projects.locations.registrations#Registration", @@ -26,7 +25,6 @@ func init() { resource.Template = "newapi_list" resource.MockTemplate = "newapi_list_grpc_mock" // resource.OutputField = strcase.ToCamel(resource.SubService) - resource.ServiceDNS = "domains.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/functions.go b/plugins/source/gcp/codegen/recipes/functions.go index 937b842bde6..e907c449f9f 100644 --- a/plugins/source/gcp/codegen/recipes/functions.go +++ b/plugins/source/gcp/codegen/recipes/functions.go @@ -12,7 +12,6 @@ func init() { Struct: &functionspb.CloudFunction{}, NewFunction: functions.NewCloudFunctionsClient, RegisterServer: functionspb.RegisterCloudFunctionsServiceServer, - ListFunction: (&functionspb.UnimplementedCloudFunctionsServiceServer{}).ListFunctions, RequestStructFields: `Parent: "projects/" + c.ProjectId + "/locations/-",`, SkipFields: []string{"SourceCode", "Trigger"}, Description: "https://cloud.google.com/functions/docs/reference/rest/v1/projects.locations.functions#CloudFunction", diff --git a/plugins/source/gcp/codegen/recipes/iam.go b/plugins/source/gcp/codegen/recipes/iam.go index 78f923d2ac0..749b69287db 100644 --- a/plugins/source/gcp/codegen/recipes/iam.go +++ b/plugins/source/gcp/codegen/recipes/iam.go @@ -61,7 +61,6 @@ func init() { if resource.OutputField == "" { resource.OutputField = strcase.ToCamel(resource.SubService) } - resource.ServiceDNS = "iam.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/logging.go b/plugins/source/gcp/codegen/recipes/logging.go index 62943bcf8f0..dd06d11f798 100644 --- a/plugins/source/gcp/codegen/recipes/logging.go +++ b/plugins/source/gcp/codegen/recipes/logging.go @@ -12,7 +12,6 @@ func init() { Struct: &pb.LogMetric{}, NewFunction: logging.NewMetricsClient, RegisterServer: pb.RegisterMetricsServiceV2Server, - ListFunction: (&pb.UnimplementedMetricsServiceV2Server{}).ListLogMetrics, PrimaryKeys: []string{"name"}, Description: "https://cloud.google.com/logging/docs/reference/v2/rest/v2/projects.metrics#LogMetric", }, @@ -21,7 +20,6 @@ func init() { Struct: &pb.LogSink{}, NewFunction: logging.NewConfigClient, RegisterServer: pb.RegisterConfigServiceV2Server, - ListFunction: (&pb.UnimplementedConfigServiceV2Server{}).ListSinks, PrimaryKeys: []string{"name"}, SkipFields: []string{"Options"}, Description: "https://cloud.google.com/logging/docs/reference/v2/rest/v2/projects.sinks#LogSink", @@ -35,7 +33,6 @@ func init() { resource.ProtobufImport = "google.golang.org/genproto/googleapis/logging/v2" resource.Template = "newapi_list" resource.MockTemplate = "newapi_list_grpc_mock" - resource.ServiceDNS = "logging.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/monitoring.go b/plugins/source/gcp/codegen/recipes/monitoring.go index baab24d9557..de7e77c77a0 100644 --- a/plugins/source/gcp/codegen/recipes/monitoring.go +++ b/plugins/source/gcp/codegen/recipes/monitoring.go @@ -12,7 +12,6 @@ func init() { Struct: &pb.AlertPolicy{}, NewFunction: monitoring.NewAlertPolicyClient, RegisterServer: pb.RegisterAlertPolicyServiceServer, - ListFunction: (&pb.UnimplementedAlertPolicyServiceServer{}).ListAlertPolicies, PrimaryKeys: []string{"name"}, Description: "https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.alertPolicies#AlertPolicy", }, @@ -25,7 +24,6 @@ func init() { resource.Template = "newapi_list" resource.MockTemplate = "newapi_list_grpc_mock" resource.RequestStructFields = `Name: "projects/" + c.ProjectId,` - resource.ServiceDNS = "monitoring.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/redis.go b/plugins/source/gcp/codegen/recipes/redis.go index 2f0b64c349b..50a20bac140 100644 --- a/plugins/source/gcp/codegen/recipes/redis.go +++ b/plugins/source/gcp/codegen/recipes/redis.go @@ -12,7 +12,6 @@ func init() { Struct: &pb.Instance{}, NewFunction: redis.NewCloudRedisClient, RegisterServer: pb.RegisterCloudRedisServer, - ListFunction: (&pb.UnimplementedCloudRedisServer{}).ListInstances, PrimaryKeys: []string{"name"}, Description: "https://cloud.google.com/memorystore/docs/redis/reference/rest/v1/projects.locations.instances#Instance", }, @@ -25,7 +24,6 @@ func init() { resource.Template = "newapi_list" resource.MockTemplate = "newapi_list_grpc_mock" resource.RequestStructFields = `Parent: "projects/" + c.ProjectId + "/locations/-",` - resource.ServiceDNS = "redis.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/run.go b/plugins/source/gcp/codegen/recipes/run.go index 3efed0d4b8b..6fa429a1b1a 100644 --- a/plugins/source/gcp/codegen/recipes/run.go +++ b/plugins/source/gcp/codegen/recipes/run.go @@ -12,7 +12,7 @@ func init() { Struct: &runv1.Location{}, SkipFetch: true, SkipMock: true, - Description: "https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location", + Description: "https://cloud.google.com/run/docs/reference/rest/v1/projects.locations#Location", Relations: []string{"Services()"}, }, { @@ -29,7 +29,6 @@ func init() { resource.Service = "run" resource.Template = "newapi_list" resource.MockTemplate = "newapi_list_grpc_mock" - resource.ServiceDNS = "run.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/secretmanager.go b/plugins/source/gcp/codegen/recipes/secretmanager.go index f0506015f2f..9a50596524a 100644 --- a/plugins/source/gcp/codegen/recipes/secretmanager.go +++ b/plugins/source/gcp/codegen/recipes/secretmanager.go @@ -12,7 +12,6 @@ func init() { Struct: &pb.Secret{}, NewFunction: secretmanager.NewClient, RegisterServer: pb.RegisterSecretManagerServiceServer, - ListFunction: (&pb.UnimplementedSecretManagerServiceServer{}).ListSecrets, PrimaryKeys: []string{"name"}, SkipFields: []string{"Expiration"}, Description: "https://cloud.google.com/secret-manager/docs/reference/rest/v1/projects.secrets#Secret", @@ -26,7 +25,6 @@ func init() { resource.Template = "newapi_list" resource.MockTemplate = "newapi_list_grpc_mock" resource.RequestStructFields = `Parent: "projects/" + c.ProjectId,` - resource.ServiceDNS = "secretmanager.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/serviceusage.go b/plugins/source/gcp/codegen/recipes/serviceusage.go index c0e2267a35b..699d9112411 100644 --- a/plugins/source/gcp/codegen/recipes/serviceusage.go +++ b/plugins/source/gcp/codegen/recipes/serviceusage.go @@ -12,7 +12,6 @@ func init() { Struct: &pb.Service{}, NewFunction: serviceusage.NewClient, RegisterServer: pb.RegisterServiceUsageServer, - ListFunction: (&pb.UnimplementedServiceUsageServer{}).ListServices, PrimaryKeys: []string{"name"}, Description: "https://cloud.google.com/service-usage/docs/reference/rest/v1/services#Service", SkipFetch: true, @@ -26,7 +25,6 @@ func init() { resource.ProtobufImport = "cloud.google.com/go/serviceusage/apiv1/serviceusagepb" resource.Template = "newapi_list" resource.MockTemplate = "newapi_list_grpc_mock" - resource.ServiceDNS = "serviceusage.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/recipes/storage.go b/plugins/source/gcp/codegen/recipes/storage.go index dfb97f9a33f..73ebd69349d 100644 --- a/plugins/source/gcp/codegen/recipes/storage.go +++ b/plugins/source/gcp/codegen/recipes/storage.go @@ -42,7 +42,6 @@ func init() { resource.MockImports = []string{"cloud.google.com/go/storage"} resource.Template = "newapi_list" resource.MockTemplate = "newapi_list_rest_mock" - resource.ServiceDNS = "storage.googleapis.com" } Resources = append(Resources, resources...) diff --git a/plugins/source/gcp/codegen/templates/newapi_list.go.tpl b/plugins/source/gcp/codegen/templates/newapi_list.go.tpl index 3e943d4d3a5..b7c9fb221be 100644 --- a/plugins/source/gcp/codegen/templates/newapi_list.go.tpl +++ b/plugins/source/gcp/codegen/templates/newapi_list.go.tpl @@ -31,8 +31,16 @@ func fetch{{.SubService | ToCamel}}(ctx context.Context, meta schema.ClientMeta, c := meta.(*client.Client) req := &pb.{{.RequestStructName}}{ {{if .RequestStructFields}}{{.RequestStructFields}}{{end}} + }{{ if .ParentFilterFunc }} + if {{.ParentFilterFunc}}(parent) { + return nil } - gcpClient, err := {{.Service}}.{{.NewFunctionName}}(ctx, c.ClientOptions...) + {{ end }} + {{ if .ClientOptions }} + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{ {{ range .ClientOptions }}{{.}},{{end}} }, clientOptions...) + gcpClient, err := {{.Service}}.{{.NewFunctionName}}(ctx, clientOptions...) + {{ else }}gcpClient, err := {{.Service}}.{{.NewFunctionName}}(ctx, c.ClientOptions...){{ end }} if err != nil { return err } @@ -53,4 +61,4 @@ func fetch{{.SubService | ToCamel}}(ctx context.Context, meta schema.ClientMeta, } return nil } -{{end}} \ No newline at end of file +{{end}} diff --git a/plugins/source/gcp/codegen/templates/newapi_list_grpc_mock.go.tpl b/plugins/source/gcp/codegen/templates/newapi_list_grpc_mock.go.tpl index 5b060f9fb05..a1de6ce5b1e 100644 --- a/plugins/source/gcp/codegen/templates/newapi_list_grpc_mock.go.tpl +++ b/plugins/source/gcp/codegen/templates/newapi_list_grpc_mock.go.tpl @@ -11,13 +11,18 @@ import ( "github.com/cloudquery/plugins/source/gcp/client" {{if .ProtobufImport}} pb "{{.ProtobufImport}}" + {{end}}{{ if .RelationsTestData.ProtobufImport }} + "{{.RelationsTestData.ProtobufImport}}" {{end}} ) func create{{.SubService | ToCamel}}(gsrv *grpc.Server) error { fakeServer := &fake{{.SubService | ToCamel}}Server{} - pb.{{.RegisterServerName}}(gsrv, fakeServer) + pb.{{.RegisterServerName}}(gsrv, fakeServer){{ if .RelationsTestData.RegisterServerName }} + fakeRelationsServer := &fake{{.SubService | ToCamel}}RelationsServer{} + {{.RelationsTestData.RegisterServerName}}(gsrv, fakeRelationsServer) + {{ end }} return nil } @@ -37,3 +42,21 @@ func (f *fake{{.SubService | ToCamel}}Server) {{.ListFunctionName}}(context.Cont func Test{{.SubService | ToCamel}}(t *testing.T) { client.MockTestGrpcHelper(t, {{.SubService | ToCamel}}(), create{{.SubService | ToCamel}}, client.TestOptions{}) } + + +{{ if .RelationsTestData.UnimplementedServerName }} +type fake{{.SubService | ToCamel}}RelationsServer struct { + {{.RelationsTestData.UnimplementedServerName}} +} + +{{ range .RelationsTestData.ListFunctions }} +func (f *fake{{$.SubService | ToCamel}}RelationsServer) {{.Signature}} { + resp := {{.ResponseStructName}}{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} +{{ end }} +{{ end }} \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/README.md b/plugins/source/gcp/docs/tables/README.md index 337b32f12ea..8d6391d5e99 100644 --- a/plugins/source/gcp/docs/tables/README.md +++ b/plugins/source/gcp/docs/tables/README.md @@ -2,9 +2,59 @@ ## Tables +- [gcp_aiplatform_job_locations](gcp_aiplatform_job_locations.md) + - [gcp_aiplatform_batch_prediction_jobs](gcp_aiplatform_batch_prediction_jobs.md) + - [gcp_aiplatform_custom_jobs](gcp_aiplatform_custom_jobs.md) + - [gcp_aiplatform_data_labeling_jobs](gcp_aiplatform_data_labeling_jobs.md) + - [gcp_aiplatform_hyperparameter_tuning_jobs](gcp_aiplatform_hyperparameter_tuning_jobs.md) + - [gcp_aiplatform_model_deployment_monitoring_jobs](gcp_aiplatform_model_deployment_monitoring_jobs.md) +- [gcp_aiplatform_dataset_locations](gcp_aiplatform_dataset_locations.md) + - [gcp_aiplatform_datasets](gcp_aiplatform_datasets.md) +- [gcp_aiplatform_endpoint_locations](gcp_aiplatform_endpoint_locations.md) + - [gcp_aiplatform_endpoints](gcp_aiplatform_endpoints.md) +- [gcp_aiplatform_featurestore_locations](gcp_aiplatform_featurestore_locations.md) + - [gcp_aiplatform_featurestores](gcp_aiplatform_featurestores.md) +- [gcp_aiplatform_indexendpoint_locations](gcp_aiplatform_indexendpoint_locations.md) + - [gcp_aiplatform_index_endpoints](gcp_aiplatform_index_endpoints.md) +- [gcp_aiplatform_index_locations](gcp_aiplatform_index_locations.md) + - [gcp_aiplatform_indexes](gcp_aiplatform_indexes.md) +- [gcp_aiplatform_metadata_locations](gcp_aiplatform_metadata_locations.md) + - [gcp_aiplatform_metadata_stores](gcp_aiplatform_metadata_stores.md) +- [gcp_aiplatform_model_locations](gcp_aiplatform_model_locations.md) + - [gcp_aiplatform_models](gcp_aiplatform_models.md) +- [gcp_aiplatform_pipeline_locations](gcp_aiplatform_pipeline_locations.md) + - [gcp_aiplatform_pipeline_jobs](gcp_aiplatform_pipeline_jobs.md) + - [gcp_aiplatform_training_pipelines](gcp_aiplatform_training_pipelines.md) +- [gcp_aiplatform_specialistpool_locations](gcp_aiplatform_specialistpool_locations.md) + - [gcp_aiplatform_specialist_pools](gcp_aiplatform_specialist_pools.md) +- [gcp_aiplatform_vizier_locations](gcp_aiplatform_vizier_locations.md) + - [gcp_aiplatform_studies](gcp_aiplatform_studies.md) +- [gcp_aiplatform_tensorboard_locations](gcp_aiplatform_tensorboard_locations.md) + - [gcp_aiplatform_tensorboards](gcp_aiplatform_tensorboards.md) +- [gcp_aiplatform_operations](gcp_aiplatform_operations.md) - [gcp_apigateway_apis](gcp_apigateway_apis.md) - [gcp_apigateway_gateways](gcp_apigateway_gateways.md) - [gcp_apikeys_keys](gcp_apikeys_keys.md) +- [gcp_appengine_apps](gcp_appengine_apps.md) +- [gcp_appengine_services](gcp_appengine_services.md) + - [gcp_appengine_versions](gcp_appengine_versions.md) + - [gcp_appengine_instances](gcp_appengine_instances.md) +- [gcp_appengine_authorized_certificates](gcp_appengine_authorized_certificates.md) +- [gcp_appengine_authorized_domains](gcp_appengine_authorized_domains.md) +- [gcp_appengine_domain_mappings](gcp_appengine_domain_mappings.md) +- [gcp_appengine_firewall_ingress_rules](gcp_appengine_firewall_ingress_rules.md) +- [gcp_artifactregistry_locations](gcp_artifactregistry_locations.md) + - [gcp_artifactregistry_repositories](gcp_artifactregistry_repositories.md) + - [gcp_artifactregistry_docker_images](gcp_artifactregistry_docker_images.md) + - [gcp_artifactregistry_files](gcp_artifactregistry_files.md) + - [gcp_artifactregistry_packages](gcp_artifactregistry_packages.md) + - [gcp_artifactregistry_tags](gcp_artifactregistry_tags.md) + - [gcp_artifactregistry_versions](gcp_artifactregistry_versions.md) +- [gcp_baremetalsolution_instances](gcp_baremetalsolution_instances.md) +- [gcp_baremetalsolution_networks](gcp_baremetalsolution_networks.md) +- [gcp_baremetalsolution_nfs_shares](gcp_baremetalsolution_nfs_shares.md) +- [gcp_baremetalsolution_volumes](gcp_baremetalsolution_volumes.md) + - [gcp_baremetalsolution_volume_luns](gcp_baremetalsolution_volume_luns.md) - [gcp_bigquery_datasets](gcp_bigquery_datasets.md) - [gcp_bigquery_tables](gcp_bigquery_tables.md) - [gcp_billing_billing_accounts](gcp_billing_billing_accounts.md) diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_batch_prediction_jobs.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_batch_prediction_jobs.md new file mode 100644 index 00000000000..115cfe2e2fe --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_batch_prediction_jobs.md @@ -0,0 +1,44 @@ +# Table: gcp_aiplatform_batch_prediction_jobs + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.batchPredictionJobs#BatchPredictionJob + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_job_locations](gcp_aiplatform_job_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|model|String| +|model_version_id|String| +|unmanaged_container_model|JSON| +|input_config|JSON| +|model_parameters|JSON| +|output_config|JSON| +|dedicated_resources|JSON| +|service_account|String| +|manual_batch_tuning_parameters|JSON| +|generate_explanation|Bool| +|explanation_spec|JSON| +|output_info|JSON| +|state|String| +|error|JSON| +|partial_failures|JSON| +|resources_consumed|JSON| +|completion_stats|JSON| +|create_time|Timestamp| +|start_time|Timestamp| +|end_time|Timestamp| +|update_time|Timestamp| +|labels|JSON| +|encryption_spec|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_custom_jobs.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_custom_jobs.md new file mode 100644 index 00000000000..1836e37b6ab --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_custom_jobs.md @@ -0,0 +1,31 @@ +# Table: gcp_aiplatform_custom_jobs + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.customJobs#CustomJob + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_job_locations](gcp_aiplatform_job_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|job_spec|JSON| +|state|String| +|create_time|Timestamp| +|start_time|Timestamp| +|end_time|Timestamp| +|update_time|Timestamp| +|error|JSON| +|labels|JSON| +|encryption_spec|JSON| +|web_access_uris|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_data_labeling_jobs.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_data_labeling_jobs.md new file mode 100644 index 00000000000..5358d030180 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_data_labeling_jobs.md @@ -0,0 +1,37 @@ +# Table: gcp_aiplatform_data_labeling_jobs + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.dataLabelingJobs#DataLabelingJob + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_job_locations](gcp_aiplatform_job_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|datasets|StringArray| +|annotation_labels|JSON| +|labeler_count|Int| +|instruction_uri|String| +|inputs_schema_uri|String| +|inputs|JSON| +|state|String| +|labeling_progress|Int| +|current_spend|JSON| +|create_time|Timestamp| +|update_time|Timestamp| +|error|JSON| +|labels|JSON| +|specialist_pools|StringArray| +|encryption_spec|JSON| +|active_learning_config|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_dataset_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_dataset_locations.md new file mode 100644 index 00000000000..3c7a42840d5 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_dataset_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_dataset_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_dataset_locations: + - [gcp_aiplatform_datasets](gcp_aiplatform_datasets.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_datasets.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_datasets.md new file mode 100644 index 00000000000..1a5012ac8d3 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_datasets.md @@ -0,0 +1,30 @@ +# Table: gcp_aiplatform_datasets + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.datasets#Dataset + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_dataset_locations](gcp_aiplatform_dataset_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|description|String| +|metadata_schema_uri|String| +|metadata|JSON| +|create_time|Timestamp| +|update_time|Timestamp| +|etag|String| +|labels|JSON| +|encryption_spec|JSON| +|metadata_artifact|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_endpoint_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_endpoint_locations.md new file mode 100644 index 00000000000..8a8575b9cdb --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_endpoint_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_endpoint_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_endpoint_locations: + - [gcp_aiplatform_endpoints](gcp_aiplatform_endpoints.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_endpoints.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_endpoints.md new file mode 100644 index 00000000000..9ce1dc68f36 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_endpoints.md @@ -0,0 +1,33 @@ +# Table: gcp_aiplatform_endpoints + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.endpoints#Endpoint + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_endpoint_locations](gcp_aiplatform_endpoint_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|description|String| +|deployed_models|JSON| +|traffic_split|JSON| +|etag|String| +|labels|JSON| +|create_time|Timestamp| +|update_time|Timestamp| +|encryption_spec|JSON| +|network|String| +|enable_private_service_connect|Bool| +|model_deployment_monitoring_job|String| +|predict_request_response_logging_config|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_featurestore_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_featurestore_locations.md new file mode 100644 index 00000000000..2f840c708a1 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_featurestore_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_featurestore_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_featurestore_locations: + - [gcp_aiplatform_featurestores](gcp_aiplatform_featurestores.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_featurestores.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_featurestores.md new file mode 100644 index 00000000000..d98d4fc755a --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_featurestores.md @@ -0,0 +1,27 @@ +# Table: gcp_aiplatform_featurestores + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.featurestores#Featurestore + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_featurestore_locations](gcp_aiplatform_featurestore_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|create_time|Timestamp| +|update_time|Timestamp| +|etag|String| +|labels|JSON| +|online_serving_config|JSON| +|state|String| +|encryption_spec|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_hyperparameter_tuning_jobs.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_hyperparameter_tuning_jobs.md new file mode 100644 index 00000000000..a3e7c9ef836 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_hyperparameter_tuning_jobs.md @@ -0,0 +1,35 @@ +# Table: gcp_aiplatform_hyperparameter_tuning_jobs + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.hyperparameterTuningJobs#HyperparameterTuningJob + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_job_locations](gcp_aiplatform_job_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|study_spec|JSON| +|max_trial_count|Int| +|parallel_trial_count|Int| +|max_failed_trial_count|Int| +|trial_job_spec|JSON| +|trials|JSON| +|state|String| +|create_time|Timestamp| +|start_time|Timestamp| +|end_time|Timestamp| +|update_time|Timestamp| +|error|JSON| +|labels|JSON| +|encryption_spec|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_index_endpoints.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_index_endpoints.md new file mode 100644 index 00000000000..6154613fdc0 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_index_endpoints.md @@ -0,0 +1,29 @@ +# Table: gcp_aiplatform_index_endpoints + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.indexEndpoints#IndexEndpoint + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_indexendpoint_locations](gcp_aiplatform_indexendpoint_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|description|String| +|deployed_indexes|JSON| +|etag|String| +|labels|JSON| +|create_time|Timestamp| +|update_time|Timestamp| +|network|String| +|enable_private_service_connect|Bool| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_index_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_index_locations.md new file mode 100644 index 00000000000..c01821b79a4 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_index_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_index_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_index_locations: + - [gcp_aiplatform_indexes](gcp_aiplatform_indexes.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_indexendpoint_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_indexendpoint_locations.md new file mode 100644 index 00000000000..b66ce067a8c --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_indexendpoint_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_indexendpoint_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_indexendpoint_locations: + - [gcp_aiplatform_index_endpoints](gcp_aiplatform_index_endpoints.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_indexes.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_indexes.md new file mode 100644 index 00000000000..cbba2e23c3c --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_indexes.md @@ -0,0 +1,31 @@ +# Table: gcp_aiplatform_indexes + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.indexes#Index + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_index_locations](gcp_aiplatform_index_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|description|String| +|metadata_schema_uri|String| +|metadata|JSON| +|deployed_indexes|JSON| +|etag|String| +|labels|JSON| +|create_time|Timestamp| +|update_time|Timestamp| +|index_stats|JSON| +|index_update_method|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_job_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_job_locations.md new file mode 100644 index 00000000000..4120ed5e09a --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_job_locations.md @@ -0,0 +1,29 @@ +# Table: gcp_aiplatform_job_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_job_locations: + - [gcp_aiplatform_batch_prediction_jobs](gcp_aiplatform_batch_prediction_jobs.md) + - [gcp_aiplatform_custom_jobs](gcp_aiplatform_custom_jobs.md) + - [gcp_aiplatform_data_labeling_jobs](gcp_aiplatform_data_labeling_jobs.md) + - [gcp_aiplatform_hyperparameter_tuning_jobs](gcp_aiplatform_hyperparameter_tuning_jobs.md) + - [gcp_aiplatform_model_deployment_monitoring_jobs](gcp_aiplatform_model_deployment_monitoring_jobs.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_metadata_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_metadata_locations.md new file mode 100644 index 00000000000..66646efff9c --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_metadata_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_metadata_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_metadata_locations: + - [gcp_aiplatform_metadata_stores](gcp_aiplatform_metadata_stores.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_metadata_stores.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_metadata_stores.md new file mode 100644 index 00000000000..1a1faf61ade --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_metadata_stores.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_metadata_stores + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.metadataStores#MetadataStore + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_metadata_locations](gcp_aiplatform_metadata_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|create_time|Timestamp| +|update_time|Timestamp| +|encryption_spec|JSON| +|description|String| +|state|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_model_deployment_monitoring_jobs.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_model_deployment_monitoring_jobs.md new file mode 100644 index 00000000000..bf58218ff66 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_model_deployment_monitoring_jobs.md @@ -0,0 +1,42 @@ +# Table: gcp_aiplatform_model_deployment_monitoring_jobs + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.modelDeploymentMonitoringJobs#ModelDeploymentMonitoringJob + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_job_locations](gcp_aiplatform_job_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|endpoint|String| +|state|String| +|schedule_state|String| +|latest_monitoring_pipeline_metadata|JSON| +|model_deployment_monitoring_objective_configs|JSON| +|model_deployment_monitoring_schedule_config|JSON| +|logging_sampling_strategy|JSON| +|model_monitoring_alert_config|JSON| +|predict_instance_schema_uri|String| +|sample_predict_instance|JSON| +|analysis_instance_schema_uri|String| +|bigquery_tables|JSON| +|log_ttl|Int| +|labels|JSON| +|create_time|Timestamp| +|update_time|Timestamp| +|next_schedule_time|Timestamp| +|stats_anomalies_base_directory|JSON| +|encryption_spec|JSON| +|enable_monitoring_pipeline_logs|Bool| +|error|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_model_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_model_locations.md new file mode 100644 index 00000000000..cf10f32ec11 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_model_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_model_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_model_locations: + - [gcp_aiplatform_models](gcp_aiplatform_models.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_models.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_models.md new file mode 100644 index 00000000000..4d4dc00707d --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_models.md @@ -0,0 +1,46 @@ +# Table: gcp_aiplatform_models + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.models#Model + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_model_locations](gcp_aiplatform_model_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|version_id|String| +|version_aliases|StringArray| +|version_create_time|Timestamp| +|version_update_time|Timestamp| +|display_name|String| +|description|String| +|version_description|String| +|predict_schemata|JSON| +|metadata_schema_uri|String| +|metadata|JSON| +|supported_export_formats|JSON| +|training_pipeline|String| +|container_spec|JSON| +|artifact_uri|String| +|supported_deployment_resources_types|IntArray| +|supported_input_storage_formats|StringArray| +|supported_output_storage_formats|StringArray| +|create_time|Timestamp| +|update_time|Timestamp| +|deployed_models|JSON| +|explanation_spec|JSON| +|etag|String| +|labels|JSON| +|encryption_spec|JSON| +|model_source_info|JSON| +|metadata_artifact|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_operations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_operations.md new file mode 100644 index 00000000000..48834cf7b3c --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_operations.md @@ -0,0 +1,18 @@ +# Table: gcp_aiplatform_operations + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.operations#Operation + +The composite primary key for this table is (**project_id**, **name**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|metadata|JSON| +|done|Bool| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_pipeline_jobs.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_pipeline_jobs.md new file mode 100644 index 00000000000..e4cf01d2564 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_pipeline_jobs.md @@ -0,0 +1,36 @@ +# Table: gcp_aiplatform_pipeline_jobs + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.pipelineJobs#PipelineJob + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_pipeline_locations](gcp_aiplatform_pipeline_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|create_time|Timestamp| +|start_time|Timestamp| +|end_time|Timestamp| +|update_time|Timestamp| +|pipeline_spec|JSON| +|state|String| +|job_detail|JSON| +|error|JSON| +|labels|JSON| +|runtime_config|JSON| +|encryption_spec|JSON| +|service_account|String| +|network|String| +|template_uri|String| +|template_metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_pipeline_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_pipeline_locations.md new file mode 100644 index 00000000000..6b70605a106 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_pipeline_locations.md @@ -0,0 +1,26 @@ +# Table: gcp_aiplatform_pipeline_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_pipeline_locations: + - [gcp_aiplatform_pipeline_jobs](gcp_aiplatform_pipeline_jobs.md) + - [gcp_aiplatform_training_pipelines](gcp_aiplatform_training_pipelines.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_specialist_pools.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_specialist_pools.md new file mode 100644 index 00000000000..685f8cb438e --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_specialist_pools.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_specialist_pools + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.specialistPools#SpecialistPool + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_specialistpool_locations](gcp_aiplatform_specialistpool_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|specialist_managers_count|Int| +|specialist_manager_emails|StringArray| +|pending_data_labeling_jobs|StringArray| +|specialist_worker_emails|StringArray| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_specialistpool_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_specialistpool_locations.md new file mode 100644 index 00000000000..ed7e5fea72f --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_specialistpool_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_specialistpool_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_specialistpool_locations: + - [gcp_aiplatform_specialist_pools](gcp_aiplatform_specialist_pools.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_studies.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_studies.md new file mode 100644 index 00000000000..8572d52ec5b --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_studies.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_studies + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.studies#Study + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_vizier_locations](gcp_aiplatform_vizier_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|study_spec|JSON| +|state|String| +|create_time|Timestamp| +|inactive_reason|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_tensorboard_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_tensorboard_locations.md new file mode 100644 index 00000000000..4784af892c6 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_tensorboard_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_tensorboard_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_tensorboard_locations: + - [gcp_aiplatform_tensorboards](gcp_aiplatform_tensorboards.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_tensorboards.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_tensorboards.md new file mode 100644 index 00000000000..88161a44520 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_tensorboards.md @@ -0,0 +1,29 @@ +# Table: gcp_aiplatform_tensorboards + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.tensorboards#Tensorboard + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_tensorboard_locations](gcp_aiplatform_tensorboard_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|description|String| +|encryption_spec|JSON| +|blob_storage_path_prefix|String| +|run_count|Int| +|create_time|Timestamp| +|update_time|Timestamp| +|labels|JSON| +|etag|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_training_pipelines.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_training_pipelines.md new file mode 100644 index 00000000000..e03e9a863ba --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_training_pipelines.md @@ -0,0 +1,36 @@ +# Table: gcp_aiplatform_training_pipelines + +https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.trainingPipelines#TrainingPipeline + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_aiplatform_pipeline_locations](gcp_aiplatform_pipeline_locations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|input_data_config|JSON| +|training_task_definition|String| +|training_task_inputs|JSON| +|training_task_metadata|JSON| +|model_to_upload|JSON| +|model_id|String| +|parent_model|String| +|state|String| +|error|JSON| +|create_time|Timestamp| +|start_time|Timestamp| +|end_time|Timestamp| +|update_time|Timestamp| +|labels|JSON| +|encryption_spec|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_aiplatform_vizier_locations.md b/plugins/source/gcp/docs/tables/gcp_aiplatform_vizier_locations.md new file mode 100644 index 00000000000..c5afc649682 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_aiplatform_vizier_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_aiplatform_vizier_locations + +https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_aiplatform_vizier_locations: + - [gcp_aiplatform_studies](gcp_aiplatform_studies.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|location_id|String| +|display_name|String| +|labels|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_appengine_apps.md b/plugins/source/gcp/docs/tables/gcp_appengine_apps.md new file mode 100644 index 00000000000..6895bca3b80 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_appengine_apps.md @@ -0,0 +1,30 @@ +# Table: gcp_appengine_apps + +https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps#Application + +The composite primary key for this table is (**project_id**, **name**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|dispatch_rules|JSON| +|auth_domain|String| +|location_id|String| +|code_bucket|String| +|default_cookie_expiration|Int| +|serving_status|String| +|default_hostname|String| +|default_bucket|String| +|service_account|String| +|iap|JSON| +|gcr_domain|String| +|database_type|String| +|feature_settings|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_appengine_authorized_certificates.md b/plugins/source/gcp/docs/tables/gcp_appengine_authorized_certificates.md new file mode 100644 index 00000000000..fabcbc436b3 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_appengine_authorized_certificates.md @@ -0,0 +1,24 @@ +# Table: gcp_appengine_authorized_certificates + +https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.authorizedCertificates#AuthorizedCertificate + +The composite primary key for this table is (**project_id**, **name**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|display_name|String| +|domain_names|StringArray| +|expire_time|Timestamp| +|certificate_raw_data|JSON| +|managed_certificate|JSON| +|visible_domain_mappings|StringArray| +|domain_mappings_count|Int| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_appengine_authorized_domains.md b/plugins/source/gcp/docs/tables/gcp_appengine_authorized_domains.md new file mode 100644 index 00000000000..9f54d777992 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_appengine_authorized_domains.md @@ -0,0 +1,17 @@ +# Table: gcp_appengine_authorized_domains + +https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.authorizedDomains#AuthorizedDomain + +The composite primary key for this table is (**project_id**, **name**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_appengine_domain_mappings.md b/plugins/source/gcp/docs/tables/gcp_appengine_domain_mappings.md new file mode 100644 index 00000000000..eb240288dd0 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_appengine_domain_mappings.md @@ -0,0 +1,19 @@ +# Table: gcp_appengine_domain_mappings + +https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.domainMappings#DomainMapping + +The composite primary key for this table is (**project_id**, **name**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|ssl_settings|JSON| +|resource_records|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_appengine_firewall_ingress_rules.md b/plugins/source/gcp/docs/tables/gcp_appengine_firewall_ingress_rules.md new file mode 100644 index 00000000000..a74c6028c3a --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_appengine_firewall_ingress_rules.md @@ -0,0 +1,19 @@ +# Table: gcp_appengine_firewall_ingress_rules + +https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.firewall.ingressRules#FirewallRule + +The primary key for this table is **project_id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|priority|Int| +|action|String| +|source_range|String| +|description|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_appengine_instances.md b/plugins/source/gcp/docs/tables/gcp_appengine_instances.md new file mode 100644 index 00000000000..6481a4d0e3e --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_appengine_instances.md @@ -0,0 +1,36 @@ +# Table: gcp_appengine_instances + +https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions.instances#Instance + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_appengine_versions](gcp_appengine_versions.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|app_engine_release|String| +|availability|String| +|vm_name|String| +|vm_zone_name|String| +|vm_id|String| +|start_time|Timestamp| +|requests|Int| +|errors|Int| +|qps|Float| +|average_latency|Int| +|memory_usage|Int| +|vm_status|String| +|vm_debug_enabled|Bool| +|vm_ip|String| +|vm_liveness|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_appengine_services.md b/plugins/source/gcp/docs/tables/gcp_appengine_services.md new file mode 100644 index 00000000000..61c5de956ab --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_appengine_services.md @@ -0,0 +1,25 @@ +# Table: gcp_appengine_services + +https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services#Service + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_appengine_services: + - [gcp_appengine_versions](gcp_appengine_versions.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|split|JSON| +|labels|JSON| +|network_settings|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_appengine_versions.md b/plugins/source/gcp/docs/tables/gcp_appengine_versions.md new file mode 100644 index 00000000000..6c52dc9dc5b --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_appengine_versions.md @@ -0,0 +1,59 @@ +# Table: gcp_appengine_versions + +https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions#Version + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_appengine_services](gcp_appengine_services.md). + +The following tables depend on gcp_appengine_versions: + - [gcp_appengine_instances](gcp_appengine_instances.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|inbound_services|IntArray| +|instance_class|String| +|network|JSON| +|zones|StringArray| +|resources|JSON| +|runtime|String| +|runtime_channel|String| +|threadsafe|Bool| +|vm|Bool| +|app_engine_apis|Bool| +|beta_settings|JSON| +|env|String| +|serving_status|String| +|created_by|String| +|create_time|Timestamp| +|disk_usage_bytes|Int| +|runtime_api_version|String| +|runtime_main_executable_path|String| +|service_account|String| +|handlers|JSON| +|error_handlers|JSON| +|libraries|JSON| +|api_config|JSON| +|env_variables|JSON| +|build_env_variables|JSON| +|default_expiration|Int| +|health_check|JSON| +|readiness_check|JSON| +|liveness_check|JSON| +|nobuild_files_regex|String| +|deployment|JSON| +|version_url|String| +|endpoints_api_service|JSON| +|entrypoint|JSON| +|vpc_access_connector|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_artifactregistry_docker_images.md b/plugins/source/gcp/docs/tables/gcp_artifactregistry_docker_images.md new file mode 100644 index 00000000000..46efbf4871a --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_artifactregistry_docker_images.md @@ -0,0 +1,26 @@ +# Table: gcp_artifactregistry_docker_images + +https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.dockerImages#DockerImage + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_artifactregistry_repositories](gcp_artifactregistry_repositories.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|uri|String| +|tags|StringArray| +|image_size_bytes|Int| +|upload_time|Timestamp| +|media_type|String| +|build_time|Timestamp| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_artifactregistry_files.md b/plugins/source/gcp/docs/tables/gcp_artifactregistry_files.md new file mode 100644 index 00000000000..69ecf3e1101 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_artifactregistry_files.md @@ -0,0 +1,25 @@ +# Table: gcp_artifactregistry_files + +https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.files#File + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_artifactregistry_repositories](gcp_artifactregistry_repositories.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|size_bytes|Int| +|hashes|JSON| +|create_time|Timestamp| +|update_time|Timestamp| +|owner|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_artifactregistry_locations.md b/plugins/source/gcp/docs/tables/gcp_artifactregistry_locations.md new file mode 100644 index 00000000000..77c1015285d --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_artifactregistry_locations.md @@ -0,0 +1,25 @@ +# Table: gcp_artifactregistry_locations + +https://cloud.google.com/artifact-registry/docs/reference/rest/Shared.Types/ListLocationsResponse#Location + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_artifactregistry_locations: + - [gcp_artifactregistry_repositories](gcp_artifactregistry_repositories.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|display_name|String| +|labels|JSON| +|location_id|String| +|metadata|IntArray| +|name (PK)|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_artifactregistry_packages.md b/plugins/source/gcp/docs/tables/gcp_artifactregistry_packages.md new file mode 100644 index 00000000000..2ad67addb09 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_artifactregistry_packages.md @@ -0,0 +1,27 @@ +# Table: gcp_artifactregistry_packages + +https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.packages#Package + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_artifactregistry_repositories](gcp_artifactregistry_repositories.md). + +The following tables depend on gcp_artifactregistry_packages: + - [gcp_artifactregistry_tags](gcp_artifactregistry_tags.md) + - [gcp_artifactregistry_versions](gcp_artifactregistry_versions.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|display_name|String| +|create_time|Timestamp| +|update_time|Timestamp| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_artifactregistry_repositories.md b/plugins/source/gcp/docs/tables/gcp_artifactregistry_repositories.md new file mode 100644 index 00000000000..a57ce3f8181 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_artifactregistry_repositories.md @@ -0,0 +1,31 @@ +# Table: gcp_artifactregistry_repositories + +https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories#Repository + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_artifactregistry_locations](gcp_artifactregistry_locations.md). + +The following tables depend on gcp_artifactregistry_repositories: + - [gcp_artifactregistry_docker_images](gcp_artifactregistry_docker_images.md) + - [gcp_artifactregistry_files](gcp_artifactregistry_files.md) + - [gcp_artifactregistry_packages](gcp_artifactregistry_packages.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|format|String| +|description|String| +|labels|JSON| +|create_time|Timestamp| +|update_time|Timestamp| +|kms_key_name|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_artifactregistry_tags.md b/plugins/source/gcp/docs/tables/gcp_artifactregistry_tags.md new file mode 100644 index 00000000000..1fba3b06ef6 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_artifactregistry_tags.md @@ -0,0 +1,21 @@ +# Table: gcp_artifactregistry_tags + +https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.packages.tags#Tag + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_artifactregistry_packages](gcp_artifactregistry_packages.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|version|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_artifactregistry_versions.md b/plugins/source/gcp/docs/tables/gcp_artifactregistry_versions.md new file mode 100644 index 00000000000..d98fe686cf5 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_artifactregistry_versions.md @@ -0,0 +1,25 @@ +# Table: gcp_artifactregistry_versions + +https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.packages.versions#Version + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_artifactregistry_packages](gcp_artifactregistry_packages.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|description|String| +|create_time|Timestamp| +|update_time|Timestamp| +|related_tags|JSON| +|metadata|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_baremetalsolution_instances.md b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_instances.md new file mode 100644 index 00000000000..c6cce07d579 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_instances.md @@ -0,0 +1,30 @@ +# Table: gcp_baremetalsolution_instances + +https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.instances#Instance + +The composite primary key for this table is (**project_id**, **name**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|create_time|Timestamp| +|update_time|Timestamp| +|machine_type|String| +|state|String| +|hyperthreading_enabled|Bool| +|labels|JSON| +|luns|JSON| +|networks|JSON| +|interactive_serial_console_enabled|Bool| +|os_image|String| +|pod|String| +|network_template|String| +|logical_interfaces|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_baremetalsolution_networks.md b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_networks.md new file mode 100644 index 00000000000..5e706e535a2 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_networks.md @@ -0,0 +1,27 @@ +# Table: gcp_baremetalsolution_networks + +https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.networks#Network + +The composite primary key for this table is (**project_id**, **name**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|type|String| +|ip_address|String| +|mac_address|StringArray| +|state|String| +|vlan_id|String| +|cidr|String| +|vrf|JSON| +|labels|JSON| +|services_cidr|String| +|reservations|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_baremetalsolution_nfs_shares.md b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_nfs_shares.md new file mode 100644 index 00000000000..1c37d70ea13 --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_nfs_shares.md @@ -0,0 +1,21 @@ +# Table: gcp_baremetalsolution_nfs_shares + +https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.nfsShares#NfsShare + +The composite primary key for this table is (**project_id**, **name**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|nfs_share_id|String| +|state|String| +|volume|String| +|allowed_clients|JSON| +|labels|JSON| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_baremetalsolution_volume_luns.md b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_volume_luns.md new file mode 100644 index 00000000000..f1cbd6798ac --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_volume_luns.md @@ -0,0 +1,29 @@ +# Table: gcp_baremetalsolution_volume_luns + +https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.volumes.luns#Lun + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +This table depends on [gcp_baremetalsolution_volumes](gcp_baremetalsolution_volumes.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|state|String| +|size_gb|Int| +|multiprotocol_type|String| +|storage_volume|String| +|shareable|Bool| +|boot_lun|Bool| +|storage_type|String| +|wwid|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_baremetalsolution_volumes.md b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_volumes.md new file mode 100644 index 00000000000..e015b06ef9f --- /dev/null +++ b/plugins/source/gcp/docs/tables/gcp_baremetalsolution_volumes.md @@ -0,0 +1,34 @@ +# Table: gcp_baremetalsolution_volumes + +https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.volumes#Volume + +The composite primary key for this table is (**project_id**, **name**). + +## Relations + +The following tables depend on gcp_baremetalsolution_volumes: + - [gcp_baremetalsolution_volume_luns](gcp_baremetalsolution_volume_luns.md) + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|project_id (PK)|String| +|name (PK)|String| +|id|String| +|storage_type|String| +|state|String| +|requested_size_gib|Int| +|current_size_gib|Int| +|emergency_size_gib|Int| +|auto_grown_size_gib|Int| +|remaining_space_gib|Int| +|snapshot_reservation_detail|JSON| +|snapshot_auto_delete_behavior|String| +|labels|JSON| +|snapshot_enabled|Bool| +|pod|String| \ No newline at end of file diff --git a/plugins/source/gcp/docs/tables/gcp_run_locations.md b/plugins/source/gcp/docs/tables/gcp_run_locations.md index 2fd1f15e952..5e9caece20e 100644 --- a/plugins/source/gcp/docs/tables/gcp_run_locations.md +++ b/plugins/source/gcp/docs/tables/gcp_run_locations.md @@ -1,6 +1,6 @@ # Table: gcp_run_locations -https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location +https://cloud.google.com/run/docs/reference/rest/v1/projects.locations#Location The primary key for this table is **_cq_id**. diff --git a/plugins/source/gcp/go.mod b/plugins/source/gcp/go.mod index 7992c4be94d..d8e2d31aa4a 100644 --- a/plugins/source/gcp/go.mod +++ b/plugins/source/gcp/go.mod @@ -3,8 +3,12 @@ module github.com/cloudquery/plugins/source/gcp go 1.19 require ( + cloud.google.com/go/aiplatform v1.27.0 cloud.google.com/go/apigateway v1.4.0 cloud.google.com/go/apikeys v0.2.0 + cloud.google.com/go/appengine v1.5.0 + cloud.google.com/go/artifactregistry v1.9.0 + cloud.google.com/go/baremetalsolution v0.4.0 cloud.google.com/go/billing v1.7.0 cloud.google.com/go/compute v1.14.0 cloud.google.com/go/container v1.8.0 @@ -14,6 +18,7 @@ require ( cloud.google.com/go/iam v0.9.0 cloud.google.com/go/kms v1.6.0 cloud.google.com/go/logging v1.6.1 + cloud.google.com/go/longrunning v0.3.0 cloud.google.com/go/monitoring v1.9.0 cloud.google.com/go/redis v1.10.0 cloud.google.com/go/resourcemanager v1.4.0 @@ -21,7 +26,7 @@ require ( cloud.google.com/go/secretmanager v1.9.0 cloud.google.com/go/serviceusage v1.4.0 cloud.google.com/go/storage v1.28.0 - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/golang/mock v1.6.0 github.com/googleapis/gax-go/v2 v2.7.0 github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 @@ -42,7 +47,6 @@ require ( require ( cloud.google.com/go v0.107.0 // indirect cloud.google.com/go/compute/metadata v0.2.2 // indirect - cloud.google.com/go/longrunning v0.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/getsentry/sentry-go v0.15.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect diff --git a/plugins/source/gcp/go.sum b/plugins/source/gcp/go.sum index 560b753022d..c118d079230 100644 --- a/plugins/source/gcp/go.sum +++ b/plugins/source/gcp/go.sum @@ -15,10 +15,18 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.107.0 h1:qkj22L7bgkl6vIeZDlOY2po43Mx/TIa2Wsa7VR+PEww= cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go/aiplatform v1.27.0 h1:DBi3Jk9XjCJ4pkkLM4NqKgj3ozUL1wq4l+d3/jTGXAI= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= cloud.google.com/go/apigateway v1.4.0 h1:IIoXKR7FKrEAQhMTz5hK2wiDz2WNFHS7eVr/L1lE/rM= cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= cloud.google.com/go/apikeys v0.2.0 h1:s4nDYHB1cFBmo53BCX+iARtcSjK+6r/LH67lacUxWtQ= cloud.google.com/go/apikeys v0.2.0/go.mod h1:X11keBkNcspckbfFooIc9i2jZpyYt3YdWfMkkCVR2y4= +cloud.google.com/go/appengine v1.5.0 h1:lmG+O5oaR9xNwaRBwE2XoMhwQHsHql5IoiGr1ptdDwU= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/artifactregistry v1.9.0 h1:3d0LRAU1K6vfqCahhl9fx2oGHcq+s5gftdix4v8Ibrc= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/baremetalsolution v0.4.0 h1:g9KO6SkakcYPcc/XjAzeuUrEOXlYPnMpuiaywYaGrmQ= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= 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= @@ -82,8 +90,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/gcp/resources/plugin/autogen_tables.go b/plugins/source/gcp/resources/plugin/autogen_tables.go index 90187a6280b..e9523133c88 100644 --- a/plugins/source/gcp/resources/plugin/autogen_tables.go +++ b/plugins/source/gcp/resources/plugin/autogen_tables.go @@ -4,8 +4,12 @@ package plugin import ( "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/resources/services/aiplatform" "github.com/cloudquery/plugins/source/gcp/resources/services/apigateway" "github.com/cloudquery/plugins/source/gcp/resources/services/apikeys" + "github.com/cloudquery/plugins/source/gcp/resources/services/appengine" + "github.com/cloudquery/plugins/source/gcp/resources/services/artifactregistry" + "github.com/cloudquery/plugins/source/gcp/resources/services/baremetalsolution" "github.com/cloudquery/plugins/source/gcp/resources/services/bigquery" "github.com/cloudquery/plugins/source/gcp/resources/services/billing" "github.com/cloudquery/plugins/source/gcp/resources/services/compute" @@ -29,9 +33,33 @@ import ( func PluginAutoGeneratedTables() []*schema.Table { return []*schema.Table{ + aiplatform.JobLocations(), + aiplatform.DatasetLocations(), + aiplatform.EndpointLocations(), + aiplatform.FeaturestoreLocations(), + aiplatform.IndexendpointLocations(), + aiplatform.IndexLocations(), + aiplatform.MetadataLocations(), + aiplatform.ModelLocations(), + aiplatform.PipelineLocations(), + aiplatform.SpecialistpoolLocations(), + aiplatform.VizierLocations(), + aiplatform.TensorboardLocations(), + aiplatform.Operations(), apigateway.Apis(), apigateway.Gateways(), apikeys.Keys(), + appengine.Apps(), + appengine.Services(), + appengine.AuthorizedCertificates(), + appengine.AuthorizedDomains(), + appengine.DomainMappings(), + appengine.FirewallIngressRules(), + artifactregistry.Locations(), + baremetalsolution.Instances(), + baremetalsolution.Networks(), + baremetalsolution.NfsShares(), + baremetalsolution.Volumes(), bigquery.Datasets(), billing.BillingAccounts(), billing.Services(), diff --git a/plugins/source/gcp/resources/services/aiplatform/batch_prediction_jobs.go b/plugins/source/gcp/resources/services/aiplatform/batch_prediction_jobs.go new file mode 100644 index 00000000000..febb4024bb2 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/batch_prediction_jobs.go @@ -0,0 +1,199 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func BatchPredictionJobs() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_batch_prediction_jobs", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.batchPredictionJobs#BatchPredictionJob`, + Resolver: fetchBatchPredictionJobs, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "model", + Type: schema.TypeString, + Resolver: schema.PathResolver("Model"), + }, + { + Name: "model_version_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ModelVersionId"), + }, + { + Name: "unmanaged_container_model", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("UnmanagedContainerModel"), + }, + { + Name: "input_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("InputConfig"), + }, + { + Name: "model_parameters", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ModelParameters"), + IgnoreInTests: true, + }, + { + Name: "output_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("OutputConfig"), + }, + { + Name: "dedicated_resources", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("DedicatedResources"), + }, + { + Name: "service_account", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceAccount"), + }, + { + Name: "manual_batch_tuning_parameters", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ManualBatchTuningParameters"), + }, + { + Name: "generate_explanation", + Type: schema.TypeBool, + Resolver: schema.PathResolver("GenerateExplanation"), + }, + { + Name: "explanation_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ExplanationSpec"), + }, + { + Name: "output_info", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("OutputInfo"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "error", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Error"), + }, + { + Name: "partial_failures", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("PartialFailures"), + }, + { + Name: "resources_consumed", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ResourcesConsumed"), + }, + { + Name: "completion_stats", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("CompletionStats"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "start_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("StartTime"), + }, + { + Name: "end_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("EndTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + }, + } +} + +func fetchBatchPredictionJobs(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListBatchPredictionJobsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewJobClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListBatchPredictionJobs(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/custom_jobs.go b/plugins/source/gcp/resources/services/aiplatform/custom_jobs.go new file mode 100644 index 00000000000..565fe870451 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/custom_jobs.go @@ -0,0 +1,133 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func CustomJobs() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_custom_jobs", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.customJobs#CustomJob`, + Resolver: fetchCustomJobs, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "job_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("JobSpec"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "start_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("StartTime"), + }, + { + Name: "end_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("EndTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "error", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Error"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + { + Name: "web_access_uris", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("WebAccessUris"), + }, + }, + } +} + +func fetchCustomJobs(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListCustomJobsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewJobClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListCustomJobs(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/data_labeling_jobs.go b/plugins/source/gcp/resources/services/aiplatform/data_labeling_jobs.go new file mode 100644 index 00000000000..a11933732c7 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/data_labeling_jobs.go @@ -0,0 +1,164 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func DataLabelingJobs() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_data_labeling_jobs", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.dataLabelingJobs#DataLabelingJob`, + Resolver: fetchDataLabelingJobs, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "datasets", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("Datasets"), + }, + { + Name: "annotation_labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("AnnotationLabels"), + }, + { + Name: "labeler_count", + Type: schema.TypeInt, + Resolver: schema.PathResolver("LabelerCount"), + }, + { + Name: "instruction_uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("InstructionUri"), + }, + { + Name: "inputs_schema_uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("InputsSchemaUri"), + }, + { + Name: "inputs", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Inputs"), + IgnoreInTests: true, + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "labeling_progress", + Type: schema.TypeInt, + Resolver: schema.PathResolver("LabelingProgress"), + }, + { + Name: "current_spend", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("CurrentSpend"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "error", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Error"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "specialist_pools", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("SpecialistPools"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + { + Name: "active_learning_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ActiveLearningConfig"), + }, + }, + } +} + +func fetchDataLabelingJobs(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListDataLabelingJobsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewJobClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListDataLabelingJobs(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/dataset_locations.go b/plugins/source/gcp/resources/services/aiplatform/dataset_locations.go new file mode 100644 index 00000000000..35d884cf2a0 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/dataset_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func DatasetLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_dataset_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchDatasetLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + Datasets(), + }, + } +} + +func fetchDatasetLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewDatasetClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/dataset_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/dataset_locations_mock_test.go new file mode 100644 index 00000000000..3d9a6e5e5ad --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/dataset_locations_mock_test.go @@ -0,0 +1,82 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createDatasetLocations(gsrv *grpc.Server) error { + fakeServer := &fakeDatasetLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeDatasetLocationsRelationsServer{} + aiplatformpb.RegisterDatasetServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeDatasetLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeDatasetLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestDatasetLocations(t *testing.T) { + client.MockTestGrpcHelper(t, DatasetLocations(), createDatasetLocations, client.TestOptions{}) +} + +type fakeDatasetLocationsRelationsServer struct { + aiplatformpb.UnimplementedDatasetServiceServer +} + +func (f *fakeDatasetLocationsRelationsServer) ListAnnotations(context.Context, *aiplatformpb.ListAnnotationsRequest) (*aiplatformpb.ListAnnotationsResponse, error) { + resp := aiplatformpb.ListAnnotationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeDatasetLocationsRelationsServer) ListDataItems(context.Context, *aiplatformpb.ListDataItemsRequest) (*aiplatformpb.ListDataItemsResponse, error) { + resp := aiplatformpb.ListDataItemsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeDatasetLocationsRelationsServer) ListDatasets(context.Context, *aiplatformpb.ListDatasetsRequest) (*aiplatformpb.ListDatasetsResponse, error) { + resp := aiplatformpb.ListDatasetsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeDatasetLocationsRelationsServer) ListSavedQueries(context.Context, *aiplatformpb.ListSavedQueriesRequest) (*aiplatformpb.ListSavedQueriesResponse, error) { + resp := aiplatformpb.ListSavedQueriesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/datasets.go b/plugins/source/gcp/resources/services/aiplatform/datasets.go new file mode 100644 index 00000000000..ad9ea0a37ff --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/datasets.go @@ -0,0 +1,129 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func Datasets() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_datasets", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.datasets#Dataset`, + Resolver: fetchDatasets, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "metadata_schema_uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("MetadataSchemaUri"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + IgnoreInTests: true, + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "etag", + Type: schema.TypeString, + Resolver: schema.PathResolver("Etag"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + { + Name: "metadata_artifact", + Type: schema.TypeString, + Resolver: schema.PathResolver("MetadataArtifact"), + }, + }, + } +} + +func fetchDatasets(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListDatasetsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewDatasetClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListDatasets(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/endpoint_locations.go b/plugins/source/gcp/resources/services/aiplatform/endpoint_locations.go new file mode 100644 index 00000000000..44bad984e86 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/endpoint_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func EndpointLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_endpoint_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchEndpointLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + Endpoints(), + }, + } +} + +func fetchEndpointLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewEndpointClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/endpoint_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/endpoint_locations_mock_test.go new file mode 100644 index 00000000000..bfb6fa03182 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/endpoint_locations_mock_test.go @@ -0,0 +1,55 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createEndpointLocations(gsrv *grpc.Server) error { + fakeServer := &fakeEndpointLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeEndpointLocationsRelationsServer{} + aiplatformpb.RegisterEndpointServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeEndpointLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeEndpointLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestEndpointLocations(t *testing.T) { + client.MockTestGrpcHelper(t, EndpointLocations(), createEndpointLocations, client.TestOptions{}) +} + +type fakeEndpointLocationsRelationsServer struct { + aiplatformpb.UnimplementedEndpointServiceServer +} + +func (f *fakeEndpointLocationsRelationsServer) ListEndpoints(context.Context, *aiplatformpb.ListEndpointsRequest) (*aiplatformpb.ListEndpointsResponse, error) { + resp := aiplatformpb.ListEndpointsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/endpoints.go b/plugins/source/gcp/resources/services/aiplatform/endpoints.go new file mode 100644 index 00000000000..a5701962fc5 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/endpoints.go @@ -0,0 +1,143 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func Endpoints() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_endpoints", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.endpoints#Endpoint`, + Resolver: fetchEndpoints, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "deployed_models", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("DeployedModels"), + }, + { + Name: "traffic_split", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("TrafficSplit"), + }, + { + Name: "etag", + Type: schema.TypeString, + Resolver: schema.PathResolver("Etag"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + { + Name: "network", + Type: schema.TypeString, + Resolver: schema.PathResolver("Network"), + }, + { + Name: "enable_private_service_connect", + Type: schema.TypeBool, + Resolver: schema.PathResolver("EnablePrivateServiceConnect"), + }, + { + Name: "model_deployment_monitoring_job", + Type: schema.TypeString, + Resolver: schema.PathResolver("ModelDeploymentMonitoringJob"), + }, + { + Name: "predict_request_response_logging_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("PredictRequestResponseLoggingConfig"), + }, + }, + } +} + +func fetchEndpoints(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListEndpointsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewEndpointClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListEndpoints(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/featurestore_locations.go b/plugins/source/gcp/resources/services/aiplatform/featurestore_locations.go new file mode 100644 index 00000000000..b9db522ea6d --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/featurestore_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func FeaturestoreLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_featurestore_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchFeaturestoreLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + Featurestores(), + }, + } +} + +func fetchFeaturestoreLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewFeaturestoreClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/featurestore_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/featurestore_locations_mock_test.go new file mode 100644 index 00000000000..29daa421fa6 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/featurestore_locations_mock_test.go @@ -0,0 +1,73 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createFeaturestoreLocations(gsrv *grpc.Server) error { + fakeServer := &fakeFeaturestoreLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeFeaturestoreLocationsRelationsServer{} + aiplatformpb.RegisterFeaturestoreServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeFeaturestoreLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeFeaturestoreLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestFeaturestoreLocations(t *testing.T) { + client.MockTestGrpcHelper(t, FeaturestoreLocations(), createFeaturestoreLocations, client.TestOptions{}) +} + +type fakeFeaturestoreLocationsRelationsServer struct { + aiplatformpb.UnimplementedFeaturestoreServiceServer +} + +func (f *fakeFeaturestoreLocationsRelationsServer) ListEntityTypes(context.Context, *aiplatformpb.ListEntityTypesRequest) (*aiplatformpb.ListEntityTypesResponse, error) { + resp := aiplatformpb.ListEntityTypesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeFeaturestoreLocationsRelationsServer) ListFeatures(context.Context, *aiplatformpb.ListFeaturesRequest) (*aiplatformpb.ListFeaturesResponse, error) { + resp := aiplatformpb.ListFeaturesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeFeaturestoreLocationsRelationsServer) ListFeaturestores(context.Context, *aiplatformpb.ListFeaturestoresRequest) (*aiplatformpb.ListFeaturestoresResponse, error) { + resp := aiplatformpb.ListFeaturestoresResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/featurestores.go b/plugins/source/gcp/resources/services/aiplatform/featurestores.go new file mode 100644 index 00000000000..1443bc1d770 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/featurestores.go @@ -0,0 +1,113 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func Featurestores() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_featurestores", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.featurestores#Featurestore`, + Resolver: fetchFeaturestores, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "etag", + Type: schema.TypeString, + Resolver: schema.PathResolver("Etag"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "online_serving_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("OnlineServingConfig"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + }, + } +} + +func fetchFeaturestores(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListFeaturestoresRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewFeaturestoreClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListFeaturestores(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/hyperparameter_tuning_jobs.go b/plugins/source/gcp/resources/services/aiplatform/hyperparameter_tuning_jobs.go new file mode 100644 index 00000000000..0d276b700b1 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/hyperparameter_tuning_jobs.go @@ -0,0 +1,153 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func HyperparameterTuningJobs() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_hyperparameter_tuning_jobs", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.hyperparameterTuningJobs#HyperparameterTuningJob`, + Resolver: fetchHyperparameterTuningJobs, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "study_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("StudySpec"), + }, + { + Name: "max_trial_count", + Type: schema.TypeInt, + Resolver: schema.PathResolver("MaxTrialCount"), + }, + { + Name: "parallel_trial_count", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ParallelTrialCount"), + }, + { + Name: "max_failed_trial_count", + Type: schema.TypeInt, + Resolver: schema.PathResolver("MaxFailedTrialCount"), + }, + { + Name: "trial_job_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("TrialJobSpec"), + }, + { + Name: "trials", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Trials"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "start_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("StartTime"), + }, + { + Name: "end_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("EndTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "error", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Error"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + }, + } +} + +func fetchHyperparameterTuningJobs(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListHyperparameterTuningJobsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewJobClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListHyperparameterTuningJobs(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/index_endpoints.go b/plugins/source/gcp/resources/services/aiplatform/index_endpoints.go new file mode 100644 index 00000000000..27be9c77fa4 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/index_endpoints.go @@ -0,0 +1,123 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func IndexEndpoints() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_index_endpoints", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.indexEndpoints#IndexEndpoint`, + Resolver: fetchIndexEndpoints, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "deployed_indexes", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("DeployedIndexes"), + }, + { + Name: "etag", + Type: schema.TypeString, + Resolver: schema.PathResolver("Etag"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "network", + Type: schema.TypeString, + Resolver: schema.PathResolver("Network"), + }, + { + Name: "enable_private_service_connect", + Type: schema.TypeBool, + Resolver: schema.PathResolver("EnablePrivateServiceConnect"), + }, + }, + } +} + +func fetchIndexEndpoints(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListIndexEndpointsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterIndexesLocations(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewIndexEndpointClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListIndexEndpoints(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/index_locations.go b/plugins/source/gcp/resources/services/aiplatform/index_locations.go new file mode 100644 index 00000000000..9dbad49ca11 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/index_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func IndexLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_index_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchIndexLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + Indexes(), + }, + } +} + +func fetchIndexLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewIndexClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/index_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/index_locations_mock_test.go new file mode 100644 index 00000000000..da8e125dcd1 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/index_locations_mock_test.go @@ -0,0 +1,55 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createIndexLocations(gsrv *grpc.Server) error { + fakeServer := &fakeIndexLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeIndexLocationsRelationsServer{} + aiplatformpb.RegisterIndexServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeIndexLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeIndexLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestIndexLocations(t *testing.T) { + client.MockTestGrpcHelper(t, IndexLocations(), createIndexLocations, client.TestOptions{}) +} + +type fakeIndexLocationsRelationsServer struct { + aiplatformpb.UnimplementedIndexServiceServer +} + +func (f *fakeIndexLocationsRelationsServer) ListIndexes(context.Context, *aiplatformpb.ListIndexesRequest) (*aiplatformpb.ListIndexesResponse, error) { + resp := aiplatformpb.ListIndexesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/indexendpoint_locations.go b/plugins/source/gcp/resources/services/aiplatform/indexendpoint_locations.go new file mode 100644 index 00000000000..829bef6b15b --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/indexendpoint_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func IndexendpointLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_indexendpoint_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchIndexendpointLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + IndexEndpoints(), + }, + } +} + +func fetchIndexendpointLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewIndexEndpointClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/indexendpoint_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/indexendpoint_locations_mock_test.go new file mode 100644 index 00000000000..e418f292491 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/indexendpoint_locations_mock_test.go @@ -0,0 +1,55 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createIndexendpointLocations(gsrv *grpc.Server) error { + fakeServer := &fakeIndexendpointLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeIndexendpointLocationsRelationsServer{} + aiplatformpb.RegisterIndexEndpointServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeIndexendpointLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeIndexendpointLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestIndexendpointLocations(t *testing.T) { + client.MockTestGrpcHelper(t, IndexendpointLocations(), createIndexendpointLocations, client.TestOptions{}) +} + +type fakeIndexendpointLocationsRelationsServer struct { + aiplatformpb.UnimplementedIndexEndpointServiceServer +} + +func (f *fakeIndexendpointLocationsRelationsServer) ListIndexEndpoints(context.Context, *aiplatformpb.ListIndexEndpointsRequest) (*aiplatformpb.ListIndexEndpointsResponse, error) { + resp := aiplatformpb.ListIndexEndpointsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/indexes.go b/plugins/source/gcp/resources/services/aiplatform/indexes.go new file mode 100644 index 00000000000..43e18b7c375 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/indexes.go @@ -0,0 +1,134 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func Indexes() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_indexes", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.indexes#Index`, + Resolver: fetchIndexes, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "metadata_schema_uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("MetadataSchemaUri"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + IgnoreInTests: true, + }, + { + Name: "deployed_indexes", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("DeployedIndexes"), + }, + { + Name: "etag", + Type: schema.TypeString, + Resolver: schema.PathResolver("Etag"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "index_stats", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("IndexStats"), + }, + { + Name: "index_update_method", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("IndexUpdateMethod"), + }, + }, + } +} + +func fetchIndexes(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListIndexesRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterIndexesLocations(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewIndexClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListIndexes(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/job_locations.go b/plugins/source/gcp/resources/services/aiplatform/job_locations.go new file mode 100644 index 00000000000..046951065a5 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/job_locations.go @@ -0,0 +1,101 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func JobLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_job_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchJobLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + BatchPredictionJobs(), + CustomJobs(), + DataLabelingJobs(), + HyperparameterTuningJobs(), + ModelDeploymentMonitoringJobs(), + }, + } +} + +func fetchJobLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewJobClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/job_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/job_locations_mock_test.go new file mode 100644 index 00000000000..2351544e454 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/job_locations_mock_test.go @@ -0,0 +1,91 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createJobLocations(gsrv *grpc.Server) error { + fakeServer := &fakeJobLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeJobLocationsRelationsServer{} + aiplatformpb.RegisterJobServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeJobLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeJobLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestJobLocations(t *testing.T) { + client.MockTestGrpcHelper(t, JobLocations(), createJobLocations, client.TestOptions{}) +} + +type fakeJobLocationsRelationsServer struct { + aiplatformpb.UnimplementedJobServiceServer +} + +func (f *fakeJobLocationsRelationsServer) ListBatchPredictionJobs(context.Context, *aiplatformpb.ListBatchPredictionJobsRequest) (*aiplatformpb.ListBatchPredictionJobsResponse, error) { + resp := aiplatformpb.ListBatchPredictionJobsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeJobLocationsRelationsServer) ListCustomJobs(context.Context, *aiplatformpb.ListCustomJobsRequest) (*aiplatformpb.ListCustomJobsResponse, error) { + resp := aiplatformpb.ListCustomJobsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeJobLocationsRelationsServer) ListDataLabelingJobs(context.Context, *aiplatformpb.ListDataLabelingJobsRequest) (*aiplatformpb.ListDataLabelingJobsResponse, error) { + resp := aiplatformpb.ListDataLabelingJobsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeJobLocationsRelationsServer) ListHyperparameterTuningJobs(context.Context, *aiplatformpb.ListHyperparameterTuningJobsRequest) (*aiplatformpb.ListHyperparameterTuningJobsResponse, error) { + resp := aiplatformpb.ListHyperparameterTuningJobsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeJobLocationsRelationsServer) ListModelDeploymentMonitoringJobs(context.Context, *aiplatformpb.ListModelDeploymentMonitoringJobsRequest) (*aiplatformpb.ListModelDeploymentMonitoringJobsResponse, error) { + resp := aiplatformpb.ListModelDeploymentMonitoringJobsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/location_filters.go b/plugins/source/gcp/resources/services/aiplatform/location_filters.go new file mode 100644 index 00000000000..412654074c2 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/location_filters.go @@ -0,0 +1,36 @@ +package aiplatform + +import ( + "github.com/cloudquery/plugin-sdk/schema" + "google.golang.org/genproto/googleapis/cloud/location" +) + +func filterLocation(parent *schema.Resource) bool { + locationId := parent.Item.(*location.Location).LocationId + // ListLocations return these, but they don't map to a valid endpoint from https://cloud.google.com/vertex-ai/docs/reference/rest + return locationId == "us" || locationId == "eu" +} + +func filterStudiesLocation(parent *schema.Resource) bool { + if filterLocation(parent) { + return true + } + locationId := parent.Item.(*location.Location).LocationId + // The endpoints for these locations return 503 status code + toFilter := []string{"asia-southeast2", "europe-central2", "me-west1", "us-south1", "us-west3"} + for _, f := range toFilter { + if locationId == f { + return true + } + } + return false +} + +func filterIndexesLocations(parent *schema.Resource) bool { + if filterLocation(parent) { + return true + } + locationId := parent.Item.(*location.Location).LocationId + // This locations returns `FailedPrecondition desc = Matching Engine is not supported in region europe-west4` + return locationId == "europe-west4" +} diff --git a/plugins/source/gcp/resources/services/aiplatform/metadata_locations.go b/plugins/source/gcp/resources/services/aiplatform/metadata_locations.go new file mode 100644 index 00000000000..796a0168319 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/metadata_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func MetadataLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_metadata_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchMetadataLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + MetadataStores(), + }, + } +} + +func fetchMetadataLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewMetadataClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/metadata_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/metadata_locations_mock_test.go new file mode 100644 index 00000000000..31437822d41 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/metadata_locations_mock_test.go @@ -0,0 +1,91 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createMetadataLocations(gsrv *grpc.Server) error { + fakeServer := &fakeMetadataLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeMetadataLocationsRelationsServer{} + aiplatformpb.RegisterMetadataServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeMetadataLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeMetadataLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestMetadataLocations(t *testing.T) { + client.MockTestGrpcHelper(t, MetadataLocations(), createMetadataLocations, client.TestOptions{}) +} + +type fakeMetadataLocationsRelationsServer struct { + aiplatformpb.UnimplementedMetadataServiceServer +} + +func (f *fakeMetadataLocationsRelationsServer) ListArtifacts(context.Context, *aiplatformpb.ListArtifactsRequest) (*aiplatformpb.ListArtifactsResponse, error) { + resp := aiplatformpb.ListArtifactsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeMetadataLocationsRelationsServer) ListContexts(context.Context, *aiplatformpb.ListContextsRequest) (*aiplatformpb.ListContextsResponse, error) { + resp := aiplatformpb.ListContextsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeMetadataLocationsRelationsServer) ListExecutions(context.Context, *aiplatformpb.ListExecutionsRequest) (*aiplatformpb.ListExecutionsResponse, error) { + resp := aiplatformpb.ListExecutionsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeMetadataLocationsRelationsServer) ListMetadataSchemas(context.Context, *aiplatformpb.ListMetadataSchemasRequest) (*aiplatformpb.ListMetadataSchemasResponse, error) { + resp := aiplatformpb.ListMetadataSchemasResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeMetadataLocationsRelationsServer) ListMetadataStores(context.Context, *aiplatformpb.ListMetadataStoresRequest) (*aiplatformpb.ListMetadataStoresResponse, error) { + resp := aiplatformpb.ListMetadataStoresResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/metadata_stores.go b/plugins/source/gcp/resources/services/aiplatform/metadata_stores.go new file mode 100644 index 00000000000..af19e30cae7 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/metadata_stores.go @@ -0,0 +1,103 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func MetadataStores() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_metadata_stores", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.metadataStores#MetadataStore`, + Resolver: fetchMetadataStores, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "state", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("State"), + }, + }, + } +} + +func fetchMetadataStores(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListMetadataStoresRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewMetadataClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListMetadataStores(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/model_deployment_monitoring_jobs.go b/plugins/source/gcp/resources/services/aiplatform/model_deployment_monitoring_jobs.go new file mode 100644 index 00000000000..6ee947da17f --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/model_deployment_monitoring_jobs.go @@ -0,0 +1,189 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func ModelDeploymentMonitoringJobs() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_model_deployment_monitoring_jobs", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.modelDeploymentMonitoringJobs#ModelDeploymentMonitoringJob`, + Resolver: fetchModelDeploymentMonitoringJobs, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "endpoint", + Type: schema.TypeString, + Resolver: schema.PathResolver("Endpoint"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "schedule_state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("ScheduleState"), + }, + { + Name: "latest_monitoring_pipeline_metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("LatestMonitoringPipelineMetadata"), + }, + { + Name: "model_deployment_monitoring_objective_configs", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ModelDeploymentMonitoringObjectiveConfigs"), + }, + { + Name: "model_deployment_monitoring_schedule_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ModelDeploymentMonitoringScheduleConfig"), + }, + { + Name: "logging_sampling_strategy", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("LoggingSamplingStrategy"), + }, + { + Name: "model_monitoring_alert_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ModelMonitoringAlertConfig"), + }, + { + Name: "predict_instance_schema_uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("PredictInstanceSchemaUri"), + }, + { + Name: "sample_predict_instance", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("SamplePredictInstance"), + IgnoreInTests: true, + }, + { + Name: "analysis_instance_schema_uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("AnalysisInstanceSchemaUri"), + }, + { + Name: "bigquery_tables", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("BigqueryTables"), + }, + { + Name: "log_ttl", + Type: schema.TypeInt, + Resolver: client.ResolveProtoDuration("LogTtl"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "next_schedule_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("NextScheduleTime"), + }, + { + Name: "stats_anomalies_base_directory", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("StatsAnomaliesBaseDirectory"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + { + Name: "enable_monitoring_pipeline_logs", + Type: schema.TypeBool, + Resolver: schema.PathResolver("EnableMonitoringPipelineLogs"), + }, + { + Name: "error", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Error"), + }, + }, + } +} + +func fetchModelDeploymentMonitoringJobs(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListModelDeploymentMonitoringJobsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewJobClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListModelDeploymentMonitoringJobs(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/model_locations.go b/plugins/source/gcp/resources/services/aiplatform/model_locations.go new file mode 100644 index 00000000000..c6c5afa2bf2 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/model_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func ModelLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_model_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchModelLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + Models(), + }, + } +} + +func fetchModelLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewModelClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/model_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/model_locations_mock_test.go new file mode 100644 index 00000000000..3101df295aa --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/model_locations_mock_test.go @@ -0,0 +1,82 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createModelLocations(gsrv *grpc.Server) error { + fakeServer := &fakeModelLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeModelLocationsRelationsServer{} + aiplatformpb.RegisterModelServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeModelLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeModelLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestModelLocations(t *testing.T) { + client.MockTestGrpcHelper(t, ModelLocations(), createModelLocations, client.TestOptions{}) +} + +type fakeModelLocationsRelationsServer struct { + aiplatformpb.UnimplementedModelServiceServer +} + +func (f *fakeModelLocationsRelationsServer) ListModelEvaluationSlices(context.Context, *aiplatformpb.ListModelEvaluationSlicesRequest) (*aiplatformpb.ListModelEvaluationSlicesResponse, error) { + resp := aiplatformpb.ListModelEvaluationSlicesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeModelLocationsRelationsServer) ListModelEvaluations(context.Context, *aiplatformpb.ListModelEvaluationsRequest) (*aiplatformpb.ListModelEvaluationsResponse, error) { + resp := aiplatformpb.ListModelEvaluationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeModelLocationsRelationsServer) ListModelVersions(context.Context, *aiplatformpb.ListModelVersionsRequest) (*aiplatformpb.ListModelVersionsResponse, error) { + resp := aiplatformpb.ListModelVersionsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeModelLocationsRelationsServer) ListModels(context.Context, *aiplatformpb.ListModelsRequest) (*aiplatformpb.ListModelsResponse, error) { + resp := aiplatformpb.ListModelsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/models.go b/plugins/source/gcp/resources/services/aiplatform/models.go new file mode 100644 index 00000000000..1bca8027957 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/models.go @@ -0,0 +1,209 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func Models() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_models", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.models#Model`, + Resolver: fetchModels, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "version_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("VersionId"), + }, + { + Name: "version_aliases", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("VersionAliases"), + }, + { + Name: "version_create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("VersionCreateTime"), + }, + { + Name: "version_update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("VersionUpdateTime"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "version_description", + Type: schema.TypeString, + Resolver: schema.PathResolver("VersionDescription"), + }, + { + Name: "predict_schemata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("PredictSchemata"), + }, + { + Name: "metadata_schema_uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("MetadataSchemaUri"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + IgnoreInTests: true, + }, + { + Name: "supported_export_formats", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("SupportedExportFormats"), + }, + { + Name: "training_pipeline", + Type: schema.TypeString, + Resolver: schema.PathResolver("TrainingPipeline"), + }, + { + Name: "container_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ContainerSpec"), + }, + { + Name: "artifact_uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("ArtifactUri"), + }, + { + Name: "supported_deployment_resources_types", + Type: schema.TypeIntArray, + Resolver: schema.PathResolver("SupportedDeploymentResourcesTypes"), + }, + { + Name: "supported_input_storage_formats", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("SupportedInputStorageFormats"), + }, + { + Name: "supported_output_storage_formats", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("SupportedOutputStorageFormats"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "deployed_models", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("DeployedModels"), + }, + { + Name: "explanation_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ExplanationSpec"), + }, + { + Name: "etag", + Type: schema.TypeString, + Resolver: schema.PathResolver("Etag"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + { + Name: "model_source_info", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ModelSourceInfo"), + }, + { + Name: "metadata_artifact", + Type: schema.TypeString, + Resolver: schema.PathResolver("MetadataArtifact"), + }, + }, + } +} + +func fetchModels(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListModelsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewModelClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListModels(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/operations.go b/plugins/source/gcp/resources/services/aiplatform/operations.go new file mode 100644 index 00000000000..21fa20ac211 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/operations.go @@ -0,0 +1,83 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/longrunning/autogen/longrunningpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func Operations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_operations", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.operations#Operation`, + Resolver: fetchOperations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + { + Name: "done", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Done"), + }, + }, + } +} + +func fetchOperations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListOperationsRequest{ + Name: "projects/" + c.ProjectId + "/locations/-", + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewPipelineClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListOperations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/operations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/operations_mock_test.go new file mode 100644 index 00000000000..e375a56fb92 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/operations_mock_test.go @@ -0,0 +1,37 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "cloud.google.com/go/longrunning/autogen/longrunningpb" +) + +func createOperations(gsrv *grpc.Server) error { + fakeServer := &fakeOperationsServer{} + pb.RegisterOperationsServer(gsrv, fakeServer) + return nil +} + +type fakeOperationsServer struct { + pb.UnimplementedOperationsServer +} + +func (f *fakeOperationsServer) ListOperations(context.Context, *pb.ListOperationsRequest) (*pb.ListOperationsResponse, error) { + resp := pb.ListOperationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestOperations(t *testing.T) { + client.MockTestGrpcHelper(t, Operations(), createOperations, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/aiplatform/pipeline_jobs.go b/plugins/source/gcp/resources/services/aiplatform/pipeline_jobs.go new file mode 100644 index 00000000000..578767f4dff --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/pipeline_jobs.go @@ -0,0 +1,160 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func PipelineJobs() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_pipeline_jobs", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.pipelineJobs#PipelineJob`, + Resolver: fetchPipelineJobs, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "start_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("StartTime"), + }, + { + Name: "end_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("EndTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "pipeline_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("PipelineSpec"), + IgnoreInTests: true, + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "job_detail", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("JobDetail"), + }, + { + Name: "error", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Error"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "runtime_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("RuntimeConfig"), + IgnoreInTests: true, + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + { + Name: "service_account", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceAccount"), + }, + { + Name: "network", + Type: schema.TypeString, + Resolver: schema.PathResolver("Network"), + }, + { + Name: "template_uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("TemplateUri"), + }, + { + Name: "template_metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("TemplateMetadata"), + }, + }, + } +} + +func fetchPipelineJobs(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListPipelineJobsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewPipelineClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListPipelineJobs(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/pipeline_locations.go b/plugins/source/gcp/resources/services/aiplatform/pipeline_locations.go new file mode 100644 index 00000000000..ac5735efa3d --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/pipeline_locations.go @@ -0,0 +1,98 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func PipelineLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_pipeline_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchPipelineLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + PipelineJobs(), + TrainingPipelines(), + }, + } +} + +func fetchPipelineLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewPipelineClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/pipeline_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/pipeline_locations_mock_test.go new file mode 100644 index 00000000000..6d30b2ad05b --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/pipeline_locations_mock_test.go @@ -0,0 +1,64 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createPipelineLocations(gsrv *grpc.Server) error { + fakeServer := &fakePipelineLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakePipelineLocationsRelationsServer{} + aiplatformpb.RegisterPipelineServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakePipelineLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakePipelineLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestPipelineLocations(t *testing.T) { + client.MockTestGrpcHelper(t, PipelineLocations(), createPipelineLocations, client.TestOptions{}) +} + +type fakePipelineLocationsRelationsServer struct { + aiplatformpb.UnimplementedPipelineServiceServer +} + +func (f *fakePipelineLocationsRelationsServer) ListPipelineJobs(context.Context, *aiplatformpb.ListPipelineJobsRequest) (*aiplatformpb.ListPipelineJobsResponse, error) { + resp := aiplatformpb.ListPipelineJobsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakePipelineLocationsRelationsServer) ListTrainingPipelines(context.Context, *aiplatformpb.ListTrainingPipelinesRequest) (*aiplatformpb.ListTrainingPipelinesResponse, error) { + resp := aiplatformpb.ListTrainingPipelinesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/specialist_pools.go b/plugins/source/gcp/resources/services/aiplatform/specialist_pools.go new file mode 100644 index 00000000000..c3c82824f5f --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/specialist_pools.go @@ -0,0 +1,103 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func SpecialistPools() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_specialist_pools", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.specialistPools#SpecialistPool`, + Resolver: fetchSpecialistPools, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "specialist_managers_count", + Type: schema.TypeInt, + Resolver: schema.PathResolver("SpecialistManagersCount"), + }, + { + Name: "specialist_manager_emails", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("SpecialistManagerEmails"), + }, + { + Name: "pending_data_labeling_jobs", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("PendingDataLabelingJobs"), + }, + { + Name: "specialist_worker_emails", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("SpecialistWorkerEmails"), + }, + }, + } +} + +func fetchSpecialistPools(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListSpecialistPoolsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewSpecialistPoolClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListSpecialistPools(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/specialistpool_locations.go b/plugins/source/gcp/resources/services/aiplatform/specialistpool_locations.go new file mode 100644 index 00000000000..3343cb82779 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/specialistpool_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func SpecialistpoolLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_specialistpool_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchSpecialistpoolLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + SpecialistPools(), + }, + } +} + +func fetchSpecialistpoolLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewSpecialistPoolClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/specialistpool_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/specialistpool_locations_mock_test.go new file mode 100644 index 00000000000..6731a08be4b --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/specialistpool_locations_mock_test.go @@ -0,0 +1,55 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createSpecialistpoolLocations(gsrv *grpc.Server) error { + fakeServer := &fakeSpecialistpoolLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeSpecialistpoolLocationsRelationsServer{} + aiplatformpb.RegisterSpecialistPoolServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeSpecialistpoolLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeSpecialistpoolLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestSpecialistpoolLocations(t *testing.T) { + client.MockTestGrpcHelper(t, SpecialistpoolLocations(), createSpecialistpoolLocations, client.TestOptions{}) +} + +type fakeSpecialistpoolLocationsRelationsServer struct { + aiplatformpb.UnimplementedSpecialistPoolServiceServer +} + +func (f *fakeSpecialistpoolLocationsRelationsServer) ListSpecialistPools(context.Context, *aiplatformpb.ListSpecialistPoolsRequest) (*aiplatformpb.ListSpecialistPoolsResponse, error) { + resp := aiplatformpb.ListSpecialistPoolsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/studies.go b/plugins/source/gcp/resources/services/aiplatform/studies.go new file mode 100644 index 00000000000..fc2983e5170 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/studies.go @@ -0,0 +1,103 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func Studies() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_studies", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.studies#Study`, + Resolver: fetchStudies, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "study_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("StudySpec"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "inactive_reason", + Type: schema.TypeString, + Resolver: schema.PathResolver("InactiveReason"), + }, + }, + } +} + +func fetchStudies(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListStudiesRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterStudiesLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewVizierClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListStudies(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/tensorboard_locations.go b/plugins/source/gcp/resources/services/aiplatform/tensorboard_locations.go new file mode 100644 index 00000000000..e076556d901 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/tensorboard_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func TensorboardLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_tensorboard_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchTensorboardLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + Tensorboards(), + }, + } +} + +func fetchTensorboardLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewTensorboardClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/tensorboard_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/tensorboard_locations_mock_test.go new file mode 100644 index 00000000000..7d1575c8950 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/tensorboard_locations_mock_test.go @@ -0,0 +1,82 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createTensorboardLocations(gsrv *grpc.Server) error { + fakeServer := &fakeTensorboardLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeTensorboardLocationsRelationsServer{} + aiplatformpb.RegisterTensorboardServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeTensorboardLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeTensorboardLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestTensorboardLocations(t *testing.T) { + client.MockTestGrpcHelper(t, TensorboardLocations(), createTensorboardLocations, client.TestOptions{}) +} + +type fakeTensorboardLocationsRelationsServer struct { + aiplatformpb.UnimplementedTensorboardServiceServer +} + +func (f *fakeTensorboardLocationsRelationsServer) ListTensorboardExperiments(context.Context, *aiplatformpb.ListTensorboardExperimentsRequest) (*aiplatformpb.ListTensorboardExperimentsResponse, error) { + resp := aiplatformpb.ListTensorboardExperimentsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeTensorboardLocationsRelationsServer) ListTensorboardRuns(context.Context, *aiplatformpb.ListTensorboardRunsRequest) (*aiplatformpb.ListTensorboardRunsResponse, error) { + resp := aiplatformpb.ListTensorboardRunsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeTensorboardLocationsRelationsServer) ListTensorboardTimeSeries(context.Context, *aiplatformpb.ListTensorboardTimeSeriesRequest) (*aiplatformpb.ListTensorboardTimeSeriesResponse, error) { + resp := aiplatformpb.ListTensorboardTimeSeriesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeTensorboardLocationsRelationsServer) ListTensorboards(context.Context, *aiplatformpb.ListTensorboardsRequest) (*aiplatformpb.ListTensorboardsResponse, error) { + resp := aiplatformpb.ListTensorboardsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/tensorboards.go b/plugins/source/gcp/resources/services/aiplatform/tensorboards.go new file mode 100644 index 00000000000..48561394381 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/tensorboards.go @@ -0,0 +1,123 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func Tensorboards() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_tensorboards", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.tensorboards#Tensorboard`, + Resolver: fetchTensorboards, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + { + Name: "blob_storage_path_prefix", + Type: schema.TypeString, + Resolver: schema.PathResolver("BlobStoragePathPrefix"), + }, + { + Name: "run_count", + Type: schema.TypeInt, + Resolver: schema.PathResolver("RunCount"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "etag", + Type: schema.TypeString, + Resolver: schema.PathResolver("Etag"), + }, + }, + } +} + +func fetchTensorboards(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListTensorboardsRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewTensorboardClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListTensorboards(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/training_pipelines.go b/plugins/source/gcp/resources/services/aiplatform/training_pipelines.go new file mode 100644 index 00000000000..bc1ebc94908 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/training_pipelines.go @@ -0,0 +1,161 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func TrainingPipelines() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_training_pipelines", + Description: `https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.trainingPipelines#TrainingPipeline`, + Resolver: fetchTrainingPipelines, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "input_data_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("InputDataConfig"), + }, + { + Name: "training_task_definition", + Type: schema.TypeString, + Resolver: schema.PathResolver("TrainingTaskDefinition"), + }, + { + Name: "training_task_inputs", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("TrainingTaskInputs"), + IgnoreInTests: true, + }, + { + Name: "training_task_metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("TrainingTaskMetadata"), + IgnoreInTests: true, + }, + { + Name: "model_to_upload", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ModelToUpload"), + IgnoreInTests: true, + }, + { + Name: "model_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ModelId"), + }, + { + Name: "parent_model", + Type: schema.TypeString, + Resolver: schema.PathResolver("ParentModel"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "error", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Error"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "start_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("StartTime"), + }, + { + Name: "end_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("EndTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "encryption_spec", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EncryptionSpec"), + }, + }, + } +} + +func fetchTrainingPipelines(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListTrainingPipelinesRequest{ + Parent: parent.Item.(*location.Location).Name, + } + if filterLocation(parent) { + return nil + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint(parent.Item.(*location.Location).LocationId + "-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewPipelineClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListTrainingPipelines(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/vizier_locations.go b/plugins/source/gcp/resources/services/aiplatform/vizier_locations.go new file mode 100644 index 00000000000..a9ae559cfbb --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/vizier_locations.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "google.golang.org/api/iterator" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/option" + + "cloud.google.com/go/aiplatform/apiv1" +) + +func VizierLocations() *schema.Table { + return &schema.Table{ + Name: "gcp_aiplatform_vizier_locations", + Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Resolver: fetchVizierLocations, + Multiplex: client.ProjectMultiplexEnabledServices("aiplatform.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + + Relations: []*schema.Table{ + Studies(), + }, + } +} + +func fetchVizierLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLocationsRequest{ + Name: "projects/" + c.ProjectId, + } + + clientOptions := c.ClientOptions + clientOptions = append([]option.ClientOption{option.WithEndpoint("us-central1-aiplatform.googleapis.com:443")}, clientOptions...) + gcpClient, err := aiplatform.NewVizierClient(ctx, clientOptions...) + + if err != nil { + return err + } + it := gcpClient.ListLocations(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/aiplatform/vizier_locations_mock_test.go b/plugins/source/gcp/resources/services/aiplatform/vizier_locations_mock_test.go new file mode 100644 index 00000000000..3d7b22077a8 --- /dev/null +++ b/plugins/source/gcp/resources/services/aiplatform/vizier_locations_mock_test.go @@ -0,0 +1,64 @@ +// Code generated by codegen; DO NOT EDIT. + +package aiplatform + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "google.golang.org/genproto/googleapis/cloud/location" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" +) + +func createVizierLocations(gsrv *grpc.Server) error { + fakeServer := &fakeVizierLocationsServer{} + pb.RegisterLocationsServer(gsrv, fakeServer) + fakeRelationsServer := &fakeVizierLocationsRelationsServer{} + aiplatformpb.RegisterVizierServiceServer(gsrv, fakeRelationsServer) + + return nil +} + +type fakeVizierLocationsServer struct { + pb.UnimplementedLocationsServer +} + +func (f *fakeVizierLocationsServer) ListLocations(context.Context, *pb.ListLocationsRequest) (*pb.ListLocationsResponse, error) { + resp := pb.ListLocationsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestVizierLocations(t *testing.T) { + client.MockTestGrpcHelper(t, VizierLocations(), createVizierLocations, client.TestOptions{}) +} + +type fakeVizierLocationsRelationsServer struct { + aiplatformpb.UnimplementedVizierServiceServer +} + +func (f *fakeVizierLocationsRelationsServer) ListStudies(context.Context, *aiplatformpb.ListStudiesRequest) (*aiplatformpb.ListStudiesResponse, error) { + resp := aiplatformpb.ListStudiesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (f *fakeVizierLocationsRelationsServer) ListTrials(context.Context, *aiplatformpb.ListTrialsRequest) (*aiplatformpb.ListTrialsResponse, error) { + resp := aiplatformpb.ListTrialsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} diff --git a/plugins/source/gcp/resources/services/appengine/apps.go b/plugins/source/gcp/resources/services/appengine/apps.go new file mode 100644 index 00000000000..b025d4c1b56 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/apps.go @@ -0,0 +1,105 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" +) + +func Apps() *schema.Table { + return &schema.Table{ + Name: "gcp_appengine_apps", + Description: `https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps#Application`, + Resolver: fetchApps, + Multiplex: client.ProjectMultiplexEnabledServices("appengine.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "dispatch_rules", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("DispatchRules"), + }, + { + Name: "auth_domain", + Type: schema.TypeString, + Resolver: schema.PathResolver("AuthDomain"), + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "code_bucket", + Type: schema.TypeString, + Resolver: schema.PathResolver("CodeBucket"), + }, + { + Name: "default_cookie_expiration", + Type: schema.TypeInt, + Resolver: client.ResolveProtoDuration("DefaultCookieExpiration"), + }, + { + Name: "serving_status", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("ServingStatus"), + }, + { + Name: "default_hostname", + Type: schema.TypeString, + Resolver: schema.PathResolver("DefaultHostname"), + }, + { + Name: "default_bucket", + Type: schema.TypeString, + Resolver: schema.PathResolver("DefaultBucket"), + }, + { + Name: "service_account", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceAccount"), + }, + { + Name: "iap", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Iap"), + }, + { + Name: "gcr_domain", + Type: schema.TypeString, + Resolver: schema.PathResolver("GcrDomain"), + }, + { + Name: "database_type", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("DatabaseType"), + }, + { + Name: "feature_settings", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("FeatureSettings"), + }, + }, + } +} diff --git a/plugins/source/gcp/resources/services/appengine/apps_fetch.go b/plugins/source/gcp/resources/services/appengine/apps_fetch.go new file mode 100644 index 00000000000..41e92f7ccc6 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/apps_fetch.go @@ -0,0 +1,30 @@ +package appengine + +import ( + "context" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + appengine "cloud.google.com/go/appengine/apiv1" +) + +func fetchApps(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.GetApplicationRequest{ + Name: "apps/" + c.ProjectId, + } + gcpClient, err := appengine.NewApplicationsClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + resp, err := gcpClient.GetApplication(ctx, req, c.CallOptions...) + if err != nil { + return err + } + res <- resp + + return nil +} diff --git a/plugins/source/gcp/resources/services/appengine/apps_mock_test.go b/plugins/source/gcp/resources/services/appengine/apps_mock_test.go new file mode 100644 index 00000000000..eef1a5481dd --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/apps_mock_test.go @@ -0,0 +1,35 @@ +package appengine + +import ( + "context" + "fmt" + "testing" + + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" +) + +func createApps(gsrv *grpc.Server) error { + fakeServer := &fakeAppsServer{} + pb.RegisterApplicationsServer(gsrv, fakeServer) + return nil +} + +type fakeAppsServer struct { + pb.UnimplementedApplicationsServer +} + +func (*fakeAppsServer) GetApplication(context.Context, *pb.GetApplicationRequest) (*pb.Application, error) { + resp := pb.Application{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + return &resp, nil +} + +func TestApps(t *testing.T) { + client.MockTestGrpcHelper(t, Apps(), createApps, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/appengine/authorized_certificates.go b/plugins/source/gcp/resources/services/appengine/authorized_certificates.go new file mode 100644 index 00000000000..380239b9161 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/authorized_certificates.go @@ -0,0 +1,107 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/appengine/apiv1" +) + +func AuthorizedCertificates() *schema.Table { + return &schema.Table{ + Name: "gcp_appengine_authorized_certificates", + Description: `https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.authorizedCertificates#AuthorizedCertificate`, + Resolver: fetchAuthorizedCertificates, + Multiplex: client.ProjectMultiplexEnabledServices("appengine.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "domain_names", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("DomainNames"), + }, + { + Name: "expire_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("ExpireTime"), + }, + { + Name: "certificate_raw_data", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("CertificateRawData"), + }, + { + Name: "managed_certificate", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ManagedCertificate"), + }, + { + Name: "visible_domain_mappings", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("VisibleDomainMappings"), + }, + { + Name: "domain_mappings_count", + Type: schema.TypeInt, + Resolver: schema.PathResolver("DomainMappingsCount"), + }, + }, + } +} + +func fetchAuthorizedCertificates(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListAuthorizedCertificatesRequest{ + Parent: "apps/" + c.ProjectId, + } + gcpClient, err := appengine.NewAuthorizedCertificatesClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListAuthorizedCertificates(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/appengine/authorized_certificates_mock_test.go b/plugins/source/gcp/resources/services/appengine/authorized_certificates_mock_test.go new file mode 100644 index 00000000000..24b10f0ddb4 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/authorized_certificates_mock_test.go @@ -0,0 +1,37 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" +) + +func createAuthorizedCertificates(gsrv *grpc.Server) error { + fakeServer := &fakeAuthorizedCertificatesServer{} + pb.RegisterAuthorizedCertificatesServer(gsrv, fakeServer) + return nil +} + +type fakeAuthorizedCertificatesServer struct { + pb.UnimplementedAuthorizedCertificatesServer +} + +func (f *fakeAuthorizedCertificatesServer) ListAuthorizedCertificates(context.Context, *pb.ListAuthorizedCertificatesRequest) (*pb.ListAuthorizedCertificatesResponse, error) { + resp := pb.ListAuthorizedCertificatesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestAuthorizedCertificates(t *testing.T) { + client.MockTestGrpcHelper(t, AuthorizedCertificates(), createAuthorizedCertificates, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/appengine/authorized_domains.go b/plugins/source/gcp/resources/services/appengine/authorized_domains.go new file mode 100644 index 00000000000..b13da0da679 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/authorized_domains.go @@ -0,0 +1,72 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/appengine/apiv1" +) + +func AuthorizedDomains() *schema.Table { + return &schema.Table{ + Name: "gcp_appengine_authorized_domains", + Description: `https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.authorizedDomains#AuthorizedDomain`, + Resolver: fetchAuthorizedDomains, + Multiplex: client.ProjectMultiplexEnabledServices("appengine.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + }, + } +} + +func fetchAuthorizedDomains(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListAuthorizedDomainsRequest{ + Parent: "apps/" + c.ProjectId, + } + gcpClient, err := appengine.NewAuthorizedDomainsClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListAuthorizedDomains(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/appengine/authorized_domains_mock_test.go b/plugins/source/gcp/resources/services/appengine/authorized_domains_mock_test.go new file mode 100644 index 00000000000..31c2bf2bf57 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/authorized_domains_mock_test.go @@ -0,0 +1,37 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" +) + +func createAuthorizedDomains(gsrv *grpc.Server) error { + fakeServer := &fakeAuthorizedDomainsServer{} + pb.RegisterAuthorizedDomainsServer(gsrv, fakeServer) + return nil +} + +type fakeAuthorizedDomainsServer struct { + pb.UnimplementedAuthorizedDomainsServer +} + +func (f *fakeAuthorizedDomainsServer) ListAuthorizedDomains(context.Context, *pb.ListAuthorizedDomainsRequest) (*pb.ListAuthorizedDomainsResponse, error) { + resp := pb.ListAuthorizedDomainsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestAuthorizedDomains(t *testing.T) { + client.MockTestGrpcHelper(t, AuthorizedDomains(), createAuthorizedDomains, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/appengine/domain_mappings.go b/plugins/source/gcp/resources/services/appengine/domain_mappings.go new file mode 100644 index 00000000000..1dba3d15541 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/domain_mappings.go @@ -0,0 +1,82 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/appengine/apiv1" +) + +func DomainMappings() *schema.Table { + return &schema.Table{ + Name: "gcp_appengine_domain_mappings", + Description: `https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.domainMappings#DomainMapping`, + Resolver: fetchDomainMappings, + Multiplex: client.ProjectMultiplexEnabledServices("appengine.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "ssl_settings", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("SslSettings"), + }, + { + Name: "resource_records", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ResourceRecords"), + }, + }, + } +} + +func fetchDomainMappings(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListDomainMappingsRequest{ + Parent: "apps/" + c.ProjectId, + } + gcpClient, err := appengine.NewDomainMappingsClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListDomainMappings(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/appengine/domain_mappings_mock_test.go b/plugins/source/gcp/resources/services/appengine/domain_mappings_mock_test.go new file mode 100644 index 00000000000..25d61b5fe4a --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/domain_mappings_mock_test.go @@ -0,0 +1,37 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" +) + +func createDomainMappings(gsrv *grpc.Server) error { + fakeServer := &fakeDomainMappingsServer{} + pb.RegisterDomainMappingsServer(gsrv, fakeServer) + return nil +} + +type fakeDomainMappingsServer struct { + pb.UnimplementedDomainMappingsServer +} + +func (f *fakeDomainMappingsServer) ListDomainMappings(context.Context, *pb.ListDomainMappingsRequest) (*pb.ListDomainMappingsResponse, error) { + resp := pb.ListDomainMappingsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestDomainMappings(t *testing.T) { + client.MockTestGrpcHelper(t, DomainMappings(), createDomainMappings, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/appengine/firewall_ingress_rules.go b/plugins/source/gcp/resources/services/appengine/firewall_ingress_rules.go new file mode 100644 index 00000000000..124aaacd3b2 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/firewall_ingress_rules.go @@ -0,0 +1,79 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/appengine/apiv1" +) + +func FirewallIngressRules() *schema.Table { + return &schema.Table{ + Name: "gcp_appengine_firewall_ingress_rules", + Description: `https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.firewall.ingressRules#FirewallRule`, + Resolver: fetchFirewallIngressRules, + Multiplex: client.ProjectMultiplexEnabledServices("appengine.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "priority", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Priority"), + }, + { + Name: "action", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("Action"), + }, + { + Name: "source_range", + Type: schema.TypeString, + Resolver: schema.PathResolver("SourceRange"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + }, + } +} + +func fetchFirewallIngressRules(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListIngressRulesRequest{ + Parent: "apps/" + c.ProjectId, + } + gcpClient, err := appengine.NewFirewallClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListIngressRules(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/appengine/firewall_ingress_rules_mock_test.go b/plugins/source/gcp/resources/services/appengine/firewall_ingress_rules_mock_test.go new file mode 100644 index 00000000000..49483d6d74c --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/firewall_ingress_rules_mock_test.go @@ -0,0 +1,37 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" +) + +func createFirewallIngressRules(gsrv *grpc.Server) error { + fakeServer := &fakeFirewallIngressRulesServer{} + pb.RegisterFirewallServer(gsrv, fakeServer) + return nil +} + +type fakeFirewallIngressRulesServer struct { + pb.UnimplementedFirewallServer +} + +func (f *fakeFirewallIngressRulesServer) ListIngressRules(context.Context, *pb.ListIngressRulesRequest) (*pb.ListIngressRulesResponse, error) { + resp := pb.ListIngressRulesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestFirewallIngressRules(t *testing.T) { + client.MockTestGrpcHelper(t, FirewallIngressRules(), createFirewallIngressRules, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/appengine/instances.go b/plugins/source/gcp/resources/services/appengine/instances.go new file mode 100644 index 00000000000..7342e04b694 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/instances.go @@ -0,0 +1,147 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/appengine/apiv1" +) + +func Instances() *schema.Table { + return &schema.Table{ + Name: "gcp_appengine_instances", + Description: `https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions.instances#Instance`, + Resolver: fetchInstances, + Multiplex: client.ProjectMultiplexEnabledServices("appengine.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "app_engine_release", + Type: schema.TypeString, + Resolver: schema.PathResolver("AppEngineRelease"), + }, + { + Name: "availability", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("Availability"), + }, + { + Name: "vm_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("VmName"), + }, + { + Name: "vm_zone_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("VmZoneName"), + }, + { + Name: "vm_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("VmId"), + }, + { + Name: "start_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("StartTime"), + }, + { + Name: "requests", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Requests"), + }, + { + Name: "errors", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Errors"), + }, + { + Name: "qps", + Type: schema.TypeFloat, + Resolver: schema.PathResolver("Qps"), + }, + { + Name: "average_latency", + Type: schema.TypeInt, + Resolver: schema.PathResolver("AverageLatency"), + }, + { + Name: "memory_usage", + Type: schema.TypeInt, + Resolver: schema.PathResolver("MemoryUsage"), + }, + { + Name: "vm_status", + Type: schema.TypeString, + Resolver: schema.PathResolver("VmStatus"), + }, + { + Name: "vm_debug_enabled", + Type: schema.TypeBool, + Resolver: schema.PathResolver("VmDebugEnabled"), + }, + { + Name: "vm_ip", + Type: schema.TypeString, + Resolver: schema.PathResolver("VmIp"), + }, + { + Name: "vm_liveness", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("VmLiveness"), + }, + }, + } +} + +func fetchInstances(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListInstancesRequest{ + Parent: parent.Item.(*pb.Version).Name, + } + gcpClient, err := appengine.NewInstancesClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListInstances(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/appengine/services.go b/plugins/source/gcp/resources/services/appengine/services.go new file mode 100644 index 00000000000..6b37b459f63 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/services.go @@ -0,0 +1,91 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/appengine/apiv1" +) + +func Services() *schema.Table { + return &schema.Table{ + Name: "gcp_appengine_services", + Description: `https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services#Service`, + Resolver: fetchServices, + Multiplex: client.ProjectMultiplexEnabledServices("appengine.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "split", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Split"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "network_settings", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("NetworkSettings"), + }, + }, + + Relations: []*schema.Table{ + Versions(), + }, + } +} + +func fetchServices(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListServicesRequest{ + Parent: "apps/" + c.ProjectId, + } + gcpClient, err := appengine.NewServicesClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListServices(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/appengine/services_mock_test.go b/plugins/source/gcp/resources/services/appengine/services_mock_test.go new file mode 100644 index 00000000000..577ab26ec91 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/services_mock_test.go @@ -0,0 +1,63 @@ +package appengine + +import ( + "context" + "fmt" + "testing" + + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" +) + +func createServices(gsrv *grpc.Server) error { + pb.RegisterServicesServer(gsrv, &fakeServicesServer{}) + pb.RegisterVersionsServer(gsrv, &fakeVersionsServer{}) + pb.RegisterInstancesServer(gsrv, &fakeInstancesServer{}) + return nil +} + +type fakeServicesServer struct { + pb.UnimplementedServicesServer +} + +func (*fakeServicesServer) ListServices(context.Context, *pb.ListServicesRequest) (*pb.ListServicesResponse, error) { + resp := pb.ListServicesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +type fakeVersionsServer struct { + pb.UnimplementedVersionsServer +} + +func (*fakeVersionsServer) ListVersions(context.Context, *pb.ListVersionsRequest) (*pb.ListVersionsResponse, error) { + resp := pb.ListVersionsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +type fakeInstancesServer struct { + pb.UnimplementedInstancesServer +} + +func (*fakeInstancesServer) ListInstances(context.Context, *pb.ListInstancesRequest) (*pb.ListInstancesResponse, error) { + resp := pb.ListInstancesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestServices(t *testing.T) { + client.MockTestGrpcHelper(t, Services(), createServices, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/appengine/versions.go b/plugins/source/gcp/resources/services/appengine/versions.go new file mode 100644 index 00000000000..2afbce3d751 --- /dev/null +++ b/plugins/source/gcp/resources/services/appengine/versions.go @@ -0,0 +1,251 @@ +// Code generated by codegen; DO NOT EDIT. + +package appengine + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/appengine/apiv1/appenginepb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/appengine/apiv1" +) + +func Versions() *schema.Table { + return &schema.Table{ + Name: "gcp_appengine_versions", + Description: `https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions#Version`, + Resolver: fetchVersions, + Multiplex: client.ProjectMultiplexEnabledServices("appengine.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "inbound_services", + Type: schema.TypeIntArray, + Resolver: schema.PathResolver("InboundServices"), + }, + { + Name: "instance_class", + Type: schema.TypeString, + Resolver: schema.PathResolver("InstanceClass"), + }, + { + Name: "network", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Network"), + }, + { + Name: "zones", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("Zones"), + }, + { + Name: "resources", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Resources"), + }, + { + Name: "runtime", + Type: schema.TypeString, + Resolver: schema.PathResolver("Runtime"), + }, + { + Name: "runtime_channel", + Type: schema.TypeString, + Resolver: schema.PathResolver("RuntimeChannel"), + }, + { + Name: "threadsafe", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Threadsafe"), + }, + { + Name: "vm", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Vm"), + }, + { + Name: "app_engine_apis", + Type: schema.TypeBool, + Resolver: schema.PathResolver("AppEngineApis"), + }, + { + Name: "beta_settings", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("BetaSettings"), + }, + { + Name: "env", + Type: schema.TypeString, + Resolver: schema.PathResolver("Env"), + }, + { + Name: "serving_status", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("ServingStatus"), + }, + { + Name: "created_by", + Type: schema.TypeString, + Resolver: schema.PathResolver("CreatedBy"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "disk_usage_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("DiskUsageBytes"), + }, + { + Name: "runtime_api_version", + Type: schema.TypeString, + Resolver: schema.PathResolver("RuntimeApiVersion"), + }, + { + Name: "runtime_main_executable_path", + Type: schema.TypeString, + Resolver: schema.PathResolver("RuntimeMainExecutablePath"), + }, + { + Name: "service_account", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServiceAccount"), + }, + { + Name: "handlers", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Handlers"), + }, + { + Name: "error_handlers", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ErrorHandlers"), + }, + { + Name: "libraries", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Libraries"), + }, + { + Name: "api_config", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ApiConfig"), + }, + { + Name: "env_variables", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EnvVariables"), + }, + { + Name: "build_env_variables", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("BuildEnvVariables"), + }, + { + Name: "default_expiration", + Type: schema.TypeInt, + Resolver: client.ResolveProtoDuration("DefaultExpiration"), + }, + { + Name: "health_check", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("HealthCheck"), + }, + { + Name: "readiness_check", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ReadinessCheck"), + }, + { + Name: "liveness_check", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("LivenessCheck"), + }, + { + Name: "nobuild_files_regex", + Type: schema.TypeString, + Resolver: schema.PathResolver("NobuildFilesRegex"), + }, + { + Name: "deployment", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Deployment"), + }, + { + Name: "version_url", + Type: schema.TypeString, + Resolver: schema.PathResolver("VersionUrl"), + }, + { + Name: "endpoints_api_service", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("EndpointsApiService"), + }, + { + Name: "entrypoint", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Entrypoint"), + }, + { + Name: "vpc_access_connector", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("VpcAccessConnector"), + }, + }, + + Relations: []*schema.Table{ + Instances(), + }, + } +} + +func fetchVersions(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListVersionsRequest{ + Parent: parent.Item.(*pb.Service).Name, + } + gcpClient, err := appengine.NewVersionsClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListVersions(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/artifactregistry/docker_images.go b/plugins/source/gcp/resources/services/artifactregistry/docker_images.go new file mode 100644 index 00000000000..e2c62937a0f --- /dev/null +++ b/plugins/source/gcp/resources/services/artifactregistry/docker_images.go @@ -0,0 +1,97 @@ +// Code generated by codegen; DO NOT EDIT. + +package artifactregistry + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/artifactregistry/apiv1/artifactregistrypb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/artifactregistry/apiv1" +) + +func DockerImages() *schema.Table { + return &schema.Table{ + Name: "gcp_artifactregistry_docker_images", + Description: `https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.dockerImages#DockerImage`, + Resolver: fetchDockerImages, + Multiplex: client.ProjectMultiplexEnabledServices("artifactregistry.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "uri", + Type: schema.TypeString, + Resolver: schema.PathResolver("Uri"), + }, + { + Name: "tags", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("Tags"), + }, + { + Name: "image_size_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ImageSizeBytes"), + }, + { + Name: "upload_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UploadTime"), + }, + { + Name: "media_type", + Type: schema.TypeString, + Resolver: schema.PathResolver("MediaType"), + }, + { + Name: "build_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("BuildTime"), + }, + }, + } +} + +func fetchDockerImages(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListDockerImagesRequest{ + Parent: parent.Item.(*pb.Repository).Name, + } + gcpClient, err := artifactregistry.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListDockerImages(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/artifactregistry/files.go b/plugins/source/gcp/resources/services/artifactregistry/files.go new file mode 100644 index 00000000000..cacab0b0864 --- /dev/null +++ b/plugins/source/gcp/resources/services/artifactregistry/files.go @@ -0,0 +1,92 @@ +// Code generated by codegen; DO NOT EDIT. + +package artifactregistry + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/artifactregistry/apiv1/artifactregistrypb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/artifactregistry/apiv1" +) + +func Files() *schema.Table { + return &schema.Table{ + Name: "gcp_artifactregistry_files", + Description: `https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.files#File`, + Resolver: fetchFiles, + Multiplex: client.ProjectMultiplexEnabledServices("artifactregistry.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "size_bytes", + Type: schema.TypeInt, + Resolver: schema.PathResolver("SizeBytes"), + }, + { + Name: "hashes", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Hashes"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "owner", + Type: schema.TypeString, + Resolver: schema.PathResolver("Owner"), + }, + }, + } +} + +func fetchFiles(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListFilesRequest{ + Parent: parent.Item.(*pb.Repository).Name, + } + gcpClient, err := artifactregistry.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListFiles(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/artifactregistry/locations.go b/plugins/source/gcp/resources/services/artifactregistry/locations.go new file mode 100644 index 00000000000..dc00e5d1288 --- /dev/null +++ b/plugins/source/gcp/resources/services/artifactregistry/locations.go @@ -0,0 +1,59 @@ +// Code generated by codegen; DO NOT EDIT. + +package artifactregistry + +import ( + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" +) + +func Locations() *schema.Table { + return &schema.Table{ + Name: "gcp_artifactregistry_locations", + Description: `https://cloud.google.com/artifact-registry/docs/reference/rest/Shared.Types/ListLocationsResponse#Location`, + Resolver: fetchLocations, + Multiplex: client.ProjectMultiplexEnabledServices("artifactregistry.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "location_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("LocationId"), + }, + { + Name: "metadata", + Type: schema.TypeIntArray, + Resolver: schema.PathResolver("Metadata"), + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + }, + + Relations: []*schema.Table{ + Repositories(), + }, + } +} diff --git a/plugins/source/gcp/resources/services/artifactregistry/locations_fetch.go b/plugins/source/gcp/resources/services/artifactregistry/locations_fetch.go new file mode 100644 index 00000000000..0757e6c7b54 --- /dev/null +++ b/plugins/source/gcp/resources/services/artifactregistry/locations_fetch.go @@ -0,0 +1,32 @@ +package artifactregistry + +import ( + "context" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "google.golang.org/api/artifactregistry/v1" +) + +func fetchLocations(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + nextPageToken := "" + gcpClient, err := artifactregistry.NewService(ctx, c.ClientOptions...) + if err != nil { + return err + } + + for { + output, err := gcpClient.Projects.Locations.List("projects/" + c.ProjectId).PageToken(nextPageToken).Context(ctx).Do() + if err != nil { + return err + } + res <- output.Locations + if output.NextPageToken == "" { + break + } + nextPageToken = output.NextPageToken + } + return nil +} diff --git a/plugins/source/gcp/resources/services/artifactregistry/packages.go b/plugins/source/gcp/resources/services/artifactregistry/packages.go new file mode 100644 index 00000000000..7370f3b55b6 --- /dev/null +++ b/plugins/source/gcp/resources/services/artifactregistry/packages.go @@ -0,0 +1,87 @@ +// Code generated by codegen; DO NOT EDIT. + +package artifactregistry + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/artifactregistry/apiv1/artifactregistrypb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/artifactregistry/apiv1" +) + +func Packages() *schema.Table { + return &schema.Table{ + Name: "gcp_artifactregistry_packages", + Description: `https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.packages#Package`, + Resolver: fetchPackages, + Multiplex: client.ProjectMultiplexEnabledServices("artifactregistry.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "display_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("DisplayName"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + }, + + Relations: []*schema.Table{ + Tags(), + Versions(), + }, + } +} + +func fetchPackages(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListPackagesRequest{ + Parent: parent.Item.(*pb.Repository).Name, + } + gcpClient, err := artifactregistry.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListPackages(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/artifactregistry/repositories.go b/plugins/source/gcp/resources/services/artifactregistry/repositories.go new file mode 100644 index 00000000000..eabfd0a1a8f --- /dev/null +++ b/plugins/source/gcp/resources/services/artifactregistry/repositories.go @@ -0,0 +1,71 @@ +// Code generated by codegen; DO NOT EDIT. + +package artifactregistry + +import ( + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" +) + +func Repositories() *schema.Table { + return &schema.Table{ + Name: "gcp_artifactregistry_repositories", + Description: `https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories#Repository`, + Resolver: fetchRepositories, + Multiplex: client.ProjectMultiplexEnabledServices("artifactregistry.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "format", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("Format"), + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "kms_key_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("KmsKeyName"), + }, + }, + + Relations: []*schema.Table{ + DockerImages(), + Files(), + Packages(), + }, + } +} diff --git a/plugins/source/gcp/resources/services/artifactregistry/repositories_fetch.go b/plugins/source/gcp/resources/services/artifactregistry/repositories_fetch.go new file mode 100644 index 00000000000..c968d0119b4 --- /dev/null +++ b/plugins/source/gcp/resources/services/artifactregistry/repositories_fetch.go @@ -0,0 +1,38 @@ +package artifactregistry + +import ( + "context" + + "google.golang.org/api/iterator" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + v1cloud "cloud.google.com/go/artifactregistry/apiv1" + pb "cloud.google.com/go/artifactregistry/apiv1/artifactregistrypb" + v1google "google.golang.org/api/artifactregistry/v1" +) + +func fetchRepositories(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListRepositoriesRequest{ + Parent: parent.Item.(*v1google.Location).Name, + } + gcpClient, err := v1cloud.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListRepositories(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + } + return nil +} diff --git a/plugins/source/gcp/resources/services/artifactregistry/tags.go b/plugins/source/gcp/resources/services/artifactregistry/tags.go new file mode 100644 index 00000000000..4efcc516243 --- /dev/null +++ b/plugins/source/gcp/resources/services/artifactregistry/tags.go @@ -0,0 +1,72 @@ +// Code generated by codegen; DO NOT EDIT. + +package artifactregistry + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/artifactregistry/apiv1/artifactregistrypb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/artifactregistry/apiv1" +) + +func Tags() *schema.Table { + return &schema.Table{ + Name: "gcp_artifactregistry_tags", + Description: `https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.packages.tags#Tag`, + Resolver: fetchTags, + Multiplex: client.ProjectMultiplexEnabledServices("artifactregistry.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "version", + Type: schema.TypeString, + Resolver: schema.PathResolver("Version"), + }, + }, + } +} + +func fetchTags(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListTagsRequest{ + Parent: parent.Item.(*pb.Package).Name, + } + gcpClient, err := artifactregistry.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListTags(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/artifactregistry/versions.go b/plugins/source/gcp/resources/services/artifactregistry/versions.go new file mode 100644 index 00000000000..7283df0c200 --- /dev/null +++ b/plugins/source/gcp/resources/services/artifactregistry/versions.go @@ -0,0 +1,92 @@ +// Code generated by codegen; DO NOT EDIT. + +package artifactregistry + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/artifactregistry/apiv1/artifactregistrypb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/artifactregistry/apiv1" +) + +func Versions() *schema.Table { + return &schema.Table{ + Name: "gcp_artifactregistry_versions", + Description: `https://cloud.google.com/artifact-registry/docs/reference/rest/v1/projects.locations.repositories.packages.versions#Version`, + Resolver: fetchVersions, + Multiplex: client.ProjectMultiplexEnabledServices("artifactregistry.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "description", + Type: schema.TypeString, + Resolver: schema.PathResolver("Description"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "related_tags", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("RelatedTags"), + }, + { + Name: "metadata", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Metadata"), + }, + }, + } +} + +func fetchVersions(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListVersionsRequest{ + Parent: parent.Item.(*pb.Package).Name, + } + gcpClient, err := artifactregistry.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListVersions(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/baremetalsolution/instances.go b/plugins/source/gcp/resources/services/baremetalsolution/instances.go new file mode 100644 index 00000000000..cd878c0f034 --- /dev/null +++ b/plugins/source/gcp/resources/services/baremetalsolution/instances.go @@ -0,0 +1,137 @@ +// Code generated by codegen; DO NOT EDIT. + +package baremetalsolution + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/baremetalsolution/apiv2" +) + +func Instances() *schema.Table { + return &schema.Table{ + Name: "gcp_baremetalsolution_instances", + Description: `https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.instances#Instance`, + Resolver: fetchInstances, + Multiplex: client.ProjectMultiplexEnabledServices("baremetalsolution.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "create_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("CreateTime"), + }, + { + Name: "update_time", + Type: schema.TypeTimestamp, + Resolver: client.ResolveProtoTimestamp("UpdateTime"), + }, + { + Name: "machine_type", + Type: schema.TypeString, + Resolver: schema.PathResolver("MachineType"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "hyperthreading_enabled", + Type: schema.TypeBool, + Resolver: schema.PathResolver("HyperthreadingEnabled"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "luns", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Luns"), + }, + { + Name: "networks", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Networks"), + }, + { + Name: "interactive_serial_console_enabled", + Type: schema.TypeBool, + Resolver: schema.PathResolver("InteractiveSerialConsoleEnabled"), + }, + { + Name: "os_image", + Type: schema.TypeString, + Resolver: schema.PathResolver("OsImage"), + }, + { + Name: "pod", + Type: schema.TypeString, + Resolver: schema.PathResolver("Pod"), + }, + { + Name: "network_template", + Type: schema.TypeString, + Resolver: schema.PathResolver("NetworkTemplate"), + }, + { + Name: "logical_interfaces", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("LogicalInterfaces"), + }, + }, + } +} + +func fetchInstances(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListInstancesRequest{ + Parent: "projects/" + c.ProjectId + "/locations/-", + } + gcpClient, err := baremetalsolution.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListInstances(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/baremetalsolution/instances_mock_test.go b/plugins/source/gcp/resources/services/baremetalsolution/instances_mock_test.go new file mode 100644 index 00000000000..69156841c11 --- /dev/null +++ b/plugins/source/gcp/resources/services/baremetalsolution/instances_mock_test.go @@ -0,0 +1,37 @@ +// Code generated by codegen; DO NOT EDIT. + +package baremetalsolution + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" +) + +func createInstances(gsrv *grpc.Server) error { + fakeServer := &fakeInstancesServer{} + pb.RegisterBareMetalSolutionServer(gsrv, fakeServer) + return nil +} + +type fakeInstancesServer struct { + pb.UnimplementedBareMetalSolutionServer +} + +func (f *fakeInstancesServer) ListInstances(context.Context, *pb.ListInstancesRequest) (*pb.ListInstancesResponse, error) { + resp := pb.ListInstancesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestInstances(t *testing.T) { + client.MockTestGrpcHelper(t, Instances(), createInstances, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/baremetalsolution/networks.go b/plugins/source/gcp/resources/services/baremetalsolution/networks.go new file mode 100644 index 00000000000..958c7239b2d --- /dev/null +++ b/plugins/source/gcp/resources/services/baremetalsolution/networks.go @@ -0,0 +1,122 @@ +// Code generated by codegen; DO NOT EDIT. + +package baremetalsolution + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/baremetalsolution/apiv2" +) + +func Networks() *schema.Table { + return &schema.Table{ + Name: "gcp_baremetalsolution_networks", + Description: `https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.networks#Network`, + Resolver: fetchNetworks, + Multiplex: client.ProjectMultiplexEnabledServices("baremetalsolution.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "type", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("Type"), + }, + { + Name: "ip_address", + Type: schema.TypeString, + Resolver: schema.PathResolver("IpAddress"), + }, + { + Name: "mac_address", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("MacAddress"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "vlan_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("VlanId"), + }, + { + Name: "cidr", + Type: schema.TypeString, + Resolver: schema.PathResolver("Cidr"), + }, + { + Name: "vrf", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Vrf"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "services_cidr", + Type: schema.TypeString, + Resolver: schema.PathResolver("ServicesCidr"), + }, + { + Name: "reservations", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Reservations"), + }, + }, + } +} + +func fetchNetworks(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListNetworksRequest{ + Parent: "projects/" + c.ProjectId + "/locations/-", + } + gcpClient, err := baremetalsolution.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListNetworks(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/baremetalsolution/networks_mock_test.go b/plugins/source/gcp/resources/services/baremetalsolution/networks_mock_test.go new file mode 100644 index 00000000000..eb9bdfba915 --- /dev/null +++ b/plugins/source/gcp/resources/services/baremetalsolution/networks_mock_test.go @@ -0,0 +1,37 @@ +// Code generated by codegen; DO NOT EDIT. + +package baremetalsolution + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" +) + +func createNetworks(gsrv *grpc.Server) error { + fakeServer := &fakeNetworksServer{} + pb.RegisterBareMetalSolutionServer(gsrv, fakeServer) + return nil +} + +type fakeNetworksServer struct { + pb.UnimplementedBareMetalSolutionServer +} + +func (f *fakeNetworksServer) ListNetworks(context.Context, *pb.ListNetworksRequest) (*pb.ListNetworksResponse, error) { + resp := pb.ListNetworksResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestNetworks(t *testing.T) { + client.MockTestGrpcHelper(t, Networks(), createNetworks, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/baremetalsolution/nfs_shares.go b/plugins/source/gcp/resources/services/baremetalsolution/nfs_shares.go new file mode 100644 index 00000000000..df3cd69b1a4 --- /dev/null +++ b/plugins/source/gcp/resources/services/baremetalsolution/nfs_shares.go @@ -0,0 +1,92 @@ +// Code generated by codegen; DO NOT EDIT. + +package baremetalsolution + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/baremetalsolution/apiv2" +) + +func NfsShares() *schema.Table { + return &schema.Table{ + Name: "gcp_baremetalsolution_nfs_shares", + Description: `https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.nfsShares#NfsShare`, + Resolver: fetchNfsShares, + Multiplex: client.ProjectMultiplexEnabledServices("baremetalsolution.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "nfs_share_id", + Type: schema.TypeString, + Resolver: schema.PathResolver("NfsShareId"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "volume", + Type: schema.TypeString, + Resolver: schema.PathResolver("Volume"), + }, + { + Name: "allowed_clients", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("AllowedClients"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + }, + } +} + +func fetchNfsShares(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListNfsSharesRequest{ + Parent: "projects/" + c.ProjectId + "/locations/-", + } + gcpClient, err := baremetalsolution.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListNfsShares(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/baremetalsolution/nfs_shares_mock_test.go b/plugins/source/gcp/resources/services/baremetalsolution/nfs_shares_mock_test.go new file mode 100644 index 00000000000..8d8867b46da --- /dev/null +++ b/plugins/source/gcp/resources/services/baremetalsolution/nfs_shares_mock_test.go @@ -0,0 +1,37 @@ +// Code generated by codegen; DO NOT EDIT. + +package baremetalsolution + +import ( + "context" + "fmt" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + "testing" + + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" +) + +func createNfsShares(gsrv *grpc.Server) error { + fakeServer := &fakeNfsSharesServer{} + pb.RegisterBareMetalSolutionServer(gsrv, fakeServer) + return nil +} + +type fakeNfsSharesServer struct { + pb.UnimplementedBareMetalSolutionServer +} + +func (f *fakeNfsSharesServer) ListNfsShares(context.Context, *pb.ListNfsSharesRequest) (*pb.ListNfsSharesResponse, error) { + resp := pb.ListNfsSharesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestNfsShares(t *testing.T) { + client.MockTestGrpcHelper(t, NfsShares(), createNfsShares, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/baremetalsolution/volume_luns.go b/plugins/source/gcp/resources/services/baremetalsolution/volume_luns.go new file mode 100644 index 00000000000..0f62807a7a0 --- /dev/null +++ b/plugins/source/gcp/resources/services/baremetalsolution/volume_luns.go @@ -0,0 +1,112 @@ +// Code generated by codegen; DO NOT EDIT. + +package baremetalsolution + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/baremetalsolution/apiv2" +) + +func VolumeLuns() *schema.Table { + return &schema.Table{ + Name: "gcp_baremetalsolution_volume_luns", + Description: `https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.volumes.luns#Lun`, + Resolver: fetchVolumeLuns, + Multiplex: client.ProjectMultiplexEnabledServices("baremetalsolution.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "size_gb", + Type: schema.TypeInt, + Resolver: schema.PathResolver("SizeGb"), + }, + { + Name: "multiprotocol_type", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("MultiprotocolType"), + }, + { + Name: "storage_volume", + Type: schema.TypeString, + Resolver: schema.PathResolver("StorageVolume"), + }, + { + Name: "shareable", + Type: schema.TypeBool, + Resolver: schema.PathResolver("Shareable"), + }, + { + Name: "boot_lun", + Type: schema.TypeBool, + Resolver: schema.PathResolver("BootLun"), + }, + { + Name: "storage_type", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("StorageType"), + }, + { + Name: "wwid", + Type: schema.TypeString, + Resolver: schema.PathResolver("Wwid"), + }, + }, + } +} + +func fetchVolumeLuns(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListLunsRequest{ + Parent: parent.Item.(*pb.Volume).Name, + } + gcpClient, err := baremetalsolution.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListLuns(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/baremetalsolution/volumes.go b/plugins/source/gcp/resources/services/baremetalsolution/volumes.go new file mode 100644 index 00000000000..d037277e48b --- /dev/null +++ b/plugins/source/gcp/resources/services/baremetalsolution/volumes.go @@ -0,0 +1,136 @@ +// Code generated by codegen; DO NOT EDIT. + +package baremetalsolution + +import ( + "context" + "google.golang.org/api/iterator" + + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugins/source/gcp/client" + + "cloud.google.com/go/baremetalsolution/apiv2" +) + +func Volumes() *schema.Table { + return &schema.Table{ + Name: "gcp_baremetalsolution_volumes", + Description: `https://cloud.google.com/bare-metal/docs/reference/rest/v2/projects.locations.volumes#Volume`, + Resolver: fetchVolumes, + Multiplex: client.ProjectMultiplexEnabledServices("baremetalsolution.googleapis.com"), + Columns: []schema.Column{ + { + Name: "project_id", + Type: schema.TypeString, + Resolver: client.ResolveProject, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("Id"), + }, + { + Name: "storage_type", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("StorageType"), + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("State"), + }, + { + Name: "requested_size_gib", + Type: schema.TypeInt, + Resolver: schema.PathResolver("RequestedSizeGib"), + }, + { + Name: "current_size_gib", + Type: schema.TypeInt, + Resolver: schema.PathResolver("CurrentSizeGib"), + }, + { + Name: "emergency_size_gib", + Type: schema.TypeInt, + Resolver: schema.PathResolver("EmergencySizeGib"), + }, + { + Name: "auto_grown_size_gib", + Type: schema.TypeInt, + Resolver: schema.PathResolver("AutoGrownSizeGib"), + }, + { + Name: "remaining_space_gib", + Type: schema.TypeInt, + Resolver: schema.PathResolver("RemainingSpaceGib"), + }, + { + Name: "snapshot_reservation_detail", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("SnapshotReservationDetail"), + }, + { + Name: "snapshot_auto_delete_behavior", + Type: schema.TypeString, + Resolver: client.ResolveProtoEnum("SnapshotAutoDeleteBehavior"), + }, + { + Name: "labels", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Labels"), + }, + { + Name: "snapshot_enabled", + Type: schema.TypeBool, + Resolver: schema.PathResolver("SnapshotEnabled"), + }, + { + Name: "pod", + Type: schema.TypeString, + Resolver: schema.PathResolver("Pod"), + }, + }, + + Relations: []*schema.Table{ + VolumeLuns(), + }, + } +} + +func fetchVolumes(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + req := &pb.ListVolumesRequest{ + Parent: "projects/" + c.ProjectId + "/locations/-", + } + gcpClient, err := baremetalsolution.NewClient(ctx, c.ClientOptions...) + if err != nil { + return err + } + it := gcpClient.ListVolumes(ctx, req, c.CallOptions...) + for { + resp, err := it.Next() + if err == iterator.Done { + break + } + if err != nil { + return err + } + + res <- resp + + } + return nil +} diff --git a/plugins/source/gcp/resources/services/baremetalsolution/volumes_mock_test.go b/plugins/source/gcp/resources/services/baremetalsolution/volumes_mock_test.go new file mode 100644 index 00000000000..0db5e2f9d1c --- /dev/null +++ b/plugins/source/gcp/resources/services/baremetalsolution/volumes_mock_test.go @@ -0,0 +1,44 @@ +package baremetalsolution + +import ( + "context" + "fmt" + "testing" + + "github.com/cloudquery/plugin-sdk/faker" + "github.com/cloudquery/plugins/source/gcp/client" + "google.golang.org/grpc" + + pb "cloud.google.com/go/baremetalsolution/apiv2/baremetalsolutionpb" +) + +func createVolumes(gsrv *grpc.Server) error { + pb.RegisterBareMetalSolutionServer(gsrv, &fakeVolumesServer{}) + return nil +} + +type fakeVolumesServer struct { + pb.UnimplementedBareMetalSolutionServer +} + +func (*fakeVolumesServer) ListVolumes(context.Context, *pb.ListVolumesRequest) (*pb.ListVolumesResponse, error) { + resp := pb.ListVolumesResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func (*fakeVolumesServer) ListLuns(context.Context, *pb.ListLunsRequest) (*pb.ListLunsResponse, error) { + resp := pb.ListLunsResponse{} + if err := faker.FakeObject(&resp); err != nil { + return nil, fmt.Errorf("failed to fake data: %w", err) + } + resp.NextPageToken = "" + return &resp, nil +} + +func TestVolumes(t *testing.T) { + client.MockTestGrpcHelper(t, Volumes(), createVolumes, client.TestOptions{}) +} diff --git a/plugins/source/gcp/resources/services/run/locations.go b/plugins/source/gcp/resources/services/run/locations.go index 11ba69d66eb..8fd8e73b5fb 100644 --- a/plugins/source/gcp/resources/services/run/locations.go +++ b/plugins/source/gcp/resources/services/run/locations.go @@ -10,7 +10,7 @@ import ( func Locations() *schema.Table { return &schema.Table{ Name: "gcp_run_locations", - Description: `https://cloud.google.com/api-gateway/docs/reference/rest/v1/projects.locations#Location`, + Description: `https://cloud.google.com/run/docs/reference/rest/v1/projects.locations#Location`, Resolver: fetchLocations, Multiplex: client.ProjectMultiplexEnabledServices("run.googleapis.com"), Columns: []schema.Column{ diff --git a/plugins/source/gcp/test/policy_cq_config.yml b/plugins/source/gcp/test/policy_cq_config.yml index 3da212552a8..c04af69f5d0 100644 --- a/plugins/source/gcp/test/policy_cq_config.yml +++ b/plugins/source/gcp/test/policy_cq_config.yml @@ -10,6 +10,6 @@ kind: destination spec: name: postgresql path: cloudquery/postgresql - version: "v1.10.0" # latest version of postgresql plugin + version: "v2.0.0" # latest version of postgresql plugin spec: connection_string: ${CQ_DSN} \ No newline at end of file diff --git a/plugins/source/github/client/client.go b/plugins/source/github/client/client.go index ea1e681b7ec..4b202c14d18 100644 --- a/plugins/source/github/client/client.go +++ b/plugins/source/github/client/client.go @@ -66,11 +66,12 @@ func Configure(ctx context.Context, logger zerolog.Logger, s specs.Source) (sche logger: logger, Github: GithubServices{ Actions: c.Actions, - Teams: c.Teams, Billing: c.Billing, - Repositories: c.Repositories, - Organizations: c.Organizations, + Dependabot: c.Dependabot, Issues: c.Issues, + Organizations: c.Organizations, + Repositories: c.Repositories, + Teams: c.Teams, }, Orgs: spec.Orgs, }, nil diff --git a/plugins/source/github/client/mocks/mock_dependabot.go b/plugins/source/github/client/mocks/mock_dependabot.go new file mode 100644 index 00000000000..eeaa0f40112 --- /dev/null +++ b/plugins/source/github/client/mocks/mock_dependabot.go @@ -0,0 +1,100 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/cloudquery/cloudquery/plugins/source/github/client (interfaces: DependabotService) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + github "github.com/google/go-github/v48/github" +) + +// MockDependabotService is a mock of DependabotService interface. +type MockDependabotService struct { + ctrl *gomock.Controller + recorder *MockDependabotServiceMockRecorder +} + +// MockDependabotServiceMockRecorder is the mock recorder for MockDependabotService. +type MockDependabotServiceMockRecorder struct { + mock *MockDependabotService +} + +// NewMockDependabotService creates a new mock instance. +func NewMockDependabotService(ctrl *gomock.Controller) *MockDependabotService { + mock := &MockDependabotService{ctrl: ctrl} + mock.recorder = &MockDependabotServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDependabotService) EXPECT() *MockDependabotServiceMockRecorder { + return m.recorder +} + +// ListOrgAlerts mocks base method. +func (m *MockDependabotService) ListOrgAlerts(arg0 context.Context, arg1 string, arg2 *github.ListAlertsOptions) ([]*github.DependabotAlert, *github.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListOrgAlerts", arg0, arg1, arg2) + ret0, _ := ret[0].([]*github.DependabotAlert) + ret1, _ := ret[1].(*github.Response) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ListOrgAlerts indicates an expected call of ListOrgAlerts. +func (mr *MockDependabotServiceMockRecorder) ListOrgAlerts(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListOrgAlerts", reflect.TypeOf((*MockDependabotService)(nil).ListOrgAlerts), arg0, arg1, arg2) +} + +// ListOrgSecrets mocks base method. +func (m *MockDependabotService) ListOrgSecrets(arg0 context.Context, arg1 string, arg2 *github.ListOptions) (*github.Secrets, *github.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListOrgSecrets", arg0, arg1, arg2) + ret0, _ := ret[0].(*github.Secrets) + ret1, _ := ret[1].(*github.Response) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ListOrgSecrets indicates an expected call of ListOrgSecrets. +func (mr *MockDependabotServiceMockRecorder) ListOrgSecrets(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListOrgSecrets", reflect.TypeOf((*MockDependabotService)(nil).ListOrgSecrets), arg0, arg1, arg2) +} + +// ListRepoAlerts mocks base method. +func (m *MockDependabotService) ListRepoAlerts(arg0 context.Context, arg1, arg2 string, arg3 *github.ListAlertsOptions) ([]*github.DependabotAlert, *github.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListRepoAlerts", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].([]*github.DependabotAlert) + ret1, _ := ret[1].(*github.Response) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ListRepoAlerts indicates an expected call of ListRepoAlerts. +func (mr *MockDependabotServiceMockRecorder) ListRepoAlerts(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListRepoAlerts", reflect.TypeOf((*MockDependabotService)(nil).ListRepoAlerts), arg0, arg1, arg2, arg3) +} + +// ListRepoSecrets mocks base method. +func (m *MockDependabotService) ListRepoSecrets(arg0 context.Context, arg1, arg2 string, arg3 *github.ListOptions) (*github.Secrets, *github.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListRepoSecrets", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*github.Secrets) + ret1, _ := ret[1].(*github.Response) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ListRepoSecrets indicates an expected call of ListRepoSecrets. +func (mr *MockDependabotServiceMockRecorder) ListRepoSecrets(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListRepoSecrets", reflect.TypeOf((*MockDependabotService)(nil).ListRepoSecrets), arg0, arg1, arg2, arg3) +} diff --git a/plugins/source/github/client/services.go b/plugins/source/github/client/services.go index b431b54ffd1..0cdd565089d 100644 --- a/plugins/source/github/client/services.go +++ b/plugins/source/github/client/services.go @@ -9,6 +9,7 @@ import ( type GithubServices struct { Actions ActionsService Billing BillingService + Dependabot DependabotService Issues IssuesService Organizations OrganizationsService Repositories RepositoriesService @@ -56,3 +57,12 @@ type IssuesService interface { type ActionsService interface { ListWorkflows(ctx context.Context, owner, repo string, opts *github.ListOptions) (*github.Workflows, *github.Response, error) } + +//go:generate mockgen -package=mocks -destination=./mocks/mock_dependabot.go . DependabotService +type DependabotService interface { + ListOrgAlerts(ctx context.Context, org string, opts *github.ListAlertsOptions) ([]*github.DependabotAlert, *github.Response, error) + ListRepoAlerts(ctx context.Context, owner, repo string, opts *github.ListAlertsOptions) ([]*github.DependabotAlert, *github.Response, error) + + ListRepoSecrets(ctx context.Context, owner, repo string, opts *github.ListOptions) (*github.Secrets, *github.Response, error) + ListOrgSecrets(ctx context.Context, org string, opts *github.ListOptions) (*github.Secrets, *github.Response, error) +} diff --git a/plugins/source/github/codegen/recipes/actions.go b/plugins/source/github/codegen/recipes/actions.go index eb419f8c3b2..43591e1497c 100644 --- a/plugins/source/github/codegen/recipes/actions.go +++ b/plugins/source/github/codegen/recipes/actions.go @@ -9,19 +9,20 @@ import ( func Actions() []*Resource { return []*Resource{ { + TableName: "workflows", Service: "actions", SubService: "workflows", - Multiplex: orgMultiplex, Struct: new(github.Workflow), - TableName: "workflows", - SkipFields: skipID, - ExtraColumns: append(orgColumns, idColumn, - codegen.ColumnDefinition{ + PKColumns: []string{"id"}, + ExtraColumns: codegen.ColumnDefinitions{ + orgColumn, + { Name: "contents", Type: schema.TypeString, Resolver: `resolveContents`, }, - ), + }, + Multiplex: orgMultiplex, }, } } diff --git a/plugins/source/github/codegen/recipes/base.go b/plugins/source/github/codegen/recipes/base.go index b443d33ef63..50bcd2ed4da 100644 --- a/plugins/source/github/codegen/recipes/base.go +++ b/plugins/source/github/codegen/recipes/base.go @@ -23,6 +23,7 @@ type Resource struct { SubService string Struct any SkipFields []string + PKColumns []string ExtraColumns []codegen.ColumnDefinition Table *codegen.TableDefinition TableName string @@ -59,6 +60,7 @@ func (r *Resource) Generate() error { r.TableName = `github_` + r.TableName r.Table, err = codegen.NewTableFromStruct(r.TableName, r.Struct, codegen.WithSkipFields(r.SkipFields), + codegen.WithPKColumns(r.PKColumns...), codegen.WithExtraColumns(r.ExtraColumns), codegen.WithTypeTransformer(timestampTransformer), ) diff --git a/plugins/source/github/codegen/recipes/billing.go b/plugins/source/github/codegen/recipes/billing.go index a2acf8cb12c..a0a1a112c5a 100644 --- a/plugins/source/github/codegen/recipes/billing.go +++ b/plugins/source/github/codegen/recipes/billing.go @@ -1,6 +1,7 @@ package recipes import ( + "github.com/cloudquery/plugin-sdk/codegen" "github.com/google/go-github/v48/github" ) @@ -9,23 +10,23 @@ func Billing() []*Resource { { Service: "billing", SubService: "action", - Multiplex: orgMultiplex, Struct: new(github.ActionBilling), - ExtraColumns: orgColumns, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + Multiplex: orgMultiplex, }, { Service: "billing", SubService: "package", - Multiplex: orgMultiplex, Struct: new(github.PackageBilling), - ExtraColumns: orgColumns, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + Multiplex: orgMultiplex, }, { Service: "billing", SubService: "storage", - Multiplex: orgMultiplex, Struct: new(github.StorageBilling), - ExtraColumns: orgColumns, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + Multiplex: orgMultiplex, }, } } diff --git a/plugins/source/github/codegen/recipes/columns.go b/plugins/source/github/codegen/recipes/columns.go index 954fd78ed3c..9dd15e4c764 100644 --- a/plugins/source/github/codegen/recipes/columns.go +++ b/plugins/source/github/codegen/recipes/columns.go @@ -6,32 +6,11 @@ import ( ) var ( - orgColumns = []codegen.ColumnDefinition{ - { - Name: "org", - Description: "The Github Organization of the resource.", - Type: schema.TypeString, - Resolver: `client.ResolveOrg`, - Options: schema.ColumnCreationOptions{PrimaryKey: true}, - }, + orgColumn = codegen.ColumnDefinition{ + Name: "org", + Description: "The Github Organization of the resource.", + Type: schema.TypeString, + Resolver: `client.ResolveOrg`, + Options: schema.ColumnCreationOptions{PrimaryKey: true}, } - idColumn = pkColumn("id", "ID") - skipID = []string{"ID"} ) - -func timestampField(name, path string) codegen.ColumnDefinition { - return codegen.ColumnDefinition{ - Name: name, - Type: schema.TypeTimestamp, - Resolver: `schema.PathResolver("` + path + `.Time")`, - } -} - -func pkColumn(name, path string) codegen.ColumnDefinition { - return codegen.ColumnDefinition{ - Name: name, - Type: schema.TypeInt, - Resolver: `schema.PathResolver("` + path + `")`, - Options: schema.ColumnCreationOptions{PrimaryKey: true}, - } -} diff --git a/plugins/source/github/codegen/recipes/dependabot.go b/plugins/source/github/codegen/recipes/dependabot.go new file mode 100644 index 00000000000..463058fc2a5 --- /dev/null +++ b/plugins/source/github/codegen/recipes/dependabot.go @@ -0,0 +1,24 @@ +package recipes + +import ( + "github.com/cloudquery/plugin-sdk/codegen" + "github.com/google/go-github/v48/github" +) + +func dependabotAlert() *Resource { + return &Resource{ + SubService: "alerts", + Struct: new(github.DependabotAlert), + PKColumns: []string{"number"}, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + } +} + +func dependabotSecret() *Resource { + return &Resource{ + SubService: "secrets", + Struct: new(github.Secret), + PKColumns: []string{"name"}, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + } +} diff --git a/plugins/source/github/codegen/recipes/external.go b/plugins/source/github/codegen/recipes/external.go index 713ef68b883..bab4c6884d2 100644 --- a/plugins/source/github/codegen/recipes/external.go +++ b/plugins/source/github/codegen/recipes/external.go @@ -1,25 +1,19 @@ package recipes import ( + "github.com/cloudquery/plugin-sdk/codegen" "github.com/google/go-github/v48/github" ) func External() []*Resource { - const ( - groupID = "GroupID" - updatedAt = "UpdatedAt" - ) return []*Resource{ { - Service: "external", - SubService: "groups", - Multiplex: orgMultiplex, - Struct: new(github.ExternalGroup), - SkipFields: append(skipID, groupID, updatedAt), - ExtraColumns: append(orgColumns, - pkColumn("group_id", groupID), - timestampField("updated_at", updatedAt), - ), + Service: "external", + SubService: "groups", + Struct: new(github.ExternalGroup), + PKColumns: []string{"group_id"}, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + Multiplex: orgMultiplex, }, } } diff --git a/plugins/source/github/codegen/recipes/hooks.go b/plugins/source/github/codegen/recipes/hooks.go index dd627c9cfc6..09a6cb02aae 100644 --- a/plugins/source/github/codegen/recipes/hooks.go +++ b/plugins/source/github/codegen/recipes/hooks.go @@ -7,47 +7,45 @@ import ( ) func Hooks() []*Resource { - const ( - deliveredAt = "DeliveredAt" - ) - return []*Resource{ { + TableName: "hooks", Service: "hooks", SubService: "hooks", - Multiplex: orgMultiplex, Struct: new(github.Hook), - TableName: "hooks", - SkipFields: skipID, - ExtraColumns: append(orgColumns, idColumn), + PKColumns: []string{"id"}, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + Multiplex: orgMultiplex, Relations: []string{"Deliveries()"}, }, { + TableName: "hook_deliveries", Service: "hooks", SubService: "deliveries", - Multiplex: "", // we skip multiplexing here as it's a relation Struct: new(github.HookDelivery), - TableName: "hook_deliveries", - SkipFields: append(skipID, deliveredAt, "Request", "Response"), - ExtraColumns: append(orgColumns, idColumn, - codegen.ColumnDefinition{ + PKColumns: []string{"id"}, + SkipFields: []string{"Request", "Response"}, + ExtraColumns: codegen.ColumnDefinitions{ + orgColumn, + { Name: "hook_id", Type: schema.TypeInt, Resolver: `client.ResolveParentColumn("ID")`, Description: "Hook ID", Options: schema.ColumnCreationOptions{PrimaryKey: true}, }, - codegen.ColumnDefinition{ + { Name: "request", Type: schema.TypeString, Resolver: `resolveRequest`, }, - codegen.ColumnDefinition{ + { Name: "response", Type: schema.TypeString, Resolver: `resolveResponse`, }, - timestampField("delivered_at", deliveredAt)), + }, + Multiplex: "", // we skip multiplexing here as it's a relation }, } } diff --git a/plugins/source/github/codegen/recipes/installations.go b/plugins/source/github/codegen/recipes/installations.go index 41a5b74f67a..0a3e6c0bed2 100644 --- a/plugins/source/github/codegen/recipes/installations.go +++ b/plugins/source/github/codegen/recipes/installations.go @@ -1,19 +1,20 @@ package recipes import ( + "github.com/cloudquery/plugin-sdk/codegen" "github.com/google/go-github/v48/github" ) func Installations() []*Resource { return []*Resource{ { + TableName: "installations", Service: "installations", SubService: "installations", - Multiplex: orgMultiplex, Struct: new(github.Installation), - TableName: "installations", - SkipFields: skipID, - ExtraColumns: append(orgColumns, idColumn), + PKColumns: []string{"id"}, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + Multiplex: orgMultiplex, }, } } diff --git a/plugins/source/github/codegen/recipes/issues.go b/plugins/source/github/codegen/recipes/issues.go index 3a97345b1b1..e2c8124486f 100644 --- a/plugins/source/github/codegen/recipes/issues.go +++ b/plugins/source/github/codegen/recipes/issues.go @@ -1,19 +1,20 @@ package recipes import ( + "github.com/cloudquery/plugin-sdk/codegen" "github.com/google/go-github/v48/github" ) func Issues() []*Resource { return []*Resource{ { + TableName: "issues", Service: "issues", SubService: "issues", - Multiplex: orgMultiplex, Struct: new(github.Issue), - TableName: "issues", - SkipFields: skipID, - ExtraColumns: append(orgColumns, idColumn), + PKColumns: []string{"id"}, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + Multiplex: orgMultiplex, }, } } diff --git a/plugins/source/github/codegen/recipes/organizations.go b/plugins/source/github/codegen/recipes/organizations.go index 1e76bf2cb17..9e19e3e134d 100644 --- a/plugins/source/github/codegen/recipes/organizations.go +++ b/plugins/source/github/codegen/recipes/organizations.go @@ -7,31 +7,42 @@ import ( ) func Organizations() []*Resource { + alert := dependabotAlert() + alert.Service = "organizations" + alert.TableName = "organization_dependabot_alerts" + + sec := dependabotSecret() + sec.Service = "organizations" + sec.TableName = "organization_dependabot_secrets" + return []*Resource{ { + TableName: "organizations", Service: "organizations", SubService: "organizations", - Multiplex: orgMultiplex, Struct: new(github.Organization), - TableName: "organizations", - SkipFields: skipID, - ExtraColumns: append(orgColumns, idColumn), - Relations: []string{"Members()"}, + PKColumns: []string{"id"}, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + Multiplex: orgMultiplex, + Relations: []string{"Alerts()", "Secrets()", "Members()"}, }, + alert, + sec, { + TableName: "organization_members", Service: "organizations", SubService: "members", - Multiplex: "", // we skip multiplexing here as it's a relation Struct: new(github.User), - TableName: "organization_members", - SkipFields: skipID, - ExtraColumns: append(orgColumns, idColumn, // we can use orgColumns here - codegen.ColumnDefinition{ + PKColumns: []string{"id"}, + ExtraColumns: codegen.ColumnDefinitions{ + orgColumn, // we can use orgColumn here + { Name: "membership", Type: schema.TypeJSON, Resolver: "resolveMembership", }, - ), + }, + Multiplex: "", // we skip multiplexing here as it's a relation }, } } diff --git a/plugins/source/github/codegen/recipes/repositories.go b/plugins/source/github/codegen/recipes/repositories.go index 44744bc5ce5..9968449a4a7 100644 --- a/plugins/source/github/codegen/recipes/repositories.go +++ b/plugins/source/github/codegen/recipes/repositories.go @@ -1,35 +1,45 @@ package recipes import ( + "github.com/cloudquery/plugin-sdk/codegen" + "github.com/cloudquery/plugin-sdk/schema" "github.com/google/go-github/v48/github" ) func Repositories() []*Resource { + repositoryID := codegen.ColumnDefinition{ + Name: "repository_id", + Type: schema.TypeInt, + Resolver: `client.ResolveParentColumn("ID")`, + Options: schema.ColumnCreationOptions{PrimaryKey: true}, + } + + alert := dependabotAlert() + alert.Service = "repositories" + alert.TableName = "repository_dependabot_alerts" + alert.SkipFields = []string{"RepositoryID"} + alert.ExtraColumns = append(alert.ExtraColumns, repositoryID) + + sec := dependabotSecret() + sec.Service = "repositories" + sec.TableName = "repository_dependabot_secrets" + sec.SkipFields = []string{"RepositoryID"} + sec.ExtraColumns = append(sec.ExtraColumns, repositoryID) + repo := repository() repo.Service = "repositories" repo.TableName = "repositories" repo.Multiplex = orgMultiplex + repo.Relations = []string{"Alerts()", "Secrets()"} - return []*Resource{repo} + return []*Resource{repo, alert, sec} } func repository() *Resource { - const ( - createdAt = "CreatedAt" - pushedAt = "PushedAt" - updatedAt = "UpdatedAt" - ) - return &Resource{ - SubService: "repositories", - Struct: new(github.Repository), - SkipFields: append(skipID, - createdAt, pushedAt, updatedAt, - ), - ExtraColumns: append(orgColumns, idColumn, - timestampField("created_at", createdAt), - timestampField("pushed_at", pushedAt), - timestampField("updated_at", updatedAt), - ), + SubService: "repositories", + Struct: new(github.Repository), + PKColumns: []string{"id"}, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, } } diff --git a/plugins/source/github/codegen/recipes/teams.go b/plugins/source/github/codegen/recipes/teams.go index 5f625f12d59..ddaff88c473 100644 --- a/plugins/source/github/codegen/recipes/teams.go +++ b/plugins/source/github/codegen/recipes/teams.go @@ -22,29 +22,31 @@ func Teams() []*Resource { return []*Resource{ { + TableName: "teams", Service: "teams", SubService: "teams", - Multiplex: orgMultiplex, Struct: new(github.Team), - TableName: "teams", - SkipFields: skipID, - ExtraColumns: append(orgColumns, idColumn), + PKColumns: []string{"id"}, + ExtraColumns: codegen.ColumnDefinitions{orgColumn}, + Multiplex: orgMultiplex, Relations: []string{"Members()", "Repositories()"}, }, { + TableName: "team_members", Service: "teams", SubService: "members", - Multiplex: "", // we skip multiplexing here as it's a relation Struct: new(github.User), - TableName: "team_members", - SkipFields: skipID, - ExtraColumns: append(orgColumns, idColumn, teamID, + PKColumns: []string{"id"}, + ExtraColumns: codegen.ColumnDefinitions{ + orgColumn, + teamID, codegen.ColumnDefinition{ Name: "membership", Type: schema.TypeJSON, Resolver: "resolveMembership", }, - ), + }, + Multiplex: "", // we skip multiplexing here as it's a relation }, repos, } diff --git a/plugins/source/github/docs/tables/README.md b/plugins/source/github/docs/tables/README.md index 23eef424988..5aa56994c90 100644 --- a/plugins/source/github/docs/tables/README.md +++ b/plugins/source/github/docs/tables/README.md @@ -12,8 +12,12 @@ - [github_hook_deliveries](github_hook_deliveries.md) - [github_installations](github_installations.md) - [github_organizations](github_organizations.md) + - [github_organization_dependabot_alerts](github_organization_dependabot_alerts.md) + - [github_organization_dependabot_secrets](github_organization_dependabot_secrets.md) - [github_organization_members](github_organization_members.md) - [github_repositories](github_repositories.md) + - [github_repository_dependabot_alerts](github_repository_dependabot_alerts.md) + - [github_repository_dependabot_secrets](github_repository_dependabot_secrets.md) - [github_teams](github_teams.md) - [github_team_members](github_team_members.md) - [github_team_repositories](github_team_repositories.md) \ No newline at end of file diff --git a/plugins/source/github/docs/tables/github_external_groups.md b/plugins/source/github/docs/tables/github_external_groups.md index c5ce498d0ae..2db91a4cf65 100644 --- a/plugins/source/github/docs/tables/github_external_groups.md +++ b/plugins/source/github/docs/tables/github_external_groups.md @@ -12,7 +12,7 @@ The composite primary key for this table is (**org**, **group_id**). |_cq_parent_id|UUID| |org (PK)|String| |group_id (PK)|Int| -|updated_at|Timestamp| |group_name|String| +|updated_at|Timestamp| |teams|JSON| |members|JSON| \ No newline at end of file diff --git a/plugins/source/github/docs/tables/github_hook_deliveries.md b/plugins/source/github/docs/tables/github_hook_deliveries.md index fff22e6099f..7a4ec88911a 100644 --- a/plugins/source/github/docs/tables/github_hook_deliveries.md +++ b/plugins/source/github/docs/tables/github_hook_deliveries.md @@ -1,6 +1,6 @@ # Table: github_hook_deliveries -The composite primary key for this table is (**org**, **id**, **hook_id**). +The composite primary key for this table is (**org**, **hook_id**, **id**). ## Relations @@ -15,12 +15,12 @@ This table depends on [github_hooks](github_hooks.md). |_cq_id|UUID| |_cq_parent_id|UUID| |org (PK)|String| -|id (PK)|Int| |hook_id (PK)|Int| |request|String| |response|String| -|delivered_at|Timestamp| +|id (PK)|Int| |guid|String| +|delivered_at|Timestamp| |redelivery|Bool| |duration|Float| |status|String| diff --git a/plugins/source/github/docs/tables/github_hooks.md b/plugins/source/github/docs/tables/github_hooks.md index da0ed855d5f..97fcb1435d4 100644 --- a/plugins/source/github/docs/tables/github_hooks.md +++ b/plugins/source/github/docs/tables/github_hooks.md @@ -16,10 +16,10 @@ The following tables depend on github_hooks: |_cq_id|UUID| |_cq_parent_id|UUID| |org (PK)|String| -|id (PK)|Int| |created_at|Timestamp| |updated_at|Timestamp| |url|String| +|id (PK)|Int| |type|String| |name|String| |test_url|String| diff --git a/plugins/source/github/docs/tables/github_issues.md b/plugins/source/github/docs/tables/github_issues.md index 6650919479d..c2c470ae8ca 100644 --- a/plugins/source/github/docs/tables/github_issues.md +++ b/plugins/source/github/docs/tables/github_issues.md @@ -14,6 +14,7 @@ The composite primary key for this table is (**org**, **id**). |id (PK)|Int| |number|Int| |state|String| +|state_reason|String| |locked|Bool| |title|String| |body|String| diff --git a/plugins/source/github/docs/tables/github_organization_dependabot_alerts.md b/plugins/source/github/docs/tables/github_organization_dependabot_alerts.md new file mode 100644 index 00000000000..8a1c49be98e --- /dev/null +++ b/plugins/source/github/docs/tables/github_organization_dependabot_alerts.md @@ -0,0 +1,31 @@ +# Table: github_organization_dependabot_alerts + +The composite primary key for this table is (**org**, **number**). + +## Relations + +This table depends on [github_organizations](github_organizations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|org (PK)|String| +|number (PK)|Int| +|state|String| +|dependency|JSON| +|security_advisory|JSON| +|security_vulnerability|JSON| +|url|String| +|html_url|String| +|created_at|Timestamp| +|updated_at|Timestamp| +|dismissed_at|Timestamp| +|dismissed_by|JSON| +|dismissed_reason|String| +|dismissed_comment|String| +|fixed_at|Timestamp| \ No newline at end of file diff --git a/plugins/source/github/docs/tables/github_organization_dependabot_secrets.md b/plugins/source/github/docs/tables/github_organization_dependabot_secrets.md new file mode 100644 index 00000000000..d404aef448c --- /dev/null +++ b/plugins/source/github/docs/tables/github_organization_dependabot_secrets.md @@ -0,0 +1,22 @@ +# Table: github_organization_dependabot_secrets + +The composite primary key for this table is (**org**, **name**). + +## Relations + +This table depends on [github_organizations](github_organizations.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|org (PK)|String| +|name (PK)|String| +|created_at|Timestamp| +|updated_at|Timestamp| +|visibility|String| +|selected_repositories_url|String| \ No newline at end of file diff --git a/plugins/source/github/docs/tables/github_organization_members.md b/plugins/source/github/docs/tables/github_organization_members.md index a949e218af0..b661132e424 100644 --- a/plugins/source/github/docs/tables/github_organization_members.md +++ b/plugins/source/github/docs/tables/github_organization_members.md @@ -15,9 +15,9 @@ This table depends on [github_organizations](github_organizations.md). |_cq_id|UUID| |_cq_parent_id|UUID| |org (PK)|String| -|id (PK)|Int| |membership|JSON| |login|String| +|id (PK)|Int| |node_id|String| |avatar_url|String| |html_url|String| diff --git a/plugins/source/github/docs/tables/github_organizations.md b/plugins/source/github/docs/tables/github_organizations.md index ad876dc69f1..cdd4298f9af 100644 --- a/plugins/source/github/docs/tables/github_organizations.md +++ b/plugins/source/github/docs/tables/github_organizations.md @@ -5,6 +5,8 @@ The composite primary key for this table is (**org**, **id**). ## Relations The following tables depend on github_organizations: + - [github_organization_dependabot_alerts](github_organization_dependabot_alerts.md) + - [github_organization_dependabot_secrets](github_organization_dependabot_secrets.md) - [github_organization_members](github_organization_members.md) ## Columns @@ -16,8 +18,8 @@ The following tables depend on github_organizations: |_cq_id|UUID| |_cq_parent_id|UUID| |org (PK)|String| -|id (PK)|Int| |login|String| +|id (PK)|Int| |node_id|String| |avatar_url|String| |html_url|String| diff --git a/plugins/source/github/docs/tables/github_repositories.md b/plugins/source/github/docs/tables/github_repositories.md index 53cbd8e2072..72c840c3db3 100644 --- a/plugins/source/github/docs/tables/github_repositories.md +++ b/plugins/source/github/docs/tables/github_repositories.md @@ -2,6 +2,12 @@ The composite primary key for this table is (**org**, **id**). +## Relations + +The following tables depend on github_repositories: + - [github_repository_dependabot_alerts](github_repository_dependabot_alerts.md) + - [github_repository_dependabot_secrets](github_repository_dependabot_secrets.md) + ## Columns | Name | Type | @@ -12,9 +18,6 @@ The composite primary key for this table is (**org**, **id**). |_cq_parent_id|UUID| |org (PK)|String| |id (PK)|Int| -|created_at|Timestamp| -|pushed_at|Timestamp| -|updated_at|Timestamp| |node_id|String| |owner|JSON| |name|String| @@ -24,6 +27,9 @@ The composite primary key for this table is (**org**, **id**). |code_of_conduct|JSON| |default_branch|String| |master_branch|String| +|created_at|Timestamp| +|pushed_at|Timestamp| +|updated_at|Timestamp| |html_url|String| |clone_url|String| |git_url|String| @@ -69,6 +75,7 @@ The composite primary key for this table is (**org**, **id**). |has_pages|Bool| |has_projects|Bool| |has_downloads|Bool| +|has_discussions|Bool| |is_template|Bool| |license_template|String| |gitignore_template|String| diff --git a/plugins/source/github/docs/tables/github_repository_dependabot_alerts.md b/plugins/source/github/docs/tables/github_repository_dependabot_alerts.md new file mode 100644 index 00000000000..e91489aff34 --- /dev/null +++ b/plugins/source/github/docs/tables/github_repository_dependabot_alerts.md @@ -0,0 +1,32 @@ +# Table: github_repository_dependabot_alerts + +The composite primary key for this table is (**org**, **repository_id**, **number**). + +## Relations + +This table depends on [github_repositories](github_repositories.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|org (PK)|String| +|repository_id (PK)|Int| +|number (PK)|Int| +|state|String| +|dependency|JSON| +|security_advisory|JSON| +|security_vulnerability|JSON| +|url|String| +|html_url|String| +|created_at|Timestamp| +|updated_at|Timestamp| +|dismissed_at|Timestamp| +|dismissed_by|JSON| +|dismissed_reason|String| +|dismissed_comment|String| +|fixed_at|Timestamp| \ No newline at end of file diff --git a/plugins/source/github/docs/tables/github_repository_dependabot_secrets.md b/plugins/source/github/docs/tables/github_repository_dependabot_secrets.md new file mode 100644 index 00000000000..f2b334f569a --- /dev/null +++ b/plugins/source/github/docs/tables/github_repository_dependabot_secrets.md @@ -0,0 +1,23 @@ +# Table: github_repository_dependabot_secrets + +The composite primary key for this table is (**org**, **repository_id**, **name**). + +## Relations + +This table depends on [github_repositories](github_repositories.md). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|org (PK)|String| +|repository_id (PK)|Int| +|name (PK)|String| +|created_at|Timestamp| +|updated_at|Timestamp| +|visibility|String| +|selected_repositories_url|String| \ No newline at end of file diff --git a/plugins/source/github/docs/tables/github_team_members.md b/plugins/source/github/docs/tables/github_team_members.md index fb9f8080b5a..a3c9f98cf75 100644 --- a/plugins/source/github/docs/tables/github_team_members.md +++ b/plugins/source/github/docs/tables/github_team_members.md @@ -1,6 +1,6 @@ # Table: github_team_members -The composite primary key for this table is (**org**, **id**, **team_id**). +The composite primary key for this table is (**org**, **team_id**, **id**). ## Relations @@ -15,10 +15,10 @@ This table depends on [github_teams](github_teams.md). |_cq_id|UUID| |_cq_parent_id|UUID| |org (PK)|String| -|id (PK)|Int| |team_id (PK)|Int| |membership|JSON| |login|String| +|id (PK)|Int| |node_id|String| |avatar_url|String| |html_url|String| diff --git a/plugins/source/github/docs/tables/github_team_repositories.md b/plugins/source/github/docs/tables/github_team_repositories.md index b1134a16c41..addf1f88006 100644 --- a/plugins/source/github/docs/tables/github_team_repositories.md +++ b/plugins/source/github/docs/tables/github_team_repositories.md @@ -1,6 +1,6 @@ # Table: github_team_repositories -The composite primary key for this table is (**org**, **id**, **team_id**). +The composite primary key for this table is (**org**, **team_id**, **id**). ## Relations @@ -15,11 +15,8 @@ This table depends on [github_teams](github_teams.md). |_cq_id|UUID| |_cq_parent_id|UUID| |org (PK)|String| -|id (PK)|Int| -|created_at|Timestamp| -|pushed_at|Timestamp| -|updated_at|Timestamp| |team_id (PK)|Int| +|id (PK)|Int| |node_id|String| |owner|JSON| |name|String| @@ -29,6 +26,9 @@ This table depends on [github_teams](github_teams.md). |code_of_conduct|JSON| |default_branch|String| |master_branch|String| +|created_at|Timestamp| +|pushed_at|Timestamp| +|updated_at|Timestamp| |html_url|String| |clone_url|String| |git_url|String| @@ -74,6 +74,7 @@ This table depends on [github_teams](github_teams.md). |has_pages|Bool| |has_projects|Bool| |has_downloads|Bool| +|has_discussions|Bool| |is_template|Bool| |license_template|String| |gitignore_template|String| diff --git a/plugins/source/github/docs/tables/github_workflows.md b/plugins/source/github/docs/tables/github_workflows.md index a586400ac43..6b25d3179af 100644 --- a/plugins/source/github/docs/tables/github_workflows.md +++ b/plugins/source/github/docs/tables/github_workflows.md @@ -11,8 +11,8 @@ The composite primary key for this table is (**org**, **id**). |_cq_id|UUID| |_cq_parent_id|UUID| |org (PK)|String| -|id (PK)|Int| |contents|String| +|id (PK)|Int| |node_id|String| |name|String| |path|String| diff --git a/plugins/source/github/go.mod b/plugins/source/github/go.mod index 10458d9b3b7..c2d224972ab 100644 --- a/plugins/source/github/go.mod +++ b/plugins/source/github/go.mod @@ -3,9 +3,9 @@ module github.com/cloudquery/cloudquery/plugins/source/github go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/golang/mock v1.6.0 - github.com/google/go-github/v48 v48.1.0 + github.com/google/go-github/v48 v48.2.0 github.com/iancoleman/strcase v0.2.0 github.com/rs/zerolog v1.28.0 github.com/thoas/go-funk v0.9.3-0.20221027085339-5573bc209e28 diff --git a/plugins/source/github/go.sum b/plugins/source/github/go.sum index fa5cdb3442d..b4bfd26f659 100644 --- a/plugins/source/github/go.sum +++ b/plugins/source/github/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -106,8 +106,8 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-github/v48 v48.1.0 h1:nqPqq+0oRY2AMR/SRskGrrP4nnewPB7e/m2+kbT/UvM= -github.com/google/go-github/v48 v48.1.0/go.mod h1:dDlehKBDo850ZPvCTK0sEqTCVWcrGl2LcDiajkYi89Y= +github.com/google/go-github/v48 v48.2.0 h1:68puzySE6WqUY9KWmpOsDEQfDZsso98rT6pZcz9HqcE= +github.com/google/go-github/v48 v48.2.0/go.mod h1:dDlehKBDo850ZPvCTK0sEqTCVWcrGl2LcDiajkYi89Y= 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/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= diff --git a/plugins/source/github/resources/services/actions/workflows.go b/plugins/source/github/resources/services/actions/workflows.go index 40fc4483d8c..10f1b0f7a27 100644 --- a/plugins/source/github/resources/services/actions/workflows.go +++ b/plugins/source/github/resources/services/actions/workflows.go @@ -22,6 +22,11 @@ func Workflows() *schema.Table { PrimaryKey: true, }, }, + { + Name: "contents", + Type: schema.TypeString, + Resolver: resolveContents, + }, { Name: "id", Type: schema.TypeInt, @@ -30,11 +35,6 @@ func Workflows() *schema.Table { PrimaryKey: true, }, }, - { - Name: "contents", - Type: schema.TypeString, - Resolver: resolveContents, - }, { Name: "node_id", Type: schema.TypeString, diff --git a/plugins/source/github/resources/services/external/groups.go b/plugins/source/github/resources/services/external/groups.go index 8b4181539d8..53e5c9e898d 100644 --- a/plugins/source/github/resources/services/external/groups.go +++ b/plugins/source/github/resources/services/external/groups.go @@ -30,16 +30,16 @@ func Groups() *schema.Table { PrimaryKey: true, }, }, - { - Name: "updated_at", - Type: schema.TypeTimestamp, - Resolver: schema.PathResolver("UpdatedAt.Time"), - }, { Name: "group_name", Type: schema.TypeString, Resolver: schema.PathResolver("GroupName"), }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, { Name: "teams", Type: schema.TypeJSON, diff --git a/plugins/source/github/resources/services/hooks/deliveries.go b/plugins/source/github/resources/services/hooks/deliveries.go index ae8dee85d09..34cd91d2f78 100644 --- a/plugins/source/github/resources/services/hooks/deliveries.go +++ b/plugins/source/github/resources/services/hooks/deliveries.go @@ -21,14 +21,6 @@ func Deliveries() *schema.Table { PrimaryKey: true, }, }, - { - Name: "id", - Type: schema.TypeInt, - Resolver: schema.PathResolver("ID"), - CreationOptions: schema.ColumnCreationOptions{ - PrimaryKey: true, - }, - }, { Name: "hook_id", Type: schema.TypeInt, @@ -49,15 +41,23 @@ func Deliveries() *schema.Table { Resolver: resolveResponse, }, { - Name: "delivered_at", - Type: schema.TypeTimestamp, - Resolver: schema.PathResolver("DeliveredAt.Time"), + Name: "id", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, }, { Name: "guid", Type: schema.TypeString, Resolver: schema.PathResolver("GUID"), }, + { + Name: "delivered_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("DeliveredAt"), + }, { Name: "redelivery", Type: schema.TypeBool, diff --git a/plugins/source/github/resources/services/hooks/hooks.go b/plugins/source/github/resources/services/hooks/hooks.go index d2c070edf44..a85b14eda2c 100644 --- a/plugins/source/github/resources/services/hooks/hooks.go +++ b/plugins/source/github/resources/services/hooks/hooks.go @@ -22,14 +22,6 @@ func Hooks() *schema.Table { PrimaryKey: true, }, }, - { - Name: "id", - Type: schema.TypeInt, - Resolver: schema.PathResolver("ID"), - CreationOptions: schema.ColumnCreationOptions{ - PrimaryKey: true, - }, - }, { Name: "created_at", Type: schema.TypeTimestamp, @@ -45,6 +37,14 @@ func Hooks() *schema.Table { Type: schema.TypeString, Resolver: schema.PathResolver("URL"), }, + { + Name: "id", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, { Name: "type", Type: schema.TypeString, diff --git a/plugins/source/github/resources/services/issues/issues.go b/plugins/source/github/resources/services/issues/issues.go index ffecfbdff21..f7f16df6090 100644 --- a/plugins/source/github/resources/services/issues/issues.go +++ b/plugins/source/github/resources/services/issues/issues.go @@ -40,6 +40,11 @@ func Issues() *schema.Table { Type: schema.TypeString, Resolver: schema.PathResolver("State"), }, + { + Name: "state_reason", + Type: schema.TypeString, + Resolver: schema.PathResolver("StateReason"), + }, { Name: "locked", Type: schema.TypeBool, diff --git a/plugins/source/github/resources/services/organizations/alerts.go b/plugins/source/github/resources/services/organizations/alerts.go new file mode 100644 index 00000000000..ee3a8acaa98 --- /dev/null +++ b/plugins/source/github/resources/services/organizations/alerts.go @@ -0,0 +1,99 @@ +// Code generated by codegen; DO NOT EDIT. + +package organizations + +import ( + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Alerts() *schema.Table { + return &schema.Table{ + Name: "github_organization_dependabot_alerts", + Resolver: fetchAlerts, + Columns: []schema.Column{ + { + Name: "org", + Type: schema.TypeString, + Resolver: client.ResolveOrg, + Description: `The Github Organization of the resource.`, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "number", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Number"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: schema.PathResolver("State"), + }, + { + Name: "dependency", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Dependency"), + }, + { + Name: "security_advisory", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("SecurityAdvisory"), + }, + { + Name: "security_vulnerability", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("SecurityVulnerability"), + }, + { + Name: "url", + Type: schema.TypeString, + Resolver: schema.PathResolver("URL"), + }, + { + Name: "html_url", + Type: schema.TypeString, + Resolver: schema.PathResolver("HTMLURL"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + { + Name: "dismissed_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("DismissedAt"), + }, + { + Name: "dismissed_by", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("DismissedBy"), + }, + { + Name: "dismissed_reason", + Type: schema.TypeString, + Resolver: schema.PathResolver("DismissedReason"), + }, + { + Name: "dismissed_comment", + Type: schema.TypeString, + Resolver: schema.PathResolver("DismissedComment"), + }, + { + Name: "fixed_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("FixedAt"), + }, + }, + } +} diff --git a/plugins/source/github/resources/services/organizations/alerts_fetch.go b/plugins/source/github/resources/services/organizations/alerts_fetch.go new file mode 100644 index 00000000000..639226fc2a4 --- /dev/null +++ b/plugins/source/github/resources/services/organizations/alerts_fetch.go @@ -0,0 +1,21 @@ +package organizations + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchAlerts(ctx context.Context, meta schema.ClientMeta, _ *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + + alerts, _, err := c.Github.Dependabot.ListOrgAlerts(ctx, c.Org, nil) + if err != nil { + return err + } + + res <- alerts + + return nil +} diff --git a/plugins/source/github/resources/services/organizations/dependabot_mock_test.go b/plugins/source/github/resources/services/organizations/dependabot_mock_test.go new file mode 100644 index 00000000000..9ec0d1fab69 --- /dev/null +++ b/plugins/source/github/resources/services/organizations/dependabot_mock_test.go @@ -0,0 +1,31 @@ +package organizations + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/cloudquery/plugins/source/github/client/mocks" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/golang/mock/gomock" + "github.com/google/go-github/v48/github" +) + +func buildDependabot(t *testing.T, ctrl *gomock.Controller) client.DependabotService { + mock := mocks.NewMockDependabotService(ctrl) + + var alert github.DependabotAlert + if err := faker.FakeObject(&alert); err != nil { + t.Fatal(err) + } + mock.EXPECT().ListOrgAlerts(gomock.Any(), gomock.Any(), gomock.Any()).Return( + []*github.DependabotAlert{&alert}, &github.Response{}, nil) + + var secret github.Secret + if err := faker.FakeObject(&secret); err != nil { + t.Fatal(err) + } + mock.EXPECT().ListOrgSecrets(gomock.Any(), gomock.Any(), gomock.Any()).Return( + &github.Secrets{TotalCount: 1, Secrets: []*github.Secret{&secret}}, &github.Response{}, nil) + + return mock +} diff --git a/plugins/source/github/resources/services/organizations/members.go b/plugins/source/github/resources/services/organizations/members.go index 1926105907a..d5f8eff7371 100644 --- a/plugins/source/github/resources/services/organizations/members.go +++ b/plugins/source/github/resources/services/organizations/members.go @@ -21,14 +21,6 @@ func Members() *schema.Table { PrimaryKey: true, }, }, - { - Name: "id", - Type: schema.TypeInt, - Resolver: schema.PathResolver("ID"), - CreationOptions: schema.ColumnCreationOptions{ - PrimaryKey: true, - }, - }, { Name: "membership", Type: schema.TypeJSON, @@ -39,6 +31,14 @@ func Members() *schema.Table { Type: schema.TypeString, Resolver: schema.PathResolver("Login"), }, + { + Name: "id", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, { Name: "node_id", Type: schema.TypeString, diff --git a/plugins/source/github/resources/services/organizations/organizations.go b/plugins/source/github/resources/services/organizations/organizations.go index b5085576e35..d61b584a05c 100644 --- a/plugins/source/github/resources/services/organizations/organizations.go +++ b/plugins/source/github/resources/services/organizations/organizations.go @@ -22,6 +22,11 @@ func Organizations() *schema.Table { PrimaryKey: true, }, }, + { + Name: "login", + Type: schema.TypeString, + Resolver: schema.PathResolver("Login"), + }, { Name: "id", Type: schema.TypeInt, @@ -30,11 +35,6 @@ func Organizations() *schema.Table { PrimaryKey: true, }, }, - { - Name: "login", - Type: schema.TypeString, - Resolver: schema.PathResolver("Login"), - }, { Name: "node_id", Type: schema.TypeString, @@ -303,6 +303,8 @@ func Organizations() *schema.Table { }, Relations: []*schema.Table{ + Alerts(), + Secrets(), Members(), }, } diff --git a/plugins/source/github/resources/services/organizations/organizations_test.go b/plugins/source/github/resources/services/organizations/organizations_test.go index 669507652dd..56341ef1dd1 100644 --- a/plugins/source/github/resources/services/organizations/organizations_test.go +++ b/plugins/source/github/resources/services/organizations/organizations_test.go @@ -33,7 +33,12 @@ func buildOrganizations(t *testing.T, ctrl *gomock.Controller) client.GithubServ mock.EXPECT().GetOrgMembership(gomock.Any(), *u.Login, gomock.Any()).Return( &m, &github.Response{}, nil) - return client.GithubServices{Organizations: mock} + dependabot := buildDependabot(t, ctrl) + + return client.GithubServices{ + Dependabot: dependabot, + Organizations: mock, + } } func TestOrganizations(t *testing.T) { diff --git a/plugins/source/github/resources/services/organizations/secrets.go b/plugins/source/github/resources/services/organizations/secrets.go new file mode 100644 index 00000000000..a5fc380a650 --- /dev/null +++ b/plugins/source/github/resources/services/organizations/secrets.go @@ -0,0 +1,54 @@ +// Code generated by codegen; DO NOT EDIT. + +package organizations + +import ( + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Secrets() *schema.Table { + return &schema.Table{ + Name: "github_organization_dependabot_secrets", + Resolver: fetchSecrets, + Columns: []schema.Column{ + { + Name: "org", + Type: schema.TypeString, + Resolver: client.ResolveOrg, + Description: `The Github Organization of the resource.`, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + { + Name: "visibility", + Type: schema.TypeString, + Resolver: schema.PathResolver("Visibility"), + }, + { + Name: "selected_repositories_url", + Type: schema.TypeString, + Resolver: schema.PathResolver("SelectedRepositoriesURL"), + }, + }, + } +} diff --git a/plugins/source/github/resources/services/organizations/secrets_fetch.go b/plugins/source/github/resources/services/organizations/secrets_fetch.go new file mode 100644 index 00000000000..214af33d74f --- /dev/null +++ b/plugins/source/github/resources/services/organizations/secrets_fetch.go @@ -0,0 +1,21 @@ +package organizations + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchSecrets(ctx context.Context, meta schema.ClientMeta, _ *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + + secrets, _, err := c.Github.Dependabot.ListOrgSecrets(ctx, c.Org, nil) + if err != nil { + return err + } + + res <- secrets.Secrets + + return nil +} diff --git a/plugins/source/github/resources/services/repositories/alerts.go b/plugins/source/github/resources/services/repositories/alerts.go new file mode 100644 index 00000000000..f4ee272c743 --- /dev/null +++ b/plugins/source/github/resources/services/repositories/alerts.go @@ -0,0 +1,107 @@ +// Code generated by codegen; DO NOT EDIT. + +package repositories + +import ( + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Alerts() *schema.Table { + return &schema.Table{ + Name: "github_repository_dependabot_alerts", + Resolver: fetchAlerts, + Columns: []schema.Column{ + { + Name: "org", + Type: schema.TypeString, + Resolver: client.ResolveOrg, + Description: `The Github Organization of the resource.`, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "repository_id", + Type: schema.TypeInt, + Resolver: client.ResolveParentColumn("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "number", + Type: schema.TypeInt, + Resolver: schema.PathResolver("Number"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "state", + Type: schema.TypeString, + Resolver: schema.PathResolver("State"), + }, + { + Name: "dependency", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Dependency"), + }, + { + Name: "security_advisory", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("SecurityAdvisory"), + }, + { + Name: "security_vulnerability", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("SecurityVulnerability"), + }, + { + Name: "url", + Type: schema.TypeString, + Resolver: schema.PathResolver("URL"), + }, + { + Name: "html_url", + Type: schema.TypeString, + Resolver: schema.PathResolver("HTMLURL"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + { + Name: "dismissed_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("DismissedAt"), + }, + { + Name: "dismissed_by", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("DismissedBy"), + }, + { + Name: "dismissed_reason", + Type: schema.TypeString, + Resolver: schema.PathResolver("DismissedReason"), + }, + { + Name: "dismissed_comment", + Type: schema.TypeString, + Resolver: schema.PathResolver("DismissedComment"), + }, + { + Name: "fixed_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("FixedAt"), + }, + }, + } +} diff --git a/plugins/source/github/resources/services/repositories/alerts_fetch.go b/plugins/source/github/resources/services/repositories/alerts_fetch.go new file mode 100644 index 00000000000..c54260ed2ae --- /dev/null +++ b/plugins/source/github/resources/services/repositories/alerts_fetch.go @@ -0,0 +1,23 @@ +package repositories + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/google/go-github/v48/github" +) + +func fetchAlerts(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + repo := parent.Item.(*github.Repository) + + alerts, _, err := c.Github.Dependabot.ListRepoAlerts(ctx, c.Org, *repo.Name, nil) + if err != nil { + return err + } + + res <- alerts + + return nil +} diff --git a/plugins/source/github/resources/services/repositories/dependabot_mock_test.go b/plugins/source/github/resources/services/repositories/dependabot_mock_test.go new file mode 100644 index 00000000000..06f8b6b0a51 --- /dev/null +++ b/plugins/source/github/resources/services/repositories/dependabot_mock_test.go @@ -0,0 +1,31 @@ +package repositories + +import ( + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/cloudquery/plugins/source/github/client/mocks" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/golang/mock/gomock" + "github.com/google/go-github/v48/github" +) + +func buildDependabot(t *testing.T, ctrl *gomock.Controller) client.DependabotService { + mock := mocks.NewMockDependabotService(ctrl) + + var alert github.DependabotAlert + if err := faker.FakeObject(&alert); err != nil { + t.Fatal(err) + } + mock.EXPECT().ListRepoAlerts(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return( + []*github.DependabotAlert{&alert}, &github.Response{}, nil) + + var secret github.Secret + if err := faker.FakeObject(&secret); err != nil { + t.Fatal(err) + } + mock.EXPECT().ListRepoSecrets(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return( + &github.Secrets{TotalCount: 1, Secrets: []*github.Secret{&secret}}, &github.Response{}, nil) + + return mock +} diff --git a/plugins/source/github/resources/services/repositories/repositories.go b/plugins/source/github/resources/services/repositories/repositories.go index 42bf6a8e72c..d18079eae4b 100644 --- a/plugins/source/github/resources/services/repositories/repositories.go +++ b/plugins/source/github/resources/services/repositories/repositories.go @@ -30,21 +30,6 @@ func Repositories() *schema.Table { PrimaryKey: true, }, }, - { - Name: "created_at", - Type: schema.TypeTimestamp, - Resolver: schema.PathResolver("CreatedAt.Time"), - }, - { - Name: "pushed_at", - Type: schema.TypeTimestamp, - Resolver: schema.PathResolver("PushedAt.Time"), - }, - { - Name: "updated_at", - Type: schema.TypeTimestamp, - Resolver: schema.PathResolver("UpdatedAt.Time"), - }, { Name: "node_id", Type: schema.TypeString, @@ -90,6 +75,21 @@ func Repositories() *schema.Table { Type: schema.TypeString, Resolver: schema.PathResolver("MasterBranch"), }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "pushed_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("PushedAt"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, { Name: "html_url", Type: schema.TypeString, @@ -315,6 +315,11 @@ func Repositories() *schema.Table { Type: schema.TypeBool, Resolver: schema.PathResolver("HasDownloads"), }, + { + Name: "has_discussions", + Type: schema.TypeBool, + Resolver: schema.PathResolver("HasDiscussions"), + }, { Name: "is_template", Type: schema.TypeBool, @@ -541,5 +546,10 @@ func Repositories() *schema.Table { Resolver: schema.PathResolver("RoleName"), }, }, + + Relations: []*schema.Table{ + Alerts(), + Secrets(), + }, } } diff --git a/plugins/source/github/resources/services/repositories/repositories_test.go b/plugins/source/github/resources/services/repositories/repositories_test.go index 6105087103b..1eeacb7fa87 100644 --- a/plugins/source/github/resources/services/repositories/repositories_test.go +++ b/plugins/source/github/resources/services/repositories/repositories_test.go @@ -25,7 +25,12 @@ func buildRepositiories(t *testing.T, ctrl *gomock.Controller) client.GithubServ mock.EXPECT().ListByOrg(gomock.Any(), "testorg", gomock.Any()).Return( []*github.Repository{&cs}, &github.Response{}, nil) - return client.GithubServices{Repositories: mock} + dependabot := buildDependabot(t, ctrl) + + return client.GithubServices{ + Dependabot: dependabot, + Repositories: mock, + } } func TestRepos(t *testing.T) { diff --git a/plugins/source/github/resources/services/repositories/secrets.go b/plugins/source/github/resources/services/repositories/secrets.go new file mode 100644 index 00000000000..9e61e04e4f7 --- /dev/null +++ b/plugins/source/github/resources/services/repositories/secrets.go @@ -0,0 +1,62 @@ +// Code generated by codegen; DO NOT EDIT. + +package repositories + +import ( + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Secrets() *schema.Table { + return &schema.Table{ + Name: "github_repository_dependabot_secrets", + Resolver: fetchSecrets, + Columns: []schema.Column{ + { + Name: "org", + Type: schema.TypeString, + Resolver: client.ResolveOrg, + Description: `The Github Organization of the resource.`, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "repository_id", + Type: schema.TypeInt, + Resolver: client.ResolveParentColumn("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, + { + Name: "visibility", + Type: schema.TypeString, + Resolver: schema.PathResolver("Visibility"), + }, + { + Name: "selected_repositories_url", + Type: schema.TypeString, + Resolver: schema.PathResolver("SelectedRepositoriesURL"), + }, + }, + } +} diff --git a/plugins/source/github/resources/services/repositories/secrets_fetch.go b/plugins/source/github/resources/services/repositories/secrets_fetch.go new file mode 100644 index 00000000000..7e724b5adba --- /dev/null +++ b/plugins/source/github/resources/services/repositories/secrets_fetch.go @@ -0,0 +1,23 @@ +package repositories + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/github/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/google/go-github/v48/github" +) + +func fetchSecrets(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + repo := parent.Item.(*github.Repository) + + secrets, _, err := c.Github.Dependabot.ListRepoSecrets(ctx, c.Org, *repo.Name, nil) + if err != nil { + return err + } + + res <- secrets.Secrets + + return nil +} diff --git a/plugins/source/github/resources/services/teams/members.go b/plugins/source/github/resources/services/teams/members.go index e54ed54cb08..1816bd348c8 100644 --- a/plugins/source/github/resources/services/teams/members.go +++ b/plugins/source/github/resources/services/teams/members.go @@ -21,14 +21,6 @@ func Members() *schema.Table { PrimaryKey: true, }, }, - { - Name: "id", - Type: schema.TypeInt, - Resolver: schema.PathResolver("ID"), - CreationOptions: schema.ColumnCreationOptions{ - PrimaryKey: true, - }, - }, { Name: "team_id", Type: schema.TypeInt, @@ -47,6 +39,14 @@ func Members() *schema.Table { Type: schema.TypeString, Resolver: schema.PathResolver("Login"), }, + { + Name: "id", + Type: schema.TypeInt, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, { Name: "node_id", Type: schema.TypeString, diff --git a/plugins/source/github/resources/services/teams/repositories.go b/plugins/source/github/resources/services/teams/repositories.go index c94c68ed217..95433cee4bb 100644 --- a/plugins/source/github/resources/services/teams/repositories.go +++ b/plugins/source/github/resources/services/teams/repositories.go @@ -22,32 +22,17 @@ func Repositories() *schema.Table { }, }, { - Name: "id", + Name: "team_id", Type: schema.TypeInt, - Resolver: schema.PathResolver("ID"), + Resolver: client.ResolveParentColumn("ID"), CreationOptions: schema.ColumnCreationOptions{ PrimaryKey: true, }, }, { - Name: "created_at", - Type: schema.TypeTimestamp, - Resolver: schema.PathResolver("CreatedAt.Time"), - }, - { - Name: "pushed_at", - Type: schema.TypeTimestamp, - Resolver: schema.PathResolver("PushedAt.Time"), - }, - { - Name: "updated_at", - Type: schema.TypeTimestamp, - Resolver: schema.PathResolver("UpdatedAt.Time"), - }, - { - Name: "team_id", + Name: "id", Type: schema.TypeInt, - Resolver: client.ResolveParentColumn("ID"), + Resolver: schema.PathResolver("ID"), CreationOptions: schema.ColumnCreationOptions{ PrimaryKey: true, }, @@ -97,6 +82,21 @@ func Repositories() *schema.Table { Type: schema.TypeString, Resolver: schema.PathResolver("MasterBranch"), }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "pushed_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("PushedAt"), + }, + { + Name: "updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("UpdatedAt"), + }, { Name: "html_url", Type: schema.TypeString, @@ -322,6 +322,11 @@ func Repositories() *schema.Table { Type: schema.TypeBool, Resolver: schema.PathResolver("HasDownloads"), }, + { + Name: "has_discussions", + Type: schema.TypeBool, + Resolver: schema.PathResolver("HasDiscussions"), + }, { Name: "is_template", Type: schema.TypeBool, diff --git a/plugins/source/gitlab/go.mod b/plugins/source/gitlab/go.mod index 9b29e0ada60..b927ca4a0b3 100644 --- a/plugins/source/gitlab/go.mod +++ b/plugins/source/gitlab/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/gitlab go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/iancoleman/strcase v0.2.0 github.com/julienschmidt/httprouter v1.3.0 github.com/rs/zerolog v1.28.0 diff --git a/plugins/source/gitlab/go.sum b/plugins/source/gitlab/go.sum index 8cd7a42b1f8..5e4c31ada7c 100644 --- a/plugins/source/gitlab/go.sum +++ b/plugins/source/gitlab/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/heroku/go.mod b/plugins/source/heroku/go.mod index 9f5dc9fbd16..7854b434b24 100644 --- a/plugins/source/heroku/go.mod +++ b/plugins/source/heroku/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/heroku go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/google/go-cmp v0.5.9 github.com/googleapis/gax-go/v2 v2.7.0 github.com/heroku/heroku-go/v5 v5.5.0 diff --git a/plugins/source/heroku/go.sum b/plugins/source/heroku/go.sum index cabf7ffad88..e3e50f609af 100644 --- a/plugins/source/heroku/go.sum +++ b/plugins/source/heroku/go.sum @@ -49,8 +49,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/k8s/go.mod b/plugins/source/k8s/go.mod index f3a18f78c44..703bd1e0485 100644 --- a/plugins/source/k8s/go.mod +++ b/plugins/source/k8s/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/k8s go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/golang/mock v1.6.0 github.com/google/gnostic v0.6.9 github.com/iancoleman/strcase v0.2.0 diff --git a/plugins/source/k8s/go.sum b/plugins/source/k8s/go.sum index 3e8ea4049ad..af3645f84a7 100644 --- a/plugins/source/k8s/go.sum +++ b/plugins/source/k8s/go.sum @@ -66,8 +66,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= diff --git a/plugins/source/k8s/test/policy_cq_config.yml b/plugins/source/k8s/test/policy_cq_config.yml index c6249346dc5..8f4a430b83a 100644 --- a/plugins/source/k8s/test/policy_cq_config.yml +++ b/plugins/source/k8s/test/policy_cq_config.yml @@ -10,6 +10,6 @@ kind: destination spec: name: postgresql path: cloudquery/postgresql - version: "v1.10.0" # latest version of postgresql plugin + version: "v2.0.0" # latest version of postgresql plugin spec: connection_string: ${CQ_DSN} \ No newline at end of file diff --git a/plugins/source/okta/go.mod b/plugins/source/okta/go.mod index 9563cd7d9b1..45412b9218b 100644 --- a/plugins/source/okta/go.mod +++ b/plugins/source/okta/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/okta go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/gertd/go-pluralize v0.2.1 github.com/gorilla/mux v1.8.0 github.com/okta/okta-sdk-golang/v3 v3.0.1 diff --git a/plugins/source/okta/go.sum b/plugins/source/okta/go.sum index 6eb3418ac51..09c0d6e719a 100644 --- a/plugins/source/okta/go.sum +++ b/plugins/source/okta/go.sum @@ -42,8 +42,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/pagerduty/go.mod b/plugins/source/pagerduty/go.mod index 995c720fd16..28f81b07911 100644 --- a/plugins/source/pagerduty/go.mod +++ b/plugins/source/pagerduty/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/PagerDuty/go-pagerduty v1.6.0 - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/iancoleman/strcase v0.2.0 github.com/rs/zerolog v1.28.0 golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 diff --git a/plugins/source/pagerduty/go.sum b/plugins/source/pagerduty/go.sum index 08df13ddf9c..1a769f7e696 100644 --- a/plugins/source/pagerduty/go.sum +++ b/plugins/source/pagerduty/go.sum @@ -44,8 +44,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/salesforce/CHANGELOG.md b/plugins/source/salesforce/CHANGELOG.md index 825c32f0d03..f2f08e25854 100644 --- a/plugins/source/salesforce/CHANGELOG.md +++ b/plugins/source/salesforce/CHANGELOG.md @@ -1 +1,10 @@ # Changelog + +## 1.0.0 (2022-12-27) + + +### Features + +* **salesforce:** New Salesforce source plugin ([#5954](https://github.com/cloudquery/cloudquery/issues/5954)) ([bf8348d](https://github.com/cloudquery/cloudquery/commit/bf8348df92b192b41a4a34a7cffdd48ec3b45bd4)) + +## Changelog diff --git a/plugins/source/salesforce/go.mod b/plugins/source/salesforce/go.mod index e5871b911d9..9f571a01624 100644 --- a/plugins/source/salesforce/go.mod +++ b/plugins/source/salesforce/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/salesforce go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/gorilla/mux v1.8.0 github.com/rs/zerolog v1.28.0 ) diff --git a/plugins/source/salesforce/go.sum b/plugins/source/salesforce/go.sum index c5d534eac0b..5a0c2517863 100644 --- a/plugins/source/salesforce/go.sum +++ b/plugins/source/salesforce/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/slack/go.mod b/plugins/source/slack/go.mod index 36efe2e203a..c11d3a9d858 100644 --- a/plugins/source/slack/go.mod +++ b/plugins/source/slack/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/slack go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/gertd/go-pluralize v0.2.1 github.com/golang/mock v1.6.0 github.com/rs/zerolog v1.28.0 diff --git a/plugins/source/slack/go.sum b/plugins/source/slack/go.sum index 4db3ebc0f9a..9c12450b374 100644 --- a/plugins/source/slack/go.sum +++ b/plugins/source/slack/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/snyk/.gitignore b/plugins/source/snyk/.gitignore new file mode 100644 index 00000000000..a1aea96316d --- /dev/null +++ b/plugins/source/snyk/.gitignore @@ -0,0 +1 @@ +snyk \ No newline at end of file diff --git a/plugins/source/snyk/.goreleaser.yaml b/plugins/source/snyk/.goreleaser.yaml new file mode 100644 index 00000000000..f2687da843e --- /dev/null +++ b/plugins/source/snyk/.goreleaser.yaml @@ -0,0 +1,14 @@ +variables: + component: source/snyk + binary: snyk + +project_name: plugins/source/snyk + +monorepo: + tag_prefix: plugins-source-snyk- + dir: plugins/source/snyk + +includes: + - from_file: + # Relative to the directory Go Releaser is run from (which is the root of the repository) + path: ./plugins/.goreleaser.yaml \ No newline at end of file diff --git a/plugins/source/snyk/CHANGELOG.md b/plugins/source/snyk/CHANGELOG.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/plugins/source/snyk/Makefile b/plugins/source/snyk/Makefile new file mode 100644 index 00000000000..2b9140514a5 --- /dev/null +++ b/plugins/source/snyk/Makefile @@ -0,0 +1,23 @@ +# Unit tests +.PHONY: test +test: + go test -timeout 3m ./... + +.PHONY: lint +lint: + @golangci-lint run --config ../../.golangci.yml + +.PHONY: gen-code +gen-code: + grep -rl '// Code generated by codegen; DO NOT EDIT.' resources/services/* | xargs rm + go run codegen/main.go + +.PHONY: gen-docs +gen-docs: + rm -rf ./docs/tables/* + go run main.go doc ./docs/tables + sed 's_(\(.*\))_(https://github.com/cloudquery/cloudquery/blob/main/plugins/source/snyk/docs/tables/\1)_' docs/tables/README.md > ../../../website/pages/docs/plugins/sources/snyk/tables.md + +# All gen targets +.PHONY: gen +gen: gen-code gen-docs diff --git a/plugins/source/snyk/README.md b/plugins/source/snyk/README.md new file mode 100644 index 00000000000..d565d6bb91b --- /dev/null +++ b/plugins/source/snyk/README.md @@ -0,0 +1,7 @@ +# Snyk Plugin + +The CloudQuery Snyk plugin pulls configuration out of Snyk and loads it into any supported CloudQuery destination (e.g. PostgreSQL). + +## Links + +- [User Guide](https://docs.cloudquery.io/docs/plugins/sources/snyk/overview) diff --git a/plugins/source/snyk/client/client.go b/plugins/source/snyk/client/client.go new file mode 100644 index 00000000000..0fa858c0d7d --- /dev/null +++ b/plugins/source/snyk/client/client.go @@ -0,0 +1,51 @@ +package client + +import ( + "context" + "fmt" + + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugin-sdk/specs" + "github.com/pavel-snyk/snyk-sdk-go/snyk" + "github.com/rs/zerolog" +) + +type Client struct { + *snyk.Client + + OrganizationID string + organizations []string + + logger zerolog.Logger +} + +var _ schema.ClientMeta = (*Client)(nil) + +func (c *Client) ID() string { + return c.OrganizationID +} + +func (c *Client) Logger() *zerolog.Logger { + return &c.logger +} + +func Configure(ctx context.Context, logger zerolog.Logger, spec specs.Source) (schema.ClientMeta, error) { + snykSpec := new(Spec) + err := spec.UnmarshalSpec(snykSpec) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal spec: %w", err) + } + + client, err := snykSpec.getClient(spec.Version) + if err != nil { + return nil, fmt.Errorf("failed to create Snyk client: %w", err) + } + + c := &Client{ + Client: client, + logger: logger, + organizations: snykSpec.Organizations, + } + + return c, c.initOrganizations(ctx) +} diff --git a/plugins/source/snyk/client/multiplexer.go b/plugins/source/snyk/client/multiplexer.go new file mode 100644 index 00000000000..4fb02f4be3e --- /dev/null +++ b/plugins/source/snyk/client/multiplexer.go @@ -0,0 +1,28 @@ +package client + +import ( + "github.com/cloudquery/plugin-sdk/schema" +) + +func SingleOrganization(meta schema.ClientMeta) []schema.ClientMeta { + client := meta.(*Client) + return []schema.ClientMeta{client.WithOrganization(client.organizations[0])} +} + +func ByOrganization(meta schema.ClientMeta) []schema.ClientMeta { + client := meta.(*Client) + l := make([]schema.ClientMeta, 0, len(client.organizations)) + for _, o := range client.organizations { + l = append(l, client.WithOrganization(o)) + } + return l +} + +func (c *Client) WithOrganization(organizationID string) schema.ClientMeta { + return &Client{ + Client: c.Client, + OrganizationID: organizationID, + organizations: c.organizations, + logger: c.logger.With().Str("organization", organizationID).Logger(), + } +} diff --git a/plugins/source/snyk/client/organizations.go b/plugins/source/snyk/client/organizations.go new file mode 100644 index 00000000000..e9b011368d0 --- /dev/null +++ b/plugins/source/snyk/client/organizations.go @@ -0,0 +1,30 @@ +package client + +import ( + "context" + + "golang.org/x/exp/slices" +) + +func (c *Client) initOrganizations(ctx context.Context) error { + if len(c.organizations) > 0 { + // already set + return nil + } + + orgs, _, err := c.Orgs.List(ctx) + if err != nil { + return err + } + organizations := make([]string, 0, len(orgs)) + for _, org := range orgs { + organizations = append(organizations, org.ID) + } + + c.organizations = organizations + return nil +} + +func (c *Client) WantOrganization(organizationID string) bool { + return slices.Contains(c.organizations, organizationID) +} diff --git a/plugins/source/snyk/client/resolvers.go b/plugins/source/snyk/client/resolvers.go new file mode 100644 index 00000000000..3549f215307 --- /dev/null +++ b/plugins/source/snyk/client/resolvers.go @@ -0,0 +1,12 @@ +package client + +import ( + "context" + + "github.com/cloudquery/plugin-sdk/schema" +) + +func ResolveOrganizationID(_ context.Context, meta schema.ClientMeta, r *schema.Resource, c schema.Column) error { + client := meta.(*Client) + return r.Set(c.Name, client.OrganizationID) +} diff --git a/plugins/source/snyk/client/spec.go b/plugins/source/snyk/client/spec.go new file mode 100644 index 00000000000..1ca22049819 --- /dev/null +++ b/plugins/source/snyk/client/spec.go @@ -0,0 +1,32 @@ +package client + +import ( + "fmt" + + "github.com/pavel-snyk/snyk-sdk-go/snyk" +) + +type Spec struct { + // APIKey required to access Snyk API + APIKey string `json:"api_key,omitempty"` + + // Organizations is a list of organizations to fetch information from. + // By default, will fetch from all organizations available for user. + Organizations []string `json:"organizations,omitempty"` + + // EndpointURL is optional parameter to override the API URL for snyk.Client. + EndpointURL string `json:"endpoint_url,omitempty"` +} + +func (s *Spec) getClient(version string) (*snyk.Client, error) { + if len(s.APIKey) == 0 { + return nil, fmt.Errorf("missing API key") + } + + options := []snyk.ClientOption{snyk.WithUserAgent("cloudquery/snyk/" + version)} + if len(s.EndpointURL) > 0 { + options = append(options, snyk.WithBaseURL(s.EndpointURL)) + } + + return snyk.NewClient(s.APIKey, options...), nil +} diff --git a/plugins/source/snyk/client/testing.go b/plugins/source/snyk/client/testing.go new file mode 100644 index 00000000000..2c6e0017025 --- /dev/null +++ b/plugins/source/snyk/client/testing.go @@ -0,0 +1,72 @@ +package client + +import ( + "context" + "fmt" + "net/http/httptest" + "os" + "testing" + "time" + + "github.com/cloudquery/plugin-sdk/plugins/source" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/cloudquery/plugin-sdk/specs" + "github.com/julienschmidt/httprouter" + "github.com/rs/zerolog" +) + +func MockTestHelper(t *testing.T, table *schema.Table, createService func(*httprouter.Router) error) { + version := "vDev" + t.Helper() + + table.IgnoreInTests = false + mux := httprouter.New() + ts := httptest.NewUnstartedServer(mux) + defer ts.Close() + + newTestExecutionClient := func(ctx context.Context, logger zerolog.Logger, _ specs.Source) (schema.ClientMeta, error) { + err := createService(mux) + if err != nil { + return nil, fmt.Errorf("failed to createService: %w", err) + } + ts.Start() + + snykClient, err := (&Spec{ + APIKey: "test-key", + Organizations: []string{"test-org"}, + EndpointURL: ts.URL + "/", // requires trailing slash + }).getClient(version) + if err != nil { + return nil, fmt.Errorf("failed to create client: %w", err) + } + + c := &Client{ + Client: snykClient, + logger: logger, + organizations: []string{"test-org"}, + } + + return c, nil + } + + l := zerolog.New(zerolog.NewTestWriter(t)).Output( + zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.StampMicro}, + ).Level(zerolog.DebugLevel).With().Timestamp().Logger() + + p := source.NewPlugin( + table.Name, + version, + []*schema.Table{ + table, + }, + newTestExecutionClient) + p.SetLogger(l) + + source.TestPluginSync(t, p, specs.Source{ + Name: "dev", + Path: "cloudquery/dev", + Version: version, + Tables: []string{table.Name}, + Destinations: []string{"mock-destination"}, + }) +} diff --git a/plugins/source/snyk/codegen/main.go b/plugins/source/snyk/codegen/main.go new file mode 100644 index 00000000000..bdf0d081b2b --- /dev/null +++ b/plugins/source/snyk/codegen/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "context" + "log" + + "github.com/cloudquery/cloudquery/plugins/source/snyk/codegen/resources" +) + +func main() { + err := resources.Generate(context.Background()) + if err != nil { + log.Fatal(err) + } +} diff --git a/plugins/source/snyk/codegen/resources/columns.go b/plugins/source/snyk/codegen/resources/columns.go new file mode 100644 index 00000000000..60df30d7983 --- /dev/null +++ b/plugins/source/snyk/codegen/resources/columns.go @@ -0,0 +1,12 @@ +package resources + +import ( + "github.com/cloudquery/plugin-sdk/codegen" + "github.com/cloudquery/plugin-sdk/schema" +) + +var organizationIDCol = codegen.ColumnDefinition{ + Name: "organization_id", + Type: schema.TypeString, + Resolver: "client.ResolveOrganizationID", +} diff --git a/plugins/source/snyk/codegen/resources/description.go b/plugins/source/snyk/codegen/resources/description.go new file mode 100644 index 00000000000..236ce7185f8 --- /dev/null +++ b/plugins/source/snyk/codegen/resources/description.go @@ -0,0 +1,10 @@ +package resources + +import ( + "reflect" +) + +func (r *Resource) description() string { + typ := reflect.TypeOf(r.Struct).Elem() + return "https://pkg.go.dev/" + typ.PkgPath() + "#" + typ.Name() +} diff --git a/plugins/source/snyk/codegen/resources/fetch.go b/plugins/source/snyk/codegen/resources/fetch.go new file mode 100644 index 00000000000..81ceca47877 --- /dev/null +++ b/plugins/source/snyk/codegen/resources/fetch.go @@ -0,0 +1,9 @@ +package resources + +import ( + "github.com/iancoleman/strcase" +) + +func (r *Resource) fetcherName() string { + return "fetch" + strcase.ToCamel(r.SubService) +} diff --git a/plugins/source/snyk/codegen/resources/generate.go b/plugins/source/snyk/codegen/resources/generate.go new file mode 100644 index 00000000000..64a99e99d1e --- /dev/null +++ b/plugins/source/snyk/codegen/resources/generate.go @@ -0,0 +1,97 @@ +package resources + +import ( + "context" + "fmt" + "os" + "path" + "runtime" + "strings" + + "github.com/cloudquery/plugin-sdk/codegen" + "golang.org/x/exp/slices" + "golang.org/x/sync/errgroup" +) + +func Generate(ctx context.Context) error { + resources := recipes() + + grp, _ := errgroup.WithContext(ctx) + for _, resource := range resources { + grp.Go(resource.generate) + } + + if err := grp.Wait(); err != nil { + return err + } + + return tables(resources) +} + +func (r *Resource) generate() error { + r.sanitize() + _, filename, _, ok := runtime.Caller(0) + if !ok { + return fmt.Errorf("failed to get caller information") + } + + dir := path.Dir(filename) + dir = path.Join(dir, "../../resources/services", r.Service) + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + return fmt.Errorf("failed to create directory %s: %w", dir, err) + } + + name := fmt.Sprintf("snyk_%s_%s", r.Service, r.SubService) + if r.Name != "" { + name = r.Name + } + + fmt.Println("generate", name) + for _, child := range r.Children { + if err := child.generate(); err != nil { + return err + } + } + + var err error + opts := []codegen.TableOption{ + codegen.WithExtraColumns(r.ExtraColumns), + codegen.WithPKColumns("id"), + // codegen.WithNameTransformer(nameTransformer), + } + + // All table names must be plural + if !strings.HasSuffix(name, "s") { + return fmt.Errorf("invalid table name: %s. must be plural", name) + } + + r.table, err = codegen.NewTableFromStruct( + name, + r.Struct, + opts..., + ) + if err != nil { + return fmt.Errorf("error generating %s: %w", name, err) + } + r.table.Description = r.description() + r.table.Resolver = r.fetcherName() + if len(r.PreResolver) > 0 { + r.table.PreResourceResolver = r.PreResolver + } + if len(r.PostResolver) > 0 { + r.table.PostResourceResolver = r.PostResolver + } + if len(r.Multiplex) > 0 { + r.table.Multiplex = r.Multiplex + } + for _, child := range r.Children { + r.table.Relations = append(r.table.Relations, csr.ToCamel(child.SubService)+"()") + } + slices.Sort(r.table.Relations) + + if err := r.generateSchema(dir); err != nil { + return err + } + + return nil +} diff --git a/plugins/source/snyk/codegen/resources/recipes.go b/plugins/source/snyk/codegen/resources/recipes.go new file mode 100644 index 00000000000..0fd1c707a45 --- /dev/null +++ b/plugins/source/snyk/codegen/resources/recipes.go @@ -0,0 +1,47 @@ +package resources + +import ( + "github.com/cloudquery/plugin-sdk/codegen" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/pavel-snyk/snyk-sdk-go/snyk" +) + +func recipes() []*Resource { + return []*Resource{ + { + Name: "snyk_dependencies", + Struct: new(snyk.Dependency), + Service: "dependency", + SubService: "dependencies", + Multiplex: "client.ByOrganization", + }, + { + Name: "snyk_organizations", + Struct: new(snyk.Organization), + Service: "organization", + Multiplex: "client.SingleOrganization", + }, + { + Name: "snyk_integrations", + Struct: new(snyk.Integration), + Service: "integration", + ExtraColumns: codegen.ColumnDefinitions{ + organizationIDCol, + codegen.ColumnDefinition{ + Name: "settings", + Type: schema.TypeJSON, + Resolver: "getIntegrationSettings", + }, + }, + Multiplex: "client.ByOrganization", + PreResolver: "getIntegration", + }, + { + Name: "snyk_projects", + Struct: new(snyk.Project), + Service: "project", + ExtraColumns: codegen.ColumnDefinitions{organizationIDCol}, + Multiplex: "client.ByOrganization", + }, + } +} diff --git a/plugins/source/snyk/codegen/resources/resource.go b/plugins/source/snyk/codegen/resources/resource.go new file mode 100644 index 00000000000..dda8c8593aa --- /dev/null +++ b/plugins/source/snyk/codegen/resources/resource.go @@ -0,0 +1,50 @@ +package resources + +import ( + "reflect" + "strings" + + "github.com/cloudquery/plugin-sdk/codegen" +) + +type Resource struct { + Name string + Struct any + Service string + SubService string + + Multiplex string + ExtraColumns codegen.ColumnDefinitions + + Children []*Resource + parent *Resource + + PreResolver string + PostResolver string + + table *codegen.TableDefinition +} + +func (r *Resource) sanitize() { + for _, child := range r.Children { + child.parent = r + if len(child.Service) == 0 { + child.Service = r.Service + } + } + + if len(r.SubService) == 0 { + r.SubService = csr.ToSnake(reflect.TypeOf(r.Struct).Elem().Name()) + if !strings.HasSuffix(r.SubService, "s") { + r.SubService += "s" + } + } +} + +func (r *Resource) Table() *codegen.TableDefinition { + return r.table +} + +func (r *Resource) Parent() *Resource { + return r.parent +} diff --git a/plugins/source/snyk/codegen/resources/schema.go b/plugins/source/snyk/codegen/resources/schema.go new file mode 100644 index 00000000000..624d4db0859 --- /dev/null +++ b/plugins/source/snyk/codegen/resources/schema.go @@ -0,0 +1,22 @@ +package resources + +import ( + "bytes" + "fmt" + "path" +) + +func (r *Resource) generateSchema(dir string) error { + tpl, err := parse("resource") + if err != nil { + return fmt.Errorf("failed to parse templates: %w", err) + } + + var buff bytes.Buffer + if err := tpl.Execute(&buff, r); err != nil { + return fmt.Errorf("failed to execute template: %w", err) + } + + filePath := path.Join(dir, r.SubService+".go") + return write(filePath, buff.Bytes()) +} diff --git a/plugins/source/snyk/codegen/resources/tables.go b/plugins/source/snyk/codegen/resources/tables.go new file mode 100644 index 00000000000..ed9aedf46f9 --- /dev/null +++ b/plugins/source/snyk/codegen/resources/tables.go @@ -0,0 +1,35 @@ +package resources + +import ( + "bytes" + "fmt" + "path" + "runtime" + + "golang.org/x/exp/slices" +) + +func tables(resources []*Resource) error { + tpl, err := parse("tables") + if err != nil { + return err + } + + sorted := make([]*Resource, len(resources)) + copy(sorted, resources) + slices.SortFunc(sorted, func(a, b *Resource) bool { return a.Name < b.Name }) + + var buff bytes.Buffer + if err := tpl.Execute(&buff, sorted); err != nil { + return fmt.Errorf("failed to execute template: %w", err) + } + + _, filename, _, ok := runtime.Caller(0) + if !ok { + return fmt.Errorf("failed to get caller information") + } + + filePath := path.Join(path.Dir(filename), "../../resources/plugin/tables.go") + + return write(filePath, buff.Bytes()) +} diff --git a/plugins/source/snyk/codegen/resources/template.go b/plugins/source/snyk/codegen/resources/template.go new file mode 100644 index 00000000000..29349c3d2ec --- /dev/null +++ b/plugins/source/snyk/codegen/resources/template.go @@ -0,0 +1,25 @@ +package resources + +import ( + "embed" + "strings" + "text/template" + + "github.com/cloudquery/plugin-sdk/codegen" + "github.com/iancoleman/strcase" +) + +//go:embed templates/*.go.tpl +var templatesFS embed.FS + +func parse(name string) (*template.Template, error) { + tpl, err := template.New(name+".go.tpl").Funcs(template.FuncMap{ + "ToCamel": strcase.ToCamel, + "ToLower": strings.ToLower, + "ToLowerCamel": strcase.ToLowerCamel, + }).ParseFS(templatesFS, "templates/*.go.tpl") + if err != nil { + return nil, err + } + return tpl.ParseFS(codegen.TemplatesFS, "templates/*.go.tpl") +} diff --git a/plugins/source/snyk/codegen/resources/templates/resource.go.tpl b/plugins/source/snyk/codegen/resources/templates/resource.go.tpl new file mode 100644 index 00000000000..82bd8595f1f --- /dev/null +++ b/plugins/source/snyk/codegen/resources/templates/resource.go.tpl @@ -0,0 +1,18 @@ +// Code generated by codegen; DO NOT EDIT. + +package {{ .Service }} + +import ( + "github.com/cloudquery/plugin-sdk/schema" + {{- if or .ExtraColumns .Multiplex }} + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + {{- end }} +) + +{{- if .Parent }} +func {{.SubService | ToLowerCamel}}() *schema.Table { +{{- else }} +func {{.SubService | ToCamel}}() *schema.Table { +{{- end }} + return &schema.Table{{template "table.go.tpl" .Table}} +} \ No newline at end of file diff --git a/plugins/source/snyk/codegen/resources/templates/tables.go.tpl b/plugins/source/snyk/codegen/resources/templates/tables.go.tpl new file mode 100644 index 00000000000..2eb17f25e1c --- /dev/null +++ b/plugins/source/snyk/codegen/resources/templates/tables.go.tpl @@ -0,0 +1,18 @@ +// Code generated by codegen; DO NOT EDIT. + +package plugin + +import ( + "github.com/cloudquery/plugin-sdk/schema" +{{- range . }} + "github.com/cloudquery/cloudquery/plugins/source/snyk/resources/services/{{ .Service }}" +{{- end }} +) + +func tables() []*schema.Table { + return []*schema.Table{ + {{- range . }} + {{ .Service }}.{{ .SubService | ToCamel }}(), + {{- end }} + } +} diff --git a/plugins/source/snyk/codegen/resources/transformers.go b/plugins/source/snyk/codegen/resources/transformers.go new file mode 100644 index 00000000000..d775f27b924 --- /dev/null +++ b/plugins/source/snyk/codegen/resources/transformers.go @@ -0,0 +1,21 @@ +package resources + +import ( + "reflect" + + "github.com/cloudquery/plugin-sdk/caser" +) + +var csr = caser.New( + caser.WithCustomInitialisms( + map[string]bool{ + "ACL": true, + "DERP": true, + "SSH": true, + }, + ), +) + +func nameTransformer(f reflect.StructField) (string, error) { + return csr.ToSnake(f.Name), nil +} diff --git a/plugins/source/snyk/codegen/resources/write.go b/plugins/source/snyk/codegen/resources/write.go new file mode 100644 index 00000000000..80d9421f55a --- /dev/null +++ b/plugins/source/snyk/codegen/resources/write.go @@ -0,0 +1,22 @@ +package resources + +import ( + "fmt" + "go/format" + "os" +) + +// write will format data as Go code & write it fo file +func write(path string, data []byte) error { + formatted, err := format.Source(data) + if err != nil { + fmt.Printf("failed to format source: %s: %v\n", path, err) + } else { + data = formatted + } + + if err := os.WriteFile(path, data, 0o644); err != nil { + return fmt.Errorf("failed to write file %s: %w", path, err) + } + return nil +} diff --git a/plugins/source/snyk/docs/tables/README.md b/plugins/source/snyk/docs/tables/README.md new file mode 100644 index 00000000000..99a51ef4640 --- /dev/null +++ b/plugins/source/snyk/docs/tables/README.md @@ -0,0 +1,8 @@ +# Source Plugin: snyk + +## Tables + +- [snyk_dependencies](snyk_dependencies.md) +- [snyk_integrations](snyk_integrations.md) +- [snyk_organizations](snyk_organizations.md) +- [snyk_projects](snyk_projects.md) \ No newline at end of file diff --git a/plugins/source/snyk/docs/tables/snyk_dependencies.md b/plugins/source/snyk/docs/tables/snyk_dependencies.md new file mode 100644 index 00000000000..243b485a6d2 --- /dev/null +++ b/plugins/source/snyk/docs/tables/snyk_dependencies.md @@ -0,0 +1,31 @@ +# Table: snyk_dependencies + +https://pkg.go.dev/github.com/pavel-snyk/snyk-sdk-go/snyk#Dependency + +The primary key for this table is **id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|id (PK)|String| +|name|String| +|type|String| +|version|String| +|latest_version|String| +|latest_version_published_date|Timestamp| +|first_published_date|Timestamp| +|is_deprecated|Bool| +|deprecated_versions|StringArray| +|dependencies_with_issues|StringArray| +|issues_critical|Int| +|issues_high|Int| +|issues_medium|Int| +|issues_low|Int| +|licenses|JSON| +|projects|JSON| +|copyright|StringArray| \ No newline at end of file diff --git a/plugins/source/snyk/docs/tables/snyk_integrations.md b/plugins/source/snyk/docs/tables/snyk_integrations.md new file mode 100644 index 00000000000..61cfcdeac15 --- /dev/null +++ b/plugins/source/snyk/docs/tables/snyk_integrations.md @@ -0,0 +1,19 @@ +# Table: snyk_integrations + +https://pkg.go.dev/github.com/pavel-snyk/snyk-sdk-go/snyk#Integration + +The primary key for this table is **id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|organization_id|String| +|settings|JSON| +|credentials|JSON| +|id (PK)|String| +|type|String| \ No newline at end of file diff --git a/plugins/source/snyk/docs/tables/snyk_organizations.md b/plugins/source/snyk/docs/tables/snyk_organizations.md new file mode 100644 index 00000000000..7d99bfa4e97 --- /dev/null +++ b/plugins/source/snyk/docs/tables/snyk_organizations.md @@ -0,0 +1,19 @@ +# Table: snyk_organizations + +https://pkg.go.dev/github.com/pavel-snyk/snyk-sdk-go/snyk#Organization + +The primary key for this table is **id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|group|JSON| +|id (PK)|String| +|name|String| +|slug|String| +|url|String| \ No newline at end of file diff --git a/plugins/source/snyk/docs/tables/snyk_projects.md b/plugins/source/snyk/docs/tables/snyk_projects.md new file mode 100644 index 00000000000..ec30313a112 --- /dev/null +++ b/plugins/source/snyk/docs/tables/snyk_projects.md @@ -0,0 +1,18 @@ +# Table: snyk_projects + +https://pkg.go.dev/github.com/pavel-snyk/snyk-sdk-go/snyk#Project + +The primary key for this table is **id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|organization_id|String| +|id (PK)|String| +|name|String| +|origin|String| \ No newline at end of file diff --git a/plugins/source/snyk/go.mod b/plugins/source/snyk/go.mod new file mode 100644 index 00000000000..9af0e8621d1 --- /dev/null +++ b/plugins/source/snyk/go.mod @@ -0,0 +1,38 @@ +module github.com/cloudquery/cloudquery/plugins/source/snyk + +go 1.19 + +require ( + github.com/cloudquery/plugin-sdk v1.13.0 + github.com/google/uuid v1.3.0 + github.com/iancoleman/strcase v0.2.0 + github.com/julienschmidt/httprouter v1.3.0 + github.com/pavel-snyk/snyk-sdk-go v0.4.1 + github.com/rs/zerolog v1.28.0 + golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15 + golang.org/x/sync v0.1.0 +) + +replace github.com/pavel-snyk/snyk-sdk-go => github.com/cloudquery/snyk-sdk-go v0.1.0 + +require ( + github.com/getsentry/sentry-go v0.16.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/thoas/go-funk v0.9.2 // indirect + golang.org/x/net v0.4.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect + google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 // indirect + google.golang.org/grpc v1.51.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/plugins/source/snyk/go.sum b/plugins/source/snyk/go.sum new file mode 100644 index 00000000000..d5493318354 --- /dev/null +++ b/plugins/source/snyk/go.sum @@ -0,0 +1,470 @@ +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/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/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= +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/avast/retry-go/v4 v4.3.1 h1:Mtg11F9PdAIMkMiio2RKcYauoVHjl2aB3zQJJlzD4cE= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +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/cloudquery/plugin-sdk v1.13.0 h1:dYA/QCrqt1tWe5rLJtGXGgT4bO7f1v6IAaRsWcCy3dU= +github.com/cloudquery/plugin-sdk v1.13.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/snyk-sdk-go v0.1.0 h1:lJ/3EhLwUAdcR/sukSA+EzAnRE1jRRxm8ewLESCNW5Q= +github.com/cloudquery/snyk-sdk-go v0.1.0/go.mod h1:LRL1TRuuM925gnyGp54WtS9p8S4yJMd0oS4JpLg+n7Y= +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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/getsentry/sentry-go v0.16.0 h1:owk+S+5XcgJLlGR/3+3s6N4d+uKwqYvh/eS0AIMjPWo= +github.com/getsentry/sentry-go v0.16.0/go.mod h1:ZXCloQLj0pG7mja5NK6NPf2V4A88YJ4pNlc2mOHwh6Y= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +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= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/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/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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +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/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 h1:hRcWZ7716+E1tkMSZJ/QeeC2dPGGB1R/4z4m9RsL8Qg= +github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3/go.mod h1:54asssGY3Bohr5FRbew+bjfuQTT2WS9V7hW7gPqmcKM= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2.0.20201002093600-73cf2ae9d891/go.mod h1:GhphxcdlaRyAuBSvo6rV71BvQcvB/vuX8ugCyybuS2k= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E= +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/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +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/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/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.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +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= +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.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= +github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/schollz/progressbar/v3 v3.12.1 h1:JAhtIrLWAn6/p7i82SrpSG3fgAwlAxi+Sy12r4AzBvQ= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/thoas/go-funk v0.9.2 h1:oKlNYv0AY5nyf9g+/GhMgS/UO2ces0QRdPKwkhY3VCk= +github.com/thoas/go-funk v0.9.2/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= +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= +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= +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/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-20221217163422-3c43f8badb15 h1:5oN1Pz/eDhCpbMbLstvIPa0b/BEQo6g6nwV3pLjfM6w= +golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15/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= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-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-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +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-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/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-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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +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/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-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-20190828213141-aed303cbaa74/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-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/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/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-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-20200806141610-86f49bd18e98/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-20221207170731-23e4bf6bdc37 h1:jmIfw8+gSvXcZSgaFAGyInDXeWzUhvYH57G/5GKMn70= +google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +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.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/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= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.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/plugins/source/snyk/main.go b/plugins/source/snyk/main.go new file mode 100644 index 00000000000..9068b6439b7 --- /dev/null +++ b/plugins/source/snyk/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/cloudquery/cloudquery/plugins/source/snyk/resources/plugin" + "github.com/cloudquery/plugin-sdk/serve" +) + +const sentryDSN = "https://c2101fe3c5fd4f91a095b2b37dc6364a@o1396617.ingest.sentry.io/4504333793165313" + +func main() { + serve.Source(plugin.Snyk(), serve.WithSourceSentryDSN(sentryDSN)) +} diff --git a/plugins/source/snyk/resources/plugin/plugin.go b/plugins/source/snyk/resources/plugin/plugin.go new file mode 100644 index 00000000000..741f3fde034 --- /dev/null +++ b/plugins/source/snyk/resources/plugin/plugin.go @@ -0,0 +1,17 @@ +package plugin + +import ( + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/plugins/source" +) + +var Version = "Development" + +func Snyk() *source.Plugin { + return source.NewPlugin( + "snyk", + Version, + tables(), + client.Configure, + ) +} diff --git a/plugins/source/snyk/resources/plugin/plugin_test.go b/plugins/source/snyk/resources/plugin/plugin_test.go new file mode 100644 index 00000000000..95b275bb78f --- /dev/null +++ b/plugins/source/snyk/resources/plugin/plugin_test.go @@ -0,0 +1,16 @@ +package plugin + +import ( + "testing" +) + +func TestSnyk(t *testing.T) { + // Note: this test is simple, but serves as a smoke test. + // The Snyk() call below also catches duplicate columns and other issues + // that may have been missed if mock tests are incomplete. + p := Snyk() + name := p.Name() + if name != "snyk" { + t.Errorf("Name() = %q, want %q", name, "snyk") + } +} diff --git a/plugins/source/snyk/resources/plugin/tables.go b/plugins/source/snyk/resources/plugin/tables.go new file mode 100644 index 00000000000..f0f433bcc98 --- /dev/null +++ b/plugins/source/snyk/resources/plugin/tables.go @@ -0,0 +1,20 @@ +// Code generated by codegen; DO NOT EDIT. + +package plugin + +import ( + "github.com/cloudquery/cloudquery/plugins/source/snyk/resources/services/dependency" + "github.com/cloudquery/cloudquery/plugins/source/snyk/resources/services/integration" + "github.com/cloudquery/cloudquery/plugins/source/snyk/resources/services/organization" + "github.com/cloudquery/cloudquery/plugins/source/snyk/resources/services/project" + "github.com/cloudquery/plugin-sdk/schema" +) + +func tables() []*schema.Table { + return []*schema.Table{ + dependency.Dependencies(), + integration.Integrations(), + organization.Organizations(), + project.Projects(), + } +} diff --git a/plugins/source/snyk/resources/services/dependency/dependencies.go b/plugins/source/snyk/resources/services/dependency/dependencies.go new file mode 100644 index 00000000000..5e39a22a75e --- /dev/null +++ b/plugins/source/snyk/resources/services/dependency/dependencies.go @@ -0,0 +1,107 @@ +// Code generated by codegen; DO NOT EDIT. + +package dependency + +import ( + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Dependencies() *schema.Table { + return &schema.Table{ + Name: "snyk_dependencies", + Description: `https://pkg.go.dev/github.com/pavel-snyk/snyk-sdk-go/snyk#Dependency`, + Resolver: fetchDependencies, + Multiplex: client.ByOrganization, + Columns: []schema.Column{ + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + }, + { + Name: "type", + Type: schema.TypeString, + Resolver: schema.PathResolver("Type"), + }, + { + Name: "version", + Type: schema.TypeString, + Resolver: schema.PathResolver("Version"), + }, + { + Name: "latest_version", + Type: schema.TypeString, + Resolver: schema.PathResolver("LatestVersion"), + }, + { + Name: "latest_version_published_date", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("LatestVersionPublishedDate"), + }, + { + Name: "first_published_date", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("FirstPublishedDate"), + }, + { + Name: "is_deprecated", + Type: schema.TypeBool, + Resolver: schema.PathResolver("IsDeprecated"), + }, + { + Name: "deprecated_versions", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("DeprecatedVersions"), + }, + { + Name: "dependencies_with_issues", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("DependenciesWithIssues"), + }, + { + Name: "issues_critical", + Type: schema.TypeInt, + Resolver: schema.PathResolver("IssuesCritical"), + }, + { + Name: "issues_high", + Type: schema.TypeInt, + Resolver: schema.PathResolver("IssuesHigh"), + }, + { + Name: "issues_medium", + Type: schema.TypeInt, + Resolver: schema.PathResolver("IssuesMedium"), + }, + { + Name: "issues_low", + Type: schema.TypeInt, + Resolver: schema.PathResolver("IssuesLow"), + }, + { + Name: "licenses", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Licenses"), + }, + { + Name: "projects", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Projects"), + }, + { + Name: "copyright", + Type: schema.TypeStringArray, + Resolver: schema.PathResolver("Copyright"), + }, + }, + } +} diff --git a/plugins/source/snyk/resources/services/dependency/dependencies_fetch.go b/plugins/source/snyk/resources/services/dependency/dependencies_fetch.go new file mode 100644 index 00000000000..c15c73fb25d --- /dev/null +++ b/plugins/source/snyk/resources/services/dependency/dependencies_fetch.go @@ -0,0 +1,26 @@ +package dependency + +import ( + "context" + "fmt" + + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchDependencies(ctx context.Context, meta schema.ClientMeta, _ *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + + result, _, err := c.Dependencies.List(ctx, c.OrganizationID) + if err != nil { + return err + } + for _, dep := range result { + res <- dep + fmt.Println(dep) + } + + res <- result + + return nil +} diff --git a/plugins/source/snyk/resources/services/dependency/dependencies_mock_test.go b/plugins/source/snyk/resources/services/dependency/dependencies_mock_test.go new file mode 100644 index 00000000000..f9b08c0766b --- /dev/null +++ b/plugins/source/snyk/resources/services/dependency/dependencies_mock_test.go @@ -0,0 +1,44 @@ +package dependency + +import ( + "encoding/json" + "net/http" + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/julienschmidt/httprouter" + "github.com/pavel-snyk/snyk-sdk-go/snyk" +) + +func createDependencies(mux *httprouter.Router) error { + var dependency snyk.Dependency + if err := faker.FakeObject(&dependency); err != nil { + return err + } + + mux.POST("/org/:orgID/dependencies", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + type DependenciesRoot struct { + Total int `json:"total,omitempty"` + Results []snyk.Dependency `json:"results,omitempty"` + } + b, err := json.Marshal(DependenciesRoot{ + Total: 1, + Results: []snyk.Dependency{dependency}, + }) + if err != nil { + http.Error(w, "unable to marshal response: "+err.Error(), http.StatusBadRequest) + return + } + if _, err := w.Write(b); err != nil { + http.Error(w, "failed to write", http.StatusBadRequest) + return + } + }) + + return nil +} + +func TestDependencies(t *testing.T) { + client.MockTestHelper(t, Dependencies(), createDependencies) +} diff --git a/plugins/source/snyk/resources/services/integration/integration_fetch.go b/plugins/source/snyk/resources/services/integration/integration_fetch.go new file mode 100644 index 00000000000..922665b8093 --- /dev/null +++ b/plugins/source/snyk/resources/services/integration/integration_fetch.go @@ -0,0 +1,50 @@ +package integration + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/schema" + "github.com/pavel-snyk/snyk-sdk-go/snyk" +) + +func fetchIntegrations(ctx context.Context, meta schema.ClientMeta, _ *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + + integrations, _, err := c.Integrations.List(ctx, c.OrganizationID) + if err != nil { + return err + } + + for typ, id := range integrations { + if len(id) > 0 { + res <- typ + } + } + + return nil +} + +func getIntegration(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource) error { + c := meta.(*client.Client) + + integration, _, err := c.Integrations.GetByType(ctx, c.OrganizationID, resource.Item.(snyk.IntegrationType)) + if err != nil { + return err + } + + resource.SetItem(integration) + + return nil +} + +func getIntegrationSettings(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, column schema.Column) error { + c := meta.(*client.Client) + + settings, _, err := c.Integrations.GetSettings(ctx, c.OrganizationID, resource.Item.(*snyk.Integration).ID) + if err != nil { + return err + } + + return resource.Set(column.Name, settings) +} diff --git a/plugins/source/snyk/resources/services/integration/integration_mock_test.go b/plugins/source/snyk/resources/services/integration/integration_mock_test.go new file mode 100644 index 00000000000..b14ccf5c6f6 --- /dev/null +++ b/plugins/source/snyk/resources/services/integration/integration_mock_test.go @@ -0,0 +1,70 @@ +package integration + +import ( + "encoding/json" + "net/http" + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/google/uuid" + "github.com/julienschmidt/httprouter" + "github.com/pavel-snyk/snyk-sdk-go/snyk" +) + +func createIntegrations(mux *httprouter.Router) error { + const basePath = "/org/:orgID/integrations" + mux.GET(basePath, func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + b, err := json.Marshal(snyk.Integrations{ + snyk.GitHubIntegrationType: uuid.NewString(), + }) + if err != nil { + http.Error(w, "unable to marshal response: "+err.Error(), http.StatusBadRequest) + return + } + if _, err := w.Write(b); err != nil { + http.Error(w, "failed to write", http.StatusBadRequest) + return + } + }) + + var integration snyk.Integration + if err := faker.FakeObject(&integration); err != nil { + return err + } + + mux.GET(basePath+"/"+snyk.GitHubIntegrationType, func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + b, err := json.Marshal(integration) + if err != nil { + http.Error(w, "unable to marshal response: "+err.Error(), http.StatusBadRequest) + return + } + if _, err := w.Write(b); err != nil { + http.Error(w, "failed to write", http.StatusBadRequest) + return + } + }) + + var settings snyk.IntegrationSettings + if err := faker.FakeObject(&settings); err != nil { + return err + } + + mux.GET(basePath+"/"+integration.ID+"/settings", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + b, err := json.Marshal(settings) + if err != nil { + http.Error(w, "unable to marshal response: "+err.Error(), http.StatusBadRequest) + return + } + if _, err := w.Write(b); err != nil { + http.Error(w, "failed to write", http.StatusBadRequest) + return + } + }) + + return nil +} + +func TestIntegrations(t *testing.T) { + client.MockTestHelper(t, Integrations(), createIntegrations) +} diff --git a/plugins/source/snyk/resources/services/integration/integrations.go b/plugins/source/snyk/resources/services/integration/integrations.go new file mode 100644 index 00000000000..819bb2b76d6 --- /dev/null +++ b/plugins/source/snyk/resources/services/integration/integrations.go @@ -0,0 +1,48 @@ +// Code generated by codegen; DO NOT EDIT. + +package integration + +import ( + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Integrations() *schema.Table { + return &schema.Table{ + Name: "snyk_integrations", + Description: `https://pkg.go.dev/github.com/pavel-snyk/snyk-sdk-go/snyk#Integration`, + Resolver: fetchIntegrations, + PreResourceResolver: getIntegration, + Multiplex: client.ByOrganization, + Columns: []schema.Column{ + { + Name: "organization_id", + Type: schema.TypeString, + Resolver: client.ResolveOrganizationID, + }, + { + Name: "settings", + Type: schema.TypeJSON, + Resolver: getIntegrationSettings, + }, + { + Name: "credentials", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Credentials"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "type", + Type: schema.TypeString, + Resolver: schema.PathResolver("Type"), + }, + }, + } +} diff --git a/plugins/source/snyk/resources/services/organization/organization_fetch.go b/plugins/source/snyk/resources/services/organization/organization_fetch.go new file mode 100644 index 00000000000..5524ea89738 --- /dev/null +++ b/plugins/source/snyk/resources/services/organization/organization_fetch.go @@ -0,0 +1,26 @@ +package organization + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchOrganizations(ctx context.Context, meta schema.ClientMeta, _ *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + + result, _, err := c.Orgs.List(ctx) + if err != nil { + return err + } + + // limit orgs + for _, org := range result { + if c.WantOrganization(org.ID) { + res <- org + } + } + + return nil +} diff --git a/plugins/source/snyk/resources/services/organization/organizations.go b/plugins/source/snyk/resources/services/organization/organizations.go new file mode 100644 index 00000000000..9c6a1475983 --- /dev/null +++ b/plugins/source/snyk/resources/services/organization/organizations.go @@ -0,0 +1,47 @@ +// Code generated by codegen; DO NOT EDIT. + +package organization + +import ( + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Organizations() *schema.Table { + return &schema.Table{ + Name: "snyk_organizations", + Description: `https://pkg.go.dev/github.com/pavel-snyk/snyk-sdk-go/snyk#Organization`, + Resolver: fetchOrganizations, + Multiplex: client.SingleOrganization, + Columns: []schema.Column{ + { + Name: "group", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("Group"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + }, + { + Name: "slug", + Type: schema.TypeString, + Resolver: schema.PathResolver("Slug"), + }, + { + Name: "url", + Type: schema.TypeString, + Resolver: schema.PathResolver("URL"), + }, + }, + } +} diff --git a/plugins/source/snyk/resources/services/organization/organizations_mock_test.go b/plugins/source/snyk/resources/services/organization/organizations_mock_test.go new file mode 100644 index 00000000000..3ec27a2af3e --- /dev/null +++ b/plugins/source/snyk/resources/services/organization/organizations_mock_test.go @@ -0,0 +1,41 @@ +package organization + +import ( + "encoding/json" + "net/http" + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/julienschmidt/httprouter" + "github.com/pavel-snyk/snyk-sdk-go/snyk" +) + +func createOrganizations(mux *httprouter.Router) error { + var organization snyk.Organization + if err := faker.FakeObject(&organization); err != nil { + return err + } + organization.ID = "test-org" + + mux.GET("/orgs", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + type organizationsRoot struct { + Organizations []snyk.Organization `json:"orgs,omitempty"` + } + b, err := json.Marshal(organizationsRoot{Organizations: []snyk.Organization{organization}}) + if err != nil { + http.Error(w, "unable to marshal response: "+err.Error(), http.StatusBadRequest) + return + } + if _, err := w.Write(b); err != nil { + http.Error(w, "failed to write", http.StatusBadRequest) + return + } + }) + + return nil +} + +func TestOrganizations(t *testing.T) { + client.MockTestHelper(t, Organizations(), createOrganizations) +} diff --git a/plugins/source/snyk/resources/services/project/projects.go b/plugins/source/snyk/resources/services/project/projects.go new file mode 100644 index 00000000000..714c3179c23 --- /dev/null +++ b/plugins/source/snyk/resources/services/project/projects.go @@ -0,0 +1,42 @@ +// Code generated by codegen; DO NOT EDIT. + +package project + +import ( + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Projects() *schema.Table { + return &schema.Table{ + Name: "snyk_projects", + Description: `https://pkg.go.dev/github.com/pavel-snyk/snyk-sdk-go/snyk#Project`, + Resolver: fetchProjects, + Multiplex: client.ByOrganization, + Columns: []schema.Column{ + { + Name: "organization_id", + Type: schema.TypeString, + Resolver: client.ResolveOrganizationID, + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("ID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "name", + Type: schema.TypeString, + Resolver: schema.PathResolver("Name"), + }, + { + Name: "origin", + Type: schema.TypeString, + Resolver: schema.PathResolver("Origin"), + }, + }, + } +} diff --git a/plugins/source/snyk/resources/services/project/projects_fetch.go b/plugins/source/snyk/resources/services/project/projects_fetch.go new file mode 100644 index 00000000000..47821922447 --- /dev/null +++ b/plugins/source/snyk/resources/services/project/projects_fetch.go @@ -0,0 +1,21 @@ +package project + +import ( + "context" + + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchProjects(ctx context.Context, meta schema.ClientMeta, _ *schema.Resource, res chan<- any) error { + c := meta.(*client.Client) + + projects, _, err := c.Projects.List(ctx, c.OrganizationID) + if err != nil { + return err + } + + res <- projects + + return nil +} diff --git a/plugins/source/snyk/resources/services/project/projects_mock_test.go b/plugins/source/snyk/resources/services/project/projects_mock_test.go new file mode 100644 index 00000000000..be5439fef8a --- /dev/null +++ b/plugins/source/snyk/resources/services/project/projects_mock_test.go @@ -0,0 +1,39 @@ +package project + +import ( + "encoding/json" + "net/http" + "testing" + + "github.com/cloudquery/cloudquery/plugins/source/snyk/client" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/julienschmidt/httprouter" + "github.com/pavel-snyk/snyk-sdk-go/snyk" +) + +func createProjects(mux *httprouter.Router) error { + var project snyk.Project + if err := faker.FakeObject(&project); err != nil { + return err + } + mux.POST("/org/:orgID/projects", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + type projectsRoot struct { + Projects []snyk.Project `json:"projects,omitempty"` + } + b, err := json.Marshal(projectsRoot{Projects: []snyk.Project{project}}) + if err != nil { + http.Error(w, "unable to marshal response: "+err.Error(), http.StatusBadRequest) + return + } + if _, err := w.Write(b); err != nil { + http.Error(w, "failed to write", http.StatusBadRequest) + return + } + }) + + return nil +} + +func TestProjects(t *testing.T) { + client.MockTestHelper(t, Projects(), createProjects) +} diff --git a/plugins/source/tailscale/.pre-commit-config.yaml b/plugins/source/tailscale/.pre-commit-config.yaml deleted file mode 100644 index 9d4561bfdea..00000000000 --- a/plugins/source/tailscale/.pre-commit-config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -repos: - - repo: https://github.com/dnephin/pre-commit-golang - rev: v0.5.0 - hooks: - # - id: go-mod-tidy - - id: golangci-lint diff --git a/plugins/source/tailscale/go.mod b/plugins/source/tailscale/go.mod index 344324ac3fd..7ff900027f0 100644 --- a/plugins/source/tailscale/go.mod +++ b/plugins/source/tailscale/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/tailscale go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/iancoleman/strcase v0.2.0 github.com/julienschmidt/httprouter v1.3.0 github.com/rs/zerolog v1.28.0 diff --git a/plugins/source/tailscale/go.sum b/plugins/source/tailscale/go.sum index 4cb9bd9b8b5..d5fcb03f570 100644 --- a/plugins/source/tailscale/go.sum +++ b/plugins/source/tailscale/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/terraform/go.mod b/plugins/source/terraform/go.mod index 0dd841e41b5..405173ced9c 100644 --- a/plugins/source/terraform/go.mod +++ b/plugins/source/terraform/go.mod @@ -9,7 +9,7 @@ require ( github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.46 github.com/aws/aws-sdk-go-v2/service/s3 v1.29.6 github.com/aws/aws-sdk-go-v2/service/sts v1.17.7 - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/golang/mock v1.6.0 github.com/rs/zerolog v1.28.0 ) diff --git a/plugins/source/terraform/go.sum b/plugins/source/terraform/go.sum index 17ffe458d35..5695468150c 100644 --- a/plugins/source/terraform/go.sum +++ b/plugins/source/terraform/go.sum @@ -78,8 +78,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/test/go.mod b/plugins/source/test/go.mod index 4abfdc2a9ba..380e83ea4a3 100644 --- a/plugins/source/test/go.mod +++ b/plugins/source/test/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/test go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/rs/zerolog v1.28.0 ) diff --git a/plugins/source/test/go.sum b/plugins/source/test/go.sum index 753fe7cdf2d..541e836f71c 100644 --- a/plugins/source/test/go.sum +++ b/plugins/source/test/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/plugins/source/vercel/go.mod b/plugins/source/vercel/go.mod index 9b477554d8d..79cfd4b2b51 100644 --- a/plugins/source/vercel/go.mod +++ b/plugins/source/vercel/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cloudquery/plugins/source/vercel go 1.19 require ( - github.com/cloudquery/plugin-sdk v1.13.1 + github.com/cloudquery/plugin-sdk v1.16.0 github.com/gertd/go-pluralize v0.2.1 github.com/gorilla/mux v1.8.0 github.com/rs/zerolog v1.28.0 diff --git a/plugins/source/vercel/go.sum b/plugins/source/vercel/go.sum index f88b27b1068..225629591c8 100644 --- a/plugins/source/vercel/go.sum +++ b/plugins/source/vercel/go.sum @@ -40,8 +40,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR 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/cloudquery/plugin-sdk v1.13.1 h1:ny/9L4C/pp77wrkLjNtGSZp70XrVkXxOAV/EI0kVVo0= -github.com/cloudquery/plugin-sdk v1.13.1/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= +github.com/cloudquery/plugin-sdk v1.16.0 h1:cAcjdHnPaeImbJJjrxNgXoO7FiNRVtSe1Bkx8tLXG9Y= +github.com/cloudquery/plugin-sdk v1.16.0/go.mod h1:PKne4lmvDFCEbTAS8EQzPohkXchwi/7NSvu77l07hCg= 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/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= diff --git a/release-please-config.json b/release-please-config.json index 9aa4b9d1db6..9505c5acbe4 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -9,9 +9,8 @@ "plugins/source/cloudflare": { "component": "plugins-source-cloudflare" }, "plugins/source/crowdstrike": { "component": "plugins-source-crowdstrike" }, "plugins/source/datadog": { "component": "plugins-source-datadog" }, - "plugins/source/digitalocean": { - "component": "plugins-source-digitalocean" - }, + "plugins/source/digitalocean": { "component": "plugins-source-digitalocean" }, + "plugins/source/fastly": { "component": "plugins-source-fastly" }, "plugins/source/gandi": { "component": "plugins-source-gandi" }, "plugins/source/gcp": { "component": "plugins-source-gcp" }, "plugins/source/github": { "component": "plugins-source-github" }, @@ -19,8 +18,9 @@ "plugins/source/heroku": { "component": "plugins-source-heroku" }, "plugins/source/k8s": { "component": "plugins-source-k8s" }, "plugins/source/okta": { "component": "plugins-source-okta" }, - "plugins/source/slack": { "component": "plugins-source-slack" }, "plugins/source/salesforce": { "component": "plugins-source-salesforce" }, + "plugins/source/slack": { "component": "plugins-source-slack" }, + "plugins/source/snyk": { "component": "plugins-source-snyk" }, "plugins/source/tailscale": { "component": "plugins-source-tailscale" }, "plugins/source/vercel": { "component": "plugins-source-vercel" }, "plugins/source/pagerduty": {"component": "plugins-source-pagerduty"}, @@ -32,6 +32,12 @@ "plugins/destination/csv": { "component": "plugins-destination-csv" }, + "plugins/destination/file": { + "component": "plugins-destination-file" + }, + "plugins/destination/gcs": { + "component": "plugins-destination-gcs" + }, "plugins/destination/sqlite": { "component": "plugins-destination-sqlite" }, diff --git a/scripts/table_diff/changes/changes.go b/scripts/table_diff/changes/changes.go index 53a7d27025f..29847ce9ad0 100644 --- a/scripts/table_diff/changes/changes.go +++ b/scripts/table_diff/changes/changes.go @@ -12,6 +12,7 @@ import ( var ( columnRegex = regexp.MustCompile(`^\|(?P.*)\|(?P.*)\|`) + pkRegex = regexp.MustCompile(`^The composite primary key for this table is \(([^)]+)\)\.`) ) type change struct { @@ -47,11 +48,33 @@ func parseColumnChange(line string) (name string, dataType string, pk bool) { return cleanName, result["dataType"], result["name"] != cleanName } +func parsePKChange(line string) (names []string) { + match := pkRegex.FindStringSubmatch(line) + if len(match) != 2 { + return nil + } + for _, part := range strings.Split(match[1], ", ") { + names = append(names, strings.Trim(part, "*")) + } + return +} + func getColumnChanges(file *gitdiff.File, table string) (changes []change) { addedColumns := make(map[string]column) deletedColumns := make(map[string]column) + var addedPK, deletedPK []string for _, fragment := range file.TextFragments { for _, line := range fragment.Lines { + pkChanges := parsePKChange(line.Line) + if len(pkChanges) > 0 { + switch line.Op { + case gitdiff.OpAdd: + addedPK = pkChanges + case gitdiff.OpDelete: + deletedPK = pkChanges + } + continue + } name, dataType, pk := parseColumnChange(line.Line) if name == "" || dataType == "" { continue @@ -115,16 +138,32 @@ func getColumnChanges(file *gitdiff.File, table string) (changes []change) { } } + // check PK: + if len(addedPK) > 0 && len(addedPK) == len(deletedPK) { + // if they are unequal the pk added/removed is correct. + changes = append(changes, change{ + Text: fmt.Sprintf("Table %s: primary key order changed from %s to %s", + backtickStrings( + table, + strings.Join(deletedPK, ", "), + strings.Join(addedPK, ", "), + )..., + ), + Breaking: true, + }) + } + sort.SliceStable(changes, func(i, j int) bool { - iBreaking := changes[i].Breaking - jBreaking := changes[j].Breaking - if iBreaking && !jBreaking { + chI := changes[i] + chJ := changes[j] + switch { + case chI.Breaking && !chJ.Breaking: return true - } - if !iBreaking && jBreaking { + case !chI.Breaking && chJ.Breaking: return false + default: + return chI.Text < chJ.Text } - return changes[i].Text < changes[j].Text }) return changes } diff --git a/scripts/table_diff/changes/changes_test.go b/scripts/table_diff/changes/changes_test.go index e94299f145a..1d4cbebf6e1 100644 --- a/scripts/table_diff/changes/changes_test.go +++ b/scripts/table_diff/changes/changes_test.go @@ -47,6 +47,26 @@ func Test_parseColumnChange(t *testing.T) { } } +func Test_parsePKChange(t *testing.T) { + type args struct { + line string + } + tests := []struct { + name string + args args + wantNames []string + }{ + {name: "PK present", args: args{line: "The composite primary key for this table is (**org**, **id**, **hook_id**)."}, wantNames: []string{"org", "id", "hook_id"}}, + {name: "no PK", args: args{}, wantNames: nil}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotNames := parsePKChange(tt.args.line) + require.Equal(t, tt.wantNames, gotNames) + }) + } +} + func Test_getChanges(t *testing.T) { tests := []struct { name string @@ -201,6 +221,96 @@ func Test_getChanges(t *testing.T) { }, }, }, + { + name: "Should mark PK order change as breaking", + diffDataFile: "testdata/pr_6012_diff.txt", + wantChanges: []change{ + { + Text: "Table `github_external_groups`: column order changed for `updated_at`", + Breaking: false, + }, + { + Text: "Table `github_hook_deliveries`: primary key order changed from `org, id, hook_id` to `org, hook_id, id`", + Breaking: true, + }, + { + Text: "Table `github_hook_deliveries`: column order changed for `delivered_at`", + Breaking: false, + }, + { + Text: "Table `github_hook_deliveries`: column order changed for `id`", + Breaking: false, + }, + { + Text: "Table `github_hooks`: column order changed for `id`", + Breaking: false, + }, + { + Text: "Table `github_issues`: column added with name `state_reason` and type `String`", + Breaking: false, + }, + { + Text: "Table `github_organization_members`: column order changed for `id`", + Breaking: false, + }, + { + Text: "Table `github_organizations`: column order changed for `id`", + Breaking: false, + }, + { + Text: "Table `github_repositories`: column added with name `has_discussions` and type `Bool`", + Breaking: false, + }, + { + Text: "Table `github_repositories`: column order changed for `created_at`", + Breaking: false, + }, + { + Text: "Table `github_repositories`: column order changed for `pushed_at`", + Breaking: false, + }, + { + Text: "Table `github_repositories`: column order changed for `updated_at`", + Breaking: false, + }, + { + Text: "Table `github_team_members`: primary key order changed from `org, id, team_id` to `org, team_id, id`", + Breaking: true, + }, + { + Text: "Table `github_team_members`: column order changed for `id`", + Breaking: false, + }, + { + Text: "Table `github_team_repositories`: primary key order changed from `org, id, team_id` to `org, team_id, id`", + Breaking: true, + }, + { + Text: "Table `github_team_repositories`: column added with name `has_discussions` and type `Bool`", + Breaking: false, + }, + { + Text: "Table `github_team_repositories`: column order changed for `created_at`", + Breaking: false, + }, + { + Text: "Table `github_team_repositories`: column order changed for `id`", + Breaking: false, + }, + { + Text: "Table `github_team_repositories`: column order changed for `pushed_at`", + Breaking: false, + }, + { + Text: "Table `github_team_repositories`: column order changed for `updated_at`", + Breaking: false, + }, + { + Text: "Table `github_workflows`: column order changed for `id`", + Breaking: false, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/scripts/table_diff/changes/testdata/pr_6012_diff.txt b/scripts/table_diff/changes/testdata/pr_6012_diff.txt new file mode 100644 index 00000000000..1ee6a04a188 --- /dev/null +++ b/scripts/table_diff/changes/testdata/pr_6012_diff.txt @@ -0,0 +1,212 @@ +diff --git a/plugins/source/github/docs/tables/github_external_groups.md b/plugins/source/github/docs/tables/github_external_groups.md +index c5ce498d0ae..2db91a4cf65 100644 +--- a/plugins/source/github/docs/tables/github_external_groups.md ++++ b/plugins/source/github/docs/tables/github_external_groups.md +@@ -12,7 +12,7 @@ The composite primary key for this table is (**org**, **group_id**). + |_cq_parent_id|UUID| + |org (PK)|String| + |group_id (PK)|Int| +-|updated_at|Timestamp| + |group_name|String| ++|updated_at|Timestamp| + |teams|JSON| + |members|JSON| +\ No newline at end of file +diff --git a/plugins/source/github/docs/tables/github_hook_deliveries.md b/plugins/source/github/docs/tables/github_hook_deliveries.md +index fff22e6099f..7a4ec88911a 100644 +--- a/plugins/source/github/docs/tables/github_hook_deliveries.md ++++ b/plugins/source/github/docs/tables/github_hook_deliveries.md +@@ -1,6 +1,6 @@ + # Table: github_hook_deliveries + +-The composite primary key for this table is (**org**, **id**, **hook_id**). ++The composite primary key for this table is (**org**, **hook_id**, **id**). + + ## Relations + +@@ -15,12 +15,12 @@ This table depends on [github_hooks](github_hooks.md). + |_cq_id|UUID| + |_cq_parent_id|UUID| + |org (PK)|String| +-|id (PK)|Int| + |hook_id (PK)|Int| + |request|String| + |response|String| +-|delivered_at|Timestamp| ++|id (PK)|Int| + |guid|String| ++|delivered_at|Timestamp| + |redelivery|Bool| + |duration|Float| + |status|String| +diff --git a/plugins/source/github/docs/tables/github_hooks.md b/plugins/source/github/docs/tables/github_hooks.md +index da0ed855d5f..97fcb1435d4 100644 +--- a/plugins/source/github/docs/tables/github_hooks.md ++++ b/plugins/source/github/docs/tables/github_hooks.md +@@ -16,10 +16,10 @@ The following tables depend on github_hooks: + |_cq_id|UUID| + |_cq_parent_id|UUID| + |org (PK)|String| +-|id (PK)|Int| + |created_at|Timestamp| + |updated_at|Timestamp| + |url|String| ++|id (PK)|Int| + |type|String| + |name|String| + |test_url|String| +diff --git a/plugins/source/github/docs/tables/github_issues.md b/plugins/source/github/docs/tables/github_issues.md +index 6650919479d..c2c470ae8ca 100644 +--- a/plugins/source/github/docs/tables/github_issues.md ++++ b/plugins/source/github/docs/tables/github_issues.md +@@ -14,6 +14,7 @@ The composite primary key for this table is (**org**, **id**). + |id (PK)|Int| + |number|Int| + |state|String| ++|state_reason|String| + |locked|Bool| + |title|String| + |body|String| +diff --git a/plugins/source/github/docs/tables/github_organization_members.md b/plugins/source/github/docs/tables/github_organization_members.md +index a949e218af0..b661132e424 100644 +--- a/plugins/source/github/docs/tables/github_organization_members.md ++++ b/plugins/source/github/docs/tables/github_organization_members.md +@@ -15,9 +15,9 @@ This table depends on [github_organizations](github_organizations.md). + |_cq_id|UUID| + |_cq_parent_id|UUID| + |org (PK)|String| +-|id (PK)|Int| + |membership|JSON| + |login|String| ++|id (PK)|Int| + |node_id|String| + |avatar_url|String| + |html_url|String| +diff --git a/plugins/source/github/docs/tables/github_organizations.md b/plugins/source/github/docs/tables/github_organizations.md +index ad876dc69f1..b3d4fbbe8ab 100644 +--- a/plugins/source/github/docs/tables/github_organizations.md ++++ b/plugins/source/github/docs/tables/github_organizations.md +@@ -16,8 +16,8 @@ The following tables depend on github_organizations: + |_cq_id|UUID| + |_cq_parent_id|UUID| + |org (PK)|String| +-|id (PK)|Int| + |login|String| ++|id (PK)|Int| + |node_id|String| + |avatar_url|String| + |html_url|String| +diff --git a/plugins/source/github/docs/tables/github_repositories.md b/plugins/source/github/docs/tables/github_repositories.md +index 53cbd8e2072..ea7d7cc1031 100644 +--- a/plugins/source/github/docs/tables/github_repositories.md ++++ b/plugins/source/github/docs/tables/github_repositories.md +@@ -12,9 +12,6 @@ The composite primary key for this table is (**org**, **id**). + |_cq_parent_id|UUID| + |org (PK)|String| + |id (PK)|Int| +-|created_at|Timestamp| +-|pushed_at|Timestamp| +-|updated_at|Timestamp| + |node_id|String| + |owner|JSON| + |name|String| +@@ -24,6 +21,9 @@ The composite primary key for this table is (**org**, **id**). + |code_of_conduct|JSON| + |default_branch|String| + |master_branch|String| ++|created_at|Timestamp| ++|pushed_at|Timestamp| ++|updated_at|Timestamp| + |html_url|String| + |clone_url|String| + |git_url|String| +@@ -69,6 +69,7 @@ The composite primary key for this table is (**org**, **id**). + |has_pages|Bool| + |has_projects|Bool| + |has_downloads|Bool| ++|has_discussions|Bool| + |is_template|Bool| + |license_template|String| + |gitignore_template|String| +diff --git a/plugins/source/github/docs/tables/github_team_members.md b/plugins/source/github/docs/tables/github_team_members.md +index fb9f8080b5a..a3c9f98cf75 100644 +--- a/plugins/source/github/docs/tables/github_team_members.md ++++ b/plugins/source/github/docs/tables/github_team_members.md +@@ -1,6 +1,6 @@ + # Table: github_team_members + +-The composite primary key for this table is (**org**, **id**, **team_id**). ++The composite primary key for this table is (**org**, **team_id**, **id**). + + ## Relations + +@@ -15,10 +15,10 @@ This table depends on [github_teams](github_teams.md). + |_cq_id|UUID| + |_cq_parent_id|UUID| + |org (PK)|String| +-|id (PK)|Int| + |team_id (PK)|Int| + |membership|JSON| + |login|String| ++|id (PK)|Int| + |node_id|String| + |avatar_url|String| + |html_url|String| +diff --git a/plugins/source/github/docs/tables/github_team_repositories.md b/plugins/source/github/docs/tables/github_team_repositories.md +index b1134a16c41..addf1f88006 100644 +--- a/plugins/source/github/docs/tables/github_team_repositories.md ++++ b/plugins/source/github/docs/tables/github_team_repositories.md +@@ -1,6 +1,6 @@ + # Table: github_team_repositories + +-The composite primary key for this table is (**org**, **id**, **team_id**). ++The composite primary key for this table is (**org**, **team_id**, **id**). + + ## Relations + +@@ -15,11 +15,8 @@ This table depends on [github_teams](github_teams.md). + |_cq_id|UUID| + |_cq_parent_id|UUID| + |org (PK)|String| +-|id (PK)|Int| +-|created_at|Timestamp| +-|pushed_at|Timestamp| +-|updated_at|Timestamp| + |team_id (PK)|Int| ++|id (PK)|Int| + |node_id|String| + |owner|JSON| + |name|String| +@@ -29,6 +26,9 @@ This table depends on [github_teams](github_teams.md). + |code_of_conduct|JSON| + |default_branch|String| + |master_branch|String| ++|created_at|Timestamp| ++|pushed_at|Timestamp| ++|updated_at|Timestamp| + |html_url|String| + |clone_url|String| + |git_url|String| +@@ -74,6 +74,7 @@ This table depends on [github_teams](github_teams.md). + |has_pages|Bool| + |has_projects|Bool| + |has_downloads|Bool| ++|has_discussions|Bool| + |is_template|Bool| + |license_template|String| + |gitignore_template|String| +diff --git a/plugins/source/github/docs/tables/github_workflows.md b/plugins/source/github/docs/tables/github_workflows.md +index a586400ac43..6b25d3179af 100644 +--- a/plugins/source/github/docs/tables/github_workflows.md ++++ b/plugins/source/github/docs/tables/github_workflows.md +@@ -11,8 +11,8 @@ The composite primary key for this table is (**org**, **id**). + |_cq_id|UUID| + |_cq_parent_id|UUID| + |org (PK)|String| +-|id (PK)|Int| + |contents|String| ++|id (PK)|Int| + |node_id|String| + |name|String| + |path|String| +s \ No newline at end of file diff --git a/website/components/QueriesExamples.tsx b/website/components/QueriesExamples.tsx index 270a45dbc62..89db14b3e48 100644 --- a/website/components/QueriesExamples.tsx +++ b/website/components/QueriesExamples.tsx @@ -61,7 +61,7 @@ const QUERIES_EXAMPLES = [ export const QueriesExamples = ({ onClick }) => { return ( -
+
{QUERIES_EXAMPLES.map(({ code, html, title, description }) => ( onClick(code)} @@ -69,7 +69,7 @@ export const QueriesExamples = ({ onClick }) => { description={description} key={title} > -
{html}
+
{html}
))}
diff --git a/website/components/pages/home.tsx b/website/components/pages/home.tsx index e75293b8f08..3e0c06617b9 100644 --- a/website/components/pages/home.tsx +++ b/website/components/pages/home.tsx @@ -141,7 +141,7 @@ export default function Home() { Integrations

- Integrate with 10+ cloud providers and SaaS apps with more than 1,000 unique tables. + Integrate with a growing list of 20+ cloud providers and SaaS apps with more than 1,000 unique tables. Sync to your favorite database, data warehouse or data lake.

diff --git a/website/content/features.ts b/website/content/features.ts index d71fe76e212..b60d56487a5 100644 --- a/website/content/features.ts +++ b/website/content/features.ts @@ -46,7 +46,7 @@ const FEATURES: Features = [ }, { name: "Database agnostic", - description: `CloudQuery can store your configuration in any supported destination such as database, datalake, streaming for further analysis.`, + description: `CloudQuery can store your configuration in any supported destination such as database, data lake or streaming platform for further analysis.`, Icon: DatabaseIcon, page: "all", }, diff --git a/website/pages/docs/plugins/destinations/_meta.json b/website/pages/docs/plugins/destinations/_meta.json index e3cda18d52c..e6620d654fc 100644 --- a/website/pages/docs/plugins/destinations/_meta.json +++ b/website/pages/docs/plugins/destinations/_meta.json @@ -2,6 +2,8 @@ "overview": "Overview", "bigquery": "BigQuery", "csv": "CSV", + "file": "File", + "gcs": "GCS", "mongodb": "MongoDB", "postgresql": "PostgreSQL", "snowflake": "Snowflake", diff --git a/website/pages/docs/plugins/destinations/bigquery/overview.md b/website/pages/docs/plugins/destinations/bigquery/overview.md index 43184b0d161..274e8149742 100644 --- a/website/pages/docs/plugins/destinations/bigquery/overview.md +++ b/website/pages/docs/plugins/destinations/bigquery/overview.md @@ -90,10 +90,6 @@ This is the top-level spec used by the BigQuery destination plugin. GCP service account key content. This allows for using different service accounts for the GCP source and BigQuery destination. If using service account keys, it is best to use [environment or file variable substitution](/docs/advanced-topics/environment-variable-substitution). -- `batch_size` (int, optional. Default: 1000) - - Number of rows to insert in a single batch. - ## Underlying library We use the official [cloud.google.com/go/bigquery](https://pkg.go.dev/cloud.google.com/go/bigquery) package for database connection. diff --git a/website/pages/docs/plugins/destinations/file/_meta.json b/website/pages/docs/plugins/destinations/file/_meta.json new file mode 100644 index 00000000000..13044ba532f --- /dev/null +++ b/website/pages/docs/plugins/destinations/file/_meta.json @@ -0,0 +1,3 @@ +{ + "overview": "Overview" +} \ No newline at end of file diff --git a/website/pages/docs/plugins/destinations/file/overview.md b/website/pages/docs/plugins/destinations/file/overview.md new file mode 100644 index 00000000000..8f7e0aa6272 --- /dev/null +++ b/website/pages/docs/plugins/destinations/file/overview.md @@ -0,0 +1,46 @@ +# File Destination Plugin + +import { getLatestVersion } from "../../../../../utils/versions"; +import { Badge } from "../../../../../components/Badge"; + + + +This destination plugin lets you sync data from a CloudQuery source to local files in various formats such as CSV, JSON. + +This is useful in local environments, but also in production environments where scalability, performance and cost are requirements. For example, this plugin can be used as part of a system that syncs sources across multiple virtual machines, uploads CSV files to a remote storage (such as S3 or GCS), and finally loads them to data lakes such as BigQuery or Athena in batch mode. + +## Example + +This example configures a CSV destination, to create CSV files in `./cq_csv_output`. Note that the CSV plugin only supports `append` write-mode. + +The (top level) spec section is described in the [Destination Spec Reference](/docs/reference/destination-spec). + +```yaml +kind: destination +spec: + name: "file" + path: "cloudquery/file" + version: "VERSION_DESTINATION_FILE" + write_mode: "append" # file only supports 'append' mode + + spec: + directory: "./cq_csv_output" + format: "csv" +``` + +## File Spec + +This is the (nested) spec used by the CSV destination Plugin. + +- `directory` (string) (required) + + Directory where all CSV files will be written. A CSV file will be created per table. + +- `format` (string) (required) + + Format of the output file. `json` and `csv` are supported. + +- `no_rotate` (bool) (optional) + + If set to true, the plugin will write to one file per table. + Otherwise, for every batch a new file will be created with a different `.` suffix. diff --git a/website/pages/docs/plugins/destinations/gcs/_meta.json b/website/pages/docs/plugins/destinations/gcs/_meta.json new file mode 100644 index 00000000000..13044ba532f --- /dev/null +++ b/website/pages/docs/plugins/destinations/gcs/_meta.json @@ -0,0 +1,3 @@ +{ + "overview": "Overview" +} \ No newline at end of file diff --git a/website/pages/docs/plugins/destinations/gcs/overview.md b/website/pages/docs/plugins/destinations/gcs/overview.md new file mode 100644 index 00000000000..675f871a9f5 --- /dev/null +++ b/website/pages/docs/plugins/destinations/gcs/overview.md @@ -0,0 +1,46 @@ +# GCS (Google Cloud Storage) Destination Plugin + +import { getLatestVersion } from "../../../../../utils/versions"; +import { Badge } from "../../../../../components/Badge"; + + + +This destination plugin lets you sync data from a CloudQuery source to remote GCS (Google Cloud Storage) storage in various formats such as CSV, JSON. + +This is useful in various use-cases, especially in data lakes where you can query the data direct from Athena or load it to various data warehouses such as BigQuery, RedShift, Snowflake and others. + +## Example + +This example configures a GCS destination, to create CSV files in `gcs://bucket_name/path/to/files`. Note that the GCS plugin only supports `append` write-mode. + +The (top level) spec section is described in the [Destination Spec Reference](/docs/reference/destination-spec). + +```yaml +kind: destination +spec: + name: "gcs" + path: "cloudquery/gcs" + version: "VERSION_DESTINATION_GCS" + write_mode: "append" # gcs only supports 'append' mode + + spec: + bucket: "bucket_name" + path: "path/to/files" + format: "csv" +``` + +## GCS Spec + +This is the (nested) spec used by the CSV destination Plugin. + +- `bucket` (string) (required) + + Bucket where to sync the files. + +- `path` (string) (required) + + Path to where the files will be uploaded in the above bucket. + +- `format` (string) (required) + + Format of the output file. `json` and `csv` are supported. diff --git a/website/pages/docs/plugins/destinations/overview.mdx b/website/pages/docs/plugins/destinations/overview.mdx index 70179fad2f7..394f38314c0 100644 --- a/website/pages/docs/plugins/destinations/overview.mdx +++ b/website/pages/docs/plugins/destinations/overview.mdx @@ -16,6 +16,8 @@ This is a list of all official and community destination plugins. [ { name: "BigQuery", stage:"Preview" }, { name: "CSV", stage:"Preview" }, + { name: "File", stage:"Preview" }, + { name: "GCS", stage:"Preview" }, { name: "MongoDB", stage:"Preview" }, { name: "PostgreSQL", stage:"GA", meta: () => * }, { name: "SQLite", stage:"Preview" }, diff --git a/website/pages/docs/plugins/destinations/postgresql/overview.md b/website/pages/docs/plugins/destinations/postgresql/overview.md index 035f84c626b..bac00a198fc 100644 --- a/website/pages/docs/plugins/destinations/postgresql/overview.md +++ b/website/pages/docs/plugins/destinations/postgresql/overview.md @@ -55,11 +55,6 @@ This is the (nested) spec used by the PostgreSQL destination Plugin. Available: "error", "warn", "info", "debug", "trace" define if and in which level to log [`pgx`](https://github.com/jackc/pgx) call. -- `batch_size` (int, optional. Default: 1000) - - Number of rows to insert in a single batch. - - Note: Make sure you use environment variable expansion in production instead of committing the credentials to the configuration file directly. ### Verbose logging for debug diff --git a/website/pages/docs/plugins/sources/_meta.json b/website/pages/docs/plugins/sources/_meta.json index 89d0e5f2479..3afc1ad3ee8 100644 --- a/website/pages/docs/plugins/sources/_meta.json +++ b/website/pages/docs/plugins/sources/_meta.json @@ -5,15 +5,19 @@ "cloudflare": "Cloudflare", "datadog": "Datadog", "digitalocean": "DigitalOcean", + "fastly": "Fastly", "gandi": "Gandi", "gcp": "GCP", "github": "GitHub", + "gitlab": "GitLab", "heroku": "Heroku", "k8s": "Kubernetes", "okta": "Okta", "salesforce": "Salesforce", "slack": "Slack", + "snyk": "Snyk", "pagerduty": "PagerDuty", + "tailscale": "Tailscale", "terraform": "Terraform", "vercel": "Vercel" } diff --git a/website/pages/docs/plugins/sources/azure/tables.md b/website/pages/docs/plugins/sources/azure/tables.md index 402e93bd9f8..04dda0dec54 100644 --- a/website/pages/docs/plugins/sources/azure/tables.md +++ b/website/pages/docs/plugins/sources/azure/tables.md @@ -74,6 +74,7 @@ - [azure_cosmos_mongo_db_databases](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_cosmos_mongo_db_databases.md) - [azure_cosmos_sql_databases](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_cosmos_sql_databases.md) - [azure_costmanagement_views](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_costmanagement_views.md) + - [azure_costmanagement_view_queries](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_costmanagement_view_queries.md) - [azure_customerinsights_hubs](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_customerinsights_hubs.md) - [azure_dashboard_grafana](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_dashboard_grafana.md) - [azure_databox_jobs](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_databox_jobs.md) @@ -210,6 +211,7 @@ - [azure_security_tasks](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_security_tasks.md) - [azure_security_topology](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_security_topology.md) - [azure_security_workspace_settings](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_security_workspace_settings.md) +- [azure_security_pricings](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_security_pricings.md) - [azure_servicebus_namespaces](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_servicebus_namespaces.md) - [azure_sql_instance_pools](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_sql_instance_pools.md) - [azure_sql_managed_instances](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/azure/docs/tables/azure_sql_managed_instances.md) diff --git a/website/pages/docs/plugins/sources/fastly/_meta.json b/website/pages/docs/plugins/sources/fastly/_meta.json new file mode 100644 index 00000000000..d2ba90ccfb4 --- /dev/null +++ b/website/pages/docs/plugins/sources/fastly/_meta.json @@ -0,0 +1,4 @@ +{ + "overview": "Overview", + "tables": "Tables" +} diff --git a/website/pages/docs/plugins/sources/fastly/overview.md b/website/pages/docs/plugins/sources/fastly/overview.md new file mode 100644 index 00000000000..caaa33689e6 --- /dev/null +++ b/website/pages/docs/plugins/sources/fastly/overview.md @@ -0,0 +1,182 @@ +# Fastly Source Plugin + +import { getLatestVersion } from "../../../../../utils/versions"; +import { Badge } from "../../../../../components/Badge"; + + + +The CloudQuery Fastly plugin reads information from your Fastly account(s) and loads it into any supported CloudQuery destination (e.g. PostgreSQL, Snowflake, BigQuery, etc). + +## Configuration + +This example syncs from Fastly to a Postgres destination, using the token provided in an environment variable called `FASTLY_API_KEY`. The (top level) source spec section is described in the [Source Spec Reference](/docs/reference/source-spec). + +```yaml +kind: source +# Common source-plugin configuration +spec: + name: fastly + path: cloudquery/fastly + version: "VERSION_SOURCE_FASTLY" + tables: ["*"] + destinations: ["postgresql"] + + # Fastly specific configuration + spec: + fastly_api_key: "${FASTLY_API_KEY}" +``` + +For more information on downloading, installing and running the CloudQuery CLI, see the [Quickstart guide](/docs/quickstart). + +## Fastly Spec + +This is the (nested) spec used by the Fastly source plugin. + +- `fastly_api_key` (string, required): + + An API token to access Fastly resources. This can be obtained by [creating a Fastly API token](https://docs.fastly.com/en/guides/using-api-tokens). It should be a *User token* with the *Global:read* scope. Automation tokens do not allow the listing of service versions. + +- `services` ([]string, optional): + + A list of Fastly service IDs to sync. If not specified, all services will be used. + +## Example Queries + +### List all services and their active versions + +```sql copy +select name, id, type, active_version from fastly_services; +``` + +```text ++----------------------+------------------------+------+----------------+ +| name | id | type | active_version | +|----------------------+------------------------+------+----------------| +| My Test Service | 1234567890abcdefghijkl | vcl | 6 | +| Another Service | 0987654321mnopqrstuvwx | vcl | 7 | ++----------------------+------------------------+------+----------------+ +``` + +### List domains attached to active versions of all services + +```sql copy +SELECT s.id AS service_id, + s.name AS service_name, + s.active_version, + d.name AS domain_name +FROM fastly_service_domains d + JOIN fastly_services s + ON d.service_id = s.id + AND d.service_version = s.active_version +ORDER BY service_name; +``` + +```text ++------------------------+----------------------+----------------+--------------------------------------+ +| service_id | service_name | active_version | domain_name | +|------------------------+----------------------+----------------+--------------------------------------| +| 1234567890abcdefghijkl | My Service | 7 | www.my-service-domain.com | +| 1234567890abcdefghijkl | My Service | 7 | my-service-domain.com | +| 0987654321mnopqrstuvwx | Test Service | 6 | my-test-service-domain.com | ++------------------------+----------------------+----------------+--------------------------------------+ +``` + +### Discover how health check definitions changed between service versions + +```sql copy +SELECT host, + path, + method, + threshold, + service_version, + check_interval +FROM fastly_service_health_checks +WHERE service_id = '1234567890abcdefghijkl' +ORDER BY service_version DESC; +``` + +```text ++-----------------------+--------+--------+-----------+-----------------+----------------+ +| host | path | method | threshold | service_version | check_interval | +|-----------------------+--------+--------+-----------+-----------------+----------------| +| my-service-domain.com | /blog | HEAD | 1 | 4 | 10000 | +| my-service-domain.com | /blog | HEAD | 2 | 3 | 20000 | +| my-service-domain.com | /blog | GET | 3 | 2 | 30000 | +| my-service-domain.com | /blog | GET | 10 | 1 | 40000 | ++-----------------------+--------+--------+-----------+-----------------+----------------+ +``` + +### Retrieve stats for a service for a specific time period + +```sql copy +SELECT to_char(Date_trunc('month', start_time), 'Month') AS month, + sum(requests) AS requests, + pg_size_pretty(Sum(resp_body_bytes) + sum(resp_header_bytes)) AS resp_bytes, + sum(status_ 2xx) AS status_2xx, + sum(status_4xx) AS status_4xx, + sum(status_5xx) AS status_5xx +FROM fastly_stats_services +WHERE service_id = '1234567890abcdefghijkl' +AND start_time >= date '2022-01-01' +AND s tart_time < date '2023-01-01' +GROUP BY date_trunc('month', start_time) +ORDER BY date_trunc('month', start_time) ASC +``` + +```text ++-----------+----------+------------+------------+------------+------------+ +| month | requests | resp_bytes | status_2xx | status_4xx | status_5xx | +|-----------+----------+------------+------------+------------+------------| +| January | 24274 | 225 MB | 17526 | 1937 | 43 | +| February | 26584 | 251 MB | 17817 | 4232 | 14 | +| March | 24508 | 240 MB | 18416 | 1788 | 18 | +| April | 25098 | 243 MB | 17892 | 3066 | 142 | +| May | 25865 | 254 MB | 18647 | 2849 | 18 | +| June | 18001 | 181 MB | 12487 | 2711 | 5 | +| July | 22005 | 206 MB | 14759 | 3414 | 30 | +| August | 19737 | 186 MB | 12824 | 3344 | 14 | +| September | 24001 | 235 MB | 15944 | 4483 | 5 | +| October | 23244 | 240 MB | 16180 | 3099 | 8 | +| November | 22119 | 201 MB | 15237 | 3832 | 2 | +| December | 18767 | 180 MB | 13414 | 2423 | 18 | ++-----------+----------+------------+------------+------------+------------+ +``` + +### Select users that don't have 2FA enabled + +```sql copy +SELECT name, + login, + two_factor_auth_enabled +FROM fastly_account_users +WHERE two_factor_auth_enabled IS FALSE +``` + +```text ++---------------+---------------------------+-------------------------+ +| name | login | two_factor_auth_enabled | +|---------------+---------------------------+-------------------------| +| Rudolph | rudolph@gmail.com | False | +| Santa | santa.northpole@gmail.com | False | ++---------------+---------------------------+-------------------------+ +``` + +### List all API tokens and their expiry dates + +```sql copy +SELECT NAME, + scope, + created_at, + last_used_at, + expires_at +FROM fastly_auth_tokens +``` + +```text ++-----------------------------------+-------------+---------------------+---------------------+---------------------+ +| name | scope | created_at | last_used_at | expires_at | +|-----------------------------------+-------------+---------------------+---------------------+---------------------| +| manage.fastly.com browser session | global | 2022-12-26 12:24:01 | | | +| Robot Santa Claus | global:read | 2022-11-25 00:00:00 | | 2024-12-25 00:00:00 | ++-----------------------------------+-------------+---------------------+---------------------+---------------------+ +``` \ No newline at end of file diff --git a/website/pages/docs/plugins/sources/fastly/tables.md b/website/pages/docs/plugins/sources/fastly/tables.md new file mode 100644 index 00000000000..5052488e4c7 --- /dev/null +++ b/website/pages/docs/plugins/sources/fastly/tables.md @@ -0,0 +1,14 @@ +# Source Plugin: fastly + +## Tables + +- [fastly_account_users](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_account_users.md) +- [fastly_account_events](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_account_events.md) +- [fastly_auth_tokens](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_auth_tokens.md) +- [fastly_services](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_services.md) + - [fastly_service_versions](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_service_versions.md) + - [fastly_service_health_checks](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_service_health_checks.md) + - [fastly_service_domains](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_service_domains.md) + - [fastly_service_backends](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_service_backends.md) +- [fastly_stats_regions](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_stats_regions.md) +- [fastly_stats_services](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/fastly/docs/tables/fastly_stats_services.md) \ No newline at end of file diff --git a/website/pages/docs/plugins/sources/gcp/tables.md b/website/pages/docs/plugins/sources/gcp/tables.md index 4027b88ac64..82aa3bb4b49 100644 --- a/website/pages/docs/plugins/sources/gcp/tables.md +++ b/website/pages/docs/plugins/sources/gcp/tables.md @@ -2,9 +2,59 @@ ## Tables +- [gcp_aiplatform_job_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_job_locations.md) + - [gcp_aiplatform_batch_prediction_jobs](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_batch_prediction_jobs.md) + - [gcp_aiplatform_custom_jobs](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_custom_jobs.md) + - [gcp_aiplatform_data_labeling_jobs](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_data_labeling_jobs.md) + - [gcp_aiplatform_hyperparameter_tuning_jobs](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_hyperparameter_tuning_jobs.md) + - [gcp_aiplatform_model_deployment_monitoring_jobs](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_model_deployment_monitoring_jobs.md) +- [gcp_aiplatform_dataset_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_dataset_locations.md) + - [gcp_aiplatform_datasets](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_datasets.md) +- [gcp_aiplatform_endpoint_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_endpoint_locations.md) + - [gcp_aiplatform_endpoints](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_endpoints.md) +- [gcp_aiplatform_featurestore_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_featurestore_locations.md) + - [gcp_aiplatform_featurestores](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_featurestores.md) +- [gcp_aiplatform_indexendpoint_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_indexendpoint_locations.md) + - [gcp_aiplatform_index_endpoints](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_index_endpoints.md) +- [gcp_aiplatform_index_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_index_locations.md) + - [gcp_aiplatform_indexes](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_indexes.md) +- [gcp_aiplatform_metadata_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_metadata_locations.md) + - [gcp_aiplatform_metadata_stores](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_metadata_stores.md) +- [gcp_aiplatform_model_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_model_locations.md) + - [gcp_aiplatform_models](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_models.md) +- [gcp_aiplatform_pipeline_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_pipeline_locations.md) + - [gcp_aiplatform_pipeline_jobs](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_pipeline_jobs.md) + - [gcp_aiplatform_training_pipelines](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_training_pipelines.md) +- [gcp_aiplatform_specialistpool_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_specialistpool_locations.md) + - [gcp_aiplatform_specialist_pools](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_specialist_pools.md) +- [gcp_aiplatform_vizier_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_vizier_locations.md) + - [gcp_aiplatform_studies](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_studies.md) +- [gcp_aiplatform_tensorboard_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_tensorboard_locations.md) + - [gcp_aiplatform_tensorboards](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_tensorboards.md) +- [gcp_aiplatform_operations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_aiplatform_operations.md) - [gcp_apigateway_apis](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_apigateway_apis.md) - [gcp_apigateway_gateways](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_apigateway_gateways.md) - [gcp_apikeys_keys](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_apikeys_keys.md) +- [gcp_appengine_apps](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_appengine_apps.md) +- [gcp_appengine_services](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_appengine_services.md) + - [gcp_appengine_versions](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_appengine_versions.md) + - [gcp_appengine_instances](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_appengine_instances.md) +- [gcp_appengine_authorized_certificates](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_appengine_authorized_certificates.md) +- [gcp_appengine_authorized_domains](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_appengine_authorized_domains.md) +- [gcp_appengine_domain_mappings](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_appengine_domain_mappings.md) +- [gcp_appengine_firewall_ingress_rules](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_appengine_firewall_ingress_rules.md) +- [gcp_artifactregistry_locations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_artifactregistry_locations.md) + - [gcp_artifactregistry_repositories](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_artifactregistry_repositories.md) + - [gcp_artifactregistry_docker_images](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_artifactregistry_docker_images.md) + - [gcp_artifactregistry_files](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_artifactregistry_files.md) + - [gcp_artifactregistry_packages](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_artifactregistry_packages.md) + - [gcp_artifactregistry_tags](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_artifactregistry_tags.md) + - [gcp_artifactregistry_versions](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_artifactregistry_versions.md) +- [gcp_baremetalsolution_instances](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_baremetalsolution_instances.md) +- [gcp_baremetalsolution_networks](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_baremetalsolution_networks.md) +- [gcp_baremetalsolution_nfs_shares](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_baremetalsolution_nfs_shares.md) +- [gcp_baremetalsolution_volumes](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_baremetalsolution_volumes.md) + - [gcp_baremetalsolution_volume_luns](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_baremetalsolution_volume_luns.md) - [gcp_bigquery_datasets](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_bigquery_datasets.md) - [gcp_bigquery_tables](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_bigquery_tables.md) - [gcp_billing_billing_accounts](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/gcp/docs/tables/gcp_billing_billing_accounts.md) diff --git a/website/pages/docs/plugins/sources/github/tables.md b/website/pages/docs/plugins/sources/github/tables.md index f59d65a09d0..ed0072d66ff 100644 --- a/website/pages/docs/plugins/sources/github/tables.md +++ b/website/pages/docs/plugins/sources/github/tables.md @@ -12,8 +12,12 @@ - [github_hook_deliveries](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_hook_deliveries.md) - [github_installations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_installations.md) - [github_organizations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_organizations.md) + - [github_organization_dependabot_alerts](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_organization_dependabot_alerts.md) + - [github_organization_dependabot_secrets](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_organization_dependabot_secrets.md) - [github_organization_members](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_organization_members.md) - [github_repositories](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_repositories.md) + - [github_repository_dependabot_alerts](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_repository_dependabot_alerts.md) + - [github_repository_dependabot_secrets](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_repository_dependabot_secrets.md) - [github_teams](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_teams.md) - [github_team_members](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_team_members.md) - [github_team_repositories](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/github/docs/tables/github_team_repositories.md) \ No newline at end of file diff --git a/website/pages/docs/plugins/sources/overview.mdx b/website/pages/docs/plugins/sources/overview.mdx index 4b329e1a104..0ff1f3691bb 100644 --- a/website/pages/docs/plugins/sources/overview.mdx +++ b/website/pages/docs/plugins/sources/overview.mdx @@ -20,6 +20,7 @@ Official source plugins follow [release stages](#source-plugin-release-stages). { name: "Azure", stage:"GA" }, { name: "GCP", stage:"GA" }, { name: "DigitalOcean", stage:"GA" }, + { name: "Fastly", stage:"Preview" }, { name: "GitHub", stage:"GA" }, { name: "GitLab", stage:"Preview" }, { name: "Heroku", stage:"Preview" }, @@ -34,6 +35,7 @@ Official source plugins follow [release stages](#source-plugin-release-stages). { name: "PagerDuty", stage:"Preview"}, { name: "Tailscale", stage:"Preview" }, { name: "Vercel", stage:"Preview" }, + { name: "Snyk", stage:"Preview" }, ] } /> diff --git a/website/pages/docs/plugins/sources/snyk/_meta.json b/website/pages/docs/plugins/sources/snyk/_meta.json new file mode 100644 index 00000000000..5ac830ef109 --- /dev/null +++ b/website/pages/docs/plugins/sources/snyk/_meta.json @@ -0,0 +1,5 @@ +{ + "overview": "Overview", + "configuration": "Configuration", + "tables": "Tables" +} diff --git a/website/pages/docs/plugins/sources/snyk/configuration.md b/website/pages/docs/plugins/sources/snyk/configuration.md new file mode 100644 index 00000000000..37fc4643b7d --- /dev/null +++ b/website/pages/docs/plugins/sources/snyk/configuration.md @@ -0,0 +1,39 @@ +# Snyk Source Plugin Configuration Reference + +## Example + +This example syncs from Snyk to a Postgres destination, using `api_key` authentication. +The (top level) source spec section is described in the [Source Spec Reference](/docs/reference/source-spec). + +```yaml +kind: source +# Common source-plugin configuration +spec: + name: snyk + path: cloudquery/snyk + version: "VERSION_SOURCE_SNYK" + tables: [ "*" ] + destinations: [ "postgresql" ] + + # Snyk specific configuration + spec: + api_key: "" + organizations: + - "" + - "" + endpoint_url: "" +``` + +## Snyk Spec + +This is the (nested) spec used by the Snyk source plugin. + +- `api_key` (string, required. Default: `SNYK_API_KEY` environment variable): + An API key to access Snyk resources. + See [Authentication for API](https://docs.snyk.io/snyk-api-info/authentication-for-api) for more information. + +- `organizations` ([]string, optional. Default: all organizations accessible via `api_key`): + You can choose to limit what organizations to sync information from. + +- `endpoint_url` (string, optional. Default: not used): + Endpoint URL to make the API requests to. diff --git a/website/pages/docs/plugins/sources/snyk/overview.md b/website/pages/docs/plugins/sources/snyk/overview.md new file mode 100644 index 00000000000..20d6f27d35d --- /dev/null +++ b/website/pages/docs/plugins/sources/snyk/overview.md @@ -0,0 +1,15 @@ +# Snyk Source Plugin + +import { getLatestVersion } from "../../../../../utils/versions"; +import { Badge } from "../../../../../components/Badge"; + + + +The CloudQuery Snyk plugin pulls configuration out of Snyk +resources and loads it into any supported CloudQuery destination (e.g. PostgreSQL). + +## Authentication + +In order to fetch information from Snyk, `cloudquery` needs to be authenticated. +An API key is required for authentication. +See [Authentication for API](https://docs.snyk.io/snyk-api-info/authentication-for-api) for more information. diff --git a/website/pages/docs/plugins/sources/snyk/tables.md b/website/pages/docs/plugins/sources/snyk/tables.md new file mode 100644 index 00000000000..5a0d6187382 --- /dev/null +++ b/website/pages/docs/plugins/sources/snyk/tables.md @@ -0,0 +1,8 @@ +# Source Plugin: snyk + +## Tables + +- [snyk_dependencies](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/snyk/docs/tables/snyk_dependencies.md) +- [snyk_integrations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/snyk/docs/tables/snyk_integrations.md) +- [snyk_organizations](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/snyk/docs/tables/snyk_organizations.md) +- [snyk_projects](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/snyk/docs/tables/snyk_projects.md) \ No newline at end of file diff --git a/website/pages/docs/reference/destination-spec.md b/website/pages/docs/reference/destination-spec.md index f4639aa6e89..fbcda873abe 100644 --- a/website/pages/docs/reference/destination-spec.md +++ b/website/pages/docs/reference/destination-spec.md @@ -61,6 +61,14 @@ Specifies the update method to use when inserting rows. The exact semantics depe - `overwrite`: Same as `overwrite-delete-stale`, but doesn't delete stale rows from previous `sync`s. - `append`: Rows are never overwritten or deleted, only appended. +{/**/} +### batch_size +{/**/} + +(`int`, optional) + +The number of resources to insert in a single batch. Only relevant for plugins that utilize batching. Each plugin has its own default value. + ### spec (`object`, optional) diff --git a/website/pages/docs/reference/source-spec.md b/website/pages/docs/reference/source-spec.md index 8eca3e54cb6..7ec8e4e189c 100644 --- a/website/pages/docs/reference/source-spec.md +++ b/website/pages/docs/reference/source-spec.md @@ -74,7 +74,7 @@ Specify the names of the destinations to sync the data of the source plugin to. ### concurrency -(`int`, optional, default: `1000000`, introduced in CLI `v1.4.1`) +(`int`, optional, default: `500000`, introduced in CLI `v1.4.1`) A best effort maximum number of Go routines to use. Lower this number to reduce memory usage. diff --git a/website/pages/how-to-guides/configuring-cloudquery-with-localstack.md b/website/pages/how-to-guides/configuring-cloudquery-with-localstack.md new file mode 100644 index 00000000000..2402179e4fd --- /dev/null +++ b/website/pages/how-to-guides/configuring-cloudquery-with-localstack.md @@ -0,0 +1,137 @@ +--- +title: Configuring CloudQuery with LocalStack +tag: integration +description: >- + How to setup CloudQuery to work with LocalStack +author: benjamin +--- + +import { HowToGuideHeader } from "../../components/HowToGuideHeader" +import { Callout } from 'nextra-theme-docs' + + + + +In this guide we will walk through how to configure CloudQuery to sync from a LocalStack instance. + + + +## Introduction to LocalStack + +[LocalStack](https://localstack.cloud/) is a fully functional local cloud stack that enables developers to Develop and test their cloud and serverless applications offline. It allows developers to test their cloud applications locally, without the need for an internet connection or an AWS account. This can be particularly useful for development and testing, as it allows developers to work on their applications offline and avoid incurring any charges for using AWS services. + + + +## Walkthrough + +Before beginning this tutorial make sure you have the following tools installed: +- [Docker](https://www.docker.com/products/docker-desktop/) +- [CloudQuery](/docs/quickstart) + + +### Step 1: Start LocalStack + +The most straightforward way of running LocalStack is to use the provided `localstack` docker image that is maintained by LocalStack. To run the image use the following command to spin up the container and to map the correct ports + +```bash copy +docker run --rm -it \ + -p 4566:4566 \ + -p 4510-4559:4510-4559 \ + -e DEBUG=1 \ + localstack/localstack +``` + + +### Step 2: Start Postgresql Database + +Start a local Postgres Database for CloudQuery to use to store the data we will sync from LocalStack. The simplest way to do this is to start a database running locally in a docker container + +```bash copy +#Create a database in Docker +docker run -d --name postgresdb \ +-p 5432:5432 \ +-e POSTGRES_PASSWORD=pass \ +postgres +``` + + +### Step 3: Configure CloudQuery Destination + +Configure a destination for CloudQuery to use to store the data. For this tutorial we will use Postgresql, but many other destinations are [available here](/docs/plugins/destinations/overview) + +```yaml +# destination.yml +kind: destination +spec: + name: "postgresql" + registry: "github" + path: "cloudquery/postgresql" + version: "VERSION_DESTINATION_POSTGRESQL" + spec: + connection_string: "postgresql://postgres:pass@localhost:5432/postgres?sslmode=disable" +``` + + +### Step 4: Configure CloudQuery Source + +Configure CloudQuery's AWS [source plugin](/docs/plugins/sources/aws/overview) to use the LocalStack endpoint. + + +```yaml +# source.yml +kind: source +spec: + # Source spec section + name: "aws" + registry: "github" + path: "cloudquery/aws" + version: "VERSION_SOURCE_AWS" + destinations: ["postgresql"] + skip_tables: + - aws_route53_delegation_sets + - aws_iam_policies + tables: + - "*" + spec: + regions: + - "us-east-1" + + # Configure the AWS SDK to use the localstack endpoint + custom_endpoint_url: http://localhost:4566 + custom_endpoint_hostname_immutable: true + custom_endpoint_partition_id: "aws" + custom_endpoint_signing_region: "us-east-1" + # There is no reason to retry failed requests to localstack + max_retries: 0 +``` + +Note that it is important to skip `aws_route53_delegation_sets` and `aws_iam_policies` as bugs in LocalStack force CloudQuery into an infinite loop + + + +### Step 5: Sync Data + +Run CloudQuery sync to sync the data from LocalStack to your local Postgres database you started in step 2 + +Make sure to use fake credentials LocalStack does not support temporary IAM credentials… + +```bash copy +AWS_ACCESS_KEY_ID=123456789100 AWS_SECRET_ACCESS_KEY=test cloudquery sync source.yml destination.yml +``` + + +You can inject the desired AWS Account ID by setting it as the `AWS_ACCESS_KEY_ID` if you don't set a value then it will be `000000000000`. You can read more about this functionality in the [LocalStack docs](https://docs.localstack.cloud/user-guide/tools/multi-account-setups/) + + + +### Step 6: Use the Data + +Query the data you just synced! + +```sql +select * from aws_ec2_vpcs; + +-- or + +select * from aws_ec2_security_groups; +``` \ No newline at end of file diff --git a/website/pages/how-to-guides/cross-account-access-aws-assumerole.md b/website/pages/how-to-guides/cross-account-access-aws-assumerole.md index 143ae7666c7..98fbc46dedf 100644 --- a/website/pages/how-to-guides/cross-account-access-aws-assumerole.md +++ b/website/pages/how-to-guides/cross-account-access-aws-assumerole.md @@ -30,13 +30,13 @@ This means that a single policy cannot grant User in Account A access to a resou In this tutorial we will show you how to do in the console (ClickOps) but feel free to automate it via your favorite IaC. -### Step 1 +### Step 1 Go to `iam→roles` and [click Create Role](https://us-east-1.console.aws.amazon.com/iamv2/home?region=us-east-1#/roles/create?step=selectEntities) ![](/images/blog/cross-account-access-aws-assumerole/step1.png) -## Step 2 +### Step 2 For **_Trusted Entity,_** Choose **_AWS account_**, click **_Another AWS account_** and fill-in the account id you want to access **from** and click next diff --git a/website/versions/cli.json b/website/versions/cli.json index 00727317824..ebc1727c887 100644 --- a/website/versions/cli.json +++ b/website/versions/cli.json @@ -1 +1 @@ -{ "latest": "cli-v2.0.27" } +{ "latest": "cli-v2.0.28" } diff --git a/website/versions/destination-bigquery.json b/website/versions/destination-bigquery.json index e679e36ebb0..709acea8c46 100644 --- a/website/versions/destination-bigquery.json +++ b/website/versions/destination-bigquery.json @@ -1 +1 @@ -{ "latest": "plugins-destination-bigquery-v1.3.0" } +{ "latest": "plugins-destination-bigquery-v2.0.0" } diff --git a/website/versions/destination-csv.json b/website/versions/destination-csv.json index dc0fb534abc..e9d01fb7b9d 100644 --- a/website/versions/destination-csv.json +++ b/website/versions/destination-csv.json @@ -1 +1 @@ -{ "latest": "plugins-destination-csv-v1.2.0" } +{ "latest": "plugins-destination-csv-v1.2.2" } diff --git a/website/versions/destination-mongodb.json b/website/versions/destination-mongodb.json index 279059bcb70..3ff1ad482a6 100644 --- a/website/versions/destination-mongodb.json +++ b/website/versions/destination-mongodb.json @@ -1 +1 @@ -{ "latest": "plugins-destination-mongodb-v1.0.0" } +{ "latest": "plugins-destination-mongodb-v1.0.2" } diff --git a/website/versions/destination-postgresql.json b/website/versions/destination-postgresql.json index 5d4c853959f..a4f1ba804df 100644 --- a/website/versions/destination-postgresql.json +++ b/website/versions/destination-postgresql.json @@ -1 +1 @@ -{ "latest": "plugins-destination-postgresql-v1.10.0" } +{ "latest": "plugins-destination-postgresql-v2.0.0" } diff --git a/website/versions/destination-snowflake.json b/website/versions/destination-snowflake.json index b92720ee751..a37d0db2af3 100644 --- a/website/versions/destination-snowflake.json +++ b/website/versions/destination-snowflake.json @@ -1 +1 @@ -{ "latest": "plugins-destination-snowflake-v1.1.0" } +{ "latest": "plugins-destination-snowflake-v1.1.2" } diff --git a/website/versions/destination-sqlite.json b/website/versions/destination-sqlite.json index a106c4bc0c1..aa5b947c4ef 100644 --- a/website/versions/destination-sqlite.json +++ b/website/versions/destination-sqlite.json @@ -1 +1 @@ -{ "latest": "plugins-destination-sqlite-v1.1.0" } +{ "latest": "plugins-destination-sqlite-v1.1.2" } diff --git a/website/versions/destination-test.json b/website/versions/destination-test.json index f839b86e7fa..2c638cc9b29 100644 --- a/website/versions/destination-test.json +++ b/website/versions/destination-test.json @@ -1 +1 @@ -{ "latest": "plugins-destination-test-v1.3.8" } +{ "latest": "plugins-destination-test-v1.3.11" } diff --git a/website/versions/source-aws.json b/website/versions/source-aws.json index 88865cc892b..6107b197ff0 100644 --- a/website/versions/source-aws.json +++ b/website/versions/source-aws.json @@ -1 +1 @@ -{ "latest": "plugins-source-aws-v8.1.0" } +{ "latest": "plugins-source-aws-v9.0.1" } diff --git a/website/versions/source-azure.json b/website/versions/source-azure.json index f656c39d12b..25d4e3641f0 100644 --- a/website/versions/source-azure.json +++ b/website/versions/source-azure.json @@ -1 +1 @@ -{ "latest": "plugins-source-azure-v2.2.0" } +{ "latest": "plugins-source-azure-v3.0.0" } diff --git a/website/versions/source-azuredevops.json b/website/versions/source-azuredevops.json new file mode 100644 index 00000000000..aab242b4126 --- /dev/null +++ b/website/versions/source-azuredevops.json @@ -0,0 +1 @@ +{ "latest": "plugins-source-azuredevops-v1.0.0" } diff --git a/website/versions/source-cloudflare.json b/website/versions/source-cloudflare.json index a2c721d7e88..8db6030c01b 100644 --- a/website/versions/source-cloudflare.json +++ b/website/versions/source-cloudflare.json @@ -1 +1 @@ -{ "latest": "plugins-source-cloudflare-v2.3.2" } +{ "latest": "plugins-source-cloudflare-v2.3.3" } diff --git a/website/versions/source-crowdstrike.json b/website/versions/source-crowdstrike.json index 008e3f30898..c6cf1fa8d65 100644 --- a/website/versions/source-crowdstrike.json +++ b/website/versions/source-crowdstrike.json @@ -1 +1 @@ -{ "latest": "plugins-source-crowdstrike-v1.0.0" } +{ "latest": "plugins-source-crowdstrike-v1.0.1" } diff --git a/website/versions/source-datadog.json b/website/versions/source-datadog.json index 04452bd75c0..4f8526f1c6f 100644 --- a/website/versions/source-datadog.json +++ b/website/versions/source-datadog.json @@ -1 +1 @@ -{ "latest": "plugins-source-datadog-v1.0.3" } +{ "latest": "plugins-source-datadog-v1.0.4" } diff --git a/website/versions/source-digitalocean.json b/website/versions/source-digitalocean.json index c6c9662e524..b1acd72748d 100644 --- a/website/versions/source-digitalocean.json +++ b/website/versions/source-digitalocean.json @@ -1 +1 @@ -{ "latest": "plugins-source-digitalocean-v4.0.0" } +{ "latest": "plugins-source-digitalocean-v4.0.1" } diff --git a/website/versions/source-fastly.json b/website/versions/source-fastly.json new file mode 100644 index 00000000000..605e9658e32 --- /dev/null +++ b/website/versions/source-fastly.json @@ -0,0 +1 @@ +{ "latest": "plugins-source-fastly-v1.0.0" } diff --git a/website/versions/source-gandi.json b/website/versions/source-gandi.json index 0e95a5b0ee2..1751f730525 100644 --- a/website/versions/source-gandi.json +++ b/website/versions/source-gandi.json @@ -1 +1 @@ -{ "latest": "plugins-source-gandi-v1.1.2" } +{ "latest": "plugins-source-gandi-v1.1.3" } diff --git a/website/versions/source-gcp.json b/website/versions/source-gcp.json index 6b0a67243f8..c91c1f0cd26 100644 --- a/website/versions/source-gcp.json +++ b/website/versions/source-gcp.json @@ -1 +1 @@ -{ "latest": "plugins-source-gcp-v5.2.0" } +{ "latest": "plugins-source-gcp-v5.3.1" } diff --git a/website/versions/source-github.json b/website/versions/source-github.json index 7a60b529fe0..a155a25745d 100644 --- a/website/versions/source-github.json +++ b/website/versions/source-github.json @@ -1 +1 @@ -{ "latest": "plugins-source-github-v1.4.1" } +{ "latest": "plugins-source-github-v1.4.2" } diff --git a/website/versions/source-gitlab.json b/website/versions/source-gitlab.json index 4d00d5ee94e..3192e86526f 100644 --- a/website/versions/source-gitlab.json +++ b/website/versions/source-gitlab.json @@ -1 +1 @@ -{ "latest": "plugins-source-gitlab-v1.0.0" } +{ "latest": "plugins-source-gitlab-v1.0.1" } diff --git a/website/versions/source-heroku.json b/website/versions/source-heroku.json index 048e7a9c7ef..5e0830f8ef5 100644 --- a/website/versions/source-heroku.json +++ b/website/versions/source-heroku.json @@ -1 +1 @@ -{ "latest": "plugins-source-heroku-v3.1.2" } +{ "latest": "plugins-source-heroku-v3.1.3" } diff --git a/website/versions/source-k8s.json b/website/versions/source-k8s.json index dd7b338622c..cc539f641aa 100644 --- a/website/versions/source-k8s.json +++ b/website/versions/source-k8s.json @@ -1 +1 @@ -{ "latest": "plugins-source-k8s-v2.5.2" } +{ "latest": "plugins-source-k8s-v2.5.3" } diff --git a/website/versions/source-okta.json b/website/versions/source-okta.json index 17375d5f056..d0c13e87a0f 100644 --- a/website/versions/source-okta.json +++ b/website/versions/source-okta.json @@ -1 +1 @@ -{ "latest": "plugins-source-okta-v2.0.0" } +{ "latest": "plugins-source-okta-v2.0.1" } diff --git a/website/versions/source-pagerduty.json b/website/versions/source-pagerduty.json index 17862146646..3081324f94b 100644 --- a/website/versions/source-pagerduty.json +++ b/website/versions/source-pagerduty.json @@ -1 +1 @@ -{ "latest": "plugins-source-pagerduty-v1.1.0" } +{ "latest": "plugins-source-pagerduty-v1.1.1" } diff --git a/website/versions/source-salesforce.json b/website/versions/source-salesforce.json new file mode 100644 index 00000000000..7590318172b --- /dev/null +++ b/website/versions/source-salesforce.json @@ -0,0 +1 @@ +{ "latest": "plugins-source-salesforce-v1.0.0" } diff --git a/website/versions/source-slack.json b/website/versions/source-slack.json index bf5be3880bf..8bac05aef01 100644 --- a/website/versions/source-slack.json +++ b/website/versions/source-slack.json @@ -1 +1 @@ -{ "latest": "plugins-source-slack-v1.0.0" } +{ "latest": "plugins-source-slack-v1.0.1" } diff --git a/website/versions/source-tailscale.json b/website/versions/source-tailscale.json index 8eb3c678941..98dff1015a3 100644 --- a/website/versions/source-tailscale.json +++ b/website/versions/source-tailscale.json @@ -1 +1 @@ -{ "latest": "plugins-source-tailscale-v1.0.1" } +{ "latest": "plugins-source-tailscale-v1.0.2" } diff --git a/website/versions/source-terraform.json b/website/versions/source-terraform.json index f9ad412f383..a3a46c0bb60 100644 --- a/website/versions/source-terraform.json +++ b/website/versions/source-terraform.json @@ -1 +1 @@ -{ "latest": "plugins-source-terraform-v1.3.2" } +{ "latest": "plugins-source-terraform-v1.3.3" } diff --git a/website/versions/source-test.json b/website/versions/source-test.json index fc467f9f114..174bcf05be8 100644 --- a/website/versions/source-test.json +++ b/website/versions/source-test.json @@ -1 +1 @@ -{ "latest": "plugins-source-test-v1.3.24" } +{ "latest": "plugins-source-test-v1.3.25" } diff --git a/website/versions/source-vercel.json b/website/versions/source-vercel.json index bd9d1c1fbf7..e639f0493ad 100644 --- a/website/versions/source-vercel.json +++ b/website/versions/source-vercel.json @@ -1 +1 @@ -{ "latest": "plugins-source-vercel-v1.0.1" } +{ "latest": "plugins-source-vercel-v1.0.2" }