diff --git a/.clomonitor.yml b/.clomonitor.yml
new file mode 100644
index 00000000..80633885
--- /dev/null
+++ b/.clomonitor.yml
@@ -0,0 +1,24 @@
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# CLOMonitor metadata file
+# This file must be located at the root of the repository
+
+# Checks exemptions
+exemptions:
+ - check: license_scanning # Check identifier (see https://github.com/cncf/clomonitor/blob/main/docs/checks.md#exemptions)
+ reason: "There are currently no plans moving forward to implement FOSSA or Snyk for scanning purposes." # Justification of this exemption (mandatory, it will be displayed on the UI)
+ - check: artifacthub_badge
+ reason: "This repository has no items that should be added to Artifact Hub."
\ No newline at end of file
diff --git a/.codecov.yaml b/.codecov.yaml
index 8739c455..95789fda 100644
--- a/.codecov.yaml
+++ b/.codecov.yaml
@@ -1,3 +1,18 @@
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
# See http://docs.codecov.io/docs/coverage-configuration
coverage:
precision: 2 # 2 = xx.xx%, 0 = xx%
@@ -29,6 +44,8 @@ coverage:
- "vendor/*"
- "Makefile"
- ".travis.yml"
+ - "pkg/devfile/parser/util/mock.go"
+ - "pkg/util/mock.go"
# See http://docs.codecov.io/docs/pull-request-comments-1
comment:
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 9c1348c4..34c731ef 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -5,14 +5,16 @@
### PR acceptance criteria:
-Testing and documentation do not need to be complete in order for this PR to be approved. We just need to ensure tracking issues are opened.
+Testing and documentation do not need to be complete in order for this PR to be approved. We just need to ensure tracking issues are opened and linked to this PR, if they are not in the PR scope due to various constraints.
-> - Open new test/doc issues under the [devfile/api](https://github.com/devfile/api/issues) repo
-> - Check each criteria if:
-> - There is a separate tracking issue. Add the issue link under the criteria
-> **or**
-> - test/doc updates are made as part of this PR
-> - If unchecked, explain why it's not needed
+
- [ ] Unit/Functional tests
@@ -23,9 +25,9 @@ Testing and documentation do not need to be complete in order for this PR to be
-- [ ] Documentation
+- [ ] Documentation (READMEs, Product Docs, Blogs, Education Modules, etc.)
-
+
- [ ] Client Impact
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
index 0ef5dfb1..c9f6ca42 100644
--- a/.github/workflows/codecov.yml
+++ b/.github/workflows/codecov.yml
@@ -1,8 +1,26 @@
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
name: Code Coverage Report
on:
push:
branches:
- main
+
+# Declare default permissions as read only.
+permissions: read-all
+
jobs:
build-and-deploy:
runs-on: ubuntu-20.04
@@ -14,7 +32,7 @@ jobs:
- name: Set up Go 1.x
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with:
- go-version: 1.19
+ go-version-file: 'go.mod'
- name: Run tests
run: make test
- name: Codecov
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index e16698ad..dbcca026 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -1,3 +1,17 @@
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
name: Validate PRs
on:
@@ -6,22 +20,29 @@ on:
pull_request:
branches: [ main ]
-jobs:
+# Declare default permissions as read only.
+permissions: read-all
+jobs:
+
build:
name: Build
runs-on: ubuntu-latest
+
+ permissions:
+ security-events: write
+
steps:
+ - name: Check out code into the Go module directory
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+
- name: Setup Go environment
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with:
- go-version: 1.19
+ go-version-file: 'go.mod'
id: go
- - name: Check out code into the Go module directory
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
-
- name: Check go mod status
run: |
make gomod_tidy
diff --git a/.github/workflows/proxy-warming.yml b/.github/workflows/proxy-warming.yml
index a63b7148..32b65e64 100644
--- a/.github/workflows/proxy-warming.yml
+++ b/.github/workflows/proxy-warming.yml
@@ -1,3 +1,17 @@
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
name: Renew documentation
on:
@@ -7,6 +21,9 @@ on:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
+# Declare default permissions as read only.
+permissions: read-all
+
jobs:
build:
name: Renew documentation
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
new file mode 100644
index 00000000..8cf248d1
--- /dev/null
+++ b/.github/workflows/scorecard.yml
@@ -0,0 +1,83 @@
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This workflow uses actions that are not certified by GitHub. They are provided
+# by a third-party and are governed by separate terms of service, privacy
+# policy, and support documentation.
+
+name: Scorecard supply-chain security
+on:
+ # For Branch-Protection check. Only the default branch is supported. See
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
+ branch_protection_rule:
+ pull_request:
+ branches: [ "main" ]
+
+# Declare default permissions as read only.
+permissions: read-all
+
+jobs:
+ analysis:
+ name: Scorecard analysis
+ runs-on: ubuntu-latest
+ permissions:
+ # Needed to upload the results to code-scanning dashboard.
+ security-events: write
+ # Needed to publish results and get a badge (see publish_results below).
+ id-token: write
+ # Uncomment the permissions below if installing in a private repository.
+ # contents: read
+ # actions: read
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ with:
+ persist-credentials: false
+
+ - name: "Run analysis"
+ uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ # (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
+ # - you want to enable the Branch-Protection check on a *public* repository, or
+ # - you are installing Scorecard on a *private* repository
+ # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
+ # repo_token: ${{ secrets.SCORECARD_TOKEN }}
+
+ # Public repositories:
+ # - Publish results to OpenSSF REST API for easy access by consumers
+ # - Allows the repository to include the Scorecard badge.
+ # - See https://github.com/ossf/scorecard-action#publishing-results.
+ # For private repositories:
+ # - `publish_results` will always be set to `false`, regardless
+ # of the value entered here.
+ publish_results: true
+
+ # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
+ # format to the repository Actions tab.
+ - name: "Upload artifact"
+ uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
+
+ # Upload the results to GitHub's code scanning dashboard.
+ - name: "Upload to code-scanning"
+ uses: github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4
+ with:
+ sarif_file: results.sarif
diff --git a/.gitignore b/.gitignore
index b98f9699..1396c90a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ main
# File created running tests
tests/**/tmp/
tests/v2/lib-test-coverage.*
+*resource.file*
# Mac related files
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4bd94ebd..138a7859 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -16,7 +16,7 @@ contribution. See the [DCO](./DCO) file for details.
The following are required to work on devfile library:
- Git
-- Go 1.15 or later
+- Go 1.19 or later
## Code of Conduct
Before contributing to this repository, see [contributor code of conduct](https://github.com/devfile/api/blob/main/CODE_OF_CONDUCT.md#contributor-covenant-code-of-conduct)
@@ -29,7 +29,7 @@ If you spot a problem with devfile library, [search if an issue already exists](
### Writing Code
-For writing the code just follow [Go guide](https://go.dev/doc/effective_go), and also test with [tesing](https://pkg.go.dev/testing). Remember to add new unit tests if new features have been introducted, or changes have been made to existing code. If there is something unclear of the style, just look at existing code which might help you to understand it better.
+For writing the code just follow [Go guide](https://go.dev/doc/effective_go), and also test with [testing](https://pkg.go.dev/testing). Remember to add new unit tests if new features have been introducted, or changes have been made to existing code. If there is something unclear of the style, just look at existing code which might help you to understand it better.
### Testing Changes
To run unit tests and api tests. Visit [library tests](tests/README.md) to find out more information on tests
@@ -69,6 +69,6 @@ Running the script with no arguments will default to update the latest devfile v
### Releases
-Currently devfile library does not have schedule for new releases. A new version is being generated and released on demand.
+Currently devfile library publish new releases annually. A new version can also be generated and released on demand.
A new branch is expected to be created for a new release.
To generate a changelog for a new release, execute `./scripts/changelog-script.sh v2.x.y` for all the changes since the release v2.x.y
diff --git a/Makefile b/Makefile
index f4c95d6c..bed0ecfa 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,18 @@
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
FILES := main
default: bin
diff --git a/OWNERS b/OWNERS
index 49711660..24e0d73e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -3,14 +3,12 @@
approvers:
- amisevsk
- elsony
+- Jdubrick
- michael-valdron
- thepetk
-- feloy
-- rm3l
reviewers:
- elsony
+- Jdubrick
- michael-valdron
-- thepetk
-- feloy
-- rm3l
\ No newline at end of file
+- thepetk
\ No newline at end of file
diff --git a/README.md b/README.md
index 902d4352..58f44fa4 100644
--- a/README.md
+++ b/README.md
@@ -2,17 +2,20 @@
## About
The Devfile Parser library is a Golang module that:
-1. parses the devfile.yaml as specified by the [api](https://devfile.github.io/devfile/api-reference.html) & [schema](https://github.com/devfile/api/tree/main/schemas/latest).
-2. writes to the devfile.yaml with the updated data.
+1. parses a devfile as specified by the [api](https://devfile.io/docs/2.2.2/devfile-schema) & [schema](https://github.com/devfile/api/tree/main/schemas/latest).
+2. writes to the specified devfile with the updated data.
3. generates Kubernetes objects for the various devfile resources.
4. defines util functions for the devfile.
-5. downloads resources from a parent devfile if specified in the devfile.yaml
+5. downloads resources from a parent devfile if specified in the devfile.
## Private repository support
@@ -226,6 +229,29 @@ The function documentation can be accessed via [pkg.go.dev](https://pkg.go.dev/g
}
```
+11. To download/access files from a private repository like a private GitHub use the `Token` property
+ ```go
+ parserArgs := parser.ParserArgs{
+ Token: "my-PAT",
+ }
+ ```
+
+ ```go
+ src: YamlSrc{
+ URL: "http://github.com/my-private-repo",
+ Token: "my-PAT",
+ }
+ values, err := ReadKubernetesYaml(src, fs, nil)
+ ```
+
+ If you would like to use the mock implementation for the `DevfileUtils` interface method defined in [pkg/devfile/parser/util/interface.go](pkg/devfile/parser/util/interface.go), then use
+ ```go
+ var devfileUtilsClient DevfileUtils
+ devfileUtilsClient = NewMockDevfileUtilsClient()
+ devfileUtilsClient.DownloadInMemory(params)
+ ```
+
+
## Projects using devfile/library
The following projects are consuming this library as a Golang dependency
@@ -246,7 +272,7 @@ Issues are tracked in the [devfile/api](https://github.com/devfile/api) repo wit
## Releases
-The devfile/library releases are created on demand. For existing devfile/library releases, please check the release [page](https://github.com/devfile/library/releases).
+The devfile/library releases are created annually or on demand. For existing devfile/library releases, please check the release [page](https://github.com/devfile/library/releases).
### Create a New Release
diff --git a/SECURITY-INSIGHTS.yml b/SECURITY-INSIGHTS.yml
new file mode 100644
index 00000000..edced808
--- /dev/null
+++ b/SECURITY-INSIGHTS.yml
@@ -0,0 +1,49 @@
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+header:
+ schema-version: 1.0.0
+ last-updated: '2024-03-01'
+ last-reviewed: '2024-03-01'
+ expiration-date: '2025-03-01T10:00:00.000Z'
+ project-url: https://github.com/devfile/library
+ project-release: 'v2.2.1'
+ commit-hash: '6aa1b8339d39e9c2db403d3817cb552d428d19e4'
+ license: 'https://raw.githubusercontent.com/devfile/library/main/LICENSE'
+project-lifecycle:
+ status: active
+ bug-fixes-only: false
+ core-maintainers:
+ - github:michael-valdron
+ - github:Jdubrick
+ - github:thepetk
+ release-cycle: https://github.com/devfile/library/blob/main/README.md#releases
+security-testing:
+- tool-type: sca
+ tool-name: Dependabot
+ comment: |
+ Dependabot is enabled for this repo.
+distribution-points:
+ - https://github.com/devfile/library
+contribution-policy:
+ accepts-pull-requests: true
+ accepts-automated-pull-requests: true
+ contributing-policy: https://github.com/devfile/library/blob/main/CONTRIBUTING.md
+ code-of-conduct: https://github.com/devfile/api/blob/main/CODE_OF_CONDUCT.md
+documentation:
+- https://github.com/devfile/library/blob/main/README.md#usage
+dependencies:
+ third-party-packages: true
+ dependencies-lists:
+ - https://github.com/devfile/library/blob/main/go.mod
\ No newline at end of file
diff --git a/devfile.yaml b/devfile.yaml
index b683cd0e..acb4d6db 100644
--- a/devfile.yaml
+++ b/devfile.yaml
@@ -1,3 +1,18 @@
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
schemaVersion: 2.2.0-latest
metadata:
name: nodejs
diff --git a/go.mod b/go.mod
index 5539c565..feaf5277 100644
--- a/go.mod
+++ b/go.mod
@@ -1,123 +1,135 @@
module github.com/devfile/library/v2
-go 1.18
+go 1.19
require (
- github.com/devfile/api/v2 v2.2.1
- github.com/devfile/registry-support/registry-library v0.0.0-20221018213054-47b3ffaeadba
- github.com/distribution/distribution/v3 v3.0.0-20211118083504-a29a3c99a684
- github.com/fatih/color v1.7.0
- github.com/fsnotify/fsnotify v1.6.0
- github.com/go-git/go-git/v5 v5.4.2
+ github.com/devfile/api/v2 v2.2.2
+ github.com/devfile/registry-support/registry-library v0.0.0-20240328155806-7c89891a72ce
+ github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2
+ github.com/fatih/color v1.14.1
+ github.com/fsnotify/fsnotify v1.7.0
+ github.com/go-git/go-git/v5 v5.11.0
github.com/gobwas/glob v0.2.3
github.com/golang/mock v1.6.0
- github.com/google/go-cmp v0.5.9
+ github.com/google/go-cmp v0.6.0
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-version v1.4.0
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348
github.com/openshift/api v0.0.0-20200930075302-db52bc4ef99f
github.com/pkg/errors v0.9.1
- github.com/spf13/afero v1.6.0
- github.com/stretchr/testify v1.8.0
+ github.com/spf13/afero v1.11.0
+ github.com/stretchr/testify v1.8.4
github.com/xeipuuv/gojsonschema v1.2.0
gopkg.in/yaml.v3 v3.0.1
- k8s.io/api v0.26.1
- k8s.io/apiextensions-apiserver v0.26.1
- k8s.io/apimachinery v0.26.1
- k8s.io/client-go v0.26.1
+ k8s.io/api v0.26.10
+ k8s.io/apiextensions-apiserver v0.26.10
+ k8s.io/apimachinery v0.26.10
+ k8s.io/client-go v0.26.10
k8s.io/klog v1.0.0
- k8s.io/pod-security-admission v0.26.1
- k8s.io/utils v0.0.0-20221128185143-99ec85e7a448
- sigs.k8s.io/controller-runtime v0.14.4
+ k8s.io/pod-security-admission v0.26.10
+ k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5
+ sigs.k8s.io/controller-runtime v0.14.7
sigs.k8s.io/yaml v1.3.0
)
require (
- github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
- github.com/Microsoft/go-winio v0.5.1 // indirect
- github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
- github.com/acomagu/bufpipe v1.0.3 // indirect
+ dario.cat/mergo v1.0.0 // indirect
+ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
+ github.com/Microsoft/go-winio v0.6.1 // indirect
+ github.com/Microsoft/hcsshim v0.11.4 // indirect
+ github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/beorn7/perks v1.0.1 // indirect
- github.com/cespare/xxhash/v2 v2.1.2 // indirect
- github.com/containerd/containerd v1.5.9 // indirect
- github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/devfile/registry-support/index/generator v0.0.0-20221018203505-df96d34d4273 // indirect
- github.com/docker/cli v20.10.11+incompatible // indirect
- github.com/docker/distribution v2.7.1+incompatible // indirect
- github.com/docker/docker v20.10.11+incompatible // indirect
- github.com/docker/docker-credential-helpers v0.6.4 // indirect
- github.com/docker/go-connections v0.4.0 // indirect
+ github.com/cespare/xxhash/v2 v2.2.0 // indirect
+ github.com/cloudflare/circl v1.3.7 // indirect
+ github.com/containerd/containerd v1.7.13 // indirect
+ github.com/containerd/log v0.1.0 // indirect
+ github.com/cyphar/filepath-securejoin v0.2.4 // indirect
+ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+ github.com/devfile/registry-support/index/generator v0.0.0-20240311135803-6215550f93d4 // indirect
+ github.com/distribution/reference v0.5.0 // indirect
+ github.com/docker/cli v25.0.1+incompatible // indirect
+ github.com/docker/distribution v2.8.3+incompatible // indirect
+ github.com/docker/docker v25.0.1+incompatible // indirect
+ github.com/docker/docker-credential-helpers v0.7.0 // indirect
+ github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
- github.com/docker/go-units v0.4.0 // indirect
- github.com/emicklei/go-restful/v3 v3.9.0 // indirect
- github.com/emirpasic/gods v1.12.0 // indirect
+ github.com/emicklei/go-restful/v3 v3.10.1 // indirect
+ github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
- github.com/go-git/gcfg v1.5.0 // indirect
- github.com/go-git/go-billy/v5 v5.3.1 // indirect
- github.com/go-logr/logr v1.2.3 // indirect
+ github.com/felixge/httpsnoop v1.0.4 // indirect
+ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
+ github.com/go-git/go-billy/v5 v5.5.0 // indirect
+ github.com/go-logr/logr v1.4.1 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.20.0 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
- github.com/golang/protobuf v1.5.2 // indirect
+ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
- github.com/hashicorp/errwrap v1.0.0 // indirect
+ github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
- github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
- github.com/klauspost/compress v1.13.6 // indirect
+ github.com/kevinburke/ssh_config v1.2.0 // indirect
+ github.com/klauspost/compress v1.17.7 // indirect
github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb // indirect
github.com/mailru/easyjson v0.7.6 // indirect
- github.com/mattn/go-colorable v0.1.2 // indirect
- github.com/mattn/go-isatty v0.0.12 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
- github.com/mitchellh/go-homedir v1.1.0 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.17 // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/reflectwalk v1.0.1 // indirect
github.com/moby/locker v1.0.1 // indirect
- github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
- github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
- github.com/opencontainers/image-spec v1.0.2 // indirect
+ github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
- github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/pjbgf/sha1cd v0.3.0 // indirect
+ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
- github.com/sirupsen/logrus v1.8.1 // indirect
+ github.com/sirupsen/logrus v1.9.3 // indirect
+ github.com/skeema/knownhosts v1.2.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
- github.com/xanzy/ssh-agent v0.3.0 // indirect
- github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
+ github.com/xanzy/ssh-agent v0.3.3 // indirect
+ github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
- golang.org/x/crypto v0.1.0 // indirect
- golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 // indirect
- golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect
- golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
- golang.org/x/sys v0.3.0 // indirect
- golang.org/x/term v0.3.0 // indirect
- golang.org/x/text v0.5.0 // indirect
- golang.org/x/time v0.3.0 // indirect
- google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
- google.golang.org/grpc v1.49.0 // indirect
- google.golang.org/protobuf v1.28.1 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
+ go.opentelemetry.io/otel v1.24.0 // indirect
+ go.opentelemetry.io/otel/metric v1.24.0 // indirect
+ go.opentelemetry.io/otel/trace v1.24.0 // indirect
+ golang.org/x/crypto v0.21.0 // indirect
+ golang.org/x/mod v0.16.0 // indirect
+ golang.org/x/net v0.22.0 // indirect
+ golang.org/x/oauth2 v0.16.0 // indirect
+ golang.org/x/sync v0.6.0 // indirect
+ golang.org/x/sys v0.18.0 // indirect
+ golang.org/x/term v0.18.0 // indirect
+ golang.org/x/text v0.14.0 // indirect
+ golang.org/x/time v0.5.0 // indirect
+ golang.org/x/tools v0.19.0 // indirect
+ google.golang.org/appengine v1.6.8 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 // indirect
+ google.golang.org/grpc v1.62.1 // indirect
+ google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
- k8s.io/component-base v0.26.1 // indirect
- k8s.io/klog/v2 v2.80.1 // indirect
+ k8s.io/component-base v0.26.10 // indirect
+ k8s.io/klog/v2 v2.90.1 // indirect
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
- oras.land/oras-go v1.1.0 // indirect
+ oras.land/oras-go v1.2.5 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
)
diff --git a/go.sum b/go.sum
index cbae8e07..4fd16dd8 100644
--- a/go.sum
+++ b/go.sum
@@ -1,4 +1,3 @@
-bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
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=
@@ -14,11 +13,6 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
-cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
-cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
-cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
-cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go/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=
@@ -27,7 +21,6 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/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=
@@ -37,358 +30,129 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
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=
+dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
+dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
-github.com/Azure/azure-sdk-for-go v56.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
-github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
-github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
-github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
-github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
-github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
-github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
-github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
-github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY=
-github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
-github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
-github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
-github.com/Azure/go-autorest/autorest/adal v0.9.15/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A=
-github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
-github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
-github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
-github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
-github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
-github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
-github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
+github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
+github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
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/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
-github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
-github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
-github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
-github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
-github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
-github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
-github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
-github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
-github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
-github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
-github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
-github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
-github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
-github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg=
-github.com/Microsoft/hcsshim v0.9.1 h1:VfDCj+QnY19ktX5TsH22JHcjaZ05RWQiwDbOyEg5ziM=
-github.com/Microsoft/hcsshim v0.9.1/go.mod h1:Y/0uV2jUab5kBI7SQgl62at0AVX7uaruzADAVmxm3eM=
-github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
-github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
+github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
+github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
+github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
+github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
+github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
-github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
-github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
-github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
-github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
+github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
+github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
-github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
-github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
-github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
-github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
-github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
-github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
-github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
-github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
-github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
-github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
-github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
-github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
-github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
-github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
-github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
-github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
-github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
-github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
-github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
-github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
-github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
-github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
-github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
-github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
-github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
-github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng=
-github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=
-github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
-github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
-github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
+github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
-github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
-github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
-github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
-github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
-github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
+github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
+github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
-github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
-github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
-github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
-github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
-github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
-github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E=
-github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
-github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
-github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI=
-github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
-github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
-github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
-github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
-github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
-github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
-github.com/containerd/cgroups v1.0.2 h1:mZBclaSgNDfPWtfhj2xJY28LZ9nYIgzB0pwSURPl6JM=
-github.com/containerd/cgroups v1.0.2/go.mod h1:qpbpJ1jmlqsR9f2IyaLPsdkCdnt0rbDVqIDlhuu5tRY=
-github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
-github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
-github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
-github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
-github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
-github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ=
-github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=
-github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
-github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
-github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
-github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
-github.com/containerd/containerd v1.5.9 h1:rs6Xg1gtIxaeyG+Smsb/0xaSDu1VgFhOCKBXxMxbsF4=
-github.com/containerd/containerd v1.5.9/go.mod h1:fvQqCfadDGga5HZyn3j4+dx56qj2I9YwBrlSdalvJYQ=
-github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
-github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
-github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
-github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
-github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
-github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
-github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
-github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
-github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
-github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
-github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
-github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
-github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
-github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU=
-github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
-github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
-github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
-github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
-github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
-github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
-github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=
-github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
-github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
-github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
-github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
-github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
-github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
-github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
-github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
-github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
-github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
-github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
-github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
-github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ=
-github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
-github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
-github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
-github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
-github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw=
-github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y=
-github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
-github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
-github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
-github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
-github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
-github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
-github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
-github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
-github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
-github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
-github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
-github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
-github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
-github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
-github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
-github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
-github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
-github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
+github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
+github.com/containerd/containerd v1.7.13 h1:wPYKIeGMN8vaggSKuV1X0wZulpMz4CrgEsZdaCyB6Is=
+github.com/containerd/containerd v1.7.13/go.mod h1:zT3up6yTRfEUa6+GsITYIJNgSVL9NQ4x4h1RPzk0Wu4=
+github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8=
+github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
+github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
-github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
-github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
-github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
-github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
-github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
-github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
+github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
+github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
-github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q=
-github.com/devfile/api/v2 v2.0.0-20220117162434-6e6e6a8bc14c/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q=
-github.com/devfile/api/v2 v2.2.0/go.mod h1:dN7xFrOVG+iPqn4UKGibXLd5oVsdE8XyK9OEb5JL3aI=
-github.com/devfile/api/v2 v2.2.1 h1:VSX297YqY4C4j4uhn7M0RdZeBaeWqyVi4NnagzEmxu0=
-github.com/devfile/api/v2 v2.2.1/go.mod h1:qp8jcw12y1JdCsxjK/7LJ7uWaJOxcY1s2LUk5PhbkbM=
-github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f/go.mod h1:uFZZdTuRqA68FVe/JoJHP92CgINyQkyWnM2Qyiim+50=
-github.com/devfile/library v1.2.1-0.20220308191614-f0f7e11b17de/go.mod h1:GSPfJaBg0+bBjBHbwBE5aerJLH6tWGQu2q2rHYd9czM=
-github.com/devfile/library/v2 v2.0.1/go.mod h1:paJ0PARAVy0br13VpBEQ4fO3rZVDxWtooQ29+23PNBk=
-github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e/go.mod h1:iRPBxs+ZjfLEduVXpCCIOzdD2588Zv9OCs/CcXMcCCY=
-github.com/devfile/registry-support/index/generator v0.0.0-20220527155645-8328a8a883be/go.mod h1:1fyDJL+fPHtcrYA6yjSVWeLmXmjCNth0d5Rq1rvtryc=
-github.com/devfile/registry-support/index/generator v0.0.0-20221018203505-df96d34d4273 h1:DXENQSRTEDsk9com38njPg5511DD12HPIgzyFUErnpM=
-github.com/devfile/registry-support/index/generator v0.0.0-20221018203505-df96d34d4273/go.mod h1:ZJnaSLjTKCvGJhWmYgQoQ1O3g78qBe4Va6ZugLmi4dE=
-github.com/devfile/registry-support/registry-library v0.0.0-20220627163229-4aa39fcb0c0a/go.mod h1:kmEjH5oO465vh36kcYdZLYeG8edVD6N/ZgzyLs1x7qs=
-github.com/devfile/registry-support/registry-library v0.0.0-20221018213054-47b3ffaeadba h1:7Ag9guD3qOSzg3PcbSMqTVHDjqZojqb5JoIIonjRjDQ=
-github.com/devfile/registry-support/registry-library v0.0.0-20221018213054-47b3ffaeadba/go.mod h1:NOtmnbozFn15w/DPD/Urc+KDlNRP4JH5m+KC5GZoAWA=
-github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
-github.com/distribution/distribution/v3 v3.0.0-20211118083504-a29a3c99a684 h1:DBZ2sN7CK6dgvHVpQsQj4sRMCbWTmd17l+5SUCjnQSY=
-github.com/distribution/distribution/v3 v3.0.0-20211118083504-a29a3c99a684/go.mod h1:UfCu3YXJJCI+IdnqGgYP82dk2+Joxmv+mUTVBES6wac=
-github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
-github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
-github.com/docker/cli v20.10.11+incompatible h1:tXU1ezXcruZQRrMP8RN2z9N91h+6egZTS1gsPsKantc=
-github.com/docker/cli v20.10.11+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
-github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
-github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
-github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v20.10.11+incompatible h1:OqzI/g/W54LczvhnccGqniFoQghHx3pklbLuhfXpqGo=
-github.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
-github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
-github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
-github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
-github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
-github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/devfile/api/v2 v2.2.2 h1:DXRCPWFlZhTIE38Of2jzTRjQHadfbxBC8GS+m+EjoCU=
+github.com/devfile/api/v2 v2.2.2/go.mod h1:qp8jcw12y1JdCsxjK/7LJ7uWaJOxcY1s2LUk5PhbkbM=
+github.com/devfile/registry-support/index/generator v0.0.0-20240311135803-6215550f93d4 h1:t09mGdy31tC2YBp6kVD7x8m0jq1CyBUSYMUvrF0iaWw=
+github.com/devfile/registry-support/index/generator v0.0.0-20240311135803-6215550f93d4/go.mod h1:3Ngbmm12LW03tAEHpDNymM7zryd5H1Xo3ZAGlBpecf8=
+github.com/devfile/registry-support/registry-library v0.0.0-20240328155806-7c89891a72ce h1:IgUCI7eCq6m0JzRx3+FZuIeJy5e+rUSQYMr3NBzrqyg=
+github.com/devfile/registry-support/registry-library v0.0.0-20240328155806-7c89891a72ce/go.mod h1:2RRLQaOYuzh8n59euz6Bu60hFoX/LLVM9uzFOFDyOZM=
+github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc=
+github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
+github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
+github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
+github.com/docker/cli v25.0.1+incompatible h1:mFpqnrS6Hsm3v1k7Wa/BO23oz0k121MTbTO1lpcGSkU=
+github.com/docker/cli v25.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
+github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker v25.0.1+incompatible h1:k5TYd5rIVQRSqcTwCID+cyVA0yRg86+Pcrz1ls0/frA=
+github.com/docker/docker v25.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
+github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
+github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
+github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
-github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
-github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
-github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
-github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=
-github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
-github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
+github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
-github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
-github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
-github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
+github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=
+github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
+github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
-github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
-github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
-github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
-github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
-github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
-github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
+github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
+github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
-github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
-github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
-github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
-github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
-github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
-github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
-github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
-github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
-github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
-github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8=
-github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
-github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
-github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
+github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
+github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
+github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
+github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
+github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
@@ -399,11 +163,12 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
-github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
-github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
+github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
@@ -417,36 +182,19 @@ github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZ
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
-github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
-github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
-github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
-github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
-github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
-github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
-github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
-github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
-github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -459,7 +207,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
-github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0 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=
@@ -477,11 +224,10 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
-github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
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/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
@@ -495,21 +241,16 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/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=
@@ -517,89 +258,34 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
-github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
-github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
-github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
-github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
-github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
-github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
-github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
-github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
-github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
-github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
-github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
-github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
-github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
-github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
-github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
-github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
-github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
+github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
-github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
-github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
-github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
-github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4=
github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
-github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
-github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
-github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
-github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
-github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
+github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
-github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
-github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
-github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
-github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
-github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
-github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
@@ -611,28 +297,21 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
-github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
-github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
-github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
+github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
-github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
+github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -640,65 +319,27 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
-github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb h1:w1g9wNDIE/pHSTmAaUhv4TZQuPBS6GV3mMz5hkgziIU=
github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4=
-github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
-github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
-github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
-github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
-github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
+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.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
+github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
-github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM=
-github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
-github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
-github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
-github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
-github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
-github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
-github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
-github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
-github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
-github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
-github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
+github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
+github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
-github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
-github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
-github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
-github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI=
-github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
-github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
-github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
-github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
-github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI=
-github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
+github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -706,94 +347,41 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
-github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
-github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
-github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
-github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8=
-github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
-github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
-github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
-github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
-github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
-github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
-github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc=
-github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
-github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
-github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
-github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
-github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
-github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
-github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
-github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
-github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
-github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
-github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
-github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
-github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
-github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
-github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
-github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
+github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
+github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/openshift/api v0.0.0-20200930075302-db52bc4ef99f h1:/msM59v15x4DaAZeJnQwkVsCGTEa1mx+nSSMehZVAHs=
github.com/openshift/api v0.0.0-20200930075302-db52bc4ef99f/go.mod h1:Si/I9UGeRR3qzg01YWPmtlr0GeGk2fnuggXJRmjAZ6U=
github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
-github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
-github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
-github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
-github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
-github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
+github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
+github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
+github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
-github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
-github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
@@ -801,16 +389,12 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
-github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
-github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
@@ -818,184 +402,92 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
-github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
-github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
-github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
-github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
-github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
-github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
-github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
-github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
-github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
-github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
-github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
-github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
-github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
-github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
-github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
-github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
-github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
-github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
-github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
-github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
-github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
-github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI=
-github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
-github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
+github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
+github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
+github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
+github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
-github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
-github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
-github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
-github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
-github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
-github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
-github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
-github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
-github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
-github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
-github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
-github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
-github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
-github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
-github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
-github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
-github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
-github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
+github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
+github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
-github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
-github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
-github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
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.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
-github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
-github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY=
-github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
-go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
-go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
-go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
-go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
-go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
-go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
-go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
-go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
-go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
-go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
-go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
-go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
-go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
-go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
-go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
-go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
-go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
-go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
+go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
+go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
+go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
+go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
+go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
+go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
+go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
+go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
-golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
-golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
-golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
+golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
+golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
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=
@@ -1018,8 +510,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -1028,34 +518,27 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
+golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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=
@@ -1066,47 +549,32 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
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-20200520004742-59133d7f0dd7/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-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
-golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 h1:Frnccbp+ok2GkUS2tC84yAq/U9Vg+0sIO7aRL3T4Xnc=
-golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
+golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
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-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
+golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
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=
@@ -1118,54 +586,35 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200217220822-9197077df867/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=
@@ -1177,74 +626,52 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/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-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
+golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
-golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
+golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.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-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
-golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
+golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1253,21 +680,16 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
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-20190328211700-ab21143f2384/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-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/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-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -1287,7 +709,6 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs
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-20200505023115-26f46d2f7ef8/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-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -1296,24 +717,17 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
-golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
-golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
+golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
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=
gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY=
-gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
-google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
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=
@@ -1330,27 +744,19 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
-google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
-google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
-google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
-google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
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/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
+google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
+google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
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-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
@@ -1359,7 +765,6 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx
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-20200117163144-32f20d992d24/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=
@@ -1370,38 +775,19 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I=
-google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
-google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 h1:IR+hp6ypxjH24bkMfEJ0yHR21+gwPWdV+/IBrPQyn3k=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs=
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.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
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.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
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=
@@ -1410,19 +796,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
-google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
-google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
-google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw=
-google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
+google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
+google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
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=
@@ -1435,39 +810,23 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-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/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
-gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
-gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
-gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -1476,14 +835,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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=
-gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
-gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
-gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
-gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
-gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
+gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
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=
@@ -1492,86 +846,43 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
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=
k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw=
-k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
-k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
-k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
-k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg=
-k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ=
-k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg=
-k8s.io/apiextensions-apiserver v0.21.3/go.mod h1:kl6dap3Gd45+21Jnh6utCx8Z2xxLm8LGDkprcd+KbsE=
-k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI=
-k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM=
+k8s.io/api v0.26.10 h1:skTnrDR0r8dg4MMLf6YZIzugxNM0BjFsWKPkNc5kOvk=
+k8s.io/api v0.26.10/go.mod h1:ou/H3yviqrHtP/DSPVTfsc7qNfmU06OhajytJfYXkXw=
+k8s.io/apiextensions-apiserver v0.26.10 h1:wAriTUc6l7gUqJKOxhmXnYo/VNJzk4oh4QLCUR4Uq+k=
+k8s.io/apiextensions-apiserver v0.26.10/go.mod h1:N2qhlxkhJLSoC4f0M1/1lNG627b45SYqnOPEVFoQXw4=
k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
-k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
-k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
-k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
-k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI=
-k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ=
-k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
-k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
-k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
-k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
-k8s.io/apiserver v0.21.3/go.mod h1:eDPWlZG6/cCCMj/JBcEpDoK+I+6i3r9GsChYBHSbAzU=
-k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
-k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
-k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
-k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU=
-k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU=
-k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE=
+k8s.io/apimachinery v0.26.10 h1:aE+J2KIbjctFqPp3Y0q4Wh2PD+l1p2g3Zp4UYjSvtGU=
+k8s.io/apimachinery v0.26.10/go.mod h1:iT1ZP4JBP34wwM+ZQ8ByPEQ81u043iqAcsJYftX9amM=
+k8s.io/client-go v0.26.10 h1:4mDzl+1IrfRxh4Ro0s65JRGJp14w77gSMUTjACYWVRo=
+k8s.io/client-go v0.26.10/go.mod h1:sh74ig838gCckU4ElYclWb24lTesPdEDPnlyg5vcbkA=
k8s.io/code-generator v0.19.0/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk=
-k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0=
-k8s.io/code-generator v0.21.3/go.mod h1:K3y0Bv9Cz2cOW2vXUrNZlFbflhuPvuadW6JdnN6gGKo=
-k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
-k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
-k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
-k8s.io/component-base v0.21.3/go.mod h1:kkuhtfEHeZM6LkX0saqSK8PbdO7A0HigUngmhhrwfGQ=
-k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4=
-k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU=
-k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
-k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
-k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
-k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
+k8s.io/component-base v0.26.10 h1:vl3Gfe5aC09mNxfnQtTng7u3rnBVrShOK3MAkqEleb0=
+k8s.io/component-base v0.26.10/go.mod h1:/IDdENUHG5uGxqcofZajovYXE9KSPzJ4yQbkYQt7oN0=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
-k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
-k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
-k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
+k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
-k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
-k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
-k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
-k8s.io/pod-security-admission v0.26.1 h1:EDIxsYFeKMzNvN/JB0PgQcuwBP6fIkIG2O8ZWJhzOp4=
-k8s.io/pod-security-admission v0.26.1/go.mod h1:hCbYTG5UtLlivmukkMPjAWf23PUBUHzEvR60xNVWN4c=
-k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y=
-k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-oras.land/oras-go v1.1.0 h1:tfWM1RT7PzUwWphqHU6ptPU3ZhwVnSw/9nEGf519rYg=
-oras.land/oras-go v1.1.0/go.mod h1:1A7vR/0KknT2UkJVWh+xMi95I/AhK8ZrxrnUSmXN0bQ=
+k8s.io/pod-security-admission v0.26.10 h1:D2MF9JbMRu3pB7Onx26DHm6MHJRh3s6ZK0UKoRRD2to=
+k8s.io/pod-security-admission v0.26.10/go.mod h1:AurbRHBkqh8GSj+nDgsY0NLefkiGCmZJbzMJXQZpte8=
+k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk=
+k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo=
+oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA=
-sigs.k8s.io/controller-runtime v0.14.4 h1:Kd/Qgx5pd2XUL08eOV2vwIq3L9GhIbJ5Nxengbd4/0M=
-sigs.k8s.io/controller-runtime v0.14.4/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
+sigs.k8s.io/controller-runtime v0.14.7 h1:Vrnm2vk9ZFlRkXATHz0W0wXcqNl7kPat8q2JyxVy0Q8=
+sigs.k8s.io/controller-runtime v0.14.7/go.mod h1:ErTs3SJCOujNUnTz4AS+uh8hp6DHMo1gj6fFndJT1X8=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
diff --git a/main.go b/main.go
index f2b37482..65ff0965 100644
--- a/main.go
+++ b/main.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/generator/generators.go b/pkg/devfile/generator/generators.go
index 547433e5..3b1ffd4c 100644
--- a/pkg/devfile/generator/generators.go
+++ b/pkg/devfile/generator/generators.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/generator/generators_test.go b/pkg/devfile/generator/generators_test.go
index 9869672e..e5c13868 100644
--- a/pkg/devfile/generator/generators_test.go
+++ b/pkg/devfile/generator/generators_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/generator/policy.go b/pkg/devfile/generator/policy.go
index c0b83dd1..45412165 100644
--- a/pkg/devfile/generator/policy.go
+++ b/pkg/devfile/generator/policy.go
@@ -1,5 +1,5 @@
//
-// Copyright 2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/generator/utils.go b/pkg/devfile/generator/utils.go
index 8d8bce28..c29cfb70 100644
--- a/pkg/devfile/generator/utils.go
+++ b/pkg/devfile/generator/utils.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/generator/utils_test.go b/pkg/devfile/generator/utils_test.go
index 3a893f93..3499e660 100644
--- a/pkg/devfile/generator/utils_test.go
+++ b/pkg/devfile/generator/utils_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/imageNameSelector.go b/pkg/devfile/imageNameSelector.go
index 5dce1554..72d7e344 100644
--- a/pkg/devfile/imageNameSelector.go
+++ b/pkg/devfile/imageNameSelector.go
@@ -1,5 +1,5 @@
//
-// Copyright 2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/imageNameSelector_test.go b/pkg/devfile/imageNameSelector_test.go
index ca4dfec8..f9227d49 100644
--- a/pkg/devfile/imageNameSelector_test.go
+++ b/pkg/devfile/imageNameSelector_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parse.go b/pkg/devfile/parse.go
index ada87de2..95d9e879 100644
--- a/pkg/devfile/parse.go
+++ b/pkg/devfile/parse.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package devfile
import (
"github.com/devfile/api/v2/pkg/validation/variables"
"github.com/devfile/library/v2/pkg/devfile/parser"
+ errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
"github.com/devfile/library/v2/pkg/devfile/validate"
)
@@ -121,7 +122,7 @@ func ParseDevfileAndValidate(args parser.ParserArgs) (d parser.DevfileObj, varWa
// generic validation on devfile content
err = validate.ValidateDevfileData(d.Data)
if err != nil {
- return d, varWarning, err
+ return d, varWarning, &errPkg.NonCompliantDevfile{Err: err.Error()}
}
return d, varWarning, err
diff --git a/pkg/devfile/parse_test.go b/pkg/devfile/parse_test.go
index eaafe75b..3faf765e 100644
--- a/pkg/devfile/parse_test.go
+++ b/pkg/devfile/parse_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package devfile
import (
"context"
+ "fmt"
"net"
"net/http"
"net/http/httptest"
@@ -151,21 +152,26 @@ metadata:
tags:
- Go
version: 1.0.0
-schemaVersion: 2.2.0
+schemaVersion: 2.2.2
`
devfileContentWithVariable := devfileContent + `variables:
PARAMS: foo`
- devfileContentWithParent := `schemaVersion: 2.2.0
+ devfileContentWithParent := `schemaVersion: 2.2.2
parent:
id: devfile1
registryUrl: http://127.0.0.1:8080/registry
`
- devfileContentWithParentNoRegistry := `schemaVersion: 2.2.0
+ devfileContentWithUnsupportedSchema := `schemaVersion: 2.2.5
parent:
id: devfile1
+ registryUrl: http://127.0.0.1:8080/registry
`
- devfileContentWithCRDParent := `schemaVersion: 2.2.0
+ devfileContentWithParentNoRegistry := `schemaVersion: 2.2.2
+parent:
+ id: devfile1
+`
+ devfileContentWithCRDParent := `schemaVersion: 2.2.2
parent:
kubernetes:
name: devfile1
@@ -229,8 +235,7 @@ spec:
type: LoadBalancer
`
uri := "127.0.0.1:8080"
- var testServer *httptest.Server
- testServer = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ testServer := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var err error
if strings.Contains(r.URL.Path, "/outerloop-deploy.yaml") {
_, err = w.Write([]byte(outerloopDeployContent))
@@ -251,7 +256,7 @@ spec:
// create a listener with the desired port.
l, err := net.Listen("tcp", uri)
if err != nil {
- t.Errorf("Test_parseParentAndPluginFromURI() unexpected error while creating listener: %v", err)
+ t.Errorf("TestParseDevfileAndValidate() unexpected error while creating listener: %v", err)
}
// NewUnstartedServer creates a listener. Close that listener and replace
@@ -262,6 +267,8 @@ spec:
testServer.Start()
defer testServer.Close()
+ unsupportedSchemaError := `error parsing devfile because of non-compliant data due to unable to find schema for version "2.2.5". The parser supports devfile schema for version 2.0.0, 2.1.0, 2.2.0, 2.2.1, 2.2.2, v1alpha2`
+
type args struct {
args parser.ParserArgs
}
@@ -273,6 +280,8 @@ spec:
wantKubernetesInline string
wantOpenshiftInline string
wantVariables map[string]string
+ additionalChecks func(parser.DevfileObj) error
+ wantErrorStr *string
}{
{
name: "with external overriding variables",
@@ -291,11 +300,13 @@ spec:
"PARAMS": "bar",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
},
{
name: "with new external variables",
@@ -315,11 +326,13 @@ spec:
"OTHER": "other",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
}, {
name: "with new external variables",
args: args{
@@ -337,11 +350,13 @@ spec:
"PARAMS": "baz",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
}, {
name: "with external variables and covertUriToInline is false",
args: args{
@@ -358,11 +373,13 @@ spec:
"PARAMS": "baz",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
},
{
name: "with flattening set to false and setBooleanDefaults to true",
@@ -380,11 +397,13 @@ spec:
"PARAMS": "baz",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
},
{
name: "with setBooleanDefaults to false",
@@ -402,11 +421,13 @@ spec:
"PARAMS": "baz",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
},
{
name: "get content from path",
@@ -415,7 +436,7 @@ spec:
ExternalVariables: map[string]string{
"PARAMS": "baz",
},
- Path: "./testdata/devfile1.yaml",
+ Path: "./testdata/devfile.yaml",
},
},
wantCommandLine: "./main baz",
@@ -423,11 +444,13 @@ spec:
"PARAMS": "baz",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
},
{
name: "get content from url",
@@ -444,11 +467,13 @@ spec:
"PARAMS": "baz",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
},
{
name: "with parent and registry url in devfile",
@@ -465,11 +490,13 @@ spec:
"PARAMS": "baz",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
},
{
name: "with parent and no registry url in devfile",
@@ -489,11 +516,13 @@ spec:
"PARAMS": "baz",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
},
{
name: "getting from cluster and setting default namespace",
@@ -521,18 +550,286 @@ spec:
"PARAMS": "baz",
},
wantVarWarning: variables.VariableWarning{
- Commands: map[string][]string{},
- Components: map[string][]string{},
- Projects: map[string][]string{},
- StarterProjects: map[string][]string{},
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
},
+ wantErrorStr: nil,
+ },
+ {
+ name: "parsing devfile with context path containing multiple devfiles => priority to devfile.yaml",
+ args: args{
+ args: parser.ParserArgs{
+ ExternalVariables: map[string]string{
+ "PARAMS": "from devfile.yaml based on priority",
+ },
+ Path: "./testdata",
+ },
+ },
+ wantCommandLine: "./main from devfile.yaml based on priority",
+ wantVariables: map[string]string{
+ "PARAMS": "from devfile.yaml based on priority",
+ },
+ wantVarWarning: variables.VariableWarning{
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
+ },
+ additionalChecks: func(devfileObj parser.DevfileObj) error {
+ if devfileObj.Data.GetMetadata().DisplayName != "Go Runtime (devfile.yaml)" {
+ return fmt.Errorf("expected 'Go Runtime (devfile.yaml)' as metadata.displayName in devfile, but got %q",
+ devfileObj.Data.GetMetadata().DisplayName)
+ }
+ return nil
+ },
+ wantErrorStr: nil,
+ },
+ {
+ name: "parsing devfile with context path containing multiple devfiles => priority to .devfile.yaml",
+ args: args{
+ args: parser.ParserArgs{
+ ExternalVariables: map[string]string{
+ "PARAMS": "from .devfile.yaml based on priority",
+ },
+ Path: "./testdata/priority-for-dot_devfile_yaml",
+ },
+ },
+ wantCommandLine: "./main from .devfile.yaml based on priority",
+ wantVariables: map[string]string{
+ "PARAMS": "from .devfile.yaml based on priority",
+ },
+ wantVarWarning: variables.VariableWarning{
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
+ },
+ additionalChecks: func(devfileObj parser.DevfileObj) error {
+ if devfileObj.Data.GetMetadata().DisplayName != "Go Runtime (.devfile.yaml)" {
+ return fmt.Errorf("expected 'Go Runtime (.devfile.yaml)' as metadata.displayName in devfile, but got %q",
+ devfileObj.Data.GetMetadata().DisplayName)
+ }
+ return nil
+ },
+ wantErrorStr: nil,
+ },
+ {
+ name: "parsing devfile with context path containing multiple devfiles => priority to devfile.yml",
+ args: args{
+ args: parser.ParserArgs{
+ ExternalVariables: map[string]string{
+ "PARAMS": "from devfile.yml based on priority",
+ },
+ Path: "./testdata/priority-for-devfile_yml",
+ },
+ },
+ wantCommandLine: "./main from devfile.yml based on priority",
+ wantVariables: map[string]string{
+ "PARAMS": "from devfile.yml based on priority",
+ },
+ wantVarWarning: variables.VariableWarning{
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
+ },
+ additionalChecks: func(devfileObj parser.DevfileObj) error {
+ if devfileObj.Data.GetMetadata().DisplayName != "Test stack (devfile.yml)" {
+ return fmt.Errorf("expected 'Test stack (devfile.yml)' as metadata.displayName in devfile, but got %q",
+ devfileObj.Data.GetMetadata().DisplayName)
+ }
+ return nil
+ },
+ wantErrorStr: nil,
+ },
+ {
+ name: "parsing devfile with context path containing multiple devfiles => priority to .devfile.yml",
+ args: args{
+ args: parser.ParserArgs{
+ ExternalVariables: map[string]string{
+ "PARAMS": "from .devfile.yml based on priority",
+ },
+ Path: "./testdata/priority-for-dot_devfile_yml",
+ },
+ },
+ wantCommandLine: "./main from .devfile.yml based on priority",
+ wantVariables: map[string]string{
+ "PARAMS": "from .devfile.yml based on priority",
+ },
+ wantVarWarning: variables.VariableWarning{
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
+ },
+ additionalChecks: func(devfileObj parser.DevfileObj) error {
+ if devfileObj.Data.GetMetadata().DisplayName != "Test stack (.devfile.yml)" {
+ return fmt.Errorf("expected 'Test stack (.devfile.yml)' as metadata.displayName in devfile, but got %q",
+ devfileObj.Data.GetMetadata().DisplayName)
+ }
+ return nil
+ },
+ wantErrorStr: nil,
+ },
+ {
+ name: "parsing devfile with .yml extension",
+ args: args{
+ args: parser.ParserArgs{
+ ExternalVariables: map[string]string{
+ "PARAMS": "from devfile.yml",
+ },
+ Path: "./testdata/devfile.yml",
+ },
+ },
+ wantCommandLine: "./main from devfile.yml",
+ wantVariables: map[string]string{
+ "PARAMS": "from devfile.yml",
+ },
+ wantVarWarning: variables.VariableWarning{
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
+ },
+ additionalChecks: func(devfileObj parser.DevfileObj) error {
+ if devfileObj.Data.GetMetadata().DisplayName != "Test stack (devfile.yml)" {
+ return fmt.Errorf("expected 'Test stack (devfile.yml)' as metadata.displayName in devfile, but got %q",
+ devfileObj.Data.GetMetadata().DisplayName)
+ }
+ return nil
+ },
+ wantErrorStr: nil,
+ },
+ {
+ name: "parsing .devfile with .yml extension",
+ args: args{
+ args: parser.ParserArgs{
+ ExternalVariables: map[string]string{
+ "PARAMS": "from .devfile.yml",
+ },
+ Path: "./testdata/.devfile.yml",
+ },
+ },
+ wantCommandLine: "./main from .devfile.yml",
+ wantVariables: map[string]string{
+ "PARAMS": "from .devfile.yml",
+ },
+ wantVarWarning: variables.VariableWarning{
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
+ },
+ additionalChecks: func(devfileObj parser.DevfileObj) error {
+ if devfileObj.Data.GetMetadata().DisplayName != "Test stack (.devfile.yml)" {
+ return fmt.Errorf("expected 'Test stack (.devfile.yml)' as metadata.displayName in devfile, but got %q",
+ devfileObj.Data.GetMetadata().DisplayName)
+ }
+ return nil
+ },
+ wantErrorStr: nil,
+ },
+ {
+ name: "parsing .devfile with .yaml extension",
+ args: args{
+ args: parser.ParserArgs{
+ ExternalVariables: map[string]string{
+ "PARAMS": "from .devfile.yaml",
+ },
+ Path: "./testdata/.devfile.yaml",
+ },
+ },
+ wantCommandLine: "./main from .devfile.yaml",
+ wantVariables: map[string]string{
+ "PARAMS": "from .devfile.yaml",
+ },
+ wantVarWarning: variables.VariableWarning{
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
+ },
+ additionalChecks: func(devfileObj parser.DevfileObj) error {
+ if devfileObj.Data.GetMetadata().DisplayName != "Go Runtime (.devfile.yaml)" {
+ return fmt.Errorf("expected 'Go Runtime (.devfile.yaml)' as metadata.displayName in devfile, but got %q",
+ devfileObj.Data.GetMetadata().DisplayName)
+ }
+ return nil
+ },
+ wantErrorStr: nil,
+ },
+ {
+ name: "parsing any valid devfile regardless of extension",
+ args: args{
+ args: parser.ParserArgs{
+ ExternalVariables: map[string]string{
+ "PARAMS": "from any valid devfile file",
+ },
+ Path: "./testdata/valid-devfile.yaml.txt",
+ },
+ },
+ wantCommandLine: "./main from any valid devfile file",
+ wantVariables: map[string]string{
+ "PARAMS": "from any valid devfile file",
+ },
+ wantVarWarning: variables.VariableWarning{
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
+ },
+ additionalChecks: func(devfileObj parser.DevfileObj) error {
+ if devfileObj.Data.GetMetadata().DisplayName != "Test stack (valid-devfile.yaml.txt)" {
+ return fmt.Errorf("expected 'Test stack (valid-devfile.yaml.txt)' as metadata.displayName in devfile, but got %q",
+ devfileObj.Data.GetMetadata().DisplayName)
+ }
+ return nil
+ },
+ wantErrorStr: nil,
+ },
+ {
+ name: "with unsupported schema version",
+ args: args{
+ args: parser.ParserArgs{
+ ExternalVariables: map[string]string{
+ "PARAMS": "baz",
+ },
+ Data: []byte(devfileContentWithUnsupportedSchema),
+ },
+ },
+ wantCommandLine: "./main baz",
+ wantVariables: map[string]string{
+ "PARAMS": "baz",
+ },
+ wantVarWarning: variables.VariableWarning{
+ Commands: map[string][]string{},
+ Components: map[string][]string{},
+ Projects: map[string][]string{},
+ StarterProjects: map[string][]string{},
+ DependentProjects: map[string][]string{},
+ },
+ wantErrorStr: &unsupportedSchemaError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotD, gotVarWarning, err := ParseDevfileAndValidate(tt.args.args)
- if err != nil {
- t.Errorf("ParseDevfileAndValidate() error = %v, wantErr nil", err)
+ if err != nil && err.Error() == *tt.wantErrorStr {
+ t.Log("Correctly identified unsupported schema version")
+ return
+ } else if err != nil {
+ t.Errorf("ParseDevfileAndValidate() error = %v, wantErrStr = %v", err, tt.wantErrorStr)
return
}
commands, err := gotD.Data.GetCommands(common.DevfileOptions{})
@@ -647,6 +944,13 @@ spec:
if !reflect.DeepEqual(variables, tt.wantVariables) {
t.Errorf("variables are %+v, expected %+v", variables, tt.wantVariables)
}
+
+ if tt.additionalChecks != nil {
+ err = tt.additionalChecks(gotD)
+ if err != nil {
+ t.Errorf("unexpected error while performing specific checks: %v", err)
+ }
+ }
})
}
}
diff --git a/pkg/devfile/parser/configurables.go b/pkg/devfile/parser/configurables.go
index 5d53c482..6d281b52 100644
--- a/pkg/devfile/parser/configurables.go
+++ b/pkg/devfile/parser/configurables.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/context/apiVersion.go b/pkg/devfile/parser/context/apiVersion.go
index 5cea0ce4..412ae315 100644
--- a/pkg/devfile/parser/context/apiVersion.go
+++ b/pkg/devfile/parser/context/apiVersion.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import (
"strings"
"github.com/devfile/library/v2/pkg/devfile/parser/data"
- "github.com/pkg/errors"
+ errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
"k8s.io/klog"
)
@@ -32,7 +32,7 @@ func (d *DevfileCtx) SetDevfileAPIVersion() error {
var r map[string]interface{}
err := json.Unmarshal(d.rawContent, &r)
if err != nil {
- return errors.Wrapf(err, "failed to decode devfile json")
+ return &errPkg.NonCompliantDevfile{Err: err.Error()}
}
// Get "schemaVersion" value from map for devfile V2
@@ -47,10 +47,10 @@ func (d *DevfileCtx) SetDevfileAPIVersion() error {
if okSchema {
// SchemaVersion cannot be empty
if schemaVersion.(string) == "" {
- return fmt.Errorf("schemaVersion in devfile: %s cannot be empty", devfilePath)
+ return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion in devfile: %s cannot be empty", devfilePath)}
}
} else {
- return fmt.Errorf("schemaVersion not present in devfile: %s", devfilePath)
+ return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion not present in devfile: %s", devfilePath)}
}
// Successful
diff --git a/pkg/devfile/parser/context/apiVersion_test.go b/pkg/devfile/parser/context/apiVersion_test.go
index 282f1fcc..a12aa9d8 100644
--- a/pkg/devfile/parser/context/apiVersion_test.go
+++ b/pkg/devfile/parser/context/apiVersion_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@ import (
"fmt"
"reflect"
"testing"
+
+ errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
)
func TestSetDevfileAPIVersion(t *testing.T) {
@@ -29,6 +31,7 @@ func TestSetDevfileAPIVersion(t *testing.T) {
concreteSchema = `{"schemaVersion": "2.2.0-latest"}`
emptyJson = "{}"
emptySchemaVersionJson = `{"schemaVersion": ""}`
+ badJson = `{"name": "Joe", "age": null]`
devfilePath = "/testpath/devfile.yaml"
devfileURL = "http://server/devfile.yaml"
)
@@ -56,13 +59,19 @@ func TestSetDevfileAPIVersion(t *testing.T) {
name: "schemaVersion not present",
devfileCtx: DevfileCtx{rawContent: []byte(emptyJson), absPath: devfilePath},
want: "",
- wantErr: fmt.Errorf("schemaVersion not present in devfile: %s", devfilePath),
+ wantErr: &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion not present in devfile: %s", devfilePath)},
},
{
name: "schemaVersion empty",
devfileCtx: DevfileCtx{rawContent: []byte(emptySchemaVersionJson), url: devfileURL},
want: "",
- wantErr: fmt.Errorf("schemaVersion in devfile: %s cannot be empty", devfileURL),
+ wantErr: &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion in devfile: %s cannot be empty", devfileURL)},
+ },
+ {
+ name: "unmarshal error",
+ devfileCtx: DevfileCtx{rawContent: []byte(badJson), url: devfileURL},
+ want: "",
+ wantErr: &errPkg.NonCompliantDevfile{Err: "invalid character ']' after object key:value pair"},
},
}
diff --git a/pkg/devfile/parser/context/content.go b/pkg/devfile/parser/context/content.go
index 52b3a45c..60abb660 100644
--- a/pkg/devfile/parser/context/content.go
+++ b/pkg/devfile/parser/context/content.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@ import (
"bytes"
"unicode"
+ errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
+ parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
"github.com/devfile/library/v2/pkg/util"
"github.com/pkg/errors"
"k8s.io/klog"
@@ -41,7 +43,7 @@ func YAMLToJSON(data []byte) ([]byte, error) {
// Is YAML, convert to JSON
data, err := yaml.YAMLToJSON(data)
if err != nil {
- return data, errors.Wrapf(err, "failed to convert devfile yaml to json")
+ return data, &errPkg.NonCompliantDevfile{Err: err.Error()}
}
// Successful
@@ -62,7 +64,7 @@ func hasPrefix(buf []byte, prefix []byte) bool {
}
// SetDevfileContent reads devfile and if devfile is in YAML format converts it to JSON
-func (d *DevfileCtx) SetDevfileContent() error {
+func (d *DevfileCtx) SetDevfileContent(devfileUtilsClient parserUtil.DevfileUtils) error {
var err error
var data []byte
@@ -72,7 +74,7 @@ func (d *DevfileCtx) SetDevfileContent() error {
if d.token != "" {
params.Token = d.token
}
- data, err = util.DownloadInMemory(params)
+ data, err = devfileUtilsClient.DownloadInMemory(params)
if err != nil {
return errors.Wrap(err, "error getting devfile info from url")
}
diff --git a/pkg/devfile/parser/context/content_test.go b/pkg/devfile/parser/context/content_test.go
index d0b4509f..abc67362 100644
--- a/pkg/devfile/parser/context/content_test.go
+++ b/pkg/devfile/parser/context/content_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import (
"os"
"testing"
+ parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
"github.com/devfile/library/v2/pkg/testingutil/filesystem"
)
@@ -67,7 +68,7 @@ func TestSetDevfileContent(t *testing.T) {
)
defer os.Remove(tempDevfile.Name())
- err := d.SetDevfileContent()
+ err := d.SetDevfileContent(parserUtil.NewDevfileUtilsClient())
if err != nil {
t.Errorf("unexpected error '%v'", err)
@@ -90,7 +91,7 @@ func TestSetDevfileContent(t *testing.T) {
)
defer os.Remove(tempDevfile.Name())
- err := d.SetDevfileContent()
+ err := d.SetDevfileContent(parserUtil.NewDevfileUtilsClient())
if err == nil {
t.Errorf("expected error, didn't get one ")
@@ -111,7 +112,7 @@ func TestSetDevfileContent(t *testing.T) {
}
)
- err := d.SetDevfileContent()
+ err := d.SetDevfileContent(parserUtil.NewDevfileUtilsClient())
if err == nil {
t.Errorf("expected an error, didn't get one")
diff --git a/pkg/devfile/parser/context/context.go b/pkg/devfile/parser/context/context.go
index 97ab49d3..fe1ac634 100644
--- a/pkg/devfile/parser/context/context.go
+++ b/pkg/devfile/parser/context/context.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,12 +16,9 @@
package parser
import (
- "fmt"
"net/url"
- "os"
- "path/filepath"
- "strings"
+ parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
"github.com/devfile/library/v2/pkg/testingutil/filesystem"
"github.com/devfile/library/v2/pkg/util"
"k8s.io/klog"
@@ -36,7 +33,10 @@ type DevfileCtx struct {
// absolute path of devfile
absPath string
- // relative path of devfile
+ // relative path of devfile.
+ // It can also be a relative or absolute path to a folder containing one or more devfiles,
+ // in which case the library will try to pick an existing one, based on the following priority order:
+ // devfile.yaml > .devfile.yaml > devfile.yml > .devfile.yml
relPath string
// raw content of the devfile
@@ -95,37 +95,30 @@ func (d *DevfileCtx) populateDevfile() (err error) {
}
// Populate fills the DevfileCtx struct with relevant context info
-func (d *DevfileCtx) Populate() (err error) {
- if !strings.HasSuffix(d.relPath, ".yaml") {
- if _, err := os.Stat(filepath.Join(d.relPath, "devfile.yaml")); os.IsNotExist(err) {
- if _, err := os.Stat(filepath.Join(d.relPath, ".devfile.yaml")); os.IsNotExist(err) {
- return fmt.Errorf("the provided path is not a valid yaml filepath, and devfile.yaml or .devfile.yaml not found in the provided path : %s", d.relPath)
- } else {
- d.relPath = filepath.Join(d.relPath, ".devfile.yaml")
- }
- } else {
- d.relPath = filepath.Join(d.relPath, "devfile.yaml")
- }
+func (d *DevfileCtx) Populate(devfileUtilsClient parserUtil.DevfileUtils) (err error) {
+ d.relPath, err = lookupDevfileFromPath(d.fs, d.relPath)
+ if err != nil {
+ return err
}
- if err := d.SetAbsPath(); err != nil {
+ if err = d.SetAbsPath(); err != nil {
return err
}
klog.V(4).Infof("absolute devfile path: '%s'", d.absPath)
// Read and save devfile content
- if err := d.SetDevfileContent(); err != nil {
+ if err = d.SetDevfileContent(devfileUtilsClient); err != nil {
return err
}
return d.populateDevfile()
}
// PopulateFromURL fills the DevfileCtx struct with relevant context info
-func (d *DevfileCtx) PopulateFromURL() (err error) {
+func (d *DevfileCtx) PopulateFromURL(devfileUtilsClient parserUtil.DevfileUtils) (err error) {
_, err = url.ParseRequestURI(d.url)
if err != nil {
return err
}
// Read and save devfile content
- if err := d.SetDevfileContent(); err != nil {
+ if err := d.SetDevfileContent(devfileUtilsClient); err != nil {
return err
}
return d.populateDevfile()
diff --git a/pkg/devfile/parser/context/context_test.go b/pkg/devfile/parser/context/context_test.go
index 3f332e88..abe80385 100644
--- a/pkg/devfile/parser/context/context_test.go
+++ b/pkg/devfile/parser/context/context_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,13 +17,16 @@ package parser
import (
"github.com/stretchr/testify/assert"
+
+ parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
+
"net/http"
"net/http/httptest"
"testing"
)
func TestPopulateFromBytes(t *testing.T) {
- failedToConvertYamlErr := "failed to convert devfile yaml to json: yaml: mapping values are not allowed in this context"
+ failedToConvertYamlErr := "mapping values are not allowed in this context"
tests := []struct {
name string
@@ -54,7 +57,7 @@ func TestPopulateFromBytes(t *testing.T) {
}
)
defer testServer.Close()
- err := d.PopulateFromURL()
+ err := d.PopulateFromURL(parserUtil.NewDevfileUtilsClient())
if (tt.expectError != nil) != (err != nil) {
t.Errorf("TestPopulateFromBytes(): unexpected error: %v, wantErr: %v", err, tt.expectError)
} else if tt.expectError != nil {
@@ -73,7 +76,7 @@ func TestPopulateFromInvalidURL(t *testing.T) {
}
)
- err := d.PopulateFromURL()
+ err := d.PopulateFromURL(parserUtil.NewDevfileUtilsClient())
if err == nil {
t.Errorf("TestPopulateFromInvalidURL(): expected an error, didn't get one")
diff --git a/pkg/devfile/parser/context/fakecontext.go b/pkg/devfile/parser/context/fakecontext.go
index 8c286a47..fbc70489 100644
--- a/pkg/devfile/parser/context/fakecontext.go
+++ b/pkg/devfile/parser/context/fakecontext.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/context/fs.go b/pkg/devfile/parser/context/fs.go
index 56f1fde3..16cf41e1 100644
--- a/pkg/devfile/parser/context/fs.go
+++ b/pkg/devfile/parser/context/fs.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/context/location.go b/pkg/devfile/parser/context/location.go
new file mode 100644
index 00000000..5cbe3200
--- /dev/null
+++ b/pkg/devfile/parser/context/location.go
@@ -0,0 +1,64 @@
+//
+// Copyright Red Hat
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package parser
+
+import (
+ "errors"
+ "fmt"
+ "io/fs"
+ "path/filepath"
+ "strings"
+
+ "github.com/devfile/library/v2/pkg/testingutil/filesystem"
+)
+
+// possibleDevfileNames contains possible filenames for a devfile.
+// Those are checked in this priority order from a given context dir.
+var possibleDevfileNames = []string{
+ "devfile.yaml",
+ ".devfile.yaml",
+ "devfile.yml",
+ ".devfile.yml",
+}
+
+// lookupDevfileFromPath returns the file path to use as devfile filename, by looking at the relative path specified in relPath.
+// If relPath is not a directory, it is returned as is.
+// For backward compatibility, if relPath is a directory, it will try to detect the first existing devfile filename under relPath,
+// based on the list of possible devfile filenames defined in the sorted possibleDevfileNames.
+// It returns any error found while interacting with the filesystem, or if no file was found from the list of possible devfile names.
+func lookupDevfileFromPath(fsys filesystem.Filesystem, relPath string) (string, error) {
+ stat, err := fsys.Stat(relPath)
+ if err != nil {
+ return "", err
+ }
+
+ if !stat.IsDir() {
+ return relPath, nil
+ }
+
+ for _, possibleDevfileName := range possibleDevfileNames {
+ p := filepath.Join(relPath, possibleDevfileName)
+ if _, err = fsys.Stat(p); errors.Is(err, fs.ErrNotExist) {
+ continue
+ }
+ return p, nil
+ }
+
+ return "", fmt.Errorf(
+ "the provided path is not a valid yaml filepath, and no possible devfile could be found in the provided path : %s. Possible filenames for a devfile: %s",
+ relPath,
+ strings.Join(possibleDevfileNames, ", "))
+}
diff --git a/pkg/devfile/parser/context/location_test.go b/pkg/devfile/parser/context/location_test.go
new file mode 100644
index 00000000..1b2b2704
--- /dev/null
+++ b/pkg/devfile/parser/context/location_test.go
@@ -0,0 +1,218 @@
+//
+// Copyright Red Hat
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package parser
+
+import (
+ "path/filepath"
+ "testing"
+
+ "github.com/devfile/library/v2/pkg/testingutil/filesystem"
+ "github.com/google/go-cmp/cmp"
+)
+
+func Test_lookupDevfileFromPath(t *testing.T) {
+ type fields struct {
+ relPath string
+ fsCustomizer func(filesystem.Filesystem) error
+ }
+ tests := []struct {
+ name string
+ fields fields
+ want string
+ wantErr bool
+ }{
+ {
+ name: "invalid relative path",
+ fields: fields{
+ relPath: "non/existent/relative/path",
+ },
+ wantErr: true,
+ },
+ {
+ name: "invalid absolute path",
+ fields: fields{
+ relPath: "/non/existent/absolute/path",
+ },
+ wantErr: true,
+ },
+ {
+ name: "relative path to file",
+ fields: fields{
+ relPath: "my-devfile.yaml",
+ fsCustomizer: func(fs filesystem.Filesystem) error {
+ _, err := fs.Create("my-devfile.yaml")
+ return err
+ },
+ },
+ wantErr: false,
+ want: "my-devfile.yaml",
+ },
+ {
+ name: "absolute path to file",
+ fields: fields{
+ relPath: "/my-absolute-devfile.yaml",
+ fsCustomizer: func(fs filesystem.Filesystem) error {
+ _, err := fs.Create("/my-absolute-devfile.yaml")
+ return err
+ },
+ },
+ wantErr: false,
+ want: "/my-absolute-devfile.yaml",
+ },
+ {
+ name: "empty directory",
+ fields: fields{
+ relPath: "my-files",
+ fsCustomizer: func(fs filesystem.Filesystem) error {
+ return fs.MkdirAll("my-files", 0755)
+ },
+ },
+ wantErr: true,
+ },
+ {
+ name: "directory with no devfile filename detected",
+ fields: fields{
+ relPath: "my-files",
+ fsCustomizer: func(fs filesystem.Filesystem) error {
+ dir := "my-files"
+ err := fs.MkdirAll("my-files", 0755)
+ if err != nil {
+ return err
+ }
+ for _, f := range possibleDevfileNames {
+ if _, err = fs.Create(filepath.Join(dir, f+".bak")); err != nil {
+ return err
+ }
+ }
+ return err
+ },
+ },
+ wantErr: true,
+ },
+ {
+ name: "directory with all possible devfile filenames => priority to devfile.yaml",
+ fields: fields{
+ relPath: "my-devfiles",
+ fsCustomizer: func(fs filesystem.Filesystem) error {
+ dir := "my-devfiles"
+ err := fs.MkdirAll("my-devfiles", 0755)
+ if err != nil {
+ return err
+ }
+ for _, f := range possibleDevfileNames {
+ if _, err = fs.Create(filepath.Join(dir, f)); err != nil {
+ return err
+ }
+ }
+ return err
+ },
+ },
+ wantErr: false,
+ want: "my-devfiles/devfile.yaml",
+ },
+ {
+ name: "directory with missing devfile.yaml => priority to .devfile.yaml",
+ fields: fields{
+ relPath: "my-devfiles",
+ fsCustomizer: func(fs filesystem.Filesystem) error {
+ dir := "my-devfiles"
+ err := fs.MkdirAll("my-devfiles", 0755)
+ if err != nil {
+ return err
+ }
+ for _, f := range possibleDevfileNames {
+ if f == "devfile.yaml" {
+ continue
+ }
+ if _, err = fs.Create(filepath.Join(dir, f)); err != nil {
+ return err
+ }
+ }
+ return err
+ },
+ },
+ wantErr: false,
+ want: "my-devfiles/.devfile.yaml",
+ },
+ {
+ name: "directory with missing devfile.yaml and .devfile.yaml => priority to devfile.yml",
+ fields: fields{
+ relPath: "my-devfiles",
+ fsCustomizer: func(fs filesystem.Filesystem) error {
+ dir := "my-devfiles"
+ err := fs.MkdirAll("my-devfiles", 0755)
+ if err != nil {
+ return err
+ }
+ for _, f := range possibleDevfileNames {
+ if f == "devfile.yaml" || f == ".devfile.yaml" {
+ continue
+ }
+ if _, err = fs.Create(filepath.Join(dir, f)); err != nil {
+ return err
+ }
+ }
+ return err
+ },
+ },
+ wantErr: false,
+ want: "my-devfiles/devfile.yml",
+ },
+ {
+ name: "directory with missing devfile.yaml and .devfile.yaml and devfile.yml => priority to .devfile.yml",
+ fields: fields{
+ relPath: "my-devfiles",
+ fsCustomizer: func(fs filesystem.Filesystem) error {
+ dir := "my-devfiles"
+ err := fs.MkdirAll("my-devfiles", 0755)
+ if err != nil {
+ return err
+ }
+ for _, f := range possibleDevfileNames {
+ if f == "devfile.yaml" || f == ".devfile.yaml" || f == "devfile.yml" {
+ continue
+ }
+ if _, err = fs.Create(filepath.Join(dir, f)); err != nil {
+ return err
+ }
+ }
+ return err
+ },
+ },
+ wantErr: false,
+ want: "my-devfiles/.devfile.yml",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ fs := filesystem.NewFakeFs()
+ var err error
+ if tt.fields.fsCustomizer != nil {
+ err = tt.fields.fsCustomizer(fs)
+ }
+ if err != nil {
+ t.Fatalf("unexpected error while setting up filesystem: %v", err)
+ }
+ got, err := lookupDevfileFromPath(fs, tt.fields.relPath)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("lookupDevfileFromPath(): unexpected error: %v. wantErr=%v", err, tt.wantErr)
+ }
+ if diff := cmp.Diff(tt.want, got); diff != "" {
+ t.Errorf("lookupDevfileFromPath(): mismatch (-want +got): %s\n", diff)
+ }
+ })
+ }
+}
diff --git a/pkg/devfile/parser/context/schema.go b/pkg/devfile/parser/context/schema.go
index ca8f37cf..e1972383 100644
--- a/pkg/devfile/parser/context/schema.go
+++ b/pkg/devfile/parser/context/schema.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import (
"fmt"
"github.com/devfile/library/v2/pkg/devfile/parser/data"
+ errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
"github.com/pkg/errors"
"github.com/xeipuuv/gojsonschema"
"k8s.io/klog"
@@ -30,7 +31,7 @@ func (d *DevfileCtx) SetDevfileJSONSchema() error {
// Check if json schema is present for the given apiVersion
jsonSchema, err := data.GetDevfileJSONSchema(d.apiVersion)
if err != nil {
- return err
+ return &errPkg.NonCompliantDevfile{Err: err.Error()}
}
d.jsonSchema = jsonSchema
return nil
@@ -54,7 +55,7 @@ func (d *DevfileCtx) ValidateDevfileSchema() error {
for _, desc := range result.Errors() {
errMsg = errMsg + fmt.Sprintf("- %s\n", desc)
}
- return fmt.Errorf(errMsg)
+ return &errPkg.NonCompliantDevfile{Err: errMsg}
}
// Sucessful
diff --git a/pkg/devfile/parser/context/schema_test.go b/pkg/devfile/parser/context/schema_test.go
index 4d14eb2e..f7d29f0f 100644
--- a/pkg/devfile/parser/context/schema_test.go
+++ b/pkg/devfile/parser/context/schema_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,9 +16,10 @@
package parser
import (
- "github.com/stretchr/testify/assert"
"testing"
+ "github.com/stretchr/testify/assert"
+
v200 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.0.0"
)
diff --git a/pkg/devfile/parser/data/helper.go b/pkg/devfile/parser/data/helper.go
index 7ce98456..4e5f1cf2 100644
--- a/pkg/devfile/parser/data/helper.go
+++ b/pkg/devfile/parser/data/helper.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package data
import (
"fmt"
"reflect"
+ "sort"
"strings"
"k8s.io/klog"
@@ -51,6 +52,7 @@ func GetDevfileJSONSchema(version string) (string, error) {
for version := range devfileApiVersionToJSONSchema {
supportedVersions = append(supportedVersions, string(version))
}
+ sort.Strings(supportedVersions)
return "", fmt.Errorf("unable to find schema for version %q. The parser supports devfile schema for version %s", version, strings.Join(supportedVersions, ", "))
}
klog.V(4).Infof("devfile apiVersion '%s' is supported", version)
diff --git a/pkg/devfile/parser/data/helper_test.go b/pkg/devfile/parser/data/helper_test.go
index da3d0f7c..d29ae474 100644
--- a/pkg/devfile/parser/data/helper_test.go
+++ b/pkg/devfile/parser/data/helper_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/interface.go b/pkg/devfile/parser/data/interface.go
index a24a06ed..f22bd40e 100644
--- a/pkg/devfile/parser/data/interface.go
+++ b/pkg/devfile/parser/data/interface.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/2.0.0/devfileJsonSchema200.go b/pkg/devfile/parser/data/v2/2.0.0/devfileJsonSchema200.go
index 431d5fc0..79320e15 100644
--- a/pkg/devfile/parser/data/v2/2.0.0/devfileJsonSchema200.go
+++ b/pkg/devfile/parser/data/v2/2.0.0/devfileJsonSchema200.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/2.1.0/devfileJsonSchema210.go b/pkg/devfile/parser/data/v2/2.1.0/devfileJsonSchema210.go
index c92b7a75..3ae5ee14 100644
--- a/pkg/devfile/parser/data/v2/2.1.0/devfileJsonSchema210.go
+++ b/pkg/devfile/parser/data/v2/2.1.0/devfileJsonSchema210.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/2.2.0/devfileJsonSchema220.go b/pkg/devfile/parser/data/v2/2.2.0/devfileJsonSchema220.go
index 138f2d88..e62cf9d5 100644
--- a/pkg/devfile/parser/data/v2/2.2.0/devfileJsonSchema220.go
+++ b/pkg/devfile/parser/data/v2/2.2.0/devfileJsonSchema220.go
@@ -15,11 +15,11 @@
package version220
-// https://raw.githubusercontent.com/devfile/api/main/schemas/latest/devfile.json
+// https://raw.githubusercontent.com/devfile/api/v2.2.0/schemas/latest/devfile.json
const JsonSchema220 = `{
"description": "Devfile describes the structure of a cloud-native devworkspace and development environment.",
"type": "object",
- "title": "Devfile schema - Version 2.2.1-alpha",
+ "title": "Devfile schema - Version 2.2.0",
"required": [
"schemaVersion"
],
@@ -212,7 +212,7 @@ const JsonSchema220 = `{
"additionalProperties": false
},
"hotReloadCapable": {
- "description": "Specify whether the command is restarted or not when the source code changes. If set to 'true' the command won't be restarted. A *hotReloadCapable* 'run' or 'debug' command is expected to handle file changes on its own and won't be restarted. A *hotReloadCapable* 'build' command is expected to be executed only once and won't be executed again. This field is taken into account only for commands 'build', 'run' and 'debug' with 'isDefault' set to 'true'.\n\nDefault value is 'false'",
+ "description": "Whether the command is capable to reload itself when source code changes. If set to 'true' the command won't be restarted and it is expected to handle file changes on its own.\n\nDefault value is 'false'",
"type": "boolean"
},
"label": {
@@ -1104,7 +1104,7 @@ const JsonSchema220 = `{
"additionalProperties": false
},
"hotReloadCapable": {
- "description": "Specify whether the command is restarted or not when the source code changes. If set to 'true' the command won't be restarted. A *hotReloadCapable* 'run' or 'debug' command is expected to handle file changes on its own and won't be restarted. A *hotReloadCapable* 'build' command is expected to be executed only once and won't be executed again. This field is taken into account only for commands 'build', 'run' and 'debug' with 'isDefault' set to 'true'.\n\nDefault value is 'false'",
+ "description": "Whether the command is capable to reload itself when source code changes. If set to 'true' the command won't be restarted and it is expected to handle file changes on its own.\n\nDefault value is 'false'",
"type": "boolean"
},
"label": {
diff --git a/pkg/devfile/parser/data/v2/2.2.1/devfileJsonSchema221.go b/pkg/devfile/parser/data/v2/2.2.1/devfileJsonSchema221.go
new file mode 100644
index 00000000..efe26957
--- /dev/null
+++ b/pkg/devfile/parser/data/v2/2.2.1/devfileJsonSchema221.go
@@ -0,0 +1,2067 @@
+//
+// Copyright Red Hat
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package version221
+
+// https://raw.githubusercontent.com/devfile/api/v2.2.1/schemas/latest/devfile.json
+const JsonSchema221 = `{
+ "description": "Devfile describes the structure of a cloud-native devworkspace and development environment.",
+ "type": "object",
+ "title": "Devfile schema - Version 2.2.1",
+ "required": [
+ "schemaVersion"
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "commands": {
+ "description": "Predefined, ready-to-use, devworkspace-related commands",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "exec"
+ ]
+ },
+ {
+ "required": [
+ "apply"
+ ]
+ },
+ {
+ "required": [
+ "composite"
+ ]
+ }
+ ],
+ "properties": {
+ "apply": {
+ "description": "Command that consists in applying a given component definition, typically bound to a devworkspace event.\n\nFor example, when an 'apply' command is bound to a 'preStart' event, and references a 'container' component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its 'dedicatedPod' field set to 'true'.\n\nWhen no 'apply' command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless 'deployByDefault' for that component is set to false.",
+ "type": "object",
+ "required": [
+ "component"
+ ],
+ "properties": {
+ "component": {
+ "description": "Describes component that will be applied",
+ "type": "string"
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "required": [
+ "kind"
+ ],
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "composite": {
+ "description": "Composite command that allows executing several sub-commands either sequentially or concurrently",
+ "type": "object",
+ "properties": {
+ "commands": {
+ "description": "The commands that comprise this composite command",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "required": [
+ "kind"
+ ],
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ },
+ "parallel": {
+ "description": "Indicates if the sub-commands should be executed concurrently",
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false
+ },
+ "exec": {
+ "description": "CLI Command executed in an existing component container",
+ "type": "object",
+ "required": [
+ "commandLine",
+ "component"
+ ],
+ "properties": {
+ "commandLine": {
+ "description": "The actual command-line string\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.",
+ "type": "string"
+ },
+ "component": {
+ "description": "Describes component to which given action relates",
+ "type": "string"
+ },
+ "env": {
+ "description": "Optional list of environment variables that have to be set before running the command",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "required": [
+ "kind"
+ ],
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "hotReloadCapable": {
+ "description": "Specify whether the command is restarted or not when the source code changes. If set to 'true' the command won't be restarted. A *hotReloadCapable* 'run' or 'debug' command is expected to handle file changes on its own and won't be restarted. A *hotReloadCapable* 'build' command is expected to be executed only once and won't be executed again. This field is taken into account only for commands 'build', 'run' and 'debug' with 'isDefault' set to 'true'.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ },
+ "workingDir": {
+ "description": "Working directory where the command should be executed\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "id": {
+ "description": "Mandatory identifier that allows referencing this command in composite commands, from a parent, or in events.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "components": {
+ "description": "List of the devworkspace components, such as editor and plugins, user-provided containers, or other types of components",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "container"
+ ]
+ },
+ {
+ "required": [
+ "kubernetes"
+ ]
+ },
+ {
+ "required": [
+ "openshift"
+ ]
+ },
+ {
+ "required": [
+ "volume"
+ ]
+ },
+ {
+ "required": [
+ "image"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "container": {
+ "description": "Allows adding and configuring devworkspace-related containers",
+ "type": "object",
+ "required": [
+ "image"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations that should be added to specific resources for this container",
+ "type": "object",
+ "properties": {
+ "deployment": {
+ "description": "Annotations to be added to deployment",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "service": {
+ "description": "Annotations to be added to service",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "args": {
+ "description": "The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command.\n\nDefaults to an empty array, meaning use whatever is defined in the image.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "command": {
+ "description": "The command to run in the dockerimage component instead of the default one provided in the image.\n\nDefaults to an empty array, meaning use whatever is defined in the image.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "cpuLimit": {
+ "type": "string"
+ },
+ "cpuRequest": {
+ "type": "string"
+ },
+ "dedicatedPod": {
+ "description": "Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "targetPort"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "default": "public",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "default": "http",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "env": {
+ "description": "Environment variables used in this container.\n\nThe following variables are reserved and cannot be overridden via env:\n\n - '$PROJECTS_ROOT'\n\n - '$PROJECT_SOURCE'",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "image": {
+ "type": "string"
+ },
+ "memoryLimit": {
+ "type": "string"
+ },
+ "memoryRequest": {
+ "type": "string"
+ },
+ "mountSources": {
+ "description": "Toggles whether or not the project source code should be mounted in the component.\n\nDefaults to true for all component types except plugins and components that set 'dedicatedPod' to true.",
+ "type": "boolean"
+ },
+ "sourceMapping": {
+ "description": "Optional specification of the path in the container where project sources should be transferred/mounted when 'mountSources' is 'true'. When omitted, the default value of /projects is used.",
+ "type": "string",
+ "default": "/projects"
+ },
+ "volumeMounts": {
+ "description": "List of volumes mounts that should be mounted is this container.",
+ "type": "array",
+ "items": {
+ "description": "Volume that should be mounted to a component container",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "description": "The volume mount name is the name of an existing 'Volume' component. If several containers mount the same volume name then they will reuse the same volume and will be able to access to the same files.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "The path in the component container where the volume should be mounted. If not path is mentioned, default path is the is '/\u003cname\u003e'.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "image": {
+ "description": "Allows specifying the definition of an image for outer loop builds",
+ "type": "object",
+ "required": [
+ "imageName"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "dockerfile"
+ ]
+ }
+ ],
+ "properties": {
+ "autoBuild": {
+ "description": "Defines if the image should be built during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "dockerfile": {
+ "description": "Allows specifying dockerfile type build",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "devfileRegistry"
+ ]
+ },
+ {
+ "required": [
+ "git"
+ ]
+ }
+ ],
+ "properties": {
+ "args": {
+ "description": "The arguments to supply to the dockerfile build.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "buildContext": {
+ "description": "Path of source directory to establish build context. Defaults to ${PROJECT_SOURCE} in the container",
+ "type": "string"
+ },
+ "devfileRegistry": {
+ "description": "Dockerfile's Devfile Registry source",
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "description": "Id in a devfile registry that contains a Dockerfile. The src in the OCI registry required for the Dockerfile build will be downloaded for building the image.",
+ "type": "string"
+ },
+ "registryUrl": {
+ "description": "Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. To ensure the Dockerfile gets resolved consistently in different environments, it is recommended to always specify the 'devfileRegistryUrl' when 'Id' is used.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "git": {
+ "description": "Dockerfile's Git source",
+ "type": "object",
+ "required": [
+ "remotes"
+ ],
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "fileLocation": {
+ "description": "Location of the Dockerfile in the Git repository when using git as Dockerfile src. Defaults to Dockerfile.",
+ "type": "string"
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "rootRequired": {
+ "description": "Specify if a privileged builder pod is required.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "uri": {
+ "description": "URI Reference of a Dockerfile. It can be a full URL or a relative URI from the current devfile as the base URI.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "imageName": {
+ "description": "Name of the image for the resulting outerloop build",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "kubernetes": {
+ "description": "Allows importing into the devworkspace the Kubernetes resources defined in a given manifest. For example this allows reusing the Kubernetes definitions used to deploy some runtime components in production.",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "inlined"
+ ]
+ }
+ ],
+ "properties": {
+ "deployByDefault": {
+ "description": "Defines if the component should be deployed during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "targetPort"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "default": "public",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "default": "http",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "inlined": {
+ "description": "Inlined manifest",
+ "type": "string"
+ },
+ "uri": {
+ "description": "Location in a file fetched from a uri.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Mandatory name that allows referencing the component from other elements (such as commands) or from an external devfile that may reference this component through a parent or a plugin.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "openshift": {
+ "description": "Allows importing into the devworkspace the OpenShift resources defined in a given manifest. For example this allows reusing the OpenShift definitions used to deploy some runtime components in production.",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "inlined"
+ ]
+ }
+ ],
+ "properties": {
+ "deployByDefault": {
+ "description": "Defines if the component should be deployed during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "targetPort"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "default": "public",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "default": "http",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "inlined": {
+ "description": "Inlined manifest",
+ "type": "string"
+ },
+ "uri": {
+ "description": "Location in a file fetched from a uri.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "volume": {
+ "description": "Allows specifying the definition of a volume shared by several other components",
+ "type": "object",
+ "properties": {
+ "ephemeral": {
+ "description": "Ephemeral volumes are not stored persistently across restarts. Defaults to false",
+ "type": "boolean"
+ },
+ "size": {
+ "description": "Size of the volume",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "events": {
+ "description": "Bindings of commands to events. Each command is referred-to by its name.",
+ "type": "object",
+ "properties": {
+ "postStart": {
+ "description": "IDs of commands that should be executed after the devworkspace is completely started. In the case of Che-Theia, these commands should be executed after all plugins and extensions have started, including project cloning. This means that those commands are not triggered until the user opens the IDE in his browser.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "postStop": {
+ "description": "IDs of commands that should be executed after stopping the devworkspace.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "preStart": {
+ "description": "IDs of commands that should be executed before the devworkspace start. Kubernetes-wise, these commands would typically be executed in init containers of the devworkspace POD.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "preStop": {
+ "description": "IDs of commands that should be executed before stopping the devworkspace.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "metadata": {
+ "description": "Optional metadata",
+ "type": "object",
+ "properties": {
+ "architectures": {
+ "description": "Optional list of processor architectures that the devfile supports, empty list suggests that the devfile can be used on any architecture",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "description": "Architecture describes the architecture type",
+ "type": "string",
+ "enum": [
+ "amd64",
+ "arm64",
+ "ppc64le",
+ "s390x"
+ ]
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes. Deprecated, use the top-level attributes field instead.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "description": {
+ "description": "Optional devfile description",
+ "type": "string"
+ },
+ "displayName": {
+ "description": "Optional devfile display name",
+ "type": "string"
+ },
+ "globalMemoryLimit": {
+ "description": "Optional devfile global memory limit",
+ "type": "string"
+ },
+ "icon": {
+ "description": "Optional devfile icon, can be a URI or a relative path in the project",
+ "type": "string"
+ },
+ "language": {
+ "description": "Optional devfile language",
+ "type": "string"
+ },
+ "name": {
+ "description": "Optional devfile name",
+ "type": "string"
+ },
+ "projectType": {
+ "description": "Optional devfile project type",
+ "type": "string"
+ },
+ "provider": {
+ "description": "Optional devfile provider information",
+ "type": "string"
+ },
+ "supportUrl": {
+ "description": "Optional link to a page that provides support information",
+ "type": "string"
+ },
+ "tags": {
+ "description": "Optional devfile tags",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "version": {
+ "description": "Optional semver-compatible version",
+ "type": "string",
+ "pattern": "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\-[0-9a-z-]+(\\.[0-9a-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$"
+ },
+ "website": {
+ "description": "Optional devfile website",
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ },
+ "parent": {
+ "description": "Parent devworkspace template",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "id"
+ ]
+ },
+ {
+ "required": [
+ "kubernetes"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Overrides of attributes encapsulated in a parent devfile. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "commands": {
+ "description": "Overrides of commands encapsulated in a parent devfile or a plugin. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "exec"
+ ]
+ },
+ {
+ "required": [
+ "apply"
+ ]
+ },
+ {
+ "required": [
+ "composite"
+ ]
+ }
+ ],
+ "properties": {
+ "apply": {
+ "description": "Command that consists in applying a given component definition, typically bound to a devworkspace event.\n\nFor example, when an 'apply' command is bound to a 'preStart' event, and references a 'container' component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its 'dedicatedPod' field set to 'true'.\n\nWhen no 'apply' command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless 'deployByDefault' for that component is set to false.",
+ "type": "object",
+ "properties": {
+ "component": {
+ "description": "Describes component that will be applied",
+ "type": "string"
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "composite": {
+ "description": "Composite command that allows executing several sub-commands either sequentially or concurrently",
+ "type": "object",
+ "properties": {
+ "commands": {
+ "description": "The commands that comprise this composite command",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ },
+ "parallel": {
+ "description": "Indicates if the sub-commands should be executed concurrently",
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false
+ },
+ "exec": {
+ "description": "CLI Command executed in an existing component container",
+ "type": "object",
+ "properties": {
+ "commandLine": {
+ "description": "The actual command-line string\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.",
+ "type": "string"
+ },
+ "component": {
+ "description": "Describes component to which given action relates",
+ "type": "string"
+ },
+ "env": {
+ "description": "Optional list of environment variables that have to be set before running the command",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "hotReloadCapable": {
+ "description": "Specify whether the command is restarted or not when the source code changes. If set to 'true' the command won't be restarted. A *hotReloadCapable* 'run' or 'debug' command is expected to handle file changes on its own and won't be restarted. A *hotReloadCapable* 'build' command is expected to be executed only once and won't be executed again. This field is taken into account only for commands 'build', 'run' and 'debug' with 'isDefault' set to 'true'.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ },
+ "workingDir": {
+ "description": "Working directory where the command should be executed\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "id": {
+ "description": "Mandatory identifier that allows referencing this command in composite commands, from a parent, or in events.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "components": {
+ "description": "Overrides of components encapsulated in a parent devfile or a plugin. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "container"
+ ]
+ },
+ {
+ "required": [
+ "kubernetes"
+ ]
+ },
+ {
+ "required": [
+ "openshift"
+ ]
+ },
+ {
+ "required": [
+ "volume"
+ ]
+ },
+ {
+ "required": [
+ "image"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "container": {
+ "description": "Allows adding and configuring devworkspace-related containers",
+ "type": "object",
+ "properties": {
+ "annotation": {
+ "description": "Annotations that should be added to specific resources for this container",
+ "type": "object",
+ "properties": {
+ "deployment": {
+ "description": "Annotations to be added to deployment",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "service": {
+ "description": "Annotations to be added to service",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "args": {
+ "description": "The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command.\n\nDefaults to an empty array, meaning use whatever is defined in the image.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "command": {
+ "description": "The command to run in the dockerimage component instead of the default one provided in the image.\n\nDefaults to an empty array, meaning use whatever is defined in the image.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "cpuLimit": {
+ "type": "string"
+ },
+ "cpuRequest": {
+ "type": "string"
+ },
+ "dedicatedPod": {
+ "description": "Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "env": {
+ "description": "Environment variables used in this container.\n\nThe following variables are reserved and cannot be overridden via env:\n\n - '$PROJECTS_ROOT'\n\n - '$PROJECT_SOURCE'",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "image": {
+ "type": "string"
+ },
+ "memoryLimit": {
+ "type": "string"
+ },
+ "memoryRequest": {
+ "type": "string"
+ },
+ "mountSources": {
+ "description": "Toggles whether or not the project source code should be mounted in the component.\n\nDefaults to true for all component types except plugins and components that set 'dedicatedPod' to true.",
+ "type": "boolean"
+ },
+ "sourceMapping": {
+ "description": "Optional specification of the path in the container where project sources should be transferred/mounted when 'mountSources' is 'true'. When omitted, the default value of /projects is used.",
+ "type": "string"
+ },
+ "volumeMounts": {
+ "description": "List of volumes mounts that should be mounted is this container.",
+ "type": "array",
+ "items": {
+ "description": "Volume that should be mounted to a component container",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "description": "The volume mount name is the name of an existing 'Volume' component. If several containers mount the same volume name then they will reuse the same volume and will be able to access to the same files.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "The path in the component container where the volume should be mounted. If not path is mentioned, default path is the is '/\u003cname\u003e'.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "image": {
+ "description": "Allows specifying the definition of an image for outer loop builds",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "dockerfile"
+ ]
+ },
+ {
+ "required": [
+ "autoBuild"
+ ]
+ }
+ ],
+ "properties": {
+ "autoBuild": {
+ "description": "Defines if the image should be built during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "dockerfile": {
+ "description": "Allows specifying dockerfile type build",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "devfileRegistry"
+ ]
+ },
+ {
+ "required": [
+ "git"
+ ]
+ }
+ ],
+ "properties": {
+ "args": {
+ "description": "The arguments to supply to the dockerfile build.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "buildContext": {
+ "description": "Path of source directory to establish build context. Defaults to ${PROJECT_SOURCE} in the container",
+ "type": "string"
+ },
+ "devfileRegistry": {
+ "description": "Dockerfile's Devfile Registry source",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "Id in a devfile registry that contains a Dockerfile. The src in the OCI registry required for the Dockerfile build will be downloaded for building the image.",
+ "type": "string"
+ },
+ "registryUrl": {
+ "description": "Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. To ensure the Dockerfile gets resolved consistently in different environments, it is recommended to always specify the 'devfileRegistryUrl' when 'Id' is used.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "git": {
+ "description": "Dockerfile's Git source",
+ "type": "object",
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "fileLocation": {
+ "description": "Location of the Dockerfile in the Git repository when using git as Dockerfile src. Defaults to Dockerfile.",
+ "type": "string"
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "rootRequired": {
+ "description": "Specify if a privileged builder pod is required.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "uri": {
+ "description": "URI Reference of a Dockerfile. It can be a full URL or a relative URI from the current devfile as the base URI.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "imageName": {
+ "description": "Name of the image for the resulting outerloop build",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "kubernetes": {
+ "description": "Allows importing into the devworkspace the Kubernetes resources defined in a given manifest. For example this allows reusing the Kubernetes definitions used to deploy some runtime components in production.",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "inlined"
+ ]
+ }
+ ],
+ "properties": {
+ "deployByDefault": {
+ "description": "Defines if the component should be deployed during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "inlined": {
+ "description": "Inlined manifest",
+ "type": "string"
+ },
+ "uri": {
+ "description": "Location in a file fetched from a uri.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Mandatory name that allows referencing the component from other elements (such as commands) or from an external devfile that may reference this component through a parent or a plugin.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "openshift": {
+ "description": "Allows importing into the devworkspace the OpenShift resources defined in a given manifest. For example this allows reusing the OpenShift definitions used to deploy some runtime components in production.",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "inlined"
+ ]
+ }
+ ],
+ "properties": {
+ "deployByDefault": {
+ "description": "Defines if the component should be deployed during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "inlined": {
+ "description": "Inlined manifest",
+ "type": "string"
+ },
+ "uri": {
+ "description": "Location in a file fetched from a uri.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "volume": {
+ "description": "Allows specifying the definition of a volume shared by several other components",
+ "type": "object",
+ "properties": {
+ "ephemeral": {
+ "description": "Ephemeral volumes are not stored persistently across restarts. Defaults to false",
+ "type": "boolean"
+ },
+ "size": {
+ "description": "Size of the volume",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "id": {
+ "description": "Id in a registry that contains a Devfile yaml file",
+ "type": "string"
+ },
+ "kubernetes": {
+ "description": "Reference to a Kubernetes CRD of type DevWorkspaceTemplate",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "namespace": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "projects": {
+ "description": "Overrides of projects encapsulated in a parent devfile. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "clonePath": {
+ "description": "Path relative to the root of the projects to which this project should be cloned into. This is a unix-style relative path (i.e. uses forward slashes). The path is invalid if it is absolute or tries to escape the project root through the usage of '..'. If not specified, defaults to the project name.",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "registryUrl": {
+ "description": "Registry URL to pull the parent devfile from when using id in the parent reference. To ensure the parent devfile gets resolved consistently in different environments, it is recommended to always specify the 'registryUrl' when 'id' is used.",
+ "type": "string"
+ },
+ "starterProjects": {
+ "description": "Overrides of starterProjects encapsulated in a parent devfile. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "description": {
+ "description": "Description of a starter project",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "subDir": {
+ "description": "Sub-directory from a starter project to be used as root for starter project.",
+ "type": "string"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "uri": {
+ "description": "URI Reference of a parent devfile YAML file. It can be a full URL or a relative URI with the current devfile as the base URI.",
+ "type": "string"
+ },
+ "variables": {
+ "description": "Overrides of variables encapsulated in a parent devfile. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "version": {
+ "description": "Specific stack/sample version to pull the parent devfile from, when using id in the parent reference. To specify 'version', 'id' must be defined and used as the import reference source. 'version' can be either a specific stack version, or 'latest'. If no 'version' specified, default version will be used.",
+ "type": "string",
+ "pattern": "^(latest)|(([1-9])\\.([0-9]+)\\.([0-9]+)(\\-[0-9a-z-]+(\\.[0-9a-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?)$"
+ }
+ },
+ "additionalProperties": false
+ },
+ "projects": {
+ "description": "Projects worked on in the devworkspace, containing names and sources locations",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "clonePath": {
+ "description": "Path relative to the root of the projects to which this project should be cloned into. This is a unix-style relative path (i.e. uses forward slashes). The path is invalid if it is absolute or tries to escape the project root through the usage of '..'. If not specified, defaults to the project name.",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "required": [
+ "remotes"
+ ],
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "schemaVersion": {
+ "description": "Devfile schema version",
+ "type": "string",
+ "pattern": "^([2-9])\\.([0-9]+)\\.([0-9]+)(\\-[0-9a-z-]+(\\.[0-9a-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$"
+ },
+ "starterProjects": {
+ "description": "StarterProjects is a project that can be used as a starting point when bootstrapping new projects",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "description": {
+ "description": "Description of a starter project",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "required": [
+ "remotes"
+ ],
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "subDir": {
+ "description": "Sub-directory from a starter project to be used as root for starter project.",
+ "type": "string"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "variables": {
+ "description": "Map of key-value variables used for string replacement in the devfile. Values can be referenced via {{variable-key}} to replace the corresponding value in string fields in the devfile. Replacement cannot be used for\n\n - schemaVersion, metadata, parent source\n\n - element identifiers, e.g. command id, component name, endpoint name, project name\n\n - references to identifiers, e.g. in events, a command's component, container's volume mount name\n\n - string enums, e.g. command group kind, endpoint exposure",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ `
diff --git a/pkg/devfile/parser/data/v2/2.2.2/devfileJsonSchema222.go b/pkg/devfile/parser/data/v2/2.2.2/devfileJsonSchema222.go
new file mode 100644
index 00000000..54ae419a
--- /dev/null
+++ b/pkg/devfile/parser/data/v2/2.2.2/devfileJsonSchema222.go
@@ -0,0 +1,2230 @@
+//
+// Copyright Red Hat
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package version222
+
+// https://raw.githubusercontent.com/devfile/api/v2.2.2/schemas/latest/devfile.json
+const JsonSchema222 = `{
+ "description": "Devfile describes the structure of a cloud-native devworkspace and development environment.",
+ "type": "object",
+ "title": "Devfile schema - Version 2.2.2",
+ "required": [
+ "schemaVersion"
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "commands": {
+ "description": "Predefined, ready-to-use, devworkspace-related commands",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "exec"
+ ]
+ },
+ {
+ "required": [
+ "apply"
+ ]
+ },
+ {
+ "required": [
+ "composite"
+ ]
+ }
+ ],
+ "properties": {
+ "apply": {
+ "description": "Command that consists in applying a given component definition, typically bound to a devworkspace event.\n\nFor example, when an 'apply' command is bound to a 'preStart' event, and references a 'container' component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its 'dedicatedPod' field set to 'true'.\n\nWhen no 'apply' command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless 'deployByDefault' for that component is set to false.",
+ "type": "object",
+ "required": [
+ "component"
+ ],
+ "properties": {
+ "component": {
+ "description": "Describes component that will be applied",
+ "type": "string"
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "required": [
+ "kind"
+ ],
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "composite": {
+ "description": "Composite command that allows executing several sub-commands either sequentially or concurrently",
+ "type": "object",
+ "properties": {
+ "commands": {
+ "description": "The commands that comprise this composite command",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "required": [
+ "kind"
+ ],
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ },
+ "parallel": {
+ "description": "Indicates if the sub-commands should be executed concurrently",
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false
+ },
+ "exec": {
+ "description": "CLI Command executed in an existing component container",
+ "type": "object",
+ "required": [
+ "commandLine",
+ "component"
+ ],
+ "properties": {
+ "commandLine": {
+ "description": "The actual command-line string\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.",
+ "type": "string"
+ },
+ "component": {
+ "description": "Describes component to which given action relates",
+ "type": "string"
+ },
+ "env": {
+ "description": "Optional list of environment variables that have to be set before running the command",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "required": [
+ "kind"
+ ],
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "hotReloadCapable": {
+ "description": "Specify whether the command is restarted or not when the source code changes. If set to 'true' the command won't be restarted. A *hotReloadCapable* 'run' or 'debug' command is expected to handle file changes on its own and won't be restarted. A *hotReloadCapable* 'build' command is expected to be executed only once and won't be executed again. This field is taken into account only for commands 'build', 'run' and 'debug' with 'isDefault' set to 'true'.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ },
+ "workingDir": {
+ "description": "Working directory where the command should be executed\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "id": {
+ "description": "Mandatory identifier that allows referencing this command in composite commands, from a parent, or in events.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "components": {
+ "description": "List of the devworkspace components, such as editor and plugins, user-provided containers, or other types of components",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "container"
+ ]
+ },
+ {
+ "required": [
+ "kubernetes"
+ ]
+ },
+ {
+ "required": [
+ "openshift"
+ ]
+ },
+ {
+ "required": [
+ "volume"
+ ]
+ },
+ {
+ "required": [
+ "image"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "container": {
+ "description": "Allows adding and configuring devworkspace-related containers",
+ "type": "object",
+ "required": [
+ "image"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations that should be added to specific resources for this container",
+ "type": "object",
+ "properties": {
+ "deployment": {
+ "description": "Annotations to be added to deployment",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "service": {
+ "description": "Annotations to be added to service",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "args": {
+ "description": "The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command.\n\nDefaults to an empty array, meaning use whatever is defined in the image.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "command": {
+ "description": "The command to run in the dockerimage component instead of the default one provided in the image.\n\nDefaults to an empty array, meaning use whatever is defined in the image.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "cpuLimit": {
+ "type": "string"
+ },
+ "cpuRequest": {
+ "type": "string"
+ },
+ "dedicatedPod": {
+ "description": "Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "targetPort"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "default": "public",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "default": "http",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "env": {
+ "description": "Environment variables used in this container.\n\nThe following variables are reserved and cannot be overridden via env:\n\n - '$PROJECTS_ROOT'\n\n - '$PROJECT_SOURCE'",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "value"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "image": {
+ "type": "string"
+ },
+ "memoryLimit": {
+ "type": "string"
+ },
+ "memoryRequest": {
+ "type": "string"
+ },
+ "mountSources": {
+ "description": "Toggles whether or not the project source code should be mounted in the component.\n\nDefaults to true for all component types except plugins and components that set 'dedicatedPod' to true.",
+ "type": "boolean"
+ },
+ "sourceMapping": {
+ "description": "Optional specification of the path in the container where project sources should be transferred/mounted when 'mountSources' is 'true'. When omitted, the default value of /projects is used.",
+ "type": "string",
+ "default": "/projects"
+ },
+ "volumeMounts": {
+ "description": "List of volumes mounts that should be mounted is this container.",
+ "type": "array",
+ "items": {
+ "description": "Volume that should be mounted to a component container",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "description": "The volume mount name is the name of an existing 'Volume' component. If several containers mount the same volume name then they will reuse the same volume and will be able to access to the same files.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "The path in the component container where the volume should be mounted. If not path is mentioned, default path is the is '/\u003cname\u003e'.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "image": {
+ "description": "Allows specifying the definition of an image for outer loop builds",
+ "type": "object",
+ "required": [
+ "imageName"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "dockerfile"
+ ]
+ }
+ ],
+ "properties": {
+ "autoBuild": {
+ "description": "Defines if the image should be built during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "dockerfile": {
+ "description": "Allows specifying dockerfile type build",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "devfileRegistry"
+ ]
+ },
+ {
+ "required": [
+ "git"
+ ]
+ }
+ ],
+ "properties": {
+ "args": {
+ "description": "The arguments to supply to the dockerfile build.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "buildContext": {
+ "description": "Path of source directory to establish build context. Defaults to ${PROJECT_SOURCE} in the container",
+ "type": "string"
+ },
+ "devfileRegistry": {
+ "description": "Dockerfile's Devfile Registry source",
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "properties": {
+ "id": {
+ "description": "Id in a devfile registry that contains a Dockerfile. The src in the OCI registry required for the Dockerfile build will be downloaded for building the image.",
+ "type": "string"
+ },
+ "registryUrl": {
+ "description": "Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. To ensure the Dockerfile gets resolved consistently in different environments, it is recommended to always specify the 'devfileRegistryUrl' when 'Id' is used.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "git": {
+ "description": "Dockerfile's Git source",
+ "type": "object",
+ "required": [
+ "remotes"
+ ],
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "fileLocation": {
+ "description": "Location of the Dockerfile in the Git repository when using git as Dockerfile src. Defaults to Dockerfile.",
+ "type": "string"
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "rootRequired": {
+ "description": "Specify if a privileged builder pod is required.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "uri": {
+ "description": "URI Reference of a Dockerfile. It can be a full URL or a relative URI from the current devfile as the base URI.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "imageName": {
+ "description": "Name of the image for the resulting outerloop build",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "kubernetes": {
+ "description": "Allows importing into the devworkspace the Kubernetes resources defined in a given manifest. For example this allows reusing the Kubernetes definitions used to deploy some runtime components in production.",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "inlined"
+ ]
+ }
+ ],
+ "properties": {
+ "deployByDefault": {
+ "description": "Defines if the component should be deployed during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "targetPort"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "default": "public",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "default": "http",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "inlined": {
+ "description": "Inlined manifest",
+ "type": "string"
+ },
+ "uri": {
+ "description": "Location in a file fetched from a uri.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Mandatory name that allows referencing the component from other elements (such as commands) or from an external devfile that may reference this component through a parent or a plugin.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "openshift": {
+ "description": "Allows importing into the devworkspace the OpenShift resources defined in a given manifest. For example this allows reusing the OpenShift definitions used to deploy some runtime components in production.",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "inlined"
+ ]
+ }
+ ],
+ "properties": {
+ "deployByDefault": {
+ "description": "Defines if the component should be deployed during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "targetPort"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "default": "public",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "default": "http",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "inlined": {
+ "description": "Inlined manifest",
+ "type": "string"
+ },
+ "uri": {
+ "description": "Location in a file fetched from a uri.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "volume": {
+ "description": "Allows specifying the definition of a volume shared by several other components",
+ "type": "object",
+ "properties": {
+ "ephemeral": {
+ "description": "Ephemeral volumes are not stored persistently across restarts. Defaults to false",
+ "type": "boolean"
+ },
+ "size": {
+ "description": "Size of the volume",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "dependentProjects": {
+ "description": "Additional projects related to the main project in the devfile, contianing names and sources locations",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "clonePath": {
+ "description": "Path relative to the root of the projects to which this project should be cloned into. This is a unix-style relative path (i.e. uses forward slashes). The path is invalid if it is absolute or tries to escape the project root through the usage of '..'. If not specified, defaults to the project name.",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "required": [
+ "remotes"
+ ],
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "events": {
+ "description": "Bindings of commands to events. Each command is referred-to by its name.",
+ "type": "object",
+ "properties": {
+ "postStart": {
+ "description": "IDs of commands that should be executed after the devworkspace is completely started. In the case of Che-Theia, these commands should be executed after all plugins and extensions have started, including project cloning. This means that those commands are not triggered until the user opens the IDE in his browser.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "postStop": {
+ "description": "IDs of commands that should be executed after stopping the devworkspace.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "preStart": {
+ "description": "IDs of commands that should be executed before the devworkspace start. Kubernetes-wise, these commands would typically be executed in init containers of the devworkspace POD.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "preStop": {
+ "description": "IDs of commands that should be executed before stopping the devworkspace.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "metadata": {
+ "description": "Optional metadata",
+ "type": "object",
+ "properties": {
+ "architectures": {
+ "description": "Optional list of processor architectures that the devfile supports, empty list suggests that the devfile can be used on any architecture",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "description": "Architecture describes the architecture type",
+ "type": "string",
+ "enum": [
+ "amd64",
+ "arm64",
+ "ppc64le",
+ "s390x"
+ ]
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes. Deprecated, use the top-level attributes field instead.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "description": {
+ "description": "Optional devfile description",
+ "type": "string"
+ },
+ "displayName": {
+ "description": "Optional devfile display name",
+ "type": "string"
+ },
+ "globalMemoryLimit": {
+ "description": "Optional devfile global memory limit",
+ "type": "string"
+ },
+ "icon": {
+ "description": "Optional devfile icon, can be a URI or a relative path in the project",
+ "type": "string"
+ },
+ "language": {
+ "description": "Optional devfile language",
+ "type": "string"
+ },
+ "name": {
+ "description": "Optional devfile name",
+ "type": "string"
+ },
+ "projectType": {
+ "description": "Optional devfile project type",
+ "type": "string"
+ },
+ "provider": {
+ "description": "Optional devfile provider information",
+ "type": "string"
+ },
+ "supportUrl": {
+ "description": "Optional link to a page that provides support information",
+ "type": "string"
+ },
+ "tags": {
+ "description": "Optional devfile tags",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "version": {
+ "description": "Optional semver-compatible version",
+ "type": "string",
+ "pattern": "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\-[0-9a-z-]+(\\.[0-9a-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$"
+ },
+ "website": {
+ "description": "Optional devfile website",
+ "type": "string"
+ }
+ },
+ "additionalProperties": true
+ },
+ "parent": {
+ "description": "Parent devworkspace template",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "id"
+ ]
+ },
+ {
+ "required": [
+ "kubernetes"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Overrides of attributes encapsulated in a parent devfile. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "commands": {
+ "description": "Overrides of commands encapsulated in a parent devfile or a plugin. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "id"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "exec"
+ ]
+ },
+ {
+ "required": [
+ "apply"
+ ]
+ },
+ {
+ "required": [
+ "composite"
+ ]
+ }
+ ],
+ "properties": {
+ "apply": {
+ "description": "Command that consists in applying a given component definition, typically bound to a devworkspace event.\n\nFor example, when an 'apply' command is bound to a 'preStart' event, and references a 'container' component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its 'dedicatedPod' field set to 'true'.\n\nWhen no 'apply' command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless 'deployByDefault' for that component is set to false.",
+ "type": "object",
+ "properties": {
+ "component": {
+ "description": "Describes component that will be applied",
+ "type": "string"
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "composite": {
+ "description": "Composite command that allows executing several sub-commands either sequentially or concurrently",
+ "type": "object",
+ "properties": {
+ "commands": {
+ "description": "The commands that comprise this composite command",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ },
+ "parallel": {
+ "description": "Indicates if the sub-commands should be executed concurrently",
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false
+ },
+ "exec": {
+ "description": "CLI Command executed in an existing component container",
+ "type": "object",
+ "properties": {
+ "commandLine": {
+ "description": "The actual command-line string\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.",
+ "type": "string"
+ },
+ "component": {
+ "description": "Describes component to which given action relates",
+ "type": "string"
+ },
+ "env": {
+ "description": "Optional list of environment variables that have to be set before running the command",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "group": {
+ "description": "Defines the group this command is part of",
+ "type": "object",
+ "properties": {
+ "isDefault": {
+ "description": "Identifies the default command for a given group kind",
+ "type": "boolean"
+ },
+ "kind": {
+ "description": "Kind of group the command is part of",
+ "type": "string",
+ "enum": [
+ "build",
+ "run",
+ "test",
+ "debug",
+ "deploy"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "hotReloadCapable": {
+ "description": "Specify whether the command is restarted or not when the source code changes. If set to 'true' the command won't be restarted. A *hotReloadCapable* 'run' or 'debug' command is expected to handle file changes on its own and won't be restarted. A *hotReloadCapable* 'build' command is expected to be executed only once and won't be executed again. This field is taken into account only for commands 'build', 'run' and 'debug' with 'isDefault' set to 'true'.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "label": {
+ "description": "Optional label that provides a label for this command to be used in Editor UI menus for example",
+ "type": "string"
+ },
+ "workingDir": {
+ "description": "Working directory where the command should be executed\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "id": {
+ "description": "Mandatory identifier that allows referencing this command in composite commands, from a parent, or in events.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "components": {
+ "description": "Overrides of components encapsulated in a parent devfile or a plugin. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "container"
+ ]
+ },
+ {
+ "required": [
+ "kubernetes"
+ ]
+ },
+ {
+ "required": [
+ "openshift"
+ ]
+ },
+ {
+ "required": [
+ "volume"
+ ]
+ },
+ {
+ "required": [
+ "image"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "container": {
+ "description": "Allows adding and configuring devworkspace-related containers",
+ "type": "object",
+ "properties": {
+ "annotation": {
+ "description": "Annotations that should be added to specific resources for this container",
+ "type": "object",
+ "properties": {
+ "deployment": {
+ "description": "Annotations to be added to deployment",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "service": {
+ "description": "Annotations to be added to service",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "args": {
+ "description": "The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command.\n\nDefaults to an empty array, meaning use whatever is defined in the image.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "command": {
+ "description": "The command to run in the dockerimage component instead of the default one provided in the image.\n\nDefaults to an empty array, meaning use whatever is defined in the image.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "cpuLimit": {
+ "type": "string"
+ },
+ "cpuRequest": {
+ "type": "string"
+ },
+ "dedicatedPod": {
+ "description": "Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "env": {
+ "description": "Environment variables used in this container.\n\nThe following variables are reserved and cannot be overridden via env:\n\n - '$PROJECTS_ROOT'\n\n - '$PROJECT_SOURCE'",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "image": {
+ "type": "string"
+ },
+ "memoryLimit": {
+ "type": "string"
+ },
+ "memoryRequest": {
+ "type": "string"
+ },
+ "mountSources": {
+ "description": "Toggles whether or not the project source code should be mounted in the component.\n\nDefaults to true for all component types except plugins and components that set 'dedicatedPod' to true.",
+ "type": "boolean"
+ },
+ "sourceMapping": {
+ "description": "Optional specification of the path in the container where project sources should be transferred/mounted when 'mountSources' is 'true'. When omitted, the default value of /projects is used.",
+ "type": "string"
+ },
+ "volumeMounts": {
+ "description": "List of volumes mounts that should be mounted is this container.",
+ "type": "array",
+ "items": {
+ "description": "Volume that should be mounted to a component container",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "description": "The volume mount name is the name of an existing 'Volume' component. If several containers mount the same volume name then they will reuse the same volume and will be able to access to the same files.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "The path in the component container where the volume should be mounted. If not path is mentioned, default path is the is '/\u003cname\u003e'.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "image": {
+ "description": "Allows specifying the definition of an image for outer loop builds",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "dockerfile"
+ ]
+ },
+ {
+ "required": [
+ "autoBuild"
+ ]
+ }
+ ],
+ "properties": {
+ "autoBuild": {
+ "description": "Defines if the image should be built during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "dockerfile": {
+ "description": "Allows specifying dockerfile type build",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "devfileRegistry"
+ ]
+ },
+ {
+ "required": [
+ "git"
+ ]
+ }
+ ],
+ "properties": {
+ "args": {
+ "description": "The arguments to supply to the dockerfile build.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "buildContext": {
+ "description": "Path of source directory to establish build context. Defaults to ${PROJECT_SOURCE} in the container",
+ "type": "string"
+ },
+ "devfileRegistry": {
+ "description": "Dockerfile's Devfile Registry source",
+ "type": "object",
+ "properties": {
+ "id": {
+ "description": "Id in a devfile registry that contains a Dockerfile. The src in the OCI registry required for the Dockerfile build will be downloaded for building the image.",
+ "type": "string"
+ },
+ "registryUrl": {
+ "description": "Devfile Registry URL to pull the Dockerfile from when using the Devfile Registry as Dockerfile src. To ensure the Dockerfile gets resolved consistently in different environments, it is recommended to always specify the 'devfileRegistryUrl' when 'Id' is used.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "git": {
+ "description": "Dockerfile's Git source",
+ "type": "object",
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "fileLocation": {
+ "description": "Location of the Dockerfile in the Git repository when using git as Dockerfile src. Defaults to Dockerfile.",
+ "type": "string"
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "rootRequired": {
+ "description": "Specify if a privileged builder pod is required.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "uri": {
+ "description": "URI Reference of a Dockerfile. It can be a full URL or a relative URI from the current devfile as the base URI.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "imageName": {
+ "description": "Name of the image for the resulting outerloop build",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "kubernetes": {
+ "description": "Allows importing into the devworkspace the Kubernetes resources defined in a given manifest. For example this allows reusing the Kubernetes definitions used to deploy some runtime components in production.",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "inlined"
+ ]
+ }
+ ],
+ "properties": {
+ "deployByDefault": {
+ "description": "Defines if the component should be deployed during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "inlined": {
+ "description": "Inlined manifest",
+ "type": "string"
+ },
+ "uri": {
+ "description": "Location in a file fetched from a uri.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Mandatory name that allows referencing the component from other elements (such as commands) or from an external devfile that may reference this component through a parent or a plugin.",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "openshift": {
+ "description": "Allows importing into the devworkspace the OpenShift resources defined in a given manifest. For example this allows reusing the OpenShift definitions used to deploy some runtime components in production.",
+ "type": "object",
+ "oneOf": [
+ {
+ "required": [
+ "uri"
+ ]
+ },
+ {
+ "required": [
+ "inlined"
+ ]
+ }
+ ],
+ "properties": {
+ "deployByDefault": {
+ "description": "Defines if the component should be deployed during startup.\n\nDefault value is 'false'",
+ "type": "boolean"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "annotation": {
+ "description": "Annotations to be added to Kubernetes Ingress or Openshift Route",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "attributes": {
+ "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "exposure": {
+ "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address.\n\nDefault value is 'public'",
+ "type": "string",
+ "enum": [
+ "public",
+ "internal",
+ "none"
+ ]
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 15,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "path": {
+ "description": "Path of the endpoint URL",
+ "type": "string"
+ },
+ "protocol": {
+ "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'",
+ "type": "string",
+ "enum": [
+ "http",
+ "https",
+ "ws",
+ "wss",
+ "tcp",
+ "udp"
+ ]
+ },
+ "secure": {
+ "description": "Describes whether the endpoint should be secured and protected by some authentication process. This requires a protocol of 'https' or 'wss'.",
+ "type": "boolean"
+ },
+ "targetPort": {
+ "description": "Port number to be used within the container component. The same port cannot be used by two different container components.",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "inlined": {
+ "description": "Inlined manifest",
+ "type": "string"
+ },
+ "uri": {
+ "description": "Location in a file fetched from a uri.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "volume": {
+ "description": "Allows specifying the definition of a volume shared by several other components",
+ "type": "object",
+ "properties": {
+ "ephemeral": {
+ "description": "Ephemeral volumes are not stored persistently across restarts. Defaults to false",
+ "type": "boolean"
+ },
+ "size": {
+ "description": "Size of the volume",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "dependentProjects": {
+ "description": "Overrides of dependentProjects encapsulated in a parent devfile. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "clonePath": {
+ "description": "Path relative to the root of the projects to which this project should be cloned into. This is a unix-style relative path (i.e. uses forward slashes). The path is invalid if it is absolute or tries to escape the project root through the usage of '..'. If not specified, defaults to the project name.",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "id": {
+ "description": "Id in a registry that contains a Devfile yaml file",
+ "type": "string"
+ },
+ "kubernetes": {
+ "description": "Reference to a Kubernetes CRD of type DevWorkspaceTemplate",
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "namespace": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "projects": {
+ "description": "Overrides of projects encapsulated in a parent devfile. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "clonePath": {
+ "description": "Path relative to the root of the projects to which this project should be cloned into. This is a unix-style relative path (i.e. uses forward slashes). The path is invalid if it is absolute or tries to escape the project root through the usage of '..'. If not specified, defaults to the project name.",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "registryUrl": {
+ "description": "Registry URL to pull the parent devfile from when using id in the parent reference. To ensure the parent devfile gets resolved consistently in different environments, it is recommended to always specify the 'registryUrl' when 'id' is used.",
+ "type": "string"
+ },
+ "starterProjects": {
+ "description": "Overrides of starterProjects encapsulated in a parent devfile. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "description": {
+ "description": "Description of a starter project",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "subDir": {
+ "description": "Sub-directory from a starter project to be used as root for starter project.",
+ "type": "string"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "uri": {
+ "description": "URI Reference of a parent devfile YAML file. It can be a full URL or a relative URI with the current devfile as the base URI.",
+ "type": "string"
+ },
+ "variables": {
+ "description": "Overrides of variables encapsulated in a parent devfile. Overriding is done according to K8S strategic merge patch standard rules.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "version": {
+ "description": "Specific stack/sample version to pull the parent devfile from, when using id in the parent reference. To specify 'version', 'id' must be defined and used as the import reference source. 'version' can be either a specific stack version, or 'latest'. If no 'version' specified, default version will be used.",
+ "type": "string",
+ "pattern": "^(latest)|(([1-9])\\.([0-9]+)\\.([0-9]+)(\\-[0-9a-z-]+(\\.[0-9a-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?)$"
+ }
+ },
+ "additionalProperties": false
+ },
+ "projects": {
+ "description": "Projects worked on in the devworkspace, containing names and sources locations",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "clonePath": {
+ "description": "Path relative to the root of the projects to which this project should be cloned into. This is a unix-style relative path (i.e. uses forward slashes). The path is invalid if it is absolute or tries to escape the project root through the usage of '..'. If not specified, defaults to the project name.",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "required": [
+ "remotes"
+ ],
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "schemaVersion": {
+ "description": "Devfile schema version",
+ "type": "string",
+ "pattern": "^([2-9])\\.([0-9]+)\\.([0-9]+)(\\-[0-9a-z-]+(\\.[0-9a-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$"
+ },
+ "starterProjects": {
+ "description": "StarterProjects is a project that can be used as a starting point when bootstrapping new projects",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "oneOf": [
+ {
+ "required": [
+ "git"
+ ]
+ },
+ {
+ "required": [
+ "zip"
+ ]
+ }
+ ],
+ "properties": {
+ "attributes": {
+ "description": "Map of implementation-dependant free-form YAML attributes.",
+ "type": "object",
+ "additionalProperties": true
+ },
+ "description": {
+ "description": "Description of a starter project",
+ "type": "string"
+ },
+ "git": {
+ "description": "Project's Git source",
+ "type": "object",
+ "required": [
+ "remotes"
+ ],
+ "properties": {
+ "checkoutFrom": {
+ "description": "Defines from what the project should be checked out. Required if there are more than one remote configured",
+ "type": "object",
+ "properties": {
+ "remote": {
+ "description": "The remote name should be used as init. Required if there are more than one remote configured",
+ "type": "string"
+ },
+ "revision": {
+ "description": "The revision to checkout from. Should be branch name, tag or commit id. Default branch is used if missing or specified revision is not found.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "remotes": {
+ "description": "The remotes map which should be initialized in the git project. Projects must have at least one remote configured while StarterProjects \u0026 Image Component's Git source can only have at most one remote configured.",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "name": {
+ "description": "Project name",
+ "type": "string",
+ "maxLength": 63,
+ "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
+ },
+ "subDir": {
+ "description": "Sub-directory from a starter project to be used as root for starter project.",
+ "type": "string"
+ },
+ "zip": {
+ "description": "Project's Zip source",
+ "type": "object",
+ "properties": {
+ "location": {
+ "description": "Zip project's source location address. Should be file path of the archive, e.g. file://$FILE_PATH",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "variables": {
+ "description": "Map of key-value variables used for string replacement in the devfile. Values can be referenced via {{variable-key}} to replace the corresponding value in string fields in the devfile. Replacement cannot be used for\n\n - schemaVersion, metadata, parent source\n\n - element identifiers, e.g. command id, component name, endpoint name, project name\n\n - references to identifiers, e.g. in events, a command's component, container's volume mount name\n\n - string enums, e.g. command group kind, endpoint exposure",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ `
diff --git a/pkg/devfile/parser/data/v2/attributes.go b/pkg/devfile/parser/data/v2/attributes.go
index 6d7ba88a..871db25c 100644
--- a/pkg/devfile/parser/data/v2/attributes.go
+++ b/pkg/devfile/parser/data/v2/attributes.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/attributes_test.go b/pkg/devfile/parser/data/v2/attributes_test.go
index c869d849..3ac0bc12 100644
--- a/pkg/devfile/parser/data/v2/attributes_test.go
+++ b/pkg/devfile/parser/data/v2/attributes_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,10 +16,11 @@
package v2
import (
- "github.com/stretchr/testify/assert"
"reflect"
"testing"
+ "github.com/stretchr/testify/assert"
+
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/api/v2/pkg/attributes"
devfilepkg "github.com/devfile/api/v2/pkg/devfile"
diff --git a/pkg/devfile/parser/data/v2/commands.go b/pkg/devfile/parser/data/v2/commands.go
index 02e4b57a..30f2dc14 100644
--- a/pkg/devfile/parser/data/v2/commands.go
+++ b/pkg/devfile/parser/data/v2/commands.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,10 +17,11 @@ package v2
import (
"fmt"
- v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
- "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
"reflect"
"strings"
+
+ v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
+ "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
)
// GetCommands returns the slice of Command objects parsed from the Devfile
diff --git a/pkg/devfile/parser/data/v2/commands_test.go b/pkg/devfile/parser/data/v2/commands_test.go
index ff918005..cc852ef2 100644
--- a/pkg/devfile/parser/data/v2/commands_test.go
+++ b/pkg/devfile/parser/data/v2/commands_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,10 +17,11 @@ package v2
import (
"fmt"
- "github.com/kylelemons/godebug/pretty"
"reflect"
"testing"
+ "github.com/kylelemons/godebug/pretty"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/api/v2/pkg/attributes"
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
diff --git a/pkg/devfile/parser/data/v2/common/command_helper.go b/pkg/devfile/parser/data/v2/common/command_helper.go
index f4a5cabf..7f8c492c 100644
--- a/pkg/devfile/parser/data/v2/common/command_helper.go
+++ b/pkg/devfile/parser/data/v2/common/command_helper.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/common/command_helper_test.go b/pkg/devfile/parser/data/v2/common/command_helper_test.go
index 8be31489..746bfb2f 100644
--- a/pkg/devfile/parser/data/v2/common/command_helper_test.go
+++ b/pkg/devfile/parser/data/v2/common/command_helper_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,10 +16,11 @@
package common
import (
- "github.com/stretchr/testify/assert"
"reflect"
"testing"
+ "github.com/stretchr/testify/assert"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
)
diff --git a/pkg/devfile/parser/data/v2/common/component_helper.go b/pkg/devfile/parser/data/v2/common/component_helper.go
index fdb34371..78bb8fc2 100644
--- a/pkg/devfile/parser/data/v2/common/component_helper.go
+++ b/pkg/devfile/parser/data/v2/common/component_helper.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/common/component_helper_test.go b/pkg/devfile/parser/data/v2/common/component_helper_test.go
index f60bf2e8..6afec92d 100644
--- a/pkg/devfile/parser/data/v2/common/component_helper_test.go
+++ b/pkg/devfile/parser/data/v2/common/component_helper_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,9 +16,10 @@
package common
import (
- "github.com/stretchr/testify/assert"
"testing"
+ "github.com/stretchr/testify/assert"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
)
diff --git a/pkg/devfile/parser/data/v2/common/errors.go b/pkg/devfile/parser/data/v2/common/errors.go
index fd192d3d..882b5864 100644
--- a/pkg/devfile/parser/data/v2/common/errors.go
+++ b/pkg/devfile/parser/data/v2/common/errors.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/common/options.go b/pkg/devfile/parser/data/v2/common/options.go
index 4817788e..bb520454 100644
--- a/pkg/devfile/parser/data/v2/common/options.go
+++ b/pkg/devfile/parser/data/v2/common/options.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/common/options_test.go b/pkg/devfile/parser/data/v2/common/options_test.go
index 1a35c057..5b184654 100644
--- a/pkg/devfile/parser/data/v2/common/options_test.go
+++ b/pkg/devfile/parser/data/v2/common/options_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/common/project_helper.go b/pkg/devfile/parser/data/v2/common/project_helper.go
index 13291a87..def52e13 100644
--- a/pkg/devfile/parser/data/v2/common/project_helper.go
+++ b/pkg/devfile/parser/data/v2/common/project_helper.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/common/project_helper_test.go b/pkg/devfile/parser/data/v2/common/project_helper_test.go
index cf1828af..1ef5df55 100644
--- a/pkg/devfile/parser/data/v2/common/project_helper_test.go
+++ b/pkg/devfile/parser/data/v2/common/project_helper_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,9 +16,10 @@
package common
import (
- "github.com/stretchr/testify/assert"
"testing"
+ "github.com/stretchr/testify/assert"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
)
diff --git a/pkg/devfile/parser/data/v2/components.go b/pkg/devfile/parser/data/v2/components.go
index 1ea32835..e3d2a564 100644
--- a/pkg/devfile/parser/data/v2/components.go
+++ b/pkg/devfile/parser/data/v2/components.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/components_test.go b/pkg/devfile/parser/data/v2/components_test.go
index a170e447..bbee3c68 100644
--- a/pkg/devfile/parser/data/v2/components_test.go
+++ b/pkg/devfile/parser/data/v2/components_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,10 +17,11 @@ package v2
import (
"fmt"
- "github.com/kylelemons/godebug/pretty"
"reflect"
"testing"
+ "github.com/kylelemons/godebug/pretty"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/api/v2/pkg/attributes"
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
diff --git a/pkg/devfile/parser/data/v2/containers.go b/pkg/devfile/parser/data/v2/containers.go
index c62ea195..1bca5607 100644
--- a/pkg/devfile/parser/data/v2/containers.go
+++ b/pkg/devfile/parser/data/v2/containers.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/containers_test.go b/pkg/devfile/parser/data/v2/containers_test.go
index 067d347c..45fb3002 100644
--- a/pkg/devfile/parser/data/v2/containers_test.go
+++ b/pkg/devfile/parser/data/v2/containers_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/events.go b/pkg/devfile/parser/data/v2/events.go
index d7caf1a8..dd7c63fa 100644
--- a/pkg/devfile/parser/data/v2/events.go
+++ b/pkg/devfile/parser/data/v2/events.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,9 +17,10 @@ package v2
import (
"fmt"
+ "strings"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
- "strings"
)
// GetEvents returns the Events Object parsed from devfile
diff --git a/pkg/devfile/parser/data/v2/events_test.go b/pkg/devfile/parser/data/v2/events_test.go
index 5227f2a9..cdf71131 100644
--- a/pkg/devfile/parser/data/v2/events_test.go
+++ b/pkg/devfile/parser/data/v2/events_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,11 +17,12 @@ package v2
import (
"fmt"
- "github.com/kylelemons/godebug/pretty"
- "github.com/stretchr/testify/assert"
"reflect"
"testing"
+ "github.com/kylelemons/godebug/pretty"
+ "github.com/stretchr/testify/assert"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
)
diff --git a/pkg/devfile/parser/data/v2/header.go b/pkg/devfile/parser/data/v2/header.go
index 69f7ae5e..4198efa0 100644
--- a/pkg/devfile/parser/data/v2/header.go
+++ b/pkg/devfile/parser/data/v2/header.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/header_test.go b/pkg/devfile/parser/data/v2/header_test.go
index c04ba630..09376040 100644
--- a/pkg/devfile/parser/data/v2/header_test.go
+++ b/pkg/devfile/parser/data/v2/header_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/parent.go b/pkg/devfile/parser/data/v2/parent.go
index 932f9323..b08bf965 100644
--- a/pkg/devfile/parser/data/v2/parent.go
+++ b/pkg/devfile/parser/data/v2/parent.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/parent_test.go b/pkg/devfile/parser/data/v2/parent_test.go
index 3dc0efad..4145847a 100644
--- a/pkg/devfile/parser/data/v2/parent_test.go
+++ b/pkg/devfile/parser/data/v2/parent_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/projects.go b/pkg/devfile/parser/data/v2/projects.go
index bbd45e43..c8f86167 100644
--- a/pkg/devfile/parser/data/v2/projects.go
+++ b/pkg/devfile/parser/data/v2/projects.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,10 +17,11 @@ package v2
import (
"fmt"
- v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
- "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
"reflect"
"strings"
+
+ v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
+ "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
)
// GetProjects returns the Project Object parsed from devfile
diff --git a/pkg/devfile/parser/data/v2/projects_test.go b/pkg/devfile/parser/data/v2/projects_test.go
index c795a952..636b8d3c 100644
--- a/pkg/devfile/parser/data/v2/projects_test.go
+++ b/pkg/devfile/parser/data/v2/projects_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/types.go b/pkg/devfile/parser/data/v2/types.go
index c35b0d7e..7904fd81 100644
--- a/pkg/devfile/parser/data/v2/types.go
+++ b/pkg/devfile/parser/data/v2/types.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/volumes.go b/pkg/devfile/parser/data/v2/volumes.go
index 8f3a5d15..9ed9c0e3 100644
--- a/pkg/devfile/parser/data/v2/volumes.go
+++ b/pkg/devfile/parser/data/v2/volumes.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/volumes_test.go b/pkg/devfile/parser/data/v2/volumes_test.go
index 3884e41b..24c4596f 100644
--- a/pkg/devfile/parser/data/v2/volumes_test.go
+++ b/pkg/devfile/parser/data/v2/volumes_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/workspace.go b/pkg/devfile/parser/data/v2/workspace.go
index a1793e1a..71e1fdd3 100644
--- a/pkg/devfile/parser/data/v2/workspace.go
+++ b/pkg/devfile/parser/data/v2/workspace.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/v2/workspace_test.go b/pkg/devfile/parser/data/v2/workspace_test.go
index 07525882..57e87a17 100644
--- a/pkg/devfile/parser/data/v2/workspace_test.go
+++ b/pkg/devfile/parser/data/v2/workspace_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/data/versions.go b/pkg/devfile/parser/data/versions.go
index 0a92dc32..bb208b75 100644
--- a/pkg/devfile/parser/data/versions.go
+++ b/pkg/devfile/parser/data/versions.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -22,6 +22,8 @@ import (
v200 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.0.0"
v210 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.1.0"
v220 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.0"
+ v221 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.1"
+ v222 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.2"
)
// SupportedApiVersions stores the supported devfile API versions
@@ -32,6 +34,8 @@ const (
APISchemaVersion200 supportedApiVersion = "2.0.0"
APISchemaVersion210 supportedApiVersion = "2.1.0"
APISchemaVersion220 supportedApiVersion = "2.2.0"
+ APISchemaVersion221 supportedApiVersion = "2.2.1"
+ APISchemaVersion222 supportedApiVersion = "2.2.2"
APIVersionAlpha2 supportedApiVersion = "v1alpha2"
)
@@ -46,6 +50,8 @@ func init() {
apiVersionToDevfileStruct[APISchemaVersion200] = reflect.TypeOf(v2.DevfileV2{})
apiVersionToDevfileStruct[APISchemaVersion210] = reflect.TypeOf(v2.DevfileV2{})
apiVersionToDevfileStruct[APISchemaVersion220] = reflect.TypeOf(v2.DevfileV2{})
+ apiVersionToDevfileStruct[APISchemaVersion221] = reflect.TypeOf(v2.DevfileV2{})
+ apiVersionToDevfileStruct[APISchemaVersion222] = reflect.TypeOf(v2.DevfileV2{})
apiVersionToDevfileStruct[APIVersionAlpha2] = reflect.TypeOf(v2.DevfileV2{})
}
@@ -58,6 +64,8 @@ func init() {
devfileApiVersionToJSONSchema[APISchemaVersion200] = v200.JsonSchema200
devfileApiVersionToJSONSchema[APISchemaVersion210] = v210.JsonSchema210
devfileApiVersionToJSONSchema[APISchemaVersion220] = v220.JsonSchema220
+ devfileApiVersionToJSONSchema[APISchemaVersion221] = v221.JsonSchema221
+ devfileApiVersionToJSONSchema[APISchemaVersion222] = v222.JsonSchema222
// should use hightest v2 schema version since it is expected to be backward compatible with the same api version
- devfileApiVersionToJSONSchema[APIVersionAlpha2] = v220.JsonSchema220
+ devfileApiVersionToJSONSchema[APIVersionAlpha2] = v222.JsonSchema222
}
diff --git a/pkg/devfile/parser/devfileobj.go b/pkg/devfile/parser/devfileobj.go
index 10438960..c090c778 100644
--- a/pkg/devfile/parser/devfileobj.go
+++ b/pkg/devfile/parser/devfileobj.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/errors/errors.go b/pkg/devfile/parser/errors/errors.go
new file mode 100644
index 00000000..6d629644
--- /dev/null
+++ b/pkg/devfile/parser/errors/errors.go
@@ -0,0 +1,31 @@
+//
+// Copyright Red Hat
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package errors
+
+import "fmt"
+
+// NonCompliantDevfile returns an error if devfile parsing failed due to Non-Compliant Devfile
+type NonCompliantDevfile struct {
+ Err string
+}
+
+func (e *NonCompliantDevfile) Error() string {
+ errMsg := "error parsing devfile because of non-compliant data"
+ if e.Err != "" {
+ errMsg = fmt.Sprintf("%s due to %v", errMsg, e.Err)
+ }
+ return errMsg
+}
diff --git a/pkg/devfile/parser/parse.go b/pkg/devfile/parser/parse.go
index f6b681f9..32de0f29 100644
--- a/pkg/devfile/parser/parse.go
+++ b/pkg/devfile/parser/parse.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ import (
"context"
"encoding/json"
"fmt"
- "io/ioutil"
"net/url"
"os"
"path"
@@ -30,6 +29,7 @@ import (
devfileCtx "github.com/devfile/library/v2/pkg/devfile/parser/context"
"github.com/devfile/library/v2/pkg/devfile/parser/data"
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
+ errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
"github.com/devfile/library/v2/pkg/util"
registryLibrary "github.com/devfile/registry-support/registry-library/library"
"k8s.io/apimachinery/pkg/types"
@@ -37,6 +37,8 @@ import (
"k8s.io/klog"
"sigs.k8s.io/controller-runtime/pkg/client"
+ parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
apiOverride "github.com/devfile/api/v2/pkg/utils/overriding"
"github.com/devfile/api/v2/pkg/validation"
@@ -63,7 +65,7 @@ func parseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolver
// Unmarshal devfile content into devfile struct
err = json.Unmarshal(d.Ctx.GetDevfileContent(), &d.Data)
if err != nil {
- return d, errors.Wrapf(err, "failed to decode devfile content")
+ return d, &errPkg.NonCompliantDevfile{Err: err.Error()}
}
if flattenedDevfile {
@@ -80,7 +82,10 @@ func parseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolver
// ParserArgs is the struct to pass into parser functions which contains required info for parsing devfile.
// It accepts devfile path, devfile URL or devfile content in []byte format.
type ParserArgs struct {
- // Path is a relative or absolute devfile path on disk
+ // Path is a relative or absolute devfile path on disk.
+ // It can also be a relative or absolute path to a folder containing one or more devfiles,
+ // in which case the library will try to pick an existing one, based on the following priority order:
+ // devfile.yaml > .devfile.yaml > devfile.yml > .devfile.yml
Path string
// URL is the URL address of the specific devfile.
URL string
@@ -117,7 +122,7 @@ type ParserArgs struct {
// DownloadGitResources downloads the resources from Git repository if true
DownloadGitResources *bool
// DevfileUtilsClient exposes the interface for mock implementation.
- DevfileUtilsClient DevfileUtils
+ DevfileUtilsClient parserUtil.DevfileUtils
}
// ImageSelectorArgs defines the structure to leverage for using image names as selectors after parsing the Devfile.
@@ -151,14 +156,14 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {
if args.Data != nil {
d.Ctx, err = devfileCtx.NewByteContentDevfileCtx(args.Data)
if err != nil {
- return d, errors.Wrap(err, "failed to set devfile content from bytes")
+ return d, err
}
} else if args.Path != "" {
d.Ctx = devfileCtx.NewDevfileCtx(args.Path)
} else if args.URL != "" {
d.Ctx = devfileCtx.NewURLDevfileCtx(args.URL)
} else {
- return d, errors.Wrap(err, "the devfile source is not provided")
+ return d, fmt.Errorf("the devfile source is not provided")
}
if args.Token != "" {
@@ -166,7 +171,7 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {
}
if args.DevfileUtilsClient == nil {
- args.DevfileUtilsClient = NewDevfileUtilsClient()
+ args.DevfileUtilsClient = parserUtil.NewDevfileUtilsClient()
}
downloadGitResources := true
@@ -191,7 +196,7 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {
d, err = populateAndParseDevfile(d, &resolutionContextTree{}, tool, flattenedDevfile)
if err != nil {
- return d, errors.Wrap(err, "failed to populateAndParseDevfile")
+ return d, err
}
setBooleanDefaults := true
@@ -213,7 +218,7 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {
if convertUriToInlined {
d.Ctx.SetConvertUriToInlined(true)
- err = parseKubeResourceFromURI(d)
+ err = parseKubeResourceFromURI(d, tool.devfileUtilsClient)
if err != nil {
return d, err
}
@@ -238,21 +243,21 @@ type resolverTools struct {
// downloadGitResources downloads the resources from Git repository if true
downloadGitResources bool
// devfileUtilsClient exposes the Git Interface to be able to use mock implementation.
- devfileUtilsClient DevfileUtils
+ devfileUtilsClient parserUtil.DevfileUtils
}
func populateAndParseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolverTools, flattenedDevfile bool) (DevfileObj, error) {
var err error
if err = resolveCtx.hasCycle(); err != nil {
- return DevfileObj{}, err
+ return DevfileObj{}, &errPkg.NonCompliantDevfile{Err: err.Error()}
}
// Fill the fields of DevfileCtx struct
if d.Ctx.GetURL() != "" {
- err = d.Ctx.PopulateFromURL()
+ err = d.Ctx.PopulateFromURL(tool.devfileUtilsClient)
} else if d.Ctx.GetDevfileContent() != nil {
err = d.Ctx.PopulateFromRaw()
} else {
- err = d.Ctx.Populate()
+ err = d.Ctx.Populate(tool.devfileUtilsClient)
}
if err != nil {
return d, err
@@ -325,7 +330,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
case parent.Kubernetes != nil:
parentDevfileObj, err = parseFromKubeCRD(parent.ImportReference, resolveCtx, tool)
default:
- return fmt.Errorf("devfile parent does not define any resources")
+ err = &errPkg.NonCompliantDevfile{Err: "devfile parent does not define any resources"}
}
if err != nil {
return err
@@ -340,8 +345,9 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
if err != nil {
return fmt.Errorf("fail to parse version of parent devfile from: %v", resolveImportReference(parent.ImportReference))
}
+
if parentDevfileVerson.GreaterThan(mainDevfileVersion) {
- return fmt.Errorf("the parent devfile version from %v is greater than the child devfile version from %v", resolveImportReference(parent.ImportReference), resolveImportReference(resolveCtx.importReference))
+ return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the parent devfile version from %v is greater than the child devfile version from %v", resolveImportReference(parent.ImportReference), resolveImportReference(resolveCtx.importReference))}
}
}
parentWorkspaceContent := parentDevfileObj.Data.GetDevfileWorkspaceSpecContent()
@@ -386,7 +392,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
case plugin.Kubernetes != nil:
pluginDevfileObj, err = parseFromKubeCRD(plugin.ImportReference, resolveCtx, tool)
default:
- return fmt.Errorf("plugin %s does not define any resources", component.Name)
+ err = &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("plugin %s does not define any resources", component.Name)}
}
if err != nil {
return err
@@ -402,7 +408,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool
return fmt.Errorf("fail to parse version of plugin devfile from: %v", resolveImportReference(component.Plugin.ImportReference))
}
if pluginDevfileVerson.GreaterThan(mainDevfileVersion) {
- return fmt.Errorf("the plugin devfile version from %v is greater than the child devfile version from %v", resolveImportReference(component.Plugin.ImportReference), resolveImportReference(resolveCtx.importReference))
+ return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the plugin devfile version from %v is greater than the child devfile version from %v", resolveImportReference(component.Plugin.ImportReference), resolveImportReference(resolveCtx.importReference))}
}
}
pluginWorkspaceContent := pluginDevfileObj.Data.GetDevfileWorkspaceSpecContent()
@@ -456,7 +462,7 @@ func parseFromURI(importReference v1.ImportReference, curDevfileCtx devfileCtx.D
newUri = path.Join(path.Dir(curDevfileCtx.GetAbsPath()), uri)
d.Ctx = devfileCtx.NewDevfileCtx(newUri)
if util.ValidateFile(newUri) != nil {
- return DevfileObj{}, fmt.Errorf("the provided path is not a valid filepath %s", newUri)
+ return DevfileObj{}, &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the provided path is not a valid filepath %s", newUri)}
}
srcDir := path.Dir(newUri)
destDir := path.Dir(curDevfileCtx.GetAbsPath())
@@ -514,7 +520,7 @@ func parseFromRegistry(importReference v1.ImportReference, resolveCtx *resolutio
}
d.Ctx, err = devfileCtx.NewByteContentDevfileCtx(devfileContent)
if err != nil {
- return d, errors.Wrap(err, "failed to set devfile content from bytes")
+ return d, err
}
newResolveCtx := resolveCtx.appendNode(importReference)
@@ -545,7 +551,7 @@ func parseFromRegistry(importReference v1.ImportReference, resolveCtx *resolutio
}
}
} else {
- return DevfileObj{}, fmt.Errorf("failed to fetch from registry, registry URL is not provided")
+ return DevfileObj{}, &errPkg.NonCompliantDevfile{Err: "failed to fetch from registry, registry URL is not provided"}
}
return DevfileObj{}, fmt.Errorf("failed to get id: %s from registry URLs provided", id)
@@ -553,7 +559,7 @@ func parseFromRegistry(importReference v1.ImportReference, resolveCtx *resolutio
func getDevfileFromRegistry(id, registryURL, version string, httpTimeout *int) ([]byte, error) {
if !strings.HasPrefix(registryURL, "http://") && !strings.HasPrefix(registryURL, "https://") {
- return nil, fmt.Errorf("the provided registryURL: %s is not a valid URL", registryURL)
+ return nil, &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the provided registryURL: %s is not a valid URL", registryURL)}
}
param := util.HTTPRequestParams{
URL: fmt.Sprintf("%s/devfiles/%s/%s", registryURL, id, version),
@@ -566,7 +572,7 @@ func getDevfileFromRegistry(id, registryURL, version string, httpTimeout *int) (
}
func getResourcesFromRegistry(id, registryURL, destDir string) error {
- stackDir, err := ioutil.TempDir(os.TempDir(), fmt.Sprintf("registry-resources-%s", id))
+ stackDir, err := os.MkdirTemp(os.TempDir(), fmt.Sprintf("registry-resources-%s", id))
if err != nil {
return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
}
@@ -588,7 +594,7 @@ func getResourcesFromRegistry(id, registryURL, destDir string) error {
func parseFromKubeCRD(importReference v1.ImportReference, resolveCtx *resolutionContextTree, tool resolverTools) (d DevfileObj, err error) {
if tool.k8sClient == nil || tool.context == nil {
- return DevfileObj{}, fmt.Errorf("Kubernetes client and context are required to parse from Kubernetes CRD")
+ return DevfileObj{}, fmt.Errorf("kubernetes client and context are required to parse from Kubernetes CRD")
}
namespace := importReference.Kubernetes.Namespace
@@ -762,7 +768,7 @@ func setEndpoints(endpoints []v1.Endpoint) {
}
// parseKubeResourceFromURI iterate through all kubernetes & openshift components, and parse from uri and update the content to inlined field in devfileObj
-func parseKubeResourceFromURI(devObj DevfileObj) error {
+func parseKubeResourceFromURI(devObj DevfileObj, devfileUtilsClient parserUtil.DevfileUtils) error {
getKubeCompOptions := common.DevfileOptions{
ComponentOptions: common.ComponentOptions{
ComponentType: v1.KubernetesComponentType,
@@ -784,7 +790,7 @@ func parseKubeResourceFromURI(devObj DevfileObj) error {
for _, kubeComp := range kubeComponents {
if kubeComp.Kubernetes != nil && kubeComp.Kubernetes.Uri != "" {
/* #nosec G601 -- not an issue, kubeComp is de-referenced in sequence*/
- err := convertK8sLikeCompUriToInlined(&kubeComp, devObj.Ctx)
+ err := convertK8sLikeCompUriToInlined(&kubeComp, devObj.Ctx, devfileUtilsClient)
if err != nil {
return errors.Wrapf(err, "failed to convert kubernetes uri to inlined for component '%s'", kubeComp.Name)
}
@@ -797,7 +803,7 @@ func parseKubeResourceFromURI(devObj DevfileObj) error {
for _, openshiftComp := range openshiftComponents {
if openshiftComp.Openshift != nil && openshiftComp.Openshift.Uri != "" {
/* #nosec G601 -- not an issue, openshiftComp is de-referenced in sequence*/
- err := convertK8sLikeCompUriToInlined(&openshiftComp, devObj.Ctx)
+ err := convertK8sLikeCompUriToInlined(&openshiftComp, devObj.Ctx, devfileUtilsClient)
if err != nil {
return errors.Wrapf(err, "failed to convert openshift uri to inlined for component '%s'", openshiftComp.Name)
}
@@ -811,14 +817,14 @@ func parseKubeResourceFromURI(devObj DevfileObj) error {
}
// convertK8sLikeCompUriToInlined read in kubernetes resources definition from uri and converts to kubernetest inlined field
-func convertK8sLikeCompUriToInlined(component *v1.Component, d devfileCtx.DevfileCtx) error {
+func convertK8sLikeCompUriToInlined(component *v1.Component, d devfileCtx.DevfileCtx, devfileUtilsClient parserUtil.DevfileUtils) error {
var uri string
if component.Kubernetes != nil {
uri = component.Kubernetes.Uri
} else if component.Openshift != nil {
uri = component.Openshift.Uri
}
- data, err := getKubernetesDefinitionFromUri(uri, d)
+ data, err := getKubernetesDefinitionFromUri(uri, d, devfileUtilsClient)
if err != nil {
return err
}
@@ -838,7 +844,7 @@ func convertK8sLikeCompUriToInlined(component *v1.Component, d devfileCtx.Devfil
}
// getKubernetesDefinitionFromUri read in kubernetes resources definition from uri and returns the raw content
-func getKubernetesDefinitionFromUri(uri string, d devfileCtx.DevfileCtx) ([]byte, error) {
+func getKubernetesDefinitionFromUri(uri string, d devfileCtx.DevfileCtx, devfileUtilsClient parserUtil.DevfileUtils) ([]byte, error) {
// validate URI
err := validation.ValidateURI(uri)
if err != nil {
@@ -873,7 +879,7 @@ func getKubernetesDefinitionFromUri(uri string, d devfileCtx.DevfileCtx) ([]byte
if d.GetToken() != "" {
params.Token = d.GetToken()
}
- data, err = util.DownloadInMemory(params)
+ data, err = devfileUtilsClient.DownloadInMemory(params)
if err != nil {
return nil, errors.Wrapf(err, "error getting kubernetes resources definition information")
}
diff --git a/pkg/devfile/parser/parse_test.go b/pkg/devfile/parser/parse_test.go
index f4e214af..f7180026 100644
--- a/pkg/devfile/parser/parse_test.go
+++ b/pkg/devfile/parser/parse_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ import (
"bytes"
"context"
"fmt"
- "io/ioutil"
"net"
"net/http"
"net/http/httptest"
@@ -39,6 +38,7 @@ import (
"github.com/devfile/library/v2/pkg/devfile/parser/data"
v2 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2"
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
+ parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
"github.com/devfile/library/v2/pkg/testingutil"
"github.com/kylelemons/godebug/pretty"
"github.com/stretchr/testify/assert"
@@ -2862,7 +2862,7 @@ func Test_parseParentAndPluginFromURI(t *testing.T) {
tt.args.devFileObj.Data.AddComponents(plugincomp)
}
- err := parseParentAndPlugin(tt.args.devFileObj, &resolutionContextTree{}, resolverTools{devfileUtilsClient: NewDevfileUtilsClient()})
+ err := parseParentAndPlugin(tt.args.devFileObj, &resolutionContextTree{}, resolverTools{devfileUtilsClient: parserUtil.NewDevfileUtilsClient()})
// Unexpected error
if (err != nil) != (tt.wantErr != nil) {
@@ -2889,6 +2889,11 @@ func Test_parseParentAndPlugin_RecursivelyReference(t *testing.T) {
Ctx: devfileCtx.NewDevfileCtx(OutputDevfileYamlPath),
Data: &v2.DevfileV2{
Devfile: v1.Devfile{
+ DevfileHeader: devfilepkg.DevfileHeader{
+ Metadata: devfilepkg.DevfileMetadata{
+ Name: "main-devfile",
+ },
+ },
DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{
Parent: &v1.Parent{
ImportReference: v1.ImportReference{
@@ -2922,6 +2927,9 @@ func Test_parseParentAndPlugin_RecursivelyReference(t *testing.T) {
Devfile: v1.Devfile{
DevfileHeader: devfilepkg.DevfileHeader{
SchemaVersion: schemaVersion,
+ Metadata: devfilepkg.DevfileMetadata{
+ Name: "parent-devfile-1",
+ },
},
DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{
Parent: &v1.Parent{
@@ -2959,6 +2967,9 @@ func Test_parseParentAndPlugin_RecursivelyReference(t *testing.T) {
Devfile: v1.Devfile{
DevfileHeader: devfilepkg.DevfileHeader{
SchemaVersion: schemaVersion,
+ Metadata: devfilepkg.DevfileMetadata{
+ Name: "parent-devfile-2",
+ },
},
DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{
Parent: &v1.Parent{
@@ -3064,6 +3075,9 @@ func Test_parseParentAndPlugin_RecursivelyReference(t *testing.T) {
Kind: "DevWorkspaceTemplate",
APIVersion: "testgroup/v1alpha2",
},
+ ObjectMeta: kubev1.ObjectMeta{
+ Name: "dwtemplate",
+ },
Spec: parentSpec,
},
}
@@ -3079,7 +3093,7 @@ func Test_parseParentAndPlugin_RecursivelyReference(t *testing.T) {
k8sClient: testK8sClient,
context: context.Background(),
httpTimeout: &httpTimeout,
- devfileUtilsClient: NewMockDevfileUtilsClient(),
+ devfileUtilsClient: parserUtil.NewDevfileUtilsClient(),
}
err := parseParentAndPlugin(devFileObj, &resolutionContextTree{}, tool)
@@ -3087,8 +3101,8 @@ func Test_parseParentAndPlugin_RecursivelyReference(t *testing.T) {
expectedErr := fmt.Sprintf("devfile has an cycle in references: main devfile -> uri: %s%s -> name: %s, namespace: %s -> uri: %s%s -> uri: %s%s", httpPrefix, uri1, name, namespace,
httpPrefix, uri2, httpPrefix, uri1)
// Unexpected error
- if err == nil || !reflect.DeepEqual(expectedErr, err.Error()) {
- t.Errorf("Test_parseParentAndPlugin_RecursivelyReference() unexpected error: %v", err)
+ if err == nil || !strings.Contains(err.Error(), expectedErr) {
+ t.Errorf("Test_parseParentAndPlugin_RecursivelyReference() error did not match: %v", err)
return
}
@@ -3335,6 +3349,48 @@ commands:
kind: deploy
isDefault: true`
+ badDevfile := `schemaVersion: 10.0.0
+metadata:
+ name: nodejs
+ version: 2.1.1
+ displayName: Node.js Runtime
+ description: Stack with Node.js 16
+components:
+ - name: image-build
+ image:
+ imageName: nodejs-image:latest
+ dockerfile:
+ uri: Dockerfile
+ buildContext: .
+ rootRequired: true
+ - name: kubernetes-deploy
+ kubernetes:
+ uri: deploy.yaml
+ endpoints:
+ - name: http-3001
+ targetPort: 3001
+ path: /
+commands:
+ - id: build-image
+ apply:
+ component: image-build
+ - id: deployk8s
+ apply:
+ component: kubernetes-deploy
+ group:
+ kind: deploy
+ - id: deploy
+ composite:
+ commands:
+ - build-image
+ - deployk8s
+ group:
+ kind: deploy
+ isDefault: true`
+
+ badYAML := `
+~: a`
+
tests := []struct {
name string
parserArgs ParserArgs
@@ -3401,6 +3457,25 @@ commands:
},
wantErr: true,
},
+ {
+ name: "error out if parser args have no devfile src",
+ parserArgs: ParserArgs{},
+ wantErr: true,
+ },
+ {
+ name: "error out if parser args have bad YAML",
+ parserArgs: ParserArgs{
+ Data: []byte(badYAML),
+ },
+ wantErr: true,
+ },
+ {
+ name: "error if parser args have a bad Devfile",
+ parserArgs: ParserArgs{
+ Data: []byte(badDevfile),
+ },
+ wantErr: true,
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -3608,6 +3683,10 @@ func Test_parseParentFromKubeCRD(t *testing.T) {
},
}
+ emptyImportReference := v1.ImportReference{
+ Version: "1",
+ }
+
importFromKubeCRD := attributes.Attributes{}.PutString(importSourceAttribute, resolveImportReference(kubeCRDReference))
parentOverridesFromMainDevfile := attributes.Attributes{}.PutString(importSourceAttribute,
resolveImportReference(kubeCRDReference)).PutString(parentOverrideAttribute, "main devfile")
@@ -3649,6 +3728,8 @@ func Test_parseParentFromKubeCRD(t *testing.T) {
},
}
+ noParentImportSrcErr := "parent does not define any resources"
+ noPluginImportSrcErr := "plugin plugin1 does not define any resources"
crdNotFoundErr := "not found"
//override all properties
@@ -3889,6 +3970,50 @@ func Test_parseParentFromKubeCRD(t *testing.T) {
},
wantErr: &crdNotFoundErr,
},
+ {
+ name: "should err out if there is no parent import reference",
+ mainDevfile: DevfileObj{
+ Ctx: devfileCtx.NewDevfileCtx(OutputDevfileYamlPath),
+ Data: &v2.DevfileV2{
+ Devfile: v1.Devfile{
+ DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{
+ Parent: &v1.Parent{
+ ImportReference: emptyImportReference,
+ },
+ DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{},
+ },
+ },
+ },
+ },
+ wantErr: &noParentImportSrcErr,
+ },
+ {
+ name: "should err out if there is no plugin import reference",
+ mainDevfile: DevfileObj{
+ Ctx: devfileCtx.NewDevfileCtx(OutputDevfileYamlPath),
+ Data: &v2.DevfileV2{
+ Devfile: v1.Devfile{
+ DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{
+ DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{
+ Components: []v1.Component{
+ {
+ Name: "plugin1",
+ ComponentUnion: v1.ComponentUnion{
+ Plugin: &v1.PluginComponent{
+ ImportReference: v1.ImportReference{
+ Version: "2",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ wantErr: &noPluginImportSrcErr,
+ },
}
for _, tt := range tests {
@@ -3969,7 +4094,7 @@ func Test_parseFromURI(t *testing.T) {
if err != nil {
fmt.Errorf("Test_parseFromURI() error: failed to marshall devfile data: %v", err)
}
- err = ioutil.WriteFile(localRelativeURI, yamlData, 0644)
+ err = os.WriteFile(localRelativeURI, yamlData, 0644)
if err != nil {
fmt.Errorf("Test_parseFromURI() error: fail to write to file: %v", err)
}
@@ -4173,7 +4298,7 @@ func Test_parseFromURI(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- got, err := parseFromURI(tt.importReference, tt.curDevfileCtx, &resolutionContextTree{}, resolverTools{devfileUtilsClient: NewDevfileUtilsClient()})
+ got, err := parseFromURI(tt.importReference, tt.curDevfileCtx, &resolutionContextTree{}, resolverTools{devfileUtilsClient: parserUtil.NewDevfileUtilsClient()})
if (err != nil) != (tt.wantErr != nil) {
t.Errorf("Test_parseFromURI() unexpected error: %v, wantErr %v", err, tt.wantErr)
} else if err == nil && !reflect.DeepEqual(got.Data, tt.wantDevFile.Data) {
@@ -4230,12 +4355,13 @@ func Test_parseFromURI_GitProviders(t *testing.T) {
invalidTokenError := "failed to clone repo with token, ensure that the url and token is correct"
invalidGitSwitchError := "failed to switch repo to revision*"
invalidDevfilePathError := "error getting devfile from url: failed to retrieve*"
- invalidGitProviderError := "Failed to download resources from parent devfile. Unsupported Git Provider for %s "
+ invalidGitProviderError := "failed to download resources from parent devfile. Unsupported Git Provider for %s "
tests := []struct {
name string
url string // alias for parent devfile URL
gitUrl *util.GitUrl
+ devfileUtilsClient parserUtil.MockDevfileUtilsClient
token string
destDir string
importReference v1.ImportReference
@@ -4244,12 +4370,18 @@ func Test_parseFromURI_GitProviders(t *testing.T) {
wantResources []string
wantResourceContent []byte
downloadGitResources bool
+ noMockData bool
}{
{
name: "private parent devfile",
url: validUrl,
gitUrl: validGitUrl,
- token: validToken,
+ devfileUtilsClient: parserUtil.MockDevfileUtilsClient{
+ DownloadOptions: util.MockDownloadOptions{
+ MockFile: minimalDevfileContent,
+ },
+ },
+ token: validToken,
importReference: v1.ImportReference{
ImportReferenceUnion: v1.ImportReferenceUnion{
Uri: server.URL,
@@ -4260,11 +4392,36 @@ func Test_parseFromURI_GitProviders(t *testing.T) {
wantResourceContent: []byte("private repo\ngit switched"),
downloadGitResources: true,
},
+ {
+ name: "private parent devfile without mock data",
+ url: validUrl,
+ devfileUtilsClient: parserUtil.MockDevfileUtilsClient{
+ DownloadOptions: util.MockDownloadOptions{
+ MockFile: minimalDevfileContent,
+ },
+ },
+ token: validToken,
+ importReference: v1.ImportReference{
+ ImportReferenceUnion: v1.ImportReferenceUnion{
+ Uri: "https://github.com/private-url-devfile",
+ },
+ },
+ wantDevFile: minimalDevfile,
+ wantResources: []string{"resource.file"},
+ wantResourceContent: []byte("private repo\ngit switched"),
+ downloadGitResources: true,
+ noMockData: true,
+ },
{
name: "public parent devfile",
url: validUrl,
gitUrl: validGitUrl,
- token: "",
+ devfileUtilsClient: parserUtil.MockDevfileUtilsClient{
+ DownloadOptions: util.MockDownloadOptions{
+ MockFile: minimalDevfileContent,
+ },
+ },
+ token: "",
importReference: v1.ImportReference{
ImportReferenceUnion: v1.ImportReferenceUnion{
Uri: server.URL,
@@ -4279,6 +4436,11 @@ func Test_parseFromURI_GitProviders(t *testing.T) {
name: "public parent devfile with download turned off",
url: validUrl,
gitUrl: validGitUrl,
+ devfileUtilsClient: parserUtil.MockDevfileUtilsClient{
+ DownloadOptions: util.MockDownloadOptions{
+ MockFile: minimalDevfileContent,
+ },
+ },
importReference: v1.ImportReference{
ImportReferenceUnion: v1.ImportReferenceUnion{
Uri: server.URL,
@@ -4413,12 +4575,15 @@ func Test_parseFromURI_GitProviders(t *testing.T) {
t.Errorf("Unexpected err: %+v", err)
}
- mockDC := NewMockDevfileUtilsClient()
- mockDC.ParentURLAlias = tt.url
- mockDC.GitTestToken = tt.token
- mockDC.MockGitURL = util.MockGitUrl(*tt.gitUrl)
+ if tt.noMockData {
+ curDevfileContext.SetToken(tt.token)
+ } else {
+ tt.devfileUtilsClient.ParentURLAlias = tt.url
+ tt.devfileUtilsClient.GitTestToken = tt.token
+ tt.devfileUtilsClient.MockGitURL = util.MockGitUrl(*tt.gitUrl)
+ }
- got, err := parseFromURI(tt.importReference, curDevfileContext, &resolutionContextTree{}, resolverTools{downloadGitResources: tt.downloadGitResources, devfileUtilsClient: mockDC})
+ got, err := parseFromURI(tt.importReference, curDevfileContext, &resolutionContextTree{}, resolverTools{downloadGitResources: tt.downloadGitResources, devfileUtilsClient: &tt.devfileUtilsClient})
// validate even if we want an error; check that no files are copied to destDir
validateGitResourceFunctions(t, tt.wantResources, tt.wantResourceContent, destDir)
@@ -4478,6 +4643,9 @@ func Test_parseFromRegistry(t *testing.T) {
stagingRegistry = "https://registry.stage.devfile.io"
)
+ badYAML := `
+~: a`
+
parentDevfile := DevfileObj{
Data: &v2.DevfileV2{
Devfile: v1.Devfile{
@@ -4535,6 +4703,7 @@ func Test_parseFromRegistry(t *testing.T) {
missingRegistryURLErr := "failed to fetch from registry, registry URL is not provided"
invalidRegistryURLErr := "Get .* dial tcp: lookup http: .*"
resourceDownloadErr := "failed to pull stack from registry .*"
+ badDevfileErr := "error parsing devfile because of non-compliant data"
testServer := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var data []byte
@@ -4542,6 +4711,8 @@ func Test_parseFromRegistry(t *testing.T) {
if strings.Contains(r.URL.Path, "/devfiles/"+registryId) {
if strings.Contains(r.URL.Path, "latest") {
data, err = yaml.Marshal(latestParentDevfile.Data)
+ } else if strings.Contains(r.URL.Path, "bad") {
+ data = []byte(badYAML)
} else if strings.Contains(r.URL.Path, "1.1.0") {
data, err = yaml.Marshal(parentDevfile.Data)
} else if r.URL.Path == fmt.Sprintf("/devfiles/%s/", registryId) {
@@ -4687,6 +4858,17 @@ func Test_parseFromRegistry(t *testing.T) {
},
wantErr: &invalidRegistryURLErr,
},
+ {
+ name: "should fail if registry returns a bad devfile content",
+ importReference: v1.ImportReference{
+ ImportReferenceUnion: v1.ImportReferenceUnion{
+ Id: registryId,
+ },
+ Version: "bad",
+ RegistryUrl: httpPrefix + registry,
+ },
+ wantErr: &badDevfileErr,
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -4731,6 +4913,7 @@ func Test_parseFromKubeCRD(t *testing.T) {
}
crdNotFoundErr := "not found"
+ noContextErr := "kubernetes client and context are required to parse from Kubernetes CRD"
tests := []struct {
name string
@@ -4779,6 +4962,20 @@ func Test_parseFromKubeCRD(t *testing.T) {
},
wantErr: &crdNotFoundErr,
},
+ {
+ name: "should err out on no context",
+ wantDevFile: parentDevfile,
+ importReference: v1.ImportReference{
+ ImportReferenceUnion: v1.ImportReferenceUnion{
+ Kubernetes: &v1.KubernetesCustomResourceImportReference{
+ Name: name,
+ Namespace: namespace,
+ },
+ },
+ },
+ devWorkspaceResources: map[string]v1.DevWorkspaceTemplate{},
+ wantErr: &noContextErr,
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -4790,6 +4987,12 @@ func Test_parseFromKubeCRD(t *testing.T) {
k8sClient: testK8sClient,
context: context.Background(),
}
+ if tt.name == "should err out on no context" {
+ tool = resolverTools{
+ k8sClient: testK8sClient,
+ context: nil,
+ }
+ }
got, err := parseFromKubeCRD(tt.importReference, &resolutionContextTree{}, tool)
if (err != nil) != (tt.wantErr != nil) {
t.Errorf("Test_parseFromKubeCRD() unexpected error: %v, wantErr %v", err, tt.wantErr)
@@ -4854,7 +5057,7 @@ func Test_DownloadGitRepoResources(t *testing.T) {
},
}
- mockDC := NewMockDevfileUtilsClient()
+ mockDC := parserUtil.NewMockDevfileUtilsClient()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
destDir := t.TempDir()
@@ -4976,7 +5179,7 @@ spec:
fmt.Errorf("Test_getKubernetesDefinitionFromUri() error: failed to create folder: %v, error: %v", path.Dir(localDeployFilePath), err)
}
- err = ioutil.WriteFile(localDeployFilePath, []byte(deployContent), 0644)
+ err = os.WriteFile(localDeployFilePath, []byte(deployContent), 0644)
if err != nil {
fmt.Errorf("Test_getKubernetesDefinitionFromUri() error: fail to write to file: %v", err)
}
@@ -5121,7 +5324,7 @@ commands:
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- got, err := getKubernetesDefinitionFromUri(tt.uri, tt.devfileCtx)
+ got, err := getKubernetesDefinitionFromUri(tt.uri, tt.devfileCtx, parserUtil.NewDevfileUtilsClient())
if (err != nil) != (tt.wantErr != nil) {
t.Errorf("Test_getKubernetesDefinitionFromUri() unexpected error: %v, wantErr %v", err, *tt.wantErr)
} else if err == nil {
diff --git a/pkg/devfile/parser/parser_mock.go b/pkg/devfile/parser/parser_mock.go
deleted file mode 100644
index aa67db92..00000000
--- a/pkg/devfile/parser/parser_mock.go
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// Copyright 2023 Red Hat, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package parser
-
-import (
- "fmt"
- "github.com/devfile/library/v2/pkg/util"
- "os"
- "strings"
-)
-
-type MockDevfileUtilsClient struct {
- ParentURLAlias string // Specify a valid git URL as an alias if using a localhost HTTP server in order to pass validation.
- MockGitURL util.MockGitUrl
- GitTestToken string // Mock Git token. Specify the string "valid-token" for the mock CloneGitRepo to pass
-}
-
-func NewMockDevfileUtilsClient() MockDevfileUtilsClient {
- return MockDevfileUtilsClient{}
-}
-
-func (gc MockDevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
-
- //the url parameter that gets passed in will be the localhost IP of the test server, so it will fail all the validation checks. We will use the global testURL variable instead
- //skip the Git Provider check since it'll fail
- if util.IsGitProviderRepo(gc.ParentURLAlias) {
- // this converts the test git URL to a mock URL
- mockGitUrl := gc.MockGitURL
- mockGitUrl.Token = gc.GitTestToken
-
- if !mockGitUrl.IsFile || mockGitUrl.Revision == "" || !strings.Contains(mockGitUrl.Path, OutputDevfileYamlPath) {
- return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url+"/"+mockGitUrl.Path)
- }
-
- stackDir, err := os.MkdirTemp("", fmt.Sprintf("git-resources"))
- if err != nil {
- return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
- }
-
- defer func(path string) {
- err := os.RemoveAll(path)
- if err != nil {
- err = fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
- }
- }(stackDir)
-
- err = mockGitUrl.CloneGitRepo(stackDir)
- if err != nil {
- return err
- }
-
- err = util.CopyAllDirFiles(stackDir, destDir)
- if err != nil {
- return err
- }
-
- } else {
- return fmt.Errorf("Failed to download resources from parent devfile. Unsupported Git Provider for %s ", gc.ParentURLAlias)
- }
-
- return nil
-}
diff --git a/pkg/devfile/parser/reader.go b/pkg/devfile/parser/reader.go
index a9c27d46..97cefcac 100644
--- a/pkg/devfile/parser/reader.go
+++ b/pkg/devfile/parser/reader.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -20,6 +20,8 @@ import (
"fmt"
"io"
+ errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors"
+ parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
"github.com/devfile/library/v2/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/afero"
@@ -38,6 +40,8 @@ type YamlSrc struct {
Path string
// URL of the yaml file
URL string
+ // Token to access a private URL like a private repository
+ Token string
// Data is the yaml content in []byte format
Data []byte
}
@@ -56,15 +60,20 @@ type KubernetesResources struct {
// It returns all the parsed Kubernetes objects as an array of interface.
// Consumers interested in the Kubernetes resources are expected to Unmarshal
// it to the struct of the respective Kubernetes resource. If a Path is being passed,
-// provide a filesystem, otherwise nil can be passed in
-func ReadKubernetesYaml(src YamlSrc, fs *afero.Afero) ([]interface{}, error) {
+// provide a filesystem, otherwise nil can be passed in.
+// Pass in an optional client to use either the actual implementation or a mock implementation of the interface.
+func ReadKubernetesYaml(src YamlSrc, fs *afero.Afero, devfileUtilsClient parserUtil.DevfileUtils) ([]interface{}, error) {
var data []byte
var err error
if src.URL != "" {
- params := util.HTTPRequestParams{URL: src.URL}
- data, err = util.DownloadInMemory(params)
+ if devfileUtilsClient == nil {
+ devfileUtilsClient = parserUtil.NewDevfileUtilsClient()
+ }
+
+ params := util.HTTPRequestParams{URL: src.URL, Token: src.Token}
+ data, err = devfileUtilsClient.DownloadInMemory(params)
if err != nil {
return nil, errors.Wrapf(err, "failed to download file %q", src.URL)
}
@@ -124,7 +133,7 @@ func ParseKubernetesYaml(values []interface{}) (KubernetesResources, error) {
var kubernetesMap map[string]interface{}
err = k8yaml.Unmarshal(byteData, &kubernetesMap)
if err != nil {
- return KubernetesResources{}, err
+ return KubernetesResources{}, &errPkg.NonCompliantDevfile{Err: err.Error()}
}
kind := kubernetesMap["kind"]
@@ -147,7 +156,7 @@ func ParseKubernetesYaml(values []interface{}) (KubernetesResources, error) {
}
if err != nil {
- return KubernetesResources{}, err
+ return KubernetesResources{}, &errPkg.NonCompliantDevfile{Err: err.Error()}
}
}
diff --git a/pkg/devfile/parser/reader_test.go b/pkg/devfile/parser/reader_test.go
index 508b0e58..f648e04b 100644
--- a/pkg/devfile/parser/reader_test.go
+++ b/pkg/devfile/parser/reader_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import (
"reflect"
"testing"
+ parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util"
"github.com/devfile/library/v2/pkg/util"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
@@ -68,10 +69,13 @@ func TestReadAndParseKubernetesYaml(t *testing.T) {
badData := append(data, 59)
+ devfileUtilsClient := parserUtil.NewDevfileUtilsClient()
+
tests := []struct {
name string
src YamlSrc
fs *afero.Afero
+ devfileUtilsClient parserUtil.DevfileUtils
testParseYamlOnly bool
wantErr bool
wantParserErr bool
@@ -87,6 +91,20 @@ func TestReadAndParseKubernetesYaml(t *testing.T) {
URL: "http://" + serverIP,
},
fs: nil,
+ devfileUtilsClient: devfileUtilsClient,
+ wantDeploymentNames: []string{"deploy-sample", "deploy-sample-2"},
+ wantServiceNames: []string{"service-sample", "service-sample-2"},
+ wantRouteNames: []string{"route-sample", "route-sample-2"},
+ wantIngressNames: []string{"ingress-sample", "ingress-sample-2"},
+ wantOtherNames: []string{"pvc-sample", "pvc-sample-2"},
+ },
+ {
+ name: "Read the YAML from the URL with no devfile utility client",
+ src: YamlSrc{
+ URL: "http://" + serverIP,
+ },
+ fs: nil,
+ devfileUtilsClient: nil,
wantDeploymentNames: []string{"deploy-sample", "deploy-sample-2"},
wantServiceNames: []string{"service-sample", "service-sample-2"},
wantRouteNames: []string{"route-sample", "route-sample-2"},
@@ -99,6 +117,7 @@ func TestReadAndParseKubernetesYaml(t *testing.T) {
Path: "../../../tests/yamls/resources.yaml",
},
fs: &fs,
+ devfileUtilsClient: devfileUtilsClient,
wantDeploymentNames: []string{"deploy-sample", "deploy-sample-2"},
wantServiceNames: []string{"service-sample", "service-sample-2"},
wantRouteNames: []string{"route-sample", "route-sample-2"},
@@ -110,16 +129,18 @@ func TestReadAndParseKubernetesYaml(t *testing.T) {
src: YamlSrc{
Path: "../../../tests/yamls/resources.yaml",
},
- fs: nil,
- wantErr: true,
+ fs: nil,
+ devfileUtilsClient: devfileUtilsClient,
+ wantErr: true,
},
{
name: "Bad Path",
src: YamlSrc{
Path: "$%^&",
},
- fs: &fs,
- wantErr: true,
+ fs: &fs,
+ devfileUtilsClient: devfileUtilsClient,
+ wantErr: true,
},
{
name: "Read the YAML from the Data",
@@ -127,6 +148,7 @@ func TestReadAndParseKubernetesYaml(t *testing.T) {
Data: data,
},
fs: nil,
+ devfileUtilsClient: devfileUtilsClient,
wantDeploymentNames: []string{"deploy-sample", "deploy-sample-2"},
wantServiceNames: []string{"service-sample", "service-sample-2"},
wantRouteNames: []string{"route-sample", "route-sample-2"},
@@ -138,39 +160,80 @@ func TestReadAndParseKubernetesYaml(t *testing.T) {
src: YamlSrc{
URL: "http://badurl",
},
- fs: nil,
- wantErr: true,
+ fs: nil,
+ devfileUtilsClient: devfileUtilsClient,
+ wantErr: true,
},
{
name: "Bad Path",
src: YamlSrc{
Path: "$%^&",
},
- fs: &fs,
- wantErr: true,
+ fs: &fs,
+ devfileUtilsClient: devfileUtilsClient,
+ wantErr: true,
},
{
name: "Bad Data",
src: YamlSrc{
Data: badData,
},
- fs: nil,
- wantErr: true,
+ fs: nil,
+ devfileUtilsClient: devfileUtilsClient,
+ wantErr: true,
},
{
name: "Invalid kube yaml Data",
src: YamlSrc{
Data: []byte("invalidyaml"),
},
- fs: nil,
- testParseYamlOnly: true,
- wantParserErr: true,
+ fs: nil,
+ devfileUtilsClient: devfileUtilsClient,
+ testParseYamlOnly: true,
+ wantParserErr: true,
+ },
+ {
+ name: "Read the YAML from the URL with mock client",
+ src: YamlSrc{
+ URL: "http://" + serverIP,
+ },
+ fs: nil,
+ devfileUtilsClient: &parserUtil.MockDevfileUtilsClient{DownloadOptions: util.MockDownloadOptions{MockFile: string(data)}, MockGitURL: util.MockGitUrl{Host: "http://github.com"}},
+ wantDeploymentNames: []string{"deploy-sample", "deploy-sample-2"},
+ wantServiceNames: []string{"service-sample", "service-sample-2"},
+ wantRouteNames: []string{"route-sample", "route-sample-2"},
+ wantIngressNames: []string{"ingress-sample", "ingress-sample-2"},
+ wantOtherNames: []string{"pvc-sample", "pvc-sample-2"},
+ },
+ {
+ name: "Read the YAML from the URL with mock client and mock token",
+ src: YamlSrc{
+ URL: "http://" + serverIP,
+ Token: "valid-token",
+ },
+ fs: nil,
+ devfileUtilsClient: &parserUtil.MockDevfileUtilsClient{DownloadOptions: util.MockDownloadOptions{MockFile: string(data)}, MockGitURL: util.MockGitUrl{Host: "http://github.com"}, GitTestToken: "valid-token"},
+ wantDeploymentNames: []string{"deploy-sample", "deploy-sample-2"},
+ wantServiceNames: []string{"service-sample", "service-sample-2"},
+ wantRouteNames: []string{"route-sample", "route-sample-2"},
+ wantIngressNames: []string{"ingress-sample", "ingress-sample-2"},
+ wantOtherNames: []string{"pvc-sample", "pvc-sample-2"},
+ },
+ {
+ name: "Bad token with mock client",
+ src: YamlSrc{
+ URL: "http://badurl",
+ Token: "invalid-token",
+ },
+ fs: nil,
+ devfileUtilsClient: &parserUtil.MockDevfileUtilsClient{DownloadOptions: util.MockDownloadOptions{MockFile: string(data)}, MockGitURL: util.MockGitUrl{Host: "http://github.com"}, GitTestToken: "invalid-token"},
+ wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- values, err := ReadKubernetesYaml(tt.src, tt.fs)
+ values, err := ReadKubernetesYaml(tt.src, tt.fs, tt.devfileUtilsClient)
if (err != nil) != tt.wantErr {
t.Errorf("unexpected error: %v, wantErr: %v", err, tt.wantErr)
return
diff --git a/pkg/devfile/parser/resolutionContext.go b/pkg/devfile/parser/resolutionContext.go
index 799ecd64..37026599 100644
--- a/pkg/devfile/parser/resolutionContext.go
+++ b/pkg/devfile/parser/resolutionContext.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/sourceAttribute.go b/pkg/devfile/parser/sourceAttribute.go
index d7365590..8009a47a 100644
--- a/pkg/devfile/parser/sourceAttribute.go
+++ b/pkg/devfile/parser/sourceAttribute.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/devfile/parser/sourceAttribute_test.go b/pkg/devfile/parser/sourceAttribute_test.go
index d997ab9a..8913896f 100644
--- a/pkg/devfile/parser/sourceAttribute_test.go
+++ b/pkg/devfile/parser/sourceAttribute_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,12 +16,13 @@
package parser
import (
+ "reflect"
+ "testing"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/api/v2/pkg/attributes"
"github.com/kylelemons/godebug/pretty"
"github.com/stretchr/testify/assert"
- "reflect"
- "testing"
)
func TestAddSourceAttributesForOverrideAndMerge(t *testing.T) {
diff --git a/pkg/devfile/parser/util/interface.go b/pkg/devfile/parser/util/interface.go
new file mode 100644
index 00000000..de28948e
--- /dev/null
+++ b/pkg/devfile/parser/util/interface.go
@@ -0,0 +1,23 @@
+//
+// Copyright Red Hat
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package util
+
+import "github.com/devfile/library/v2/pkg/util"
+
+type DevfileUtils interface {
+ DownloadGitRepoResources(url string, destDir string, token string) error
+ DownloadInMemory(params util.HTTPRequestParams) ([]byte, error)
+}
diff --git a/pkg/devfile/parser/util/mock.go b/pkg/devfile/parser/util/mock.go
new file mode 100644
index 00000000..f0eff2ff
--- /dev/null
+++ b/pkg/devfile/parser/util/mock.go
@@ -0,0 +1,147 @@
+//
+// Copyright Red Hat
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package util
+
+import (
+ "fmt"
+ "net/http"
+ "os"
+
+ "github.com/devfile/library/v2/pkg/util"
+)
+
+// Default filenames for create devfile to be used in mocks
+const (
+ OutputDevfileYamlPath = "devfile.yaml"
+)
+
+type MockDevfileUtilsClient struct {
+ // Specify a valid git URL as an alias if using a localhost HTTP server in order to pass validation.
+ ParentURLAlias string
+
+ // MockGitUrl struct for mocking git related ops
+ MockGitURL util.MockGitUrl
+
+ // Mock Git token. Specify the string "valid-token" for the mock CloneGitRepo to pass
+ GitTestToken string
+
+ // Options to specify what file download needs to be mocked
+ DownloadOptions util.MockDownloadOptions
+}
+
+func NewMockDevfileUtilsClient() MockDevfileUtilsClient {
+ return MockDevfileUtilsClient{}
+}
+
+func (gc *MockDevfileUtilsClient) DownloadInMemory(params util.HTTPRequestParams) ([]byte, error) {
+ var httpClient = &http.Client{Transport: &http.Transport{
+ ResponseHeaderTimeout: util.HTTPRequestResponseTimeout,
+ }, Timeout: util.HTTPRequestResponseTimeout}
+
+ if gc.MockGitURL.Host != "" {
+ if util.IsGitProviderRepo(gc.MockGitURL.Host) {
+ gc.MockGitURL.Token = gc.GitTestToken
+ }
+ } else if params.URL != "" {
+ // Not all clients have the ability to pass in mock data
+ // So we should be adaptable and use the function params
+ // and mock the output
+ if util.IsGitProviderRepo(params.URL) {
+ gc.MockGitURL.Host = params.URL
+ gc.MockGitURL.Token = params.Token
+ }
+ }
+
+ if gc.DownloadOptions.MockParent == nil {
+ gc.DownloadOptions.MockParent = &util.MockParent{}
+ }
+
+ file, err := gc.MockGitURL.DownloadInMemoryWithClient(params, httpClient, gc.DownloadOptions)
+
+ if gc.DownloadOptions.MockParent != nil && gc.DownloadOptions.MockParent.IsMainDevfileDownloaded && gc.DownloadOptions.MockParent.IsParentDevfileDownloaded {
+ // Since gc is a pointer, if both the main and parent devfiles are downloaded, reset the flag.
+ // So that other tests can use the Mock Parent Devfile download if required.
+ gc.DownloadOptions.MockParent.IsMainDevfileDownloaded = false
+ gc.DownloadOptions.MockParent.IsParentDevfileDownloaded = false
+ }
+
+ if gc.MockGitURL.Host != "" && params.URL != "" {
+ // Since gc is a pointer, reset the mock data if both the URL and Host are present
+ gc.MockGitURL.Host = ""
+ gc.MockGitURL.Token = ""
+ }
+
+ return file, err
+}
+
+func (gc MockDevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
+
+ // if mock data is unavailable as certain clients cant provide mock data
+ // then adapt and create mock data from actual params
+ if gc.ParentURLAlias == "" {
+ gc.ParentURLAlias = url
+ gc.MockGitURL.IsFile = true
+ gc.MockGitURL.Revision = "main"
+ gc.MockGitURL.Path = OutputDevfileYamlPath
+ gc.MockGitURL.Host = "github.com"
+ gc.MockGitURL.Protocol = "https"
+ gc.MockGitURL.Owner = "devfile"
+ gc.MockGitURL.Repo = "library"
+ }
+
+ if gc.GitTestToken == "" {
+ gc.GitTestToken = token
+ }
+
+ //the url parameter that gets passed in will be the localhost IP of the test server, so it will fail all the validation checks. We will use the global testURL variable instead
+ //skip the Git Provider check since it'll fail
+ if util.IsGitProviderRepo(gc.ParentURLAlias) {
+ // this converts the test git URL to a mock URL
+ mockGitUrl := gc.MockGitURL
+ mockGitUrl.Token = gc.GitTestToken
+
+ if !mockGitUrl.IsFile || mockGitUrl.Revision == "" || !ValidateDevfileExistence((mockGitUrl.Path)) {
+ return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url+"/"+mockGitUrl.Path)
+ }
+
+ stackDir, err := os.MkdirTemp("", "git-resources")
+ if err != nil {
+ return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
+ }
+
+ defer func(path string) {
+ err = os.RemoveAll(path)
+ if err != nil {
+ err = fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
+ }
+ }(stackDir)
+
+ err = mockGitUrl.CloneGitRepo(stackDir)
+ if err != nil {
+ return err
+ }
+
+ err = util.CopyAllDirFiles(stackDir, destDir)
+ if err != nil {
+ return err
+ }
+
+ } else {
+ return fmt.Errorf("failed to download resources from parent devfile. Unsupported Git Provider for %s ", gc.ParentURLAlias)
+ }
+
+ return nil
+}
diff --git a/pkg/devfile/parser/util/utils.go b/pkg/devfile/parser/util/utils.go
new file mode 100644
index 00000000..af840d86
--- /dev/null
+++ b/pkg/devfile/parser/util/utils.go
@@ -0,0 +1,98 @@
+//
+// Copyright Red Hat
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package util
+
+import (
+ "fmt"
+ "os"
+ "path"
+ "strings"
+
+ "github.com/devfile/library/v2/pkg/util"
+ "github.com/hashicorp/go-multierror"
+)
+
+// Contains common naming conventions for devfiles to look for when downloading resources
+var DevfilePossibilities = [...]string{"devfile.yaml", ".devfile.yaml", "devfile.yml", ".devfile.yml"}
+
+type DevfileUtilsClient struct {
+}
+
+func NewDevfileUtilsClient() DevfileUtilsClient {
+ return DevfileUtilsClient{}
+}
+
+// DownloadInMemory is a wrapper to the util.DownloadInMemory() call.
+// This is done to help devfile/library clients invoke this function with a client.
+func (c DevfileUtilsClient) DownloadInMemory(params util.HTTPRequestParams) ([]byte, error) {
+ return util.DownloadInMemory(params)
+}
+
+// DownloadGitRepoResources downloads the git repository resources
+func (c DevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
+ var returnedErr error
+ if util.IsGitProviderRepo(url) {
+ gitUrl, err := util.NewGitURL(url, token)
+ if err != nil {
+ return err
+ }
+
+ if !gitUrl.IsFile || gitUrl.Revision == "" || !ValidateDevfileExistence((gitUrl.Path)) {
+ return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url)
+ }
+
+ stackDir, err := os.MkdirTemp("", "git-resources")
+ if err != nil {
+ return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
+ }
+
+ defer func(path string) {
+ err := os.RemoveAll(path)
+ if err != nil {
+ returnedErr = multierror.Append(returnedErr, err)
+ }
+ }(stackDir)
+
+ gitUrl.Token = token
+
+ err = gitUrl.CloneGitRepo(stackDir)
+ if err != nil {
+ returnedErr = multierror.Append(returnedErr, err)
+ return returnedErr
+ }
+
+ dir := path.Dir(path.Join(stackDir, gitUrl.Path))
+ err = util.CopyAllDirFiles(dir, destDir)
+ if err != nil {
+ returnedErr = multierror.Append(returnedErr, err)
+ return returnedErr
+ }
+ } else {
+ return fmt.Errorf("failed to download resources from parent devfile. Unsupported Git Provider for %s ", url)
+ }
+
+ return nil
+}
+
+// ValidateDevfileExistence verifies if any of the naming possibilities for devfile are present in the url path
+func ValidateDevfileExistence(path string) bool {
+ for _, devfile := range DevfilePossibilities {
+ if strings.Contains(path, devfile) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/pkg/devfile/parser/util/utils_test.go b/pkg/devfile/parser/util/utils_test.go
new file mode 100644
index 00000000..e188ea9b
--- /dev/null
+++ b/pkg/devfile/parser/util/utils_test.go
@@ -0,0 +1,197 @@
+//
+// Copyright Red Hat
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package util
+
+import (
+ "fmt"
+ "net/http"
+ "net/http/httptest"
+ "reflect"
+ "testing"
+
+ "github.com/devfile/library/v2/pkg/util"
+ "github.com/kylelemons/godebug/pretty"
+ "github.com/stretchr/testify/assert"
+)
+
+const (
+ RawGitHubHost string = "raw.githubusercontent.com"
+)
+
+func TestDownloadInMemoryClient(t *testing.T) {
+ const downloadErr = "failed to retrieve %s, 404: Not Found"
+ // Start a local HTTP server
+ server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+ // Send response to be tested
+ _, err := rw.Write([]byte("OK"))
+ if err != nil {
+ t.Error(err)
+ }
+ }))
+
+ // Close the server when test finishes
+ defer server.Close()
+
+ devfileUtilsClient := NewDevfileUtilsClient()
+
+ tests := []struct {
+ name string
+ url string
+ token string
+ client DevfileUtils
+ want []byte
+ wantParent []byte
+ wantErr string
+ }{
+ {
+ name: "Case 1: Input url is valid",
+ client: devfileUtilsClient,
+ url: server.URL,
+ want: []byte{79, 75},
+ },
+ {
+ name: "Case 2: Input url is invalid",
+ client: devfileUtilsClient,
+ url: "invalid",
+ wantErr: "unsupported protocol scheme",
+ },
+ {
+ name: "Case 3: Git provider with invalid url",
+ client: devfileUtilsClient,
+ url: "github.com/mike-hoang/invalid-repo",
+ token: "",
+ want: []byte(nil),
+ wantErr: "failed to parse git repo. error:*",
+ },
+ {
+ name: "Case 4: Public Github repo with missing blob",
+ client: devfileUtilsClient,
+ url: "https://github.com/devfile/library/main/README.md",
+ wantErr: "failed to parse git repo. error: url path to directory or file should contain 'tree' or 'blob'*",
+ },
+ {
+ name: "Case 5: Public Github repo, with invalid token ",
+ client: devfileUtilsClient,
+ url: "https://github.com/devfile/library/blob/main/devfile.yaml",
+ token: "fake-token",
+ wantErr: fmt.Sprintf(downloadErr, "https://"+RawGitHubHost+"/devfile/library/main/devfile.yaml"),
+ },
+ {
+ name: "Case 6: Input url is valid with a mock client, dont use mock data during invocation",
+ client: &MockDevfileUtilsClient{},
+ url: server.URL,
+ want: []byte{79, 75},
+ },
+ {
+ name: "Case 7: Input url is valid with a mock client and mock token",
+ client: &MockDevfileUtilsClient{MockGitURL: util.MockGitUrl{Host: "https://github.com/devfile/library/blob/main/devfile.yaml"}, GitTestToken: "valid-token", DownloadOptions: util.MockDownloadOptions{MockFile: "OK"}},
+ url: "https://github.com/devfile/library/blob/main/devfile.yaml",
+ want: []byte{79, 75},
+ },
+ {
+ name: "Case 8: Public Github repo, with invalid token ",
+ client: &MockDevfileUtilsClient{MockGitURL: util.MockGitUrl{Host: "https://github.com/devfile/library/blob/main/devfile.yaml"}, GitTestToken: "invalid-token"},
+ url: "https://github.com/devfile/library/blob/main/devfile.yaml",
+ wantErr: "failed to retrieve https://github.com/devfile/library/blob/main/devfile.yaml",
+ },
+ {
+ name: "Case 9: Input github url is valid with a mock client, dont use mock data during invocation",
+ client: &MockDevfileUtilsClient{},
+ url: "https://raw.githubusercontent.com/maysunfaisal/OK/main/OK.txt",
+ want: []byte{79, 75},
+ },
+ {
+ name: "Case 10: Test devfile with private parent",
+ client: &MockDevfileUtilsClient{},
+ url: "https://github.com/devfile/library/blob/main/devfile.yaml",
+ token: "parent-devfile",
+ want: []byte(util.MockDevfileWithParentRef),
+ wantParent: []byte(util.MockParentDevfile),
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ data, err := tt.client.DownloadInMemory(util.HTTPRequestParams{URL: tt.url, Token: tt.token})
+ if (err != nil) != (tt.wantErr != "") {
+ t.Errorf("Failed to download file with error: %s", err)
+ } else if err == nil && !reflect.DeepEqual(data, tt.want) {
+ t.Errorf("Expected: %v, received: %v, difference at %v", string(tt.want), string(data[:]), pretty.Compare(tt.want, data))
+ } else if err != nil {
+ assert.Regexp(t, tt.wantErr, err.Error(), "Error message should match")
+ }
+
+ if len(tt.wantParent) > 0 {
+ data, err := tt.client.DownloadInMemory(util.HTTPRequestParams{URL: tt.url, Token: tt.token})
+ if (err != nil) != (tt.wantErr != "") {
+ t.Errorf("Failed to download file with error: %s", err)
+ } else if err == nil && !reflect.DeepEqual(data, tt.wantParent) {
+ t.Errorf("Expected: %v, received: %v, difference at %v", string(tt.wantParent), string(data[:]), pretty.Compare(tt.wantParent, data))
+ } else if err != nil {
+ assert.Regexp(t, tt.wantErr, err.Error(), "Error message should match")
+ }
+ }
+ })
+ }
+}
+
+func TestValidateDevfileExistence(t *testing.T) {
+
+ tests := []struct {
+ name string
+ url string
+ wantErr bool
+ expectedValue bool
+ }{
+ {
+ name: "recognizes devfile.yaml",
+ url: "https://dummyurlpath/devfile/registry/main/stacks/python/3.0.0/devfile.yaml",
+ wantErr: false,
+ expectedValue: true,
+ },
+ {
+ name: "recognizes devfile.yml",
+ url: "https://dummyurlpath/devfile/registry/main/stacks/python/3.0.0/devfile.yml",
+ wantErr: false,
+ expectedValue: true,
+ },
+ {
+ name: "recognizes .devfile.yaml",
+ url: "https://dummyurlpath/devfile/registry/main/stacks/python/3.0.0/.devfile.yaml",
+ wantErr: false,
+ expectedValue: true,
+ },
+ {
+ name: "recognizes .devfile.yml",
+ url: "https://dummyurlpath/devfile/registry/main/stacks/python/3.0.0/.devfile.yml",
+ wantErr: false,
+ expectedValue: true,
+ },
+ {
+ name: "no valid devfile in path",
+ url: "https://dummyurlpath/devfile/registry/main/stacks/python/3.0.0/deploy.yaml",
+ wantErr: true,
+ expectedValue: false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ res := ValidateDevfileExistence(tt.url)
+ assert.EqualValues(t, tt.expectedValue, res, "expected res = %t, got %t", tt.expectedValue, res)
+ })
+ }
+}
diff --git a/pkg/devfile/parser/utils.go b/pkg/devfile/parser/utils.go
index 477e3903..57a6cd2b 100644
--- a/pkg/devfile/parser/utils.go
+++ b/pkg/devfile/parser/utils.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,75 +17,13 @@ package parser
import (
"fmt"
- "github.com/devfile/library/v2/pkg/util"
- "github.com/hashicorp/go-multierror"
- "os"
- "path"
"reflect"
- "strings"
devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/library/v2/pkg/devfile/parser/data"
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
)
-type DevfileUtilsClient struct {
-}
-
-func NewDevfileUtilsClient() DevfileUtilsClient {
- return DevfileUtilsClient{}
-}
-
-type DevfileUtils interface {
- DownloadGitRepoResources(url string, destDir string, token string) error
-}
-
-// DownloadGitRepoResources mock implementation of the real method.
-func (gc DevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
- var returnedErr error
- if util.IsGitProviderRepo(url) {
- gitUrl, err := util.NewGitURL(url, token)
- if err != nil {
- return err
- }
-
- if !gitUrl.IsFile || gitUrl.Revision == "" || !strings.Contains(gitUrl.Path, OutputDevfileYamlPath) {
- return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url)
- }
-
- stackDir, err := os.MkdirTemp("", fmt.Sprintf("git-resources"))
- if err != nil {
- return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
- }
-
- defer func(path string) {
- err := os.RemoveAll(path)
- if err != nil {
- returnedErr = multierror.Append(returnedErr, err)
- }
- }(stackDir)
-
- gitUrl.Token = token
-
- err = gitUrl.CloneGitRepo(stackDir)
- if err != nil {
- returnedErr = multierror.Append(returnedErr, err)
- return returnedErr
- }
-
- dir := path.Dir(path.Join(stackDir, gitUrl.Path))
- err = util.CopyAllDirFiles(dir, destDir)
- if err != nil {
- returnedErr = multierror.Append(returnedErr, err)
- return returnedErr
- }
- } else {
- return fmt.Errorf("Failed to download resources from parent devfile. Unsupported Git Provider for %s ", url)
- }
-
- return nil
-}
-
// GetDeployComponents gets the default deploy command associated components
func GetDeployComponents(devfileData data.DevfileData) (map[string]string, error) {
deployCommandFilter := common.DevfileOptions{
diff --git a/pkg/devfile/parser/utils_test.go b/pkg/devfile/parser/utils_test.go
index 56c7ea58..4895ee01 100644
--- a/pkg/devfile/parser/utils_test.go
+++ b/pkg/devfile/parser/utils_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -192,11 +192,7 @@ func TestGetDeployComponents(t *testing.T) {
mockApplyCommands.Return(nil, fmt.Errorf(*tt.wantMockErr2))
}
- devObj := DevfileObj{
- Data: mockDevfileData,
- }
-
- componentMap, err := GetDeployComponents(devObj.Data)
+ componentMap, err := GetDeployComponents(mockDevfileData)
// Unexpected error
if (err != nil) != (tt.wantErr != nil) {
t.Errorf("TestGetDeployComponents() error: %v, wantErr %v", err, tt.wantErr)
@@ -368,11 +364,7 @@ func TestGetImageBuildComponent(t *testing.T) {
mockGetComponents.Return(nil, fmt.Errorf(*tt.wantMockErr))
}
- devObj := DevfileObj{
- Data: mockDevfileData,
- }
-
- component, err := GetImageBuildComponent(devObj.Data, tt.deployAssociatedComponents)
+ component, err := GetImageBuildComponent(mockDevfileData, tt.deployAssociatedComponents)
// Unexpected error
if (err != nil) != (tt.wantErr != nil) {
t.Errorf("TestGetImageBuildComponent() error: %v, wantErr %v", err, tt.wantErr)
diff --git a/pkg/devfile/parser/writer.go b/pkg/devfile/parser/writer.go
index ed3f2870..948130a8 100644
--- a/pkg/devfile/parser/writer.go
+++ b/pkg/devfile/parser/writer.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import (
"k8s.io/klog"
)
-// WriteYamlDevfile creates a devfile.yaml file
+// WriteYamlDevfile writes the content of the Devfile data to its absolute path on the filesystem.
func (d *DevfileObj) WriteYamlDevfile() error {
// Check kubernetes components, and restore original uri content
@@ -41,7 +41,7 @@ func (d *DevfileObj) WriteYamlDevfile() error {
if err != nil {
return errors.Wrapf(err, "failed to marshal devfile object into yaml")
}
- // Write to devfile.yaml
+ // Write to the absolute path
fs := d.Ctx.GetFs()
if fs == nil {
fs = filesystem.DefaultFs{}
@@ -52,7 +52,7 @@ func (d *DevfileObj) WriteYamlDevfile() error {
}
// Successful
- klog.V(2).Infof("devfile yaml created at: '%s'", OutputDevfileYamlPath)
+ klog.V(2).Infof("devfile written to: '%s'", d.Ctx.GetAbsPath())
return nil
}
diff --git a/pkg/devfile/parser/writer_test.go b/pkg/devfile/parser/writer_test.go
index db50c8ec..d8e5710a 100644
--- a/pkg/devfile/parser/writer_test.go
+++ b/pkg/devfile/parser/writer_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,67 +17,96 @@ package parser
import (
"fmt"
+ "strings"
+ "testing"
+
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
apiAttributes "github.com/devfile/api/v2/pkg/attributes"
devfilepkg "github.com/devfile/api/v2/pkg/devfile"
devfileCtx "github.com/devfile/library/v2/pkg/devfile/parser/context"
v2 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2"
"github.com/devfile/library/v2/pkg/testingutil/filesystem"
- "strings"
- "testing"
)
-func TestWriteYamlDevfile(t *testing.T) {
+func TestDevfileObj_WriteYamlDevfile(t *testing.T) {
var (
schemaVersion = "2.2.0"
- testName = "TestName"
uri = "./relative/path/deploy.yaml"
uri2 = "./relative/path/deploy2.yaml"
- attributes = apiAttributes.Attributes{}.PutString(K8sLikeComponentOriginalURIKey, uri)
- attributes2 = apiAttributes.Attributes{}.PutString(K8sLikeComponentOriginalURIKey, uri2)
)
- t.Run("write yaml devfile", func(t *testing.T) {
-
- // Use fakeFs
- fs := filesystem.NewFakeFs()
+ tests := []struct {
+ name string
+ fileName string
+ wantErr bool
+ }{
+ {
+ name: "write devfile with .yaml extension",
+ fileName: OutputDevfileYamlPath,
+ },
+ {
+ name: "write .devfile with .yaml extension",
+ fileName: ".devfile.yaml",
+ },
+ {
+ name: "write devfile with .yml extension",
+ fileName: "devfile.yml",
+ },
+ {
+ name: "write .devfile with .yml extension",
+ fileName: ".devfile.yml",
+ },
+ {
+ name: "write any file, regardless of name and extension",
+ fileName: "some-random-file",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ var (
+ // Use fakeFs
+ fs = filesystem.NewFakeFs()
+ attributes = apiAttributes.Attributes{}.PutString(K8sLikeComponentOriginalURIKey, uri)
+ attributes2 = apiAttributes.Attributes{}.PutString(K8sLikeComponentOriginalURIKey, uri2)
+ )
- // DevfileObj
- devfileObj := DevfileObj{
- Ctx: devfileCtx.FakeContext(fs, OutputDevfileYamlPath),
- Data: &v2.DevfileV2{
- Devfile: v1.Devfile{
- DevfileHeader: devfilepkg.DevfileHeader{
- SchemaVersion: schemaVersion,
- Metadata: devfilepkg.DevfileMetadata{
- Name: testName,
+ // DevfileObj
+ devfileObj := DevfileObj{
+ Ctx: devfileCtx.FakeContext(fs, tt.fileName),
+ Data: &v2.DevfileV2{
+ Devfile: v1.Devfile{
+ DevfileHeader: devfilepkg.DevfileHeader{
+ SchemaVersion: schemaVersion,
+ Metadata: devfilepkg.DevfileMetadata{
+ Name: tt.name,
+ },
},
- },
- DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{
- DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{
- Components: []v1.Component{
- {
- Name: "kubeComp",
- Attributes: attributes,
- ComponentUnion: v1.ComponentUnion{
- Kubernetes: &v1.KubernetesComponent{
- K8sLikeComponent: v1.K8sLikeComponent{
- K8sLikeComponentLocation: v1.K8sLikeComponentLocation{
- Inlined: "placeholder",
+ DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{
+ DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{
+ Components: []v1.Component{
+ {
+ Name: "kubeComp",
+ Attributes: attributes,
+ ComponentUnion: v1.ComponentUnion{
+ Kubernetes: &v1.KubernetesComponent{
+ K8sLikeComponent: v1.K8sLikeComponent{
+ K8sLikeComponentLocation: v1.K8sLikeComponentLocation{
+ Inlined: "placeholder",
+ },
},
},
},
},
- },
- {
- Name: "openshiftComp",
- Attributes: attributes2,
- ComponentUnion: v1.ComponentUnion{
- Openshift: &v1.OpenshiftComponent{
- K8sLikeComponent: v1.K8sLikeComponent{
- K8sLikeComponentLocation: v1.K8sLikeComponentLocation{
- Inlined: "placeholder",
+ {
+ Name: "openshiftComp",
+ Attributes: attributes2,
+ ComponentUnion: v1.ComponentUnion{
+ Openshift: &v1.OpenshiftComponent{
+ K8sLikeComponent: v1.K8sLikeComponent{
+ K8sLikeComponentLocation: v1.K8sLikeComponentLocation{
+ Inlined: "placeholder",
+ },
},
},
},
@@ -87,24 +116,26 @@ func TestWriteYamlDevfile(t *testing.T) {
},
},
},
- },
- }
- devfileObj.Ctx.SetConvertUriToInlined(true)
+ }
+ devfileObj.Ctx.SetConvertUriToInlined(true)
- // test func()
- err := devfileObj.WriteYamlDevfile()
- if err != nil {
- t.Errorf("TestWriteYamlDevfile() unexpected error: '%v'", err)
- }
+ // test func()
+ err := devfileObj.WriteYamlDevfile()
+ if (err != nil) != tt.wantErr {
+ t.Errorf("TestWriteYamlDevfile() unexpected error: '%v', wantErr=%v", err, tt.wantErr)
+ return
+ }
- if _, err := fs.Stat(OutputDevfileYamlPath); err != nil {
- t.Errorf("TestWriteYamlDevfile() unexpected error: '%v'", err)
- }
+ if _, err := fs.Stat(tt.fileName); err != nil {
+ t.Errorf("TestWriteYamlDevfile() unexpected error: '%v'", err)
+ }
+
+ data, err := fs.ReadFile(tt.fileName)
+ if err != nil {
+ t.Errorf("TestWriteYamlDevfile() unexpected error: '%v'", err)
+ return
+ }
- data, err := fs.ReadFile(OutputDevfileYamlPath)
- if err != nil {
- t.Errorf("TestWriteYamlDevfile() unexpected error: '%v'", err)
- } else {
content := string(data)
if strings.Contains(content, "inlined") || strings.Contains(content, K8sLikeComponentOriginalURIKey) {
t.Errorf("TestWriteYamlDevfile() failed: kubernetes component should not contain inlined or %s", K8sLikeComponentOriginalURIKey)
@@ -115,6 +146,6 @@ func TestWriteYamlDevfile(t *testing.T) {
if !strings.Contains(content, fmt.Sprintf("uri: %s", uri2)) {
t.Errorf("TestWriteYamlDevfile() failed: openshift component does not contain uri")
}
- }
- })
+ })
+ }
}
diff --git a/pkg/devfile/testdata/.devfile.yaml b/pkg/devfile/testdata/.devfile.yaml
new file mode 100644
index 00000000..927dff87
--- /dev/null
+++ b/pkg/devfile/testdata/.devfile.yaml
@@ -0,0 +1,35 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ endpoints:
+ - name: http
+ targetPort: 8080
+ image: golang:latest
+ memoryLimit: 1024Mi
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Stack with the latest Go version
+ displayName: Go Runtime (.devfile.yaml)
+ icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg
+ language: go
+ name: my-go-app
+ projectType: go
+ tags:
+ - Go
+ version: 1.0.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/testdata/.devfile.yml b/pkg/devfile/testdata/.devfile.yml
new file mode 100644
index 00000000..3625c0b8
--- /dev/null
+++ b/pkg/devfile/testdata/.devfile.yml
@@ -0,0 +1,28 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ image: busybox:latest
+ command: [tail]
+ args: [ -f, /dev/null ]
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Test stack (Busybox)
+ displayName: Test stack (.devfile.yml)
+ name: my-test-app
+ version: 0.1.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/testdata/devfile1.yaml b/pkg/devfile/testdata/devfile.yaml
similarity index 95%
rename from pkg/devfile/testdata/devfile1.yaml
rename to pkg/devfile/testdata/devfile.yaml
index 9286575b..63abe9ce 100644
--- a/pkg/devfile/testdata/devfile1.yaml
+++ b/pkg/devfile/testdata/devfile.yaml
@@ -24,7 +24,7 @@ components:
name: outerloop-deploy2
metadata:
description: Stack with the latest Go version
- displayName: Go Runtime
+ displayName: Go Runtime (devfile.yaml)
icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg
language: go
name: my-go-app
diff --git a/pkg/devfile/testdata/devfile.yml b/pkg/devfile/testdata/devfile.yml
new file mode 100644
index 00000000..23bd7e0b
--- /dev/null
+++ b/pkg/devfile/testdata/devfile.yml
@@ -0,0 +1,28 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ image: busybox:latest
+ command: [tail]
+ args: [ -f, /dev/null ]
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Test stack (Busybox)
+ displayName: Test stack (devfile.yml)
+ name: my-test-app
+ version: 0.1.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/testdata/priority-for-devfile_yml/.devfile.yml b/pkg/devfile/testdata/priority-for-devfile_yml/.devfile.yml
new file mode 100644
index 00000000..3625c0b8
--- /dev/null
+++ b/pkg/devfile/testdata/priority-for-devfile_yml/.devfile.yml
@@ -0,0 +1,28 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ image: busybox:latest
+ command: [tail]
+ args: [ -f, /dev/null ]
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Test stack (Busybox)
+ displayName: Test stack (.devfile.yml)
+ name: my-test-app
+ version: 0.1.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/testdata/priority-for-devfile_yml/devfile.yml b/pkg/devfile/testdata/priority-for-devfile_yml/devfile.yml
new file mode 100644
index 00000000..23bd7e0b
--- /dev/null
+++ b/pkg/devfile/testdata/priority-for-devfile_yml/devfile.yml
@@ -0,0 +1,28 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ image: busybox:latest
+ command: [tail]
+ args: [ -f, /dev/null ]
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Test stack (Busybox)
+ displayName: Test stack (devfile.yml)
+ name: my-test-app
+ version: 0.1.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/testdata/priority-for-dot_devfile_yaml/.devfile.yaml b/pkg/devfile/testdata/priority-for-dot_devfile_yaml/.devfile.yaml
new file mode 100644
index 00000000..927dff87
--- /dev/null
+++ b/pkg/devfile/testdata/priority-for-dot_devfile_yaml/.devfile.yaml
@@ -0,0 +1,35 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ endpoints:
+ - name: http
+ targetPort: 8080
+ image: golang:latest
+ memoryLimit: 1024Mi
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Stack with the latest Go version
+ displayName: Go Runtime (.devfile.yaml)
+ icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg
+ language: go
+ name: my-go-app
+ projectType: go
+ tags:
+ - Go
+ version: 1.0.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/testdata/priority-for-dot_devfile_yaml/.devfile.yml b/pkg/devfile/testdata/priority-for-dot_devfile_yaml/.devfile.yml
new file mode 100644
index 00000000..3625c0b8
--- /dev/null
+++ b/pkg/devfile/testdata/priority-for-dot_devfile_yaml/.devfile.yml
@@ -0,0 +1,28 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ image: busybox:latest
+ command: [tail]
+ args: [ -f, /dev/null ]
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Test stack (Busybox)
+ displayName: Test stack (.devfile.yml)
+ name: my-test-app
+ version: 0.1.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/testdata/priority-for-dot_devfile_yaml/devfile.yml b/pkg/devfile/testdata/priority-for-dot_devfile_yaml/devfile.yml
new file mode 100644
index 00000000..23bd7e0b
--- /dev/null
+++ b/pkg/devfile/testdata/priority-for-dot_devfile_yaml/devfile.yml
@@ -0,0 +1,28 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ image: busybox:latest
+ command: [tail]
+ args: [ -f, /dev/null ]
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Test stack (Busybox)
+ displayName: Test stack (devfile.yml)
+ name: my-test-app
+ version: 0.1.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/testdata/priority-for-dot_devfile_yml/.devfile.yml b/pkg/devfile/testdata/priority-for-dot_devfile_yml/.devfile.yml
new file mode 100644
index 00000000..3625c0b8
--- /dev/null
+++ b/pkg/devfile/testdata/priority-for-dot_devfile_yml/.devfile.yml
@@ -0,0 +1,28 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ image: busybox:latest
+ command: [tail]
+ args: [ -f, /dev/null ]
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Test stack (Busybox)
+ displayName: Test stack (.devfile.yml)
+ name: my-test-app
+ version: 0.1.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/testdata/valid-devfile.yaml.txt b/pkg/devfile/testdata/valid-devfile.yaml.txt
new file mode 100644
index 00000000..8cb9d9e9
--- /dev/null
+++ b/pkg/devfile/testdata/valid-devfile.yaml.txt
@@ -0,0 +1,28 @@
+commands:
+- exec:
+ commandLine: ./main {{ PARAMS }}
+ component: runtime
+ group:
+ isDefault: true
+ kind: run
+ workingDir: ${PROJECT_SOURCE}
+ id: run
+components:
+- container:
+ image: busybox:latest
+ command: [tail]
+ args: [ -f, /dev/null ]
+ mountSources: true
+ name: runtime
+- kubernetes:
+ uri: http://127.0.0.1:8080/outerloop-deploy.yaml
+ name: outerloop-deploy
+- openshift:
+ uri: http://127.0.0.1:8080/outerloop-service.yaml
+ name: outerloop-deploy2
+metadata:
+ description: Test stack (Busybox)
+ displayName: Test stack (valid-devfile.yaml.txt)
+ name: my-test-app
+ version: 0.1.0
+schemaVersion: 2.2.0
\ No newline at end of file
diff --git a/pkg/devfile/validate/validate.go b/pkg/devfile/validate/validate.go
index e40d89ab..73f63cf0 100644
--- a/pkg/devfile/validate/validate.go
+++ b/pkg/devfile/validate/validate.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package validate
import (
"fmt"
+
v2Validation "github.com/devfile/api/v2/pkg/validation"
devfileData "github.com/devfile/library/v2/pkg/devfile/parser/data"
v2 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2"
diff --git a/pkg/testingutil/containers.go b/pkg/testingutil/containers.go
index 00720ea1..d8c73bab 100644
--- a/pkg/testingutil/containers.go
+++ b/pkg/testingutil/containers.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/testingutil/devfile.go b/pkg/testingutil/devfile.go
index 46ef97fa..46b16c4e 100644
--- a/pkg/testingutil/devfile.go
+++ b/pkg/testingutil/devfile.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/testingutil/filesystem/default_fs.go b/pkg/testingutil/filesystem/default_fs.go
index 9eea63fc..155a85e3 100644
--- a/pkg/testingutil/filesystem/default_fs.go
+++ b/pkg/testingutil/filesystem/default_fs.go
@@ -22,13 +22,12 @@ limitations under the License.
package filesystem
import (
- "io/ioutil"
"os"
"path/filepath"
"time"
)
-// DefaultFs implements Filesystem using same-named functions from "os" and "io/ioutil"
+// DefaultFs implements Filesystem using same-named functions from "os"
type DefaultFs struct{}
var _ Filesystem = DefaultFs{}
@@ -97,33 +96,64 @@ func (DefaultFs) Getwd() (dir string, err error) {
return os.Getwd()
}
-// ReadFile via ioutil.ReadFile
+// ReadFile via os.ReadFile
func (DefaultFs) ReadFile(filename string) ([]byte, error) {
- return ioutil.ReadFile(filename)
+ return os.ReadFile(filename)
}
-// WriteFile via ioutil.WriteFile
+// WriteFile via os.WriteFile
func (DefaultFs) WriteFile(filename string, data []byte, perm os.FileMode) error {
- return ioutil.WriteFile(filename, data, perm)
+ return os.WriteFile(filename, data, perm)
+}
+
+// MkdirTemp via os.MkdirTemp
+func (DefaultFs) MkdirTemp(dir, prefix string) (string, error) {
+ return os.MkdirTemp(dir, prefix)
}
// TempDir via ioutil.TempDir
-func (DefaultFs) TempDir(dir, prefix string) (string, error) {
- return ioutil.TempDir(dir, prefix)
+// Deprecated: as ioutil.TempDir is deprecated TempDir is replaced by MkdirTemp which uses os.MkdirTemp.
+// TempDir now uses MkdirTemp.
+func (fs DefaultFs) TempDir(dir, prefix string) (string, error) {
+ return fs.MkdirTemp(dir, prefix)
}
-// TempFile via ioutil.TempFile
-func (DefaultFs) TempFile(dir, prefix string) (File, error) {
- file, err := ioutil.TempFile(dir, prefix)
+// CreateTemp via os.CreateTemp
+func (DefaultFs) CreateTemp(dir, prefix string) (File, error) {
+ file, err := os.CreateTemp(dir, prefix)
if err != nil {
return nil, err
}
return &defaultFile{file}, nil
}
-// ReadDir via ioutil.ReadDir
+// TempFile via ioutil.TempFile
+// Deprecated: as ioutil.TempFile is deprecated TempFile is replaced by CreateTemp which uses os.CreateTemp.
+// TempFile now uses CreateTemp.
+func (fs DefaultFs) TempFile(dir, prefix string) (File, error) {
+ return fs.CreateTemp(dir, prefix)
+}
+
+// ReadDir via os.ReadDir
func (DefaultFs) ReadDir(dirname string) ([]os.FileInfo, error) {
- return ioutil.ReadDir(dirname)
+ dirEntries, err := os.ReadDir(dirname)
+
+ if err != nil {
+ return []os.FileInfo{}, err
+ }
+
+ dirsInfo := make([]os.FileInfo, 0, len(dirEntries))
+ for _, dirEntry := range dirEntries {
+ info, err := dirEntry.Info()
+
+ if err != nil {
+ return dirsInfo, err
+ }
+
+ dirsInfo = append(dirsInfo, info)
+ }
+
+ return dirsInfo, nil
}
// Walk via filepath.Walk
diff --git a/pkg/testingutil/filesystem/filesystem.go b/pkg/testingutil/filesystem/filesystem.go
index e71b6ffc..3efb95ea 100644
--- a/pkg/testingutil/filesystem/filesystem.go
+++ b/pkg/testingutil/filesystem/filesystem.go
@@ -41,13 +41,13 @@ type Filesystem interface {
Remove(name string) error
Chmod(name string, mode os.FileMode) error
Getwd() (dir string, err error)
-
- // from "io/ioutil"
ReadFile(filename string) ([]byte, error)
WriteFile(filename string, data []byte, perm os.FileMode) error
TempDir(dir, prefix string) (string, error)
TempFile(dir, prefix string) (File, error)
ReadDir(dirname string) ([]os.FileInfo, error)
+
+ // from "filepath"
Walk(root string, walkFn filepath.WalkFunc) error
}
diff --git a/pkg/testingutil/filesystem/singleton.go b/pkg/testingutil/filesystem/singleton.go
index 1d16ade7..7c562708 100644
--- a/pkg/testingutil/filesystem/singleton.go
+++ b/pkg/testingutil/filesystem/singleton.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/testingutil/k8sClient.go b/pkg/testingutil/k8sClient.go
index 7a7ab087..809e6fce 100644
--- a/pkg/testingutil/k8sClient.go
+++ b/pkg/testingutil/k8sClient.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/testingutil/resources.go b/pkg/testingutil/resources.go
index 7e70cf9f..e0028dd7 100644
--- a/pkg/testingutil/resources.go
+++ b/pkg/testingutil/resources.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/util/git.go b/pkg/util/git.go
index f9ca6f1f..22ebf3ff 100644
--- a/pkg/util/git.go
+++ b/pkg/util/git.go
@@ -1,5 +1,5 @@
//
-// Copyright 2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/util/git_test.go b/pkg/util/git_test.go
index 634c62aa..c0369ba0 100644
--- a/pkg/util/git_test.go
+++ b/pkg/util/git_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,12 +16,13 @@
package util
import (
- "github.com/kylelemons/godebug/pretty"
- "github.com/stretchr/testify/assert"
"os"
"path/filepath"
"reflect"
"testing"
+
+ "github.com/kylelemons/godebug/pretty"
+ "github.com/stretchr/testify/assert"
)
func Test_ParseGitUrl(t *testing.T) {
diff --git a/pkg/util/httpcache.go b/pkg/util/httpcache.go
index 8efa0a94..d3dd1b8a 100644
--- a/pkg/util/httpcache.go
+++ b/pkg/util/httpcache.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package util
import (
- "io/ioutil"
"os"
"path/filepath"
"time"
@@ -26,11 +25,21 @@ import (
// cleanHttpCache checks cacheDir and deletes all files that were modified more than cacheTime back
func cleanHttpCache(cacheDir string, cacheTime time.Duration) error {
- cacheFiles, err := ioutil.ReadDir(cacheDir)
+ cacheEntries, err := os.ReadDir(cacheDir)
if err != nil {
return err
}
+ cacheFiles := make([]os.FileInfo, 0, len(cacheEntries))
+ for _, cacheEntry := range cacheEntries {
+ info, err := cacheEntry.Info()
+ if err != nil {
+ return err
+ }
+
+ cacheFiles = append(cacheFiles, info)
+ }
+
for _, f := range cacheFiles {
if f.ModTime().Add(cacheTime).Before(time.Now()) {
klog.V(4).Infof("Removing cache file %s, because it is older than %s", f.Name(), cacheTime.String())
diff --git a/pkg/util/mock.go b/pkg/util/mock.go
index bdfc4110..9a87bfde 100644
--- a/pkg/util/mock.go
+++ b/pkg/util/mock.go
@@ -1,5 +1,5 @@
//
-// Copyright 2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -33,6 +33,18 @@ type MockGitUrl struct {
IsFile bool // defines if the URL points to a file in the repo
}
+type MockDownloadOptions struct {
+ MockDevfile bool
+ MockDockerfile bool
+ MockFile string
+ MockParent *MockParent
+}
+
+type MockParent struct {
+ IsMainDevfileDownloaded bool
+ IsParentDevfileDownloaded bool
+}
+
func (m *MockGitUrl) GetToken() string {
return m.Token
}
@@ -51,6 +63,8 @@ var mockExecute = func(baseDir string, cmd CommandType, args ...string) ([]byte,
// private repository
if hasPassword {
switch password {
+ case "parent-devfile":
+ fallthrough
case "valid-token":
_, err := resourceFile.WriteString("private repo\n")
if err != nil {
@@ -130,6 +144,236 @@ func (m *MockGitUrl) CloneGitRepo(destDir string) error {
return nil
}
+var mockDevfile = `
+schemaVersion: 2.2.0
+metadata:
+ displayName: Go Mock Runtime
+ icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg
+ language: go
+ name: go
+ projectType: go
+ tags:
+ - Go
+ version: 1.0.0
+components:
+ - container:
+ image: golang:latest
+ memoryLimit: 1024Mi
+ mountSources: true
+ sourceMapping: /project
+ name: runtime
+ - name: image-build
+ image:
+ imageName: go-image:latest
+ dockerfile:
+ uri: docker/Dockerfile
+ buildContext: .
+ rootRequired: false
+ - name: kubernetes-deploy
+ kubernetes:
+ inlined: |-
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ creationTimestamp: null
+ labels:
+ test: test
+ name: deploy-sample
+ endpoints:
+ - name: http-8081
+ targetPort: 8081
+ path: /
+commands:
+ - exec:
+ commandLine: GOCACHE=/project/.cache go build main.go
+ component: runtime
+ group:
+ kind: build
+ workingDir: /project
+ id: build
+ - exec:
+ commandLine: ./main
+ component: runtime
+ group:
+ kind: run
+ workingDir: /project
+ id: run
+ - id: build-image
+ apply:
+ component: image-build
+ - id: deployk8s
+ apply:
+ component: kubernetes-deploy
+ - id: deploy
+ composite:
+ commands:
+ - build-image
+ - deployk8s
+ group:
+ kind: deploy
+ isDefault: true
+`
+
+var MockDevfileWithParentRef = `
+schemaVersion: 2.2.0
+metadata:
+ displayName: Go Mock Runtime
+ icon: https://raw.githubusercontent.com/devfile-samples/devfile-stack-icons/main/golang.svg
+ language: go
+ name: go
+ projectType: go
+ tags:
+ - Go
+ version: 1.0.0
+parent:
+ uri: https://github.com/private-url-devfile
+components:
+ - container:
+ image: golang:latest
+ memoryLimit: 1024Mi
+ mountSources: true
+ sourceMapping: /project
+ name: runtime
+ - name: image-build
+ image:
+ imageName: go-image:latest
+ dockerfile:
+ uri: docker/Dockerfile
+ buildContext: .
+ rootRequired: false
+ - name: kubernetes-deploy
+ kubernetes:
+ inlined: |-
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ creationTimestamp: null
+ labels:
+ test: test
+ name: deploy-sample
+ endpoints:
+ - name: http-8081
+ targetPort: 8081
+ path: /
+commands:
+ - exec:
+ commandLine: GOCACHE=/project/.cache go build main.go
+ component: runtime
+ group:
+ kind: build
+ workingDir: /project
+ id: build
+ - exec:
+ commandLine: ./main
+ component: runtime
+ group:
+ kind: run
+ workingDir: /project
+ id: run
+ - id: build-image
+ apply:
+ component: image-build
+ - id: deployk8s
+ apply:
+ component: kubernetes-deploy
+ - id: deploy
+ composite:
+ commands:
+ - build-image
+ - deployk8s
+ group:
+ kind: deploy
+ isDefault: true
+`
+
+var MockParentDevfile = `
+schemaVersion: 2.2.0
+metadata:
+ displayName: Go Mock Parent
+ language: go
+ name: goparent
+ projectType: go
+ tags:
+ - Go
+ version: 1.0.0
+components:
+ - container:
+ endpoints:
+ - name: http
+ targetPort: 8080
+ image: golang:latest
+ memoryLimit: 1024Mi
+ mountSources: true
+ sourceMapping: /project
+ name: runtime2
+commands:
+ - exec:
+ commandLine: GOCACHE=/project/.cache go build main.go
+ component: runtime2
+ group:
+ isDefault: true
+ kind: build
+ workingDir: /project
+ id: build2
+ - exec:
+ commandLine: ./main
+ component: runtime2
+ group:
+ isDefault: true
+ kind: run
+ workingDir: /project
+ id: run2
+`
+
+var mockDockerfile = `
+FROM python:slim
+
+WORKDIR /projects
+
+RUN python3 -m venv venv
+RUN . venv/bin/activate
+
+# optimize image caching
+COPY requirements.txt .
+RUN pip install -r requirements.txt
+
+COPY . .
+
+EXPOSE 8081
+CMD [ "waitress-serve", "--port=8081", "app:app"]
+`
+
+func (m MockGitUrl) DownloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient, options MockDownloadOptions) ([]byte, error) {
+
+ if m.GetToken() == "valid-token" {
+ switch {
+ case options.MockDevfile:
+ return []byte(mockDevfile), nil
+ case options.MockDockerfile:
+ return []byte(mockDockerfile), nil
+ case len(options.MockFile) > 0:
+ return []byte(options.MockFile), nil
+ default:
+ return []byte(mockDevfile), nil
+ }
+ } else if m.GetToken() == "parent-devfile" {
+ if options.MockParent != nil && !options.MockParent.IsMainDevfileDownloaded {
+ options.MockParent.IsMainDevfileDownloaded = true
+ return []byte(MockDevfileWithParentRef), nil
+ }
+
+ if options.MockParent != nil && !options.MockParent.IsParentDevfileDownloaded {
+ options.MockParent.IsParentDevfileDownloaded = true
+ return []byte(MockParentDevfile), nil
+ }
+ } else if m.GetToken() == "" {
+ // if no token is provided, assume normal operation
+ return DownloadInMemory(params)
+ }
+
+ return nil, fmt.Errorf("failed to retrieve %s", params.URL)
+}
+
func (m *MockGitUrl) SetToken(token string) error {
m.Token = token
return nil
diff --git a/pkg/util/util.go b/pkg/util/util.go
index 6ce8a6d6..463593ad 100644
--- a/pkg/util/util.go
+++ b/pkg/util/util.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -21,12 +21,7 @@ import (
"bytes"
"crypto/rand"
"fmt"
- gitpkg "github.com/go-git/go-git/v5"
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/gregjones/httpcache"
- "github.com/gregjones/httpcache/diskcache"
"io"
- "io/ioutil"
"math/big"
"net"
"net/http"
@@ -45,6 +40,11 @@ import (
"syscall"
"time"
+ gitpkg "github.com/go-git/go-git/v5"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/gregjones/httpcache"
+ "github.com/gregjones/httpcache/diskcache"
+
"github.com/devfile/library/v2/pkg/testingutil/filesystem"
"github.com/fatih/color"
"github.com/gobwas/glob"
@@ -819,7 +819,7 @@ func HTTPGetRequest(request HTTPRequestParams, cacheFor int) ([]byte, error) {
}
// Process http response
- bytes, err := ioutil.ReadAll(resp.Body)
+ bytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
@@ -855,7 +855,11 @@ func FilterIgnores(filesChanged, filesDeleted, absIgnoreRules []string) (filesCh
// IsValidProjectDir checks that the folder to download the project from devfile is
// either empty or only contains the devfile used.
func IsValidProjectDir(path string, devfilePath string) error {
- files, err := ioutil.ReadDir(path)
+ return isValidProjectDirOnFS(path, devfilePath, filesystem.DefaultFs{})
+}
+
+func isValidProjectDirOnFS(path string, devfilePath string, fs filesystem.Filesystem) error {
+ files, err := fs.ReadDir(path)
if err != nil {
return err
}
@@ -1090,29 +1094,31 @@ func DownloadFileInMemory(url string) ([]byte, error) {
}
defer resp.Body.Close()
- return ioutil.ReadAll(resp.Body)
+ return io.ReadAll(resp.Body)
}
-// DownloadInMemory uses HTTPRequestParams to download the file and return bytes
+// DownloadInMemory uses HTTPRequestParams to download the file and return bytes.
+// Use the pkg/devfile/parser/utils.go DownloadInMemory() invocation if you want to
+// call with a client instead.
func DownloadInMemory(params HTTPRequestParams) ([]byte, error) {
var httpClient = &http.Client{Transport: &http.Transport{
ResponseHeaderTimeout: HTTPRequestResponseTimeout,
}, Timeout: HTTPRequestResponseTimeout}
- var g GitUrl
+ var g *GitUrl
var err error
if IsGitProviderRepo(params.URL) {
- g, err = NewGitUrlWithURL(params.URL)
+ g, err = NewGitURL(params.URL, params.Token)
if err != nil {
return nil, errors.Errorf("failed to parse git repo. error: %v", err)
}
}
- return downloadInMemoryWithClient(params, httpClient, g)
+ return g.downloadInMemoryWithClient(params, httpClient)
}
-func downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient, g GitUrl) ([]byte, error) {
+func (g *GitUrl) downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient) ([]byte, error) {
var url string
url = params.URL
req, err := http.NewRequest("GET", url, nil)
@@ -1144,7 +1150,7 @@ func downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient,
}
defer resp.Body.Close()
- return ioutil.ReadAll(resp.Body)
+ return io.ReadAll(resp.Body)
}
// ValidateK8sResourceName sanitizes kubernetes resource name with the following requirements:
diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go
index 19961b0c..fe0a1785 100644
--- a/pkg/util/util_test.go
+++ b/pkg/util/util_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2021-2023 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,11 +17,6 @@ package util
import (
"fmt"
- "github.com/devfile/library/v2/pkg/testingutil/filesystem"
- "github.com/kylelemons/godebug/pretty"
- "github.com/stretchr/testify/assert"
- "io/ioutil"
- corev1 "k8s.io/api/core/v1"
"net"
"net/http"
"net/http/httptest"
@@ -33,6 +28,11 @@ import (
"runtime"
"strconv"
"testing"
+
+ "github.com/devfile/library/v2/pkg/testingutil/filesystem"
+ "github.com/kylelemons/godebug/pretty"
+ "github.com/stretchr/testify/assert"
+ corev1 "k8s.io/api/core/v1"
)
func TestNamespaceOpenShiftObject(t *testing.T) {
@@ -853,6 +853,74 @@ func TestFilterIgnores(t *testing.T) {
}
}
+func TestIsValidProjectDir(t *testing.T) {
+ const validProjectDirPath = "/projectDirs/validProjectDir"
+ const emptyProjectDirPath = "/projectDirs/emptyProjectDir"
+ const invalidProjectDirWithFiles = "/projectDirs/invalidProjectDirWithFiles"
+ const invalidProjectDirWithSubDirPath = "/projectDirs/invalidProjectDirWithSubDir"
+ fs := filesystem.NewFakeFs()
+ tests := []struct {
+ name string
+ path string
+ devfilePath string
+ isDevfilePathDir bool
+ otherFiles []string
+ wantErr bool
+ }{
+ {
+ name: "Case 1: Valid project directory",
+ path: validProjectDirPath,
+ devfilePath: "devfile.yaml",
+ },
+ {
+ name: "Case 2: Valid empty project directory",
+ path: emptyProjectDirPath,
+ },
+ {
+ name: "Case 3: Invalid project directory with files",
+ path: invalidProjectDirWithFiles,
+ devfilePath: "devfile.yaml",
+ otherFiles: []string{"package.json", "app.js"},
+ wantErr: true,
+ },
+ {
+ name: "Case 4: Invalid project directory with subdirectory",
+ path: invalidProjectDirWithSubDirPath,
+ devfilePath: "devfile",
+ isDevfilePathDir: true,
+ wantErr: true,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ // Create test projectDir
+ fs.MkdirAll(tt.path, os.ModePerm)
+
+ // create devfile (or subdir)
+ if tt.devfilePath != "" {
+ if tt.isDevfilePathDir {
+ fs.MkdirAll(filepath.Join(tt.path, tt.devfilePath), os.ModePerm)
+ } else {
+ fs.Create(filepath.Join(tt.path, tt.devfilePath))
+ }
+ }
+
+ // create other files
+ for _, otherFile := range tt.otherFiles {
+ fs.Create(filepath.Join(tt.path, otherFile))
+ }
+
+ err := isValidProjectDirOnFS(tt.path, tt.devfilePath, fs)
+ if !tt.wantErr && err != nil {
+ t.Errorf("Got unexpected error: %v", err)
+ } else if tt.wantErr && err == nil {
+ t.Errorf("Expected an error but got nil")
+ }
+ })
+ }
+}
+
func TestDownloadFile(t *testing.T) {
// Start a local HTTP server
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
@@ -919,7 +987,7 @@ func TestDownloadFile(t *testing.T) {
t.Errorf("Failed to download file with error %s", err)
}
- got, err := ioutil.ReadFile(tt.filepath)
+ got, err := os.ReadFile(tt.filepath)
if err != nil {
t.Errorf("Failed to read file with error %s", err)
}
@@ -1043,11 +1111,11 @@ func TestValidateK8sResourceName(t *testing.T) {
func TestValidateFile(t *testing.T) {
// Create temp dir and temp file
- tempDir, err := ioutil.TempDir("", "")
+ tempDir, err := os.MkdirTemp("", "")
if err != nil {
t.Errorf("Failed to create temp dir: %s, error: %v", tempDir, err)
}
- tempFile, err := ioutil.TempFile(tempDir, "")
+ tempFile, err := os.CreateTemp(tempDir, "")
if err != nil {
t.Errorf("Failed to create temp file: %s, error: %v", tempFile.Name(), err)
}
@@ -1086,13 +1154,13 @@ func TestValidateFile(t *testing.T) {
func TestCopyFile(t *testing.T) {
// Create temp dir
- tempDir, err := ioutil.TempDir("", "")
+ tempDir, err := os.MkdirTemp("", "")
if err != nil {
t.Errorf("Failed to create temp dir: %s, error: %v", tempDir, err)
}
// Create temp file under temp dir as source file
- tempFile, err := ioutil.TempFile(tempDir, "")
+ tempFile, err := os.CreateTemp(tempDir, "")
if err != nil {
t.Errorf("Failed to create temp file: %s, error: %v", tempFile.Name(), err)
}
diff --git a/replaceSchemaFile.go b/replaceSchemaFile.go
index ade02f84..b4137892 100644
--- a/replaceSchemaFile.go
+++ b/replaceSchemaFile.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@ package main
import (
"fmt"
- "io/ioutil"
"os"
"strings"
)
@@ -38,7 +37,7 @@ func ReplaceSchemaFile() {
fmt.Printf("Writing to file: %s\n", filePath)
fileContent := fmt.Sprintf("package %s\n\n// %s\nconst %s = `%s\n`\n", packageVersion, schemaURL, jsonSchemaVersion, newSchema)
- if err := ioutil.WriteFile(filePath, []byte(fileContent), 0644); err != nil {
+ if err := os.WriteFile(filePath, []byte(fileContent), 0600); err != nil {
printErr(err)
os.Exit(1)
}
diff --git a/scripts/changelog-script.sh b/scripts/changelog-script.sh
index e5bbade9..b0a88de2 100755
--- a/scripts/changelog-script.sh
+++ b/scripts/changelog-script.sh
@@ -1,6 +1,20 @@
-
#!/bin/bash
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
# This script uses github_changelog_generator to generate a changelog and requires:
#
# 1. set an env GITHUB_TOKEN for the Github token
diff --git a/scripts/updateApi.sh b/scripts/updateApi.sh
index 91726f24..3593f817 100755
--- a/scripts/updateApi.sh
+++ b/scripts/updateApi.sh
@@ -1,5 +1,20 @@
#!/bin/bash
+#
+# Copyright Red Hat
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
BLUE='\033[1;34m'
GREEN='\033[0;32m'
RED='\033[0;31m'
diff --git a/tests/v2/libraryTest/library_test.go b/tests/v2/libraryTest/library_test.go
index b4c2c9c4..65c13ebe 100644
--- a/tests/v2/libraryTest/library_test.go
+++ b/tests/v2/libraryTest/library_test.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/tests/v2/utils/library/command_test_utils.go b/tests/v2/utils/library/command_test_utils.go
index 020f3a57..d3f0d8a3 100644
--- a/tests/v2/utils/library/command_test_utils.go
+++ b/tests/v2/utils/library/command_test_utils.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package utils
import (
"errors"
"fmt"
- "io/ioutil"
+ "os"
"github.com/google/go-cmp/cmp"
"sigs.k8s.io/yaml"
@@ -81,7 +81,7 @@ func VerifyCommands(devfile *commonUtils.TestDevfile, parserCommands []schema.Co
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......marshall devfile %s", parserFilename)))
} else {
- err = ioutil.WriteFile(parserFilename, c, 0644)
+ err = os.WriteFile(parserFilename, c, 0644)
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......write devfile %s", parserFilename)))
}
@@ -91,7 +91,7 @@ func VerifyCommands(devfile *commonUtils.TestDevfile, parserCommands []schema.Co
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......marshall devfile %s", testFilename)))
} else {
- err = ioutil.WriteFile(testFilename, c, 0644)
+ err = os.WriteFile(testFilename, c, 0644)
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......write devfile %s", testFilename)))
}
diff --git a/tests/v2/utils/library/component_test_utils.go b/tests/v2/utils/library/component_test_utils.go
index 45afc239..c4d5265e 100644
--- a/tests/v2/utils/library/component_test_utils.go
+++ b/tests/v2/utils/library/component_test_utils.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package utils
import (
"errors"
"fmt"
- "io/ioutil"
+ "os"
schema "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
commonUtils "github.com/devfile/api/v2/test/v200/utils/common"
@@ -87,7 +87,7 @@ func VerifyComponents(devfile *commonUtils.TestDevfile, parserComponents []schem
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......marshall devfile %s", parserFilename)))
} else {
- err = ioutil.WriteFile(parserFilename, c, 0644)
+ err = os.WriteFile(parserFilename, c, 0644)
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......write devfile %s", parserFilename)))
}
@@ -97,7 +97,7 @@ func VerifyComponents(devfile *commonUtils.TestDevfile, parserComponents []schem
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......marshall devfile %s", testFilename)))
} else {
- err = ioutil.WriteFile(testFilename, c, 0644)
+ err = os.WriteFile(testFilename, c, 0644)
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......write devfile %s", testFilename)))
}
diff --git a/tests/v2/utils/library/project_test_utils.go b/tests/v2/utils/library/project_test_utils.go
index cac9c7df..3e372a7b 100644
--- a/tests/v2/utils/library/project_test_utils.go
+++ b/tests/v2/utils/library/project_test_utils.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package utils
import (
"errors"
"fmt"
- "io/ioutil"
+ "os"
"github.com/google/go-cmp/cmp"
"sigs.k8s.io/yaml"
@@ -93,7 +93,7 @@ func VerifyProjects(devfile *commonUtils.TestDevfile, parserProjects []schema.Pr
// Compare entire array of projects
if !cmp.Equal(parserProjects, devfile.SchemaDevFile.Projects) {
// Compare failed so compare each project to find which one(s) don't compare
- errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf("Project array compare failed.")))
+ errorString = append(errorString, commonUtils.LogErrorMessage("Project array compare failed."))
for _, project := range parserProjects {
if testProject, found := getSchemaProject(devfile.SchemaDevFile.Projects, project.Name); found {
if !cmp.Equal(project, *testProject) {
@@ -105,7 +105,7 @@ func VerifyProjects(devfile *commonUtils.TestDevfile, parserProjects []schema.Pr
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......marshall devfile %s", parserFilename)))
} else {
- err = ioutil.WriteFile(parserFilename, c, 0644)
+ err = os.WriteFile(parserFilename, c, 0644)
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......write devfile %s", parserFilename)))
}
@@ -115,7 +115,7 @@ func VerifyProjects(devfile *commonUtils.TestDevfile, parserProjects []schema.Pr
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......marshall devfile %s", testFilename)))
} else {
- err = ioutil.WriteFile(testFilename, c, 0644)
+ err = os.WriteFile(testFilename, c, 0644)
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......write devfile %s", testFilename)))
}
@@ -135,7 +135,7 @@ func VerifyProjects(devfile *commonUtils.TestDevfile, parserProjects []schema.Pr
}
}
} else {
- commonUtils.LogInfoMessage(fmt.Sprintf("Project structures matched"))
+ commonUtils.LogInfoMessage("Project structures matched")
}
var err error
@@ -154,7 +154,7 @@ func VerifyStarterProjects(devfile *commonUtils.TestDevfile, parserStarterProjec
// Compare entire array of projects
if !cmp.Equal(parserStarterProjects, devfile.SchemaDevFile.StarterProjects) {
// Compare failed so compare each project to find which one(s) don't compare
- errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf("Starter Project array compare failed.")))
+ errorString = append(errorString, commonUtils.LogErrorMessage("Starter Project array compare failed."))
for _, starterProject := range parserStarterProjects {
if testStarterProject, found := getSchemaStarterProject(devfile.SchemaDevFile.StarterProjects, starterProject.Name); found {
if !cmp.Equal(starterProject, *testStarterProject) {
@@ -166,7 +166,7 @@ func VerifyStarterProjects(devfile *commonUtils.TestDevfile, parserStarterProjec
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......marshall devfile %s", parserFilename)))
} else {
- err = ioutil.WriteFile(parserFilename, c, 0644)
+ err = os.WriteFile(parserFilename, c, 0644)
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......write devfile %s", parserFilename)))
}
@@ -176,7 +176,7 @@ func VerifyStarterProjects(devfile *commonUtils.TestDevfile, parserStarterProjec
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......marshall devfile %s", testFilename)))
} else {
- err = ioutil.WriteFile(testFilename, c, 0644)
+ err = os.WriteFile(testFilename, c, 0644)
if err != nil {
errorString = append(errorString, commonUtils.LogErrorMessage(fmt.Sprintf(".......write devfile %s", testFilename)))
}
@@ -196,7 +196,7 @@ func VerifyStarterProjects(devfile *commonUtils.TestDevfile, parserStarterProjec
}
}
} else {
- commonUtils.LogInfoMessage(fmt.Sprintf("Starter Project structures matched"))
+ commonUtils.LogInfoMessage("Starter Project structures matched")
}
var err error
diff --git a/tests/v2/utils/library/test_utils.go b/tests/v2/utils/library/test_utils.go
index d8585967..2fae02a7 100644
--- a/tests/v2/utils/library/test_utils.go
+++ b/tests/v2/utils/library/test_utils.go
@@ -1,5 +1,5 @@
//
-// Copyright 2022 Red Hat, Inc.
+// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.