diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 0000000..e836356 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,42 @@ +name: Bug Report +description: Create a report to help us improve +title: "bug: " +labels: + - kind/bug +body: + - type: textarea + id: description + attributes: + label: Describe the bug + description: Please provide a clear and concise description of the bug. + placeholder: | + Add logs and screenshots if any. + validations: + required: true + + - type: textarea + id: reproducing + attributes: + label: Steps To Reproduce + description: Steps to reproduce the behavior. + placeholder: | + 1. Go to '...' + 2. Click on '...' + 3. Scroll down to '...' + 4. See the error + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected Behaviour + description: A clear and concise description of what you expected to happen. + validations: + required: true + + - type: textarea + id: additional + attributes: + label: Additional Context + description: Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/community_meeting.yaml b/.github/ISSUE_TEMPLATE/community_meeting.yaml new file mode 100644 index 0000000..eadfc3d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/community_meeting.yaml @@ -0,0 +1,25 @@ +name: Community Meeting Agenda +description: Create a new weekly meeting agenda +title: "Community Meeting [DATE]" +labels: + - community-meeting +body: + - type: textarea + attributes: + label: Overview + value: | + At 11am Eastern, 8am Pacific, 3pm UTC; [find your time](https://www.timeanddate.com/worldclock/converter.html?iso=20210518T150000&p1=1440&p2=4826&p3=234&p4=195) + + Video call link: https://meet.google.com/bvb-qmdk-qwr + Or dial: ‪(DE) +49 40 8081619805‬ PIN: ‪475 948 161‬# + More phone numbers: https://meet.google.com/tel/qhs-tuik-kwj?pin=7061261814168&hs=1 + + Meeting recordings available on YouTube at https://www.youtube.com/playlist?list=PLqN7RcoCwL96nXIIW6O51l8Lu_J-f5D27 + + Incoming issues: https://github.com/orgs/kcp-dev/projects/1/views/22 + + Milestone epics: https://github.com/kcp-dev/kcp/issues?q=is%3Aopen+is%3Aissue+label%3Amilestone-blocker+label%3Aepic + + Add topics you'd like to discuss below! + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/epic.yaml b/.github/ISSUE_TEMPLATE/epic.yaml new file mode 100644 index 0000000..e592be2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/epic.yaml @@ -0,0 +1,49 @@ +name: Epic +description: For tracking a large feature, including how to demo it. +title: "epic: " +labels: + - epic +body: + - type: textarea + id: objective + attributes: + label: Demo Objective + description: Please describe the objective of your demo. + placeholder: | + - [ ] User should be able to ... + - [ ] ... + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Demo Steps + description: Please describe the steps for the demo. + placeholder: | + 1. Admin does X + 1. User does Y + 1. Everyone is happy :) + + - type: checkboxes + id: action-items + attributes: + label: Action Items + description: Please check the following + options: + - label: Scope of the current demo is necessary to fit in the prototype boundaries + required: true + - label: Contribute to the final demo script and recording + + - type: textarea + id: stories + attributes: + label: Stories + placeholder: | + - [ ] (Example) Add new API group + - [ ] (Example) Add Widget API type + - [ ] (Example) Add WidgetController + - [ ] (Example) **stretch-goal:** Add Widgets to `kubectl kcp` plugin + - Out-of-scope (prototype x): Send Widgets to space + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml new file mode 100644 index 0000000..2cedc7e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -0,0 +1,48 @@ +name: Feature Request +description: Suggest an idea for this project +title: "feature: " +labels: + - kind/feature +body: + - type: textarea + id: problem + attributes: + label: Feature Description + description: Is your feature request related to a problem? A clear and concise description of what the problem is. + placeholder: I'm always frustrated when [...] + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed Solution + description: A clear and consise description of what you want to happen. + placeholder: We can do [...] + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternative Solutions + description: A clear and consise description of any alternative solutions or features that you've considered. + placeholder: I think another approach would be [...] + validations: + required: false + + - type: checkboxes + id: contribute + attributes: + label: Want to contribute? + options: + - label: I would like to work on this issue. + required: false + + - type: textarea + id: additional + attributes: + label: Additional Context + description: Add any other context or screenshots about the feature request here. + validations: + required: false diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..78f506b --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,7 @@ +version: 2 +updates: +# Maintain dependencies for GitHub Actions +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..d6ac1ab --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,31 @@ + +## Summary + +## Related issue(s) + +Fixes # + +## Release Notes + + + +```release-note +NONE +``` diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml new file mode 100644 index 0000000..5c8d3cd --- /dev/null +++ b/.github/workflows/goreleaser.yml @@ -0,0 +1,54 @@ +name: goreleaser + +on: + pull_request: + paths: + - .github/workflows/goreleaser.yml + - .goreleaser.yaml + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-go@v5 + with: + go-version: v1.22.2 + - name: Delete non-semver tags + run: 'git tag -d $(git tag -l | grep -v "^v")' + - name: Set LDFLAGS + run: echo LDFLAGS="$(make ldflags)" >> $GITHUB_ENV + - name: Run GoReleaser on tag + if: github.event_name != 'pull_request' + uses: goreleaser/goreleaser-action@v4 + with: + distribution: goreleaser + version: latest + args: release --timeout 60m + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + KREW_GITHUB_TOKEN: ${{ secrets.KREW_GITHUB_TOKEN }} + - name: Run GoReleaser on pull request + if: github.event_name == 'pull_request' + uses: goreleaser/goreleaser-action@v4 + with: + distribution: goreleaser + version: latest + args: release --timeout 60m --snapshot + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + KREW_GITHUB_TOKEN: ${{ secrets.KREW_GITHUB_TOKEN }} + - uses: cytopia/upload-artifact-retry-action@v0.1.7 + if: ${{ always() }} + with: + name: binaries + path: dist/*.tar.gz diff --git a/.github/workflows/images.yaml b/.github/workflows/images.yaml new file mode 100644 index 0000000..ccce0a9 --- /dev/null +++ b/.github/workflows/images.yaml @@ -0,0 +1,56 @@ +name: Create and publish a Container image + +on: + push: + branches: + - 'main' + workflow_dispatch: + +permissions: + contents: read + packages: write + id-token: write + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + GOPRIVATE: github.com/{organisation} + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + build-and-push-image: + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write + # + steps: + - name: Checkout repository + uses: actions/checkout@v4 + # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. + # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. + # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. + - name: Build and push Docker image + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + GH_TOKEN=${{ secrets.GH_TOKEN }} diff --git a/.github/workflows/pr-verifier.yaml b/.github/workflows/pr-verifier.yaml new file mode 100644 index 0000000..ac40e2c --- /dev/null +++ b/.github/workflows/pr-verifier.yaml @@ -0,0 +1,23 @@ +name: PR Verifier + +on: + # NB: using `pull_request_target` runs this in the context of + # the base repository, so it has permission to upload to the checks API. + # This means changes won't kick in to this file until merged onto the + # main branch. + pull_request_target: + types: [opened, edited, reopened, synchronize] + +jobs: + verify: + name: verify PR contents + permissions: + checks: write + pull-requests: read + runs-on: ubuntu-latest + steps: + - name: Verifier action + id: verifier + uses: kubernetes-sigs/kubebuilder-release-tools@v0.4.3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fab5198 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.gcp +**__debug* +.vscode +vendor +hack/tools/* +bin/* diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..7445fe2 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,27 @@ + +builds: +- id: "gcp" + main: ./cmd/gcp + binary: bin/gcp + ldflags: + - "{{ .Env.LDFLAGS }}" + goos: + - linux + - darwin + goarch: + - amd64 + - arm64 + - ppc64le + ignore: + - goos: darwin + goarch: ppc64le + env: + - CGO_ENABLED=0 +archives: +- id: gcp + builds: + - gcp + +release: + draft: true + mode: keep-existing diff --git a/.prow.yaml b/.prow.yaml new file mode 100644 index 0000000..2000962 --- /dev/null +++ b/.prow.yaml @@ -0,0 +1,80 @@ +presubmits: + - name: pull-kcp-verify + always_run: true + decorate: true + clone_uri: "https://github.com/kcp-dev/kcp" + labels: + preset-goproxy: "true" + spec: + containers: + - image: ghcr.io/kcp-dev/infra/build:1.22.2-1 + command: + - make + - verify-boilerplate + - verify-modules + - verify-k8s-deps + - verify-imports + resources: + requests: + memory: 1Gi + cpu: 1 + + - name: pull-gco-lint + always_run: true + decorate: true + clone_uri: "https://github.com/kcp-dev/kcp" + labels: + preset-goproxy: "true" + spec: + containers: + - image: ghcr.io/kcp-dev/infra/build:1.22.2-1 + command: + - make + - lint + resources: + requests: + memory: 4Gi + cpu: 2 + + - name: pull-gcp-build-image + always_run: true + decorate: true + clone_uri: "https://github.com/kcp-dev/generic-controlplane" + labels: + preset-goproxy: "true" + spec: + containers: + - image: quay.io/containers/buildah:v1.30.0 + command: + - hack/build-image.sh + env: + - name: DRY_RUN + value: '1' + # docker-in-docker needs privileged mode + securityContext: + privileged: true + resources: + requests: + memory: 1Gi + cpu: 1 + + - name: pull-gcp-test-unit + always_run: true + decorate: true + clone_uri: "https://github.com/kcp-dev/generic-controlplane" + labels: + preset-goproxy: "true" + spec: + containers: + - image: ghcr.io/kcp-dev/infra/build:1.22.2-1 + command: + - make + - test + env: + - name: USE_GOTESTSUM + value: '1' + resources: + requests: + memory: 4Gi + cpu: 2 + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3c730a9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,16 @@ +# Contributing to kcp + +We're thrilled that you're interested in contributing to kcp! Please visit our +[full contributing guide](https://docs.kcp.io/kcp/main/en/CONTRIBUTING/) on our documentation site. + +Beside that, what coverns the project and all contributions to it must follow +the [KCP Project Governance](./GOVERNANCE.md). + +From the KCP Project Governance, the following manifesto should guide the technical +decisions through-out all contributions: + +> kcp maintainers strive to be good citizens in the Kubernetes project. +> kcp maintainers see kcp always as part of the Kubernetes ecosystem and always strive to keep that ecosystem united. In particular, this means: +> - kcp strives to not divert from Kubernetes, but strives to extend its use-cases to non-container control planes while keeping the ecosystems of libraries and tooling united. +> - kcp – as a consumer of Kubernetes API Machinery – will strive to stay 100% compatible with the semantics of Kubernetes APIs, while removing container orchestration specific functionality. +> - kcp strives to upstream changes to Kubernetes code as much as possible. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2cab1f0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,66 @@ +# syntax=docker/dockerfile:1.4 + +# Copyright 2024 The KCP Authors. +# +# 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. + +# Build the binary +FROM --platform=${BUILDPLATFORM} docker.io/golang:1.22.2 AS builder +WORKDIR /workspace + +# Install dependencies. +RUN apt-get update && apt-get install -y jq && mkdir bin + +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +USER 0 + +# Install kubectl. +RUN wget "https://dl.k8s.io/release/$(go list -m -json k8s.io/kubernetes | jq -r .Version)/bin/linux/$(uname -m | sed 's/aarch.*/arm64/;s/armv8.*/arm64/;s/x86_64/amd64/')/kubectl" -O bin/kubectl && chmod +x bin/kubectl + +ENV GOPRIVATE=github.com/faroshq/cluster-proxy +ARG GH_TOKEN + +# and so that source changes don't invalidate our downloaded layer +ENV GOPROXY=direct + +RUN --mount=type=cache,target=/go/pkg/mod \ + git config --global url."https://${GH_TOKEN}:@github.com/".insteadOf "https://github.com/" && \ + go mod download && \ + git config --global --unset url."https://${GH_TOKEN}:@github.com/".insteadOf + +# Copy the sources +COPY ./ ./ + +ARG TARGETOS +ARG TARGETARCH + +RUN --mount=type=cache,target=/root/.cache/go-build \ + --mount=type=cache,target=/go/pkg/mod \ + make OS=${TARGETOS} ARCH=${TARGETARCH} + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:debug +WORKDIR / +COPY --from=builder /etc/ssl/certs /etc/ssl/certs +COPY --from=builder workspace/bin/gcp / +ENV KUBECONFIG=/etc/gcp/config/admin.kubeconfig +# Use uid of nonroot user (65532) because kubernetes expects numeric user when applying pod security policies +RUN ["/busybox/sh", "-c", "mkdir -p /data && chown 65532:65532 /data"] +USER 65532:65532 +WORKDIR /data +VOLUME /data +ENTRYPOINT ["/gcp"] +CMD ["start"] diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..4f12d33 --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,167 @@ +# Generic Control Plane Project Governance + +The kcp project is dedicated to democratizing Control Planes beyond container +orchestration. This governance explains how the project is run. + +- [Generic Control Plane Project Governance](#generic-control-plane-project-governance) + - [Manifesto](#manifesto) + - [Values](#values) + - [Maintainers](#maintainers) + - [Becoming a Maintainer](#becoming-a-maintainer) + - [Bootstrapping Maintainers](#bootstrapping-maintainers) + - [Removing a Maintainer](#removing-a-maintainer) + - [Meetings](#meetings) + - [Code of Conduct](#code-of-conduct) + - [Security Response Team](#security-response-team) + - [Voting](#voting) + - [Modifying this Charter](#modifying-this-charter) + +## Manifesto + + * kcp maintainers strive to be good citizens in the Kubernetes project. + * kcp maintainers see kcp always as part of the Kubernetes ecosystem and always + strive to keep that ecosystem united. In particular, this means: + * kcp strives to not divert from Kubernetes, but strives to extend its + use-cases to non-container control planes while keeping the ecosystems of + libraries and tooling united. + * kcp – as a consumer of Kubernetes API Machinery – will strive to stay 100% + compatible with the semantics of Kubernetes APIs, while removing container + orchestration specific functionality. + * kcp strives to upstream changes to Kubernetes code as much as possible. + +## Values + +The kcp and its leadership embrace the following values: + + * *Openness*: Communication and decision-making happens in the open and is + discoverable for future reference. As much as possible, all discussions and + work take place in public forums and open repositories. + * *Fairness*: All stakeholders have the opportunity to provide feedback and + submit contributions, which will be considered on their merits. + * *Community over Product or Company*: Sustaining and growing our community + takes priority over shipping code or sponsors' organizational goals. Each + contributor participates in the project as an individual. + * *Inclusivity*: We innovate through different perspectives and skill sets, + which can only be accomplished in a welcoming and respectful environment. + * *Participation*: Responsibilities within the project are earned through + participation, and there is a clear path up the contributor ladder into + leadership positions. + +## Maintainers + +kcp maintainers have write access to the [project GitHub repository](https://github.com/kcp-dev/kcp). +They can merge their own patches or patches from others. The current maintainers +can be found as top-level approvers in [OWNERS](./OWNERS). Maintainers collectively +manage the project's resources and contributors. + +This privilege is granted with some expectation of responsibility: maintainers +are people who care about the kcp project and want to help it grow and +improve. A maintainer is not just someone who can make changes, but someone who +has demonstrated their ability to collaborate with the team, get the most +knowledgeable people to review code and docs, contribute high-quality code, and +follow through to fix issues (in code or tests). + +A maintainer is a contributor to the project's success and a citizen helping +the project succeed. + +The collective team of all Maintainers is known as the Maintainer Council, which +is the governing body for the project. + +## Becoming a Maintainer + + + +To become a Maintainer you need to demonstrate the following: + + * commitment to the project: + * participate in discussions, contributions, code and documentation reviews + for 3 months or more, + * perform reviews for 5 non-trivial pull requests, + * contribute 5 non-trivial pull requests and have them merged, + * ability to write quality code and/or documentation, + * ability to collaborate with the team, + * understanding of how the team works (policies, processes for testing and code review, etc), + * understanding of the project's code base and coding and documentation style. + + +A new Maintainer must be proposed by an existing maintainer by sending a message to the +[developer mailing list](https://groups.google.com/g/kcp-dev). A simple majority +vote of existing Maintainers approves the application. + +Maintainers who are selected will be granted the necessary GitHub rights, +and invited to the [private maintainer mailing list](https://groups.google.com/g/kcp-dev-private). + +### Bootstrapping Maintainers + +To bootstrap the process, 3 maintainers are defined (in the initial PR adding +this to the repository) that do not necessarily follow the above rules. When a +new maintainer is added following the above rules, the existing maintainers +define one not following the rules to step down, until all of them follow the +rules. + +### Removing a Maintainer + +Maintainers may resign at any time if they feel that they will not be able to +continue fulfilling their project duties. + +Maintainers may also be removed after being inactive, failure to fulfill their +Maintainer responsibilities, violating the Code of Conduct, or other reasons. +Inactivity is defined as a period of very low or no activity in the project for +a year or more, with no definite schedule to return to full Maintainer activity. + +A Maintainer may be removed at any time by a 2/3 vote of the remaining maintainers. + +Depending on the reason for removal, a Maintainer may be converted to Emeritus +status. Emeritus Maintainers will still be consulted on some project matters, +and can be rapidly returned to Maintainer status if their availability changes. + + +## Meetings + +Time zones permitting, Maintainers are expected to participate in the public +community call meeting. Maintainers will also have closed meetings in order to +discuss security reports or Code of Conduct violations. Such meetings should be +scheduled by any Maintainer on receipt of a security issue or CoC report. +All current Maintainers must be invited to such closed meetings, except for any +Maintainer who is accused of a CoC violation. + +## Code of Conduct + + + +[Code of Conduct](./code-of-conduct.md) +violations by community members will be discussed and resolved +on the [private Maintainer mailing list](https://groups.google.com/g/kcp-dev-private). + +## Security Response Team + +The Maintainers will appoint a Security Response Team to handle security reports. +This committee may simply consist of the Maintainer Council themselves. If this +responsibility is delegated, the Maintainers will appoint a team of at least two +contributors to handle it. The Maintainers will review who is assigned to this +at least once a year. + +The Security Response Team is responsible for handling all reports of security +holes and breaches according to the [security policy](./SECURITY.md). + +## Voting + +While most business in kcp is conducted by "lazy consensus", periodically +the Maintainers may need to vote on specific actions or changes. +A vote can be taken on [the developer mailing list](https://groups.google.com/g/kcp-dev) or +[the private Maintainer mailing list](https://groups.google.com/g/kcp-dev-private) +for security or conduct matters. Votes may also be taken at the community call +meeting. Any Maintainer may demand a vote be taken. + +Most votes require a simple majority of all Maintainers to succeed. Maintainers +can be removed by a 2/3 majority vote of all Maintainers, and changes to this +Governance require a 2/3 vote of all Maintainers. + +## Modifying this Charter + +Changes to this Governance and its supporting documents may be approved by a +2/3 vote of the Maintainers. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e1d9157 --- /dev/null +++ b/Makefile @@ -0,0 +1,183 @@ +# Copyright 2024 The KCP Authors. +# +# 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. + +# We need bash for some conditional logic below. +SHELL := /usr/bin/env bash -e + +#----------------------------------------------------------------------------- +# Workaround git issues on OpenShift Prow CI, where the user running in the +# job is not guaranteed to own the repo checkout. +#----------------------------------------------------------------------------- +ifeq ($(CI),true) + $(shell git config --global --add safe.directory '*') +endif + +GO_INSTALL = ./hack/go-install.sh + +TOOLS_DIR=hack/tools +TOOLS_GOBIN_DIR := $(abspath $(TOOLS_DIR)) +GOBIN_DIR=$(abspath ./bin) +PATH := $(GOBIN_DIR):$(TOOLS_GOBIN_DIR):$(PATH) +TMPDIR := $(shell mktemp -d) +KIND_CLUSTER_NAME ?= kind + +# Detect the path used for the install target +ifeq (,$(shell go env GOBIN)) +INSTALL_GOBIN=$(shell go env GOPATH)/bin +else +INSTALL_GOBIN=$(shell go env GOBIN) +endif + +OPENSHIFT_GOIMPORTS_VER := c72f1dc2e3aacfa00aece3391d938c9bc734e791 +OPENSHIFT_GOIMPORTS_BIN := openshift-goimports +OPENSHIFT_GOIMPORTS := $(TOOLS_DIR)/$(OPENSHIFT_GOIMPORTS_BIN)-$(OPENSHIFT_GOIMPORTS_VER) +export OPENSHIFT_GOIMPORTS # so hack scripts can use it + +GOLANGCI_LINT_VER := v1.54.2 +GOLANGCI_LINT_BIN := golangci-lint +GOLANGCI_LINT := $(TOOLS_GOBIN_DIR)/$(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VER) + +STATICCHECK_VER := 2023.1 +STATICCHECK_BIN := staticcheck +STATICCHECK := $(TOOLS_GOBIN_DIR)/$(STATICCHECK_BIN)-$(STATICCHECK_VER) + +GOTESTSUM_VER := v1.8.1 +GOTESTSUM_BIN := gotestsum +GOTESTSUM := $(abspath $(TOOLS_DIR))/$(GOTESTSUM_BIN)-$(GOTESTSUM_VER) + + +ARCH := $(shell go env GOARCH) +OS := $(shell go env GOOS) + +KUBE_MAJOR_VERSION := $(shell go mod edit -json | jq '.Require[] | select(.Path == "k8s.io/kubernetes") | .Version' --raw-output | sed 's/v\([0-9]*\).*/\1/') +KUBE_MINOR_VERSION := $(shell go mod edit -json | jq '.Require[] | select(.Path == "k8s.io/kubernetes") | .Version' --raw-output | sed "s/v[0-9]*\.\([0-9]*\).*/\1/") +GIT_COMMIT := $(shell git rev-parse --short HEAD || echo 'local') +GIT_DIRTY := $(shell git diff --quiet && echo 'clean' || echo 'dirty') +GIT_VERSION := $(shell go mod edit -json | jq '.Require[] | select(.Path == "k8s.io/kubernetes") | .Version' --raw-output)+kcp-$(shell git describe --tags --match='v*' --abbrev=14 "$(GIT_COMMIT)^{commit}" 2>/dev/null || echo v0.0.0-$(GIT_COMMIT)) +BUILD_DATE := $(shell date -u +'%Y-%m-%dT%H:%M:%SZ') +LDFLAGS := \ + -X k8s.io/client-go/pkg/version.gitCommit=${GIT_COMMIT} \ + -X k8s.io/client-go/pkg/version.gitTreeState=${GIT_DIRTY} \ + -X k8s.io/client-go/pkg/version.gitVersion=${GIT_VERSION} \ + -X k8s.io/client-go/pkg/version.gitMajor=${KUBE_MAJOR_VERSION} \ + -X k8s.io/client-go/pkg/version.gitMinor=${KUBE_MINOR_VERSION} \ + -X k8s.io/client-go/pkg/version.buildDate=${BUILD_DATE} \ + \ + -X k8s.io/component-base/version.gitCommit=${GIT_COMMIT} \ + -X k8s.io/component-base/version.gitTreeState=${GIT_DIRTY} \ + -X k8s.io/component-base/version.gitVersion=${GIT_VERSION} \ + -X k8s.io/component-base/version.gitMajor=${KUBE_MAJOR_VERSION} \ + -X k8s.io/component-base/version.gitMinor=${KUBE_MINOR_VERSION} \ + -X k8s.io/component-base/version.buildDate=${BUILD_DATE} \ + -extldflags '-static' +all: build +.PHONY: all + +ldflags: + @echo $(LDFLAGS) + +.PHONY: require-% +require-%: + @if ! command -v $* 1> /dev/null 2>&1; then echo "$* not found in ${PATH}"; exit 1; fi + +build: WHAT ?= ./cmd/... +build: require-jq require-go require-git verify-go-versions ## Build the project + set -x; for W in $(WHAT); do \ + W=$$(echo "$${W}" | sed 's,^\./,github.com/kcp-dev/generic-controlplane/,') && \ + GOOS=$(OS) GOARCH=$(ARCH) CGO_ENABLED=0 go build $(BUILDFLAGS) -ldflags="$(LDFLAGS)" -o bin $${W}; \ + done +.PHONY: build + +.PHONY: build-all +build-all: + GOOS=$(OS) GOARCH=$(ARCH) $(MAKE) build WHAT='./cmd/...' + +install: WHAT ?= ./cmd/... +install: require-jq require-go require-git verify-go-versions ## Install the project + set -x; for W in $(WHAT); do \ + W=$$(echo "$${W}" | sed 's,^\./,github.com/kcp-dev/generic-controlplane/,') && \ + GOOS=$(OS) GOARCH=$(ARCH) CGO_ENABLED=0 go install -ldflags="$(LDFLAGS)" $${W}; \ + done +.PHONY: install + +$(GOLANGCI_LINT): + GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/golangci/golangci-lint/cmd/golangci-lint $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER) + +$(STATICCHECK): + GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) honnef.co/go/tools/cmd/staticcheck $(STATICCHECK_BIN) $(STATICCHECK_VER) + +$(LOGCHECK): + GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) sigs.k8s.io/logtools/logcheck $(LOGCHECK_BIN) $(LOGCHECK_VER) + +lint: $(GOLANGCI_LINT) $(STATICCHECK) $(LOGCHECK) ## Verify lint + $(GOLANGCI_LINT) run --timeout 20m ./... + $(STATICCHECK) -checks ST1019,ST1005 ./... +.PHONY: lint + +$(GOTESTSUM): + GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) gotest.tools/gotestsum $(GOTESTSUM_BIN) $(GOTESTSUM_VER) + +tools: $(GOLANGCI_LINT) $(CONTROLLER_GEN) $(KCP_APIGEN_GEN) $(YAML_PATCH) $(GOTESTSUM) $(OPENSHIFT_GOIMPORTS) $(CODE_GENERATOR) ## Install tools +.PHONY: tools + +$(OPENSHIFT_GOIMPORTS): + GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/openshift-eng/openshift-goimports $(OPENSHIFT_GOIMPORTS_BIN) $(OPENSHIFT_GOIMPORTS_VER) + +.PHONY: imports +imports: $(OPENSHIFT_GOIMPORTS) verify-go-versions + $(OPENSHIFT_GOIMPORTS) -m github.com/kcp-dev/generic-controlplane + +$(TOOLS_DIR)/verify_boilerplate.py: + mkdir -p $(TOOLS_DIR) + curl --fail --retry 3 -L -o $(TOOLS_DIR)/verify_boilerplate.py https://raw.githubusercontent.com/kubernetes/repo-infra/master/hack/verify_boilerplate.py + chmod +x $(TOOLS_DIR)/verify_boilerplate.py + +.PHONY: verify-boilerplate +verify-boilerplate: $(TOOLS_DIR)/verify_boilerplate.py ## Verify boilerplate + $(TOOLS_DIR)/verify_boilerplate.py --boilerplate-dir=hack/boilerplate --skip docs/venv + +GO_TEST = go test +ifdef USE_GOTESTSUM +GO_TEST = $(GOTESTSUM) $(GOTESTSUM_ARGS) -- +endif + +test: WHAT ?= ./... +# We will need to move into the sub package, of sdk to run those tests. +test: ## Run tests + $(GO_TEST) -race $(COUNT_ARG) -coverprofile=coverage.txt -covermode=atomic $(TEST_ARGS) $$(go list "$(WHAT)") + +.PHONY: verify-imports +verify-imports: ## Verify imports + hack/verify-imports.sh + +.PHONY: verify-go-versions +verify-go-versions: ## Verify go versions + hack/verify-go-versions.sh + +.PHONY: clean +clean: clean-workdir ## Clean all + rm -fr $(TOOLS_DIR) + rm -f $(GOBIN_DIR)/* + +.PHONY: clean-workdir +clean-workdir: WORK_DIR ?= . +clean-workdir: ## Clean workdir + rm -fr $(WORK_DIR)/.gcp* + + +.PHONY: help +help: ## Show this help + @grep -hE '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +include Makefile.venv diff --git a/Makefile.venv b/Makefile.venv new file mode 100644 index 0000000..c79b9bb --- /dev/null +++ b/Makefile.venv @@ -0,0 +1,274 @@ +# +# SEAMLESSLY MANAGE PYTHON VIRTUAL ENVIRONMENT WITH A MAKEFILE +# +# https://github.com/sio/Makefile.venv v2022.07.20 +# +# +# Insert `include Makefile.venv` at the bottom of your Makefile to enable these +# rules. +# +# When writing your Makefile use '$(VENV)/python' to refer to the Python +# interpreter within virtual environment and '$(VENV)/executablename' for any +# other executable in venv. +# +# This Makefile provides the following targets: +# venv +# Use this as a dependency for any target that requires virtual +# environment to be created and configured +# python, ipython +# Use these to launch interactive Python shell within virtual environment +# shell, bash, zsh +# Launch interactive command line shell. "shell" target launches the +# default shell Makefile executes its rules in (usually /bin/sh). +# "bash" and "zsh" can be used to refer to the specific desired shell. +# show-venv +# Show versions of Python and pip, and the path to the virtual environment +# clean-venv +# Remove virtual environment +# $(VENV)/executable_name +# Install `executable_name` with pip. Only packages with names matching +# the name of the corresponding executable are supported. +# Use this as a lightweight mechanism for development dependencies +# tracking. E.g. for one-off tools that are not required in every +# developer's environment, therefore are not included into +# requirements.txt or setup.py. +# Note: +# Rules using such target or dependency MUST be defined below +# `include` directive to make use of correct $(VENV) value. +# Example: +# codestyle: $(VENV)/pyflakes +# $(VENV)/pyflakes . +# See `ipython` target below for another example. +# +# This Makefile can be configured via following variables: +# PY +# Command name for system Python interpreter. It is used only initially to +# create the virtual environment +# Default: python3 +# REQUIREMENTS_TXT +# Space separated list of paths to requirements.txt files. +# Paths are resolved relative to current working directory. +# Default: requirements.txt +# +# Non-existent files are treated as hard dependencies, +# recipes for creating such files must be provided by the main Makefile. +# Providing empty value (REQUIREMENTS_TXT=) turns off processing of +# requirements.txt even when the file exists. +# SETUP_PY +# Space separated list of paths to setup.py files. +# Corresponding packages will be installed into venv in editable mode +# along with all their dependencies +# Default: setup.py +# +# Non-existent and empty values are treated in the same way as for REQUIREMENTS_TXT. +# WORKDIR +# Parent directory for the virtual environment. +# Default: current working directory. +# VENVDIR +# Python virtual environment directory. +# Default: $(WORKDIR)/.venv +# +# This Makefile was written for GNU Make and may not work with other make +# implementations. +# +# +# Copyright (c) 2019-2020 Vitaly Potyarkin +# +# Licensed under the Apache License, Version 2.0 +# +# + + +# +# Configuration variables +# + +WORKDIR?=. +VENVDIR?=$(WORKDIR)/.venv +REQUIREMENTS_TXT?=$(wildcard requirements.txt) # Multiple paths are supported (space separated) +SETUP_PY?=$(wildcard setup.py) # Multiple paths are supported (space separated) +SETUP_CFG?=$(foreach s,$(SETUP_PY),$(wildcard $(patsubst %setup.py,%setup.cfg,$(s)))) +MARKER=.initialized-with-Makefile.venv + + +# +# Python interpreter detection +# + +_PY_AUTODETECT_MSG=Detected Python interpreter: $(PY). Use PY environment variable to override + +ifeq (ok,$(shell test -e /dev/null 2>&1 && echo ok)) +NULL_STDERR=2>/dev/null +else +NULL_STDERR=2>NUL +endif + +ifndef PY +_PY_OPTION:=python3 +ifeq (ok,$(shell $(_PY_OPTION) -c "print('ok')" $(NULL_STDERR))) +PY=$(_PY_OPTION) +endif +endif + +ifndef PY +_PY_OPTION:=$(VENVDIR)/bin/python +ifeq (ok,$(shell $(_PY_OPTION) -c "print('ok')" $(NULL_STDERR))) +PY=$(_PY_OPTION) +$(info $(_PY_AUTODETECT_MSG)) +endif +endif + +ifndef PY +_PY_OPTION:=$(subst /,\,$(VENVDIR)/Scripts/python) +ifeq (ok,$(shell $(_PY_OPTION) -c "print('ok')" $(NULL_STDERR))) +PY=$(_PY_OPTION) +$(info $(_PY_AUTODETECT_MSG)) +endif +endif + +ifndef PY +_PY_OPTION:=py -3 +ifeq (ok,$(shell $(_PY_OPTION) -c "print('ok')" $(NULL_STDERR))) +PY=$(_PY_OPTION) +$(info $(_PY_AUTODETECT_MSG)) +endif +endif + +ifndef PY +_PY_OPTION:=python +ifeq (ok,$(shell $(_PY_OPTION) -c "print('ok')" $(NULL_STDERR))) +PY=$(_PY_OPTION) +$(info $(_PY_AUTODETECT_MSG)) +endif +endif + +ifndef PY +define _PY_AUTODETECT_ERR +Could not detect Python interpreter automatically. +Please specify path to interpreter via PY environment variable. +endef +$(error $(_PY_AUTODETECT_ERR)) +endif + + +# +# Internal variable resolution +# + +VENV=$(VENVDIR)/bin +EXE= +# Detect windows +ifeq (win32,$(shell $(PY) -c "import __future__, sys; print(sys.platform)")) +VENV=$(VENVDIR)/Scripts +EXE=.exe +endif + +touch=touch $(1) +ifeq (,$(shell command -v touch $(NULL_STDERR))) +# https://ss64.com/nt/touch.html +touch=type nul >> $(subst /,\,$(1)) && copy /y /b $(subst /,\,$(1))+,, $(subst /,\,$(1)) +endif + +RM?=rm -f +ifeq (,$(shell command -v $(firstword $(RM)) $(NULL_STDERR))) +RMDIR:=rd /s /q +else +RMDIR:=$(RM) -r +endif + + +# +# Virtual environment +# + +.PHONY: venv +venv: $(VENV)/$(MARKER) + +.PHONY: clean-venv +clean-venv: + -$(RMDIR) "$(VENVDIR)" + +.PHONY: show-venv +show-venv: venv + @$(VENV)/python -c "import sys; print('Python ' + sys.version.replace('\n',''))" + @$(VENV)/pip --version + @echo venv: $(VENVDIR) + +.PHONY: debug-venv +debug-venv: + @echo "PATH (Shell)=$$PATH" + @$(MAKE) --version + $(info PATH (GNU Make)="$(PATH)") + $(info SHELL="$(SHELL)") + $(info PY="$(PY)") + $(info REQUIREMENTS_TXT="$(REQUIREMENTS_TXT)") + $(info SETUP_PY="$(SETUP_PY)") + $(info SETUP_CFG="$(SETUP_CFG)") + $(info VENVDIR="$(VENVDIR)") + $(info VENVDEPENDS="$(VENVDEPENDS)") + $(info WORKDIR="$(WORKDIR)") + + +# +# Dependencies +# + +ifneq ($(strip $(REQUIREMENTS_TXT)),) +VENVDEPENDS+=$(REQUIREMENTS_TXT) +endif + +ifneq ($(strip $(SETUP_PY)),) +VENVDEPENDS+=$(SETUP_PY) +endif +ifneq ($(strip $(SETUP_CFG)),) +VENVDEPENDS+=$(SETUP_CFG) +endif + +$(VENV): + $(PY) -m venv $(VENVDIR) + $(VENV)/python -m pip install --upgrade pip setuptools wheel + +$(VENV)/$(MARKER): $(VENVDEPENDS) | $(VENV) +ifneq ($(strip $(REQUIREMENTS_TXT)),) + $(VENV)/pip install $(foreach path,$(REQUIREMENTS_TXT),-r $(path)) +endif +ifneq ($(strip $(SETUP_PY)),) + $(VENV)/pip install $(foreach path,$(SETUP_PY),-e $(dir $(path))) +endif + $(call touch,$(VENV)/$(MARKER)) + + +# +# Interactive shells +# + +.PHONY: python +python: venv + exec $(VENV)/python + +.PHONY: ipython +ipython: $(VENV)/ipython + exec $(VENV)/ipython + +.PHONY: shell +shell: venv + . $(VENV)/activate && exec $(notdir $(SHELL)) + +.PHONY: bash zsh +bash zsh: venv + . $(VENV)/activate && exec $@ + + +# +# Commandline tools (wildcard rule, executable name must match package name) +# + +ifneq ($(EXE),) +$(VENV)/%: $(VENV)/%$(EXE) ; +.PHONY: $(VENV)/% +.PRECIOUS: $(VENV)/%$(EXE) +endif + +$(VENV)/%$(EXE): $(VENV)/$(MARKER) + $(VENV)/pip install --upgrade $* + $(call touch,$@) diff --git a/OWNERS b/OWNERS new file mode 100644 index 0000000..565ef38 --- /dev/null +++ b/OWNERS @@ -0,0 +1,3 @@ +approvers: +- sttts +- mjudeikis diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES new file mode 100644 index 0000000..f0342cc --- /dev/null +++ b/OWNERS_ALIASES @@ -0,0 +1,6 @@ +# See the OWNERS_ALIASES docs: https://git.k8s.io/community/contributors/guide/owners.md#owners_aliases + +aliases: + api-approvers: + - sttts + - mjudeikis diff --git a/README.md b/README.md new file mode 100644 index 0000000..19e3a91 --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# Generic Control Plane + +# IMPORTANT: + +Generic Control Plane is a new project under KCP umbrella and is not yet ready for production use. We are actively working on the project and welcome contributions from the community. If you are interested in contributing, please see our [contributing guide](CONTRIBUTING.md). + +## Overview + +Generic Control plane is a Kubernetes based control plane focusing on: + +- A **control plane** for Kubernetes-native APIs that can be used **without Kubernetes** +- Enabling API service providers to **offer APIs centrally** + +gcp can be a building block for SaaS service providers who need a robust API base platform out-of-the-box. +The goal is to be useful to cloud providers as well as enterprise IT departments offering APIs within their company. + +## Documentation + +To get started with generic control plane: + +```bash +# Clone the repository +git clone https://github.com/kcp-dev/generic-controlplane.git + +# Build the project +cd generic-controlplane && make build + +# Start standalone gcp +./bin/gcp start + +# Access the gcp API +export KUBECONFIG=.gcp/admin.kubeconfig + +# Check resources in the gcp API +kubectl api-resources +``` + +## Contributing + +We ❤️ our contributors! If you're interested in helping us out, please check out [contributing to Generic Control Plane](CONTRIBUTING.md). + +This community has a [Code of Conduct](./code-of-conduct.md). Please make sure to follow it. + +## Getting in touch + +There are several ways to communicate with us: + +- The [`#kcp-dev` channel](https://app.slack.com/client/T09NY5SBT/C021U8WSAFK) in the [Kubernetes Slack workspace](https://slack.k8s.io). +- Our mailing lists: + - [kcp-dev](https://groups.google.com/g/kcp-dev) for development discussions. + - [kcp-users](https://groups.google.com/g/kcp-users) for discussions among users and potential users. +- By joining the kcp-dev mailing list, you should receive an invite to our bi-weekly community meetings. +- See recordings of past community meetings on [YouTube](https://www.youtube.com/channel/UCfP_yS5uYix0ppSbm2ltS5Q). +- The next community meeting dates are available via our [CNCF community group](https://community.cncf.io/kcp/). +- Check the [community meeting notes document](https://docs.google.com/document/d/1PrEhbmq1WfxFv1fTikDBZzXEIJkUWVHdqDFxaY1Ply4) for future and past meeting agendas. +- Browse the [shared Google Drive](https://drive.google.com/drive/folders/1FN7AZ_Q1CQor6eK0gpuKwdGFNwYI517M?usp=sharing) to share design docs, notes, etc. + - Members of the kcp-dev mailing list can view this drive. + +## License +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fkcp-dev%2Fkcp.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fkcp-dev%2Fkcp?ref=badge_large) diff --git a/generic-control-plane/main.go b/cmd/gcp/main.go similarity index 62% rename from generic-control-plane/main.go rename to cmd/gcp/main.go index 4e55786..c022b72 100644 --- a/generic-control-plane/main.go +++ b/cmd/gcp/main.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Kubernetes Authors. +Copyright 2024 The KCP Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,24 +14,36 @@ See the License for the specific language governing permissions and limitations under the License. */ -// sample-generic-controlplane is a kube-like generic control plane -// It is compatible to kube-apiserver, but lacks the container domain -// specific APIs. package main import ( "os" + "github.com/kcp-dev/kcp/cli/pkg/help" + "github.com/spf13/cobra" + "k8s.io/component-base/cli" _ "k8s.io/component-base/logs/json/register" _ "k8s.io/component-base/metrics/prometheus/clientgo" _ "k8s.io/component-base/metrics/prometheus/version" - "k8s.io/kubernetes/cmd/sample-generic-controlplane/server" + server "github.com/kcp-dev/generic-controlplane/server/cmd" ) func main() { + cmd := &cobra.Command{ + Use: "gcp", + Short: "Generic Control Plane (GCP)", + Long: help.Doc(` + GCP is a generic control plane server, a system serving APIs like Kubernetes, but without the container domain specific APIs. + `), + SilenceUsage: true, + SilenceErrors: true, + } + command := server.NewCommand() - code := cli.Run(command) + cmd.AddCommand(command) + + code := cli.Run(cmd) os.Exit(code) } diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 0000000..2f4430b --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1,83 @@ +This project is following the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). + +# Community Code of Conduct + +As contributors, maintainers, and participants in the CNCF community, and in the interest of fostering +an open and welcoming community, we pledge to respect all people who participate or contribute +through reporting issues, posting feature requests, updating documentation, +submitting pull requests or patches, attending conferences or events, or engaging in other community or project activities. + +We are committed to making participation in the CNCF community a harassment-free experience for everyone, regardless of age, body size, caste, disability, ethnicity, level of experience, family status, gender, gender identity and expression, marital status, military or veteran status, nationality, personal appearance, race, religion, sexual orientation, socieconomic status, tribe, or any other dimension of diversity. + +## Scope + +This code of conduct applies: +* within project and community spaces, +* in other spaces when an individual CNCF community participant's words or actions are directed at or are about a CNCF project, the CNCF community, or another CNCF community participant. + +### CNCF Events + +CNCF events that are produced by the Linux Foundation with professional events staff are governed by the Linux Foundation [Events Code of Conduct](https://events.linuxfoundation.org/code-of-conduct/) available on the event page. This is designed to be used in conjunction with the CNCF Code of Conduct. + +## Our Standards + +The CNCF Community is open, inclusive and respectful. Every member of our community has the right to have their identity respected. + +Examples of behavior that contributes to a positive environment include but are not limited to: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community +* Using welcoming and inclusive language + + +Examples of unacceptable behavior include but are not limited to: + +* The use of sexualized language or imagery +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment in any form +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Violence, threatening violence, or encouraging others to engage in violent behavior +* Stalking or following someone without their consent +* Unwelcome physical contact +* Unwelcome sexual or romantic attention or advances +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +The following behaviors are also prohibited: +* Providing knowingly false or misleading information in connection with a Code of Conduct investigation or otherwise intentionally tampering with an investigation. +* Retaliating against a person because they reported an incident or provided information about an incident as a witness. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. +By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect +of managing a CNCF project. +Project maintainers who do not follow or enforce the Code of Conduct may be temporarily or permanently removed from the project team. + +## Reporting + +For incidents occurring in the Kubernetes community, contact the [Kubernetes Code of Conduct Committee](https://git.k8s.io/community/committee-code-of-conduct) via . You can expect a response within three business days. + +For other projects, or for incidents that are project-agnostic or impact multiple CNCF projects, please contact the [CNCF Code of Conduct Committee](https://www.cncf.io/conduct/committee/) via conduct@cncf.io. Alternatively, you can contact any of the individual members of the [CNCF Code of Conduct Committee](https://www.cncf.io/conduct/committee/) to submit your report. For more detailed instructions on how to submit a report, including how to submit a report anonymously, please see our [Incident Resolution Procedures](https://www.cncf.io/conduct/procedures/). You can expect a response within three business days. + +For incidents ocurring at CNCF event that is produced by the Linux Foundation, please contact eventconduct@cncf.io. + +## Enforcement + +Upon review and investigation of a reported incident, the CoC response team that has jurisdiction will determine what action is appropriate based on this Code of Conduct and its related documentation. + +For information about which Code of Conduct incidents are handled by project leadership, which incidents are handled by the CNCF Code of Conduct Committee, and which incidents are handled by the Linux Foundation (including its events team), see our [Jurisdiction Policy](https://www.cncf.io/conduct/jurisdiction/). + +## Amendments + +Consistent with the CNCF Charter, any substantive changes to this Code of Conduct must be approved by the Technical Oversight Committee. + +## Acknowledgements + +This Code of Conduct is adapted from the Contributor Covenant +(http://contributor-covenant.org), version 2.0 available at +http://contributor-covenant.org/version/2/0/code_of_conduct/ diff --git a/coverage.txt b/coverage.txt new file mode 100644 index 0000000..474e439 --- /dev/null +++ b/coverage.txt @@ -0,0 +1,135 @@ +mode: atomic +github.com/kcp-dev/generic-controlplane/cmd/gcp/main.go:17.13,33.2 5 0 +github.com/kcp-dev/generic-controlplane/server/admission/plugins.go:42.62,60.2 2 0 +github.com/kcp-dev/generic-controlplane/server/admission/plugins.go:63.52,80.2 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:36.106,37.50 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:37.50,42.3 4 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:43.2,43.58 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:43.58,47.3 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:50.103,55.33 4 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:55.33,57.21 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:57.21,58.12 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:61.3,61.35 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:61.35,62.35 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:62.35,64.5 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/help.go:68.2,68.45 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:45.13,47.2 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:50.34,53.28 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:53.28,54.30 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:54.30,55.26 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:55.26,57.5 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:58.9,58.55 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:58.55,60.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:63.2,73.59 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:73.59,78.4 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:79.55,85.111 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:85.111,87.5 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:88.4,91.18 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:91.18,93.5 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:95.4,95.59 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:95.59,97.5 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:100.4,103.38 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:105.55,106.29 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:106.29,107.21 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:107.21,109.6 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:111.4,111.14 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:115.2,121.43 6 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:121.43,123.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:125.2,136.59 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:136.59,141.4 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:142.55,146.4 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:148.2,156.17 4 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:160.68,167.16 4 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:167.16,169.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:170.2,171.16 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:171.16,173.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:176.2,176.42 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:176.42,178.81 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:178.81,180.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:183.2,184.16 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:184.16,186.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:188.2,189.16 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:189.16,191.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:194.2,196.16 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:196.16,198.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:200.2,200.26 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:204.100,208.16 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:208.16,210.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:211.2,215.16 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:215.16,217.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:218.2,219.16 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:219.16,221.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:222.2,223.16 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:223.16,225.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:226.2,226.68 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:226.68,228.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:231.2,232.16 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:232.16,235.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/server.go:237.2,237.30 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:51.66,56.2 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:58.50,59.14 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:59.14,61.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:63.2,65.67 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:65.67,67.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:69.2,69.13 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:72.59,73.14 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:73.14,75.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:77.2,80.136 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:86.133,104.257 5 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:104.257,105.44 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:105.44,107.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:109.3,109.40 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:109.40,111.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:113.3,113.25 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:116.2,118.54 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:121.127,127.2 4 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:129.117,147.24 6 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:147.24,150.3 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/authentication.go:152.2,152.20 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:66.54,77.2 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:81.56,86.31 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:86.31,89.17 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:89.17,91.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:94.2,100.16 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:100.16,102.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:105.2,106.16 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:106.16,108.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:110.2,112.16 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:112.16,114.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:115.2,119.16 4 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:119.16,121.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:122.2,125.16 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:125.16,127.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/config.go:128.2,130.15 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:66.42,100.2 9 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:102.56,113.2 5 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:115.57,116.125 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:116.125,119.3 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:121.2,122.77 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:122.77,125.64 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:125.64,128.18 3 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:128.18,130.5 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:132.4,133.18 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:133.18,135.5 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:136.4,136.72 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:136.72,138.5 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:139.9,139.24 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:139.24,141.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:144.3,146.63 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:146.63,148.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:153.2,158.47 5 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:158.47,160.17 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:160.17,162.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:164.2,164.83 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:164.83,166.17 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:166.17,168.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:170.2,170.72 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:170.72,172.17 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:172.17,174.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:176.2,176.59 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:176.59,178.17 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:178.17,180.4 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:183.2,184.16 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:184.16,186.3 1 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:188.2,197.8 2 0 +github.com/kcp-dev/generic-controlplane/server/cmd/options/options.go:200.47,208.2 5 0 diff --git a/go.mod b/go.mod index f487d99..c5ea814 100644 --- a/go.mod +++ b/go.mod @@ -1,150 +1,170 @@ -module github.com/faroshq/genericcontrolplane +module github.com/kcp-dev/generic-controlplane go 1.22.2 replace ( - k8s.io/apiextensions-apiserver => github.com/sttts/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20240501191542-d434306649a8 - k8s.io/apimachinery => github.com/sttts/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20240501191542-d434306649a8 - k8s.io/apiserver => github.com/sttts/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20240501191542-d434306649a8 - k8s.io/client-go => github.com/sttts/kubernetes/staging/src/k8s.io/client-go v0.0.0-20240501191542-d434306649a8 - k8s.io/cloud-provider => github.com/sttts/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20240501191542-d434306649a8 - k8s.io/cluster-bootstrap => github.com/sttts/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20240501191542-d434306649a8 - k8s.io/component-base => github.com/sttts/kubernetes/staging/src/k8s.io/component-base v0.0.0-20240501191542-d434306649a8 - k8s.io/component-helpers => github.com/sttts/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20240501191542-d434306649a8 - k8s.io/controller-manager => github.com/sttts/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20240501191542-d434306649a8 - k8s.io/csi-translation-lib => github.com/sttts/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20240501191542-d434306649a8 - k8s.io/dynamic-resource-allocation => github.com/sttts/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20240501191542-d434306649a8 - k8s.io/kms => github.com/sttts/kubernetes/staging/src/k8s.io/kms v0.0.0-20240501191542-d434306649a8 - k8s.io/kube-aggregator => github.com/sttts/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20240501191542-d434306649a8 - k8s.io/kubelet => github.com/sttts/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20240501191542-d434306649a8 - k8s.io/kubernetes => github.com/sttts/kubernetes v0.0.0-20240501191542-d434306649a8 - k8s.io/kubernetes/pkg/kubeapiserver => github.com/sttts/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20240501191542-d434306649a8 - k8s.io/mount-utils => github.com/sttts/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20240501191542-d434306649a8 - k8s.io/pod-security-admission => github.com/sttts/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20240501191542-d434306649a8 + k8s.io/api => github.com/mjudeikis/kubernetes/staging/src/k8s.io/api v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/apiextensions-apiserver => github.com/mjudeikis/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/apimachinery => github.com/mjudeikis/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/apiserver => github.com/mjudeikis/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/client-go => github.com/mjudeikis/kubernetes/staging/src/k8s.io/client-go v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/cloud-provider => github.com/mjudeikis/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/cluster-bootstrap => github.com/mjudeikis/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/component-base => github.com/mjudeikis/kubernetes/staging/src/k8s.io/component-base v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/component-helpers => github.com/mjudeikis/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/controller-manager => github.com/mjudeikis/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/csi-translation-lib => github.com/mjudeikis/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/dynamic-resource-allocation => github.com/mjudeikis/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/kms => github.com/mjudeikis/kubernetes/staging/src/k8s.io/kms v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/kube-aggregator => github.com/mjudeikis/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/kubelet => github.com/mjudeikis/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/kubernetes => github.com/mjudeikis/kubernetes v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/kubernetes/pkg/kubeapiserver => github.com/mjudeikis/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/mount-utils => github.com/mjudeikis/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20240512101111-3f9e84a36b95 + k8s.io/pod-security-admission => github.com/mjudeikis/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20240512101111-3f9e84a36b95 ) require ( + github.com/davecgh/go-spew v1.1.1 + github.com/google/uuid v1.6.0 + github.com/kcp-dev/kcp v0.24.0 + github.com/kcp-dev/kcp/cli v0.24.0 + github.com/spf13/cobra v1.8.0 + github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace + k8s.io/apiextensions-apiserver v0.30.0 + k8s.io/apimachinery v0.30.0 + k8s.io/apiserver v0.30.0 + k8s.io/client-go v1.5.2 k8s.io/component-base v0.30.0 - k8s.io/kubernetes v0.0.0-00010101000000-000000000000 + k8s.io/klog/v2 v2.120.1 + k8s.io/kube-aggregator v0.30.0 + k8s.io/kubernetes v1.30.0 ) require ( - github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-oidc v2.2.1+incompatible // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/distribution/reference v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/emicklei/go-restful/v3 v3.12.0 // indirect + github.com/evanphx/json-patch v5.9.0+incompatible // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // 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/cel-go v0.20.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect - github.com/imdario/mergo v0.3.6 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jonboulle/clockwork v0.2.2 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-runewidth v0.0.12 // indirect github.com/moby/spdystream v0.2.0 // indirect - github.com/moby/sys/mountinfo v0.6.2 // indirect - github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect + github.com/moby/sys/mountinfo v0.7.1 // indirect + github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/muesli/reflow v0.3.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/runc v1.1.12 // indirect - github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78 // indirect + github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pquerna/cachecontrol v0.1.0 // indirect - github.com/prometheus/client_golang v1.19.0 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.48.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/pquerna/cachecontrol v0.2.0 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.14.0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/cobra v1.7.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/stoewer/go-strcase v1.2.0 // indirect + github.com/soheilhy/cmux v0.1.5 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect + github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect + go.etcd.io/bbolt v1.3.9 // indirect go.etcd.io/etcd/api/v3 v3.5.13 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect + go.etcd.io/etcd/client/v2 v2.305.13 // indirect go.etcd.io/etcd/client/v3 v3.5.13 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 // indirect - go.opentelemetry.io/otel v1.20.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect - go.opentelemetry.io/otel/metric v1.20.0 // indirect - go.opentelemetry.io/otel/sdk v1.20.0 // indirect - go.opentelemetry.io/otel/trace v1.20.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.etcd.io/etcd/pkg/v3 v3.5.13 // indirect + go.etcd.io/etcd/raft/v3 v3.5.13 // indirect + go.etcd.io/etcd/server/v3 v3.5.13 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect + go.opentelemetry.io/otel v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/sdk v1.26.0 // indirect + go.opentelemetry.io/otel/trace v1.26.0 // indirect + go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.18.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.3.0 // indirect - golang.org/x/tools v0.18.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.21.0 // indirect + google.golang.org/genproto v0.0.0-20240509183442-62759503f434 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240509183442-62759503f434 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 // indirect + google.golang.org/grpc v1.63.2 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.30.0 // indirect - k8s.io/apiextensions-apiserver v0.0.0 // indirect - k8s.io/apimachinery v0.30.0 // indirect - k8s.io/apiserver v0.0.0 // indirect - k8s.io/client-go v0.30.0 // indirect - k8s.io/cloud-provider v0.0.0 // indirect - k8s.io/cluster-bootstrap v0.0.0 // indirect - k8s.io/component-helpers v0.0.0 // indirect - k8s.io/controller-manager v0.0.0 // indirect - k8s.io/dynamic-resource-allocation v0.0.0 // indirect - k8s.io/klog/v2 v2.120.1 // indirect - k8s.io/kms v0.0.0 // indirect - k8s.io/kube-aggregator v0.0.0 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/kubelet v0.0.0 // indirect - k8s.io/mount-utils v0.0.0 // indirect - k8s.io/pod-security-admission v0.0.0 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 // indirect + k8s.io/cloud-provider v0.30.0 // indirect + k8s.io/cluster-bootstrap v0.30.0 // indirect + k8s.io/component-helpers v0.30.0 // indirect + k8s.io/controller-manager v0.30.0 // indirect + k8s.io/dynamic-resource-allocation v0.30.0 // indirect + k8s.io/kms v0.30.0 // indirect + k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect + k8s.io/kubelet v0.30.0 // indirect + k8s.io/mount-utils v0.30.0 // indirect + k8s.io/pod-security-admission v0.30.0 // indirect + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index c58c273..98b4741 100644 --- a/go.sum +++ b/go.sum @@ -1,57 +1,65 @@ -cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o= -cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= -cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -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= +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= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= 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 h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 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/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= 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/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/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= +github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +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.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 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= @@ -59,14 +67,16 @@ 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.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -74,11 +84,13 @@ 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.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= @@ -87,29 +99,32 @@ github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= @@ -118,119 +133,140 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kcp-dev/kcp v0.24.0 h1:x06ZmV4jD62Bud4LTZ0ZhYKnU8HV4SaC4itnNXh8+60= +github.com/kcp-dev/kcp v0.24.0/go.mod h1:O4UpjzfI7Dua73XcxI7jy8nO1JWYKKfZCN4FoRTrhq4= +github.com/kcp-dev/kcp/cli v0.24.0 h1:F5+yCnG6HZLLkomVXVUgs9FLIHv1wECO63w69llfVw8= +github.com/kcp-dev/kcp/cli v0.24.0/go.mod h1:ANd0Za2j1ukYbhHPephgKcWoS++m23NoZsBdQNHyBj4= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mjudeikis/kubernetes v0.0.0-20240512101111-3f9e84a36b95 h1:3QimZjv0Ge7TIITXGuxt9CBLAACA4CE7MEM9HBN48Zw= +github.com/mjudeikis/kubernetes v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:IfbAr+1Z8XzU3C4sYcgGNZZEdOUI0mCVXzyDElNyYyo= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/api v0.0.0-20240512101111-3f9e84a36b95 h1:TE3DP215WWS5sUYFoA447vu2gZRl3PKOrf7NpWG28N8= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/api v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:ICDfU3tSHIYVrHWwk7OAOqC+sibWZwRjdfciCGsb6Go= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20240512101111-3f9e84a36b95 h1:OnstMz0+9XMzcK7iaNQuofkKnRv/3jxNK64MnKrnWZ0= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:3IgbG+YR82gyT2p7cZvK4IW3wp6U7r9ZDsX1uCUF+xM= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20240512101111-3f9e84a36b95 h1:AGhmt50FyvDWGlrhf7bdCDzYN2nHFJgEHh8FcCIFLcg= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:9LC0WdADQ0Pnq0O3Hxd58YdbR27+AVmT43g7knHYsS8= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20240512101111-3f9e84a36b95 h1:Cazb3G05fkKDCtIwm6DH/vMyF7F6K+svJnB3eNkP50U= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:NF5YiYdzdWdKWs92aLIZ12RPy35Es9JFEmwQkUWsa24= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/client-go v0.0.0-20240512101111-3f9e84a36b95 h1:Eo5PGQcW0vTypJnM4cIeeJidR3Zs9SaTdNSbjrgLdW4= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/client-go v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:z+ySpYalmBfJ9MFoAg2UOU7oQFp0tmbhM5CQgBnUYMQ= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20240512101111-3f9e84a36b95 h1:CGgVxCc37iywiIUXWudrUgd8CtRszD4S8Et+3yNH0S8= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:0RsCch2QyMNzzNsAa22RQI6rVdPTISm4740cLvIVsdI= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20240512101111-3f9e84a36b95 h1:xpBzUClL8rg+7WgGD3J+8E4PI2XeX1o/kQ8Cu9vVopY= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:UQkCN/yAyK9GkwLx9OvIewMG++WMMmqM1ol0dZeih0Q= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/component-base v0.0.0-20240512101111-3f9e84a36b95 h1:Pt0L2Fm8Yi+w5yb6Gmb4PWdgg1R81JQ2gRmREM2+9Rc= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/component-base v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:XWhuH85JxTDm/OFNA90C1jVe/CX0wAZ5MD4a0SzvMfM= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20240512101111-3f9e84a36b95 h1:SbPg4fWAiBDBsS1JhNvW0B9mttQVkn1o03LcrYiAqaY= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:gq9wIgbQtWxfRsrD8B0v3uscn4AowpQLKcJTIotoZUk= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20240512101111-3f9e84a36b95 h1:GcvSjGucrPtLu2hKhhmJA2kMRr5zDcuIzk2JF4KqD4I= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:fani0h571V5hIVCoQrQwikZvM55nGq/WqTzH5AOOWEk= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20240512101111-3f9e84a36b95 h1:pLYow/E1zceGepQ2dBh9KR2hgXX39bb+GRi0V+WXYVw= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:9vQV+VVn1JokCsMW64sBjO2q+mBi5+63qx97umgN1KY= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20240512101111-3f9e84a36b95 h1:BbQjT6x11VDpd2fJ42ni5guBPdJRAt++IxDzRb6q2n4= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:2PFH7IVAz6TLCx7BMgCaIHq4b/9D5hKx60wXEEYdNdU= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/kms v0.0.0-20240512101111-3f9e84a36b95 h1:oPMC3rX5DxnB20yOL4ZnYzmNq6DEXCyNwY5b/QFEJG4= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/kms v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:JWkEZgNbzdaGYIVX8NnySZwwnVK2agjCfABZ7qdTDCI= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20240512101111-3f9e84a36b95 h1:E5ybPl3rxODIHusn+CPJ6m/J77HtB3Rec+yCNRgP73M= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:AsZ97EEoow2At2PSjth3hfDP8u+FlE0ztot2mju+TcQ= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20240512101111-3f9e84a36b95 h1:ukXrXI+Z11b07/kSjZiq4sz0DB7/2zQbvp02j+xyd0Y= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:26ueMeEXGMWoRpluqlgNi6bPKLEHfg1ao+3/5hG7NxE= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20240512101111-3f9e84a36b95 h1:WkYOwa1MU0/sSSNVmp6SuZC7WndhcAbwB7mUGe96zbQ= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:XgFjea/ua9X2Npt7E+LUHW88UBQWiWfLzHByG66/OGs= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20240512101111-3f9e84a36b95 h1:Nc1n94oXRgy67yWt73iCJM7adlCUqdCefEYwCkLK+zU= +github.com/mjudeikis/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20240512101111-3f9e84a36b95/go.mod h1:rZikTqeHWJerLiexSbU7UMmpEdVo5RkFxba57hqsaWo= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= -github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= -github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= -github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= +github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= 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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= -github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE= -github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= +github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= 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/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= -github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78 h1:R5M2qXZiK/mWPMT4VldCOiSL9HIAMuxQZWdG0CSM5+4= -github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= -github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= -github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= -github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k= +github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s= +github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace h1:9PNP1jnUjRhfmGMlkXHjYPishpcw4jpSt/V/xYY3FMA= +github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= 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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -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/sttts/kubernetes v0.0.0-20240501191542-d434306649a8 h1:rjCO7okpt5iB6gXPB1o7RL2nja38OMKtIs+jkhZ0mbk= -github.com/sttts/kubernetes v0.0.0-20240501191542-d434306649a8/go.mod h1:mtKIz7WDSI3OAunKH7RalLWpTfM54ZIEKHEZKaUv3RQ= -github.com/sttts/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20240501191542-d434306649a8 h1:UjBIO5AKh2wd5MfKP/SWk4PLWDzGb3Bgj975ZqSMQ68= -github.com/sttts/kubernetes/staging/src/k8s.io/apiextensions-apiserver v0.0.0-20240501191542-d434306649a8/go.mod h1:FKGrpMXNRPdHAcq9Ll+0EbyJLZb5xJtAB8YAcJ2IHU4= -github.com/sttts/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20240501191542-d434306649a8 h1:/37f3Qj/gxYM7rjlRznE9oar/cYSr54Z//SXyG/49v8= -github.com/sttts/kubernetes/staging/src/k8s.io/apimachinery v0.0.0-20240501191542-d434306649a8/go.mod h1:9LC0WdADQ0Pnq0O3Hxd58YdbR27+AVmT43g7knHYsS8= -github.com/sttts/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20240501191542-d434306649a8 h1:clyGvgekQnxxgcLDnv9lphyVObpBk5YgwEixzInfYk0= -github.com/sttts/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20240501191542-d434306649a8/go.mod h1:6btq9lzI0uhiGvbuf1ZFkA0sWEjURp17yHnJTaDiras= -github.com/sttts/kubernetes/staging/src/k8s.io/client-go v0.0.0-20240501191542-d434306649a8 h1:jMyvdvQpMAldy184PCWsSh9A8/52sXYdFHOAmhtCtK4= -github.com/sttts/kubernetes/staging/src/k8s.io/client-go v0.0.0-20240501191542-d434306649a8/go.mod h1:A3RL10HzbALCJxikIH+Ljlp8Ny1E4lDxKiUrUOQ1sxQ= -github.com/sttts/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20240501191542-d434306649a8 h1:eH4OMbY8imLU1z/PR797dWARvR9ybBObf22gfihOjJI= -github.com/sttts/kubernetes/staging/src/k8s.io/cloud-provider v0.0.0-20240501191542-d434306649a8/go.mod h1:Ku7HUBiUkHCa3etw3YRGrj+S4ypaINqv7y9YPaogpxg= -github.com/sttts/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20240501191542-d434306649a8 h1:m+soJL8qO5xouLo5zLz52j9MkMpwyTjyZrJmkIEt7oQ= -github.com/sttts/kubernetes/staging/src/k8s.io/cluster-bootstrap v0.0.0-20240501191542-d434306649a8/go.mod h1:UQkCN/yAyK9GkwLx9OvIewMG++WMMmqM1ol0dZeih0Q= -github.com/sttts/kubernetes/staging/src/k8s.io/component-base v0.0.0-20240501191542-d434306649a8 h1:aIm8/3qw/E9YAVUC9CRqM9ZRA1OxB8drL83GjFA6pIM= -github.com/sttts/kubernetes/staging/src/k8s.io/component-base v0.0.0-20240501191542-d434306649a8/go.mod h1:PmzUSOfov/qVcyM0uokja7tni09R0XkCuleQIbVo650= -github.com/sttts/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20240501191542-d434306649a8 h1:V1GBn0MnZvyhNmJVPhVHNyJMQf5KuAatbtjlrifrWUY= -github.com/sttts/kubernetes/staging/src/k8s.io/component-helpers v0.0.0-20240501191542-d434306649a8/go.mod h1:OC0nNFIHPHm6PQKhXop7gXAwetlVIVdn1VvEZSvqObA= -github.com/sttts/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20240501191542-d434306649a8 h1:G5dfTF1vWITqhBGrxrzg8zkD9u0Cy1652ijFO20GXzU= -github.com/sttts/kubernetes/staging/src/k8s.io/controller-manager v0.0.0-20240501191542-d434306649a8/go.mod h1:CzmlPpBQy4Xta15DMmue1Lv03HG6N80v6+lKg+W80mw= -github.com/sttts/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20240501191542-d434306649a8 h1:7T3o81QCh4/DfrJiwjy1Edu81wN7eprDj88FNm22u14= -github.com/sttts/kubernetes/staging/src/k8s.io/csi-translation-lib v0.0.0-20240501191542-d434306649a8/go.mod h1:9vQV+VVn1JokCsMW64sBjO2q+mBi5+63qx97umgN1KY= -github.com/sttts/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20240501191542-d434306649a8 h1:4zkwObUHjCZ3xmPNcFEfytXIQuJGjy5tL5cCyYfpgJk= -github.com/sttts/kubernetes/staging/src/k8s.io/dynamic-resource-allocation v0.0.0-20240501191542-d434306649a8/go.mod h1:7cgdK3rYa6fQFHX715vIui8ObmgR8DSmNB+EwTXpDJY= -github.com/sttts/kubernetes/staging/src/k8s.io/kms v0.0.0-20240501191542-d434306649a8 h1:Jo44j4qS+YQw4hnspQ+04sNDXpMEmOWxfMxgaLJLjvY= -github.com/sttts/kubernetes/staging/src/k8s.io/kms v0.0.0-20240501191542-d434306649a8/go.mod h1:JWkEZgNbzdaGYIVX8NnySZwwnVK2agjCfABZ7qdTDCI= -github.com/sttts/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20240501191542-d434306649a8 h1:1neu/47kfwFh40OjwyeSuWu+y9KBUVuAhaubgGUEqnk= -github.com/sttts/kubernetes/staging/src/k8s.io/kube-aggregator v0.0.0-20240501191542-d434306649a8/go.mod h1:KkrIdAcENXjUEuyRnvAed0ouc4zBPLzKMDFba/iLQsw= -github.com/sttts/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20240501191542-d434306649a8 h1:DExAR9sp1I9uivYdFh2mB5fuLaBwSwe82UTQWB5QEc0= -github.com/sttts/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20240501191542-d434306649a8/go.mod h1:Dk9+7yJ1KfpxdrW8d2lTFVoUq2fRmEIvmpesgPJAjs0= -github.com/sttts/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20240501191542-d434306649a8 h1:iGf9YdK1gewybL3APV8IqL275yW8k+raHVCcg4LbDTI= -github.com/sttts/kubernetes/staging/src/k8s.io/mount-utils v0.0.0-20240501191542-d434306649a8/go.mod h1:XgFjea/ua9X2Npt7E+LUHW88UBQWiWfLzHByG66/OGs= -github.com/sttts/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20240501191542-d434306649a8 h1:htyCChX/We7rERFyyFAGN4lS5obSDStyWQWTriNaoxY= -github.com/sttts/kubernetes/staging/src/k8s.io/pod-security-admission v0.0.0-20240501191542-d434306649a8/go.mod h1:EusRwJFhCZZhX1XN69YTF+CNjLiHbvVhVdquOHXJSRk= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= @@ -253,94 +289,135 @@ go.etcd.io/etcd/raft/v3 v3.5.13 h1:7r/NKAOups1YnKcfro2RvGGo2PTuizF/xh26Z2CTAzA= go.etcd.io/etcd/raft/v3 v3.5.13/go.mod h1:uUFibGLn2Ksm2URMxN1fICGhk8Wu96EfDQyuLhAcAmw= go.etcd.io/etcd/server/v3 v3.5.13 h1:V6KG+yMfMSqWt+lGnhFpP5z5dRUj1BDRJ5k1fQ9DFok= go.etcd.io/etcd/server/v3 v3.5.13/go.mod h1:K/8nbsGupHqmr5MkgaZpLlH1QdX1pcNQLAkODy44XcQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 h1:PzIubN4/sjByhDRHLviCjJuweBXWFZWhghjg7cS28+M= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0/go.mod h1:Ct6zzQEuGK3WpJs2n4dn+wfJYzd/+hNnxMRTWjGn30M= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= -go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc= -go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0= -go.opentelemetry.io/otel/metric v1.20.0 h1:ZlrO8Hu9+GAhnepmRGhSU7/VkpjrNowxRN9GyKR4wzA= -go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM= -go.opentelemetry.io/otel/sdk v1.20.0 h1:5Jf6imeFZlZtKv9Qbo6qt2ZkmWtdWx/wzcCbNUlAWGM= -go.opentelemetry.io/otel/sdk v1.20.0/go.mod h1:rmkSx1cZCm/tn16iWDn1GQbLtsW/LvsdEEFzCSRM6V0= -go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ= -go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= +go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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.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-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= -golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.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-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-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/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-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.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -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/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.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.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -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/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20240509183442-62759503f434 h1:+PQKEGakpJad0y8bF9UJlgg4dO2U5H+cydccJNjzkww= +google.golang.org/genproto v0.0.0-20240509183442-62759503f434/go.mod h1:i4np6Wrjp8EujFAUn0CM0SH+iZhY1EbrfzEIJbFkHFM= +google.golang.org/genproto/googleapis/api v0.0.0-20240509183442-62759503f434 h1:OpXbo8JnN8+jZGPrL4SSfaDjSCjupr8lXyBAbexEm/U= +google.golang.org/genproto/googleapis/api v0.0.0-20240509183442-62759503f434/go.mod h1:FfiGhwUm6CJviekPrc0oJ+7h29e+DmWU6UtjX0ZvI7Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 h1:umK/Ey0QEzurTNlsV3R+MfxHAb78HCEX/IkuR+zH4WQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434/go.mod h1:I7Y+G38R2bu5j1aLzfFmQfTcU/WnFuqDwLZAbvKTKpM= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= @@ -351,22 +428,23 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= 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.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= -k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 h1:/U5vjBbQn3RChhv7P11uhYvCSm5G2GaIi5AIGBS6r4c= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0/go.mod h1:z7+wmGM2dfIiLRfrC6jb5kV2Mq/sK1ZP303cxzkV5Y4= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f h1:0LQagt0gDpKqvIkAMPaRGcXawNMouPECM1+F9BVxEaM= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f/go.mod h1:S9tOR0FxgyusSNR+MboCuiDpVWkAifZvaYI1Q2ubgro= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/hack/OWNERS b/hack/OWNERS new file mode 100644 index 0000000..5acf548 --- /dev/null +++ b/hack/OWNERS @@ -0,0 +1,6 @@ +approvers: +- ncdc +- sttts +- stevekuznetsov +reviewers: +- csams diff --git a/hack/boilerplate/boilerplate.Dockerfile.txt b/hack/boilerplate/boilerplate.Dockerfile.txt new file mode 100644 index 0000000..ba9ca5f --- /dev/null +++ b/hack/boilerplate/boilerplate.Dockerfile.txt @@ -0,0 +1,16 @@ +# syntax=docker/dockerfile:1.4 + +# Copyright YEAR The KCP Authors. +# +# 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. + diff --git a/hack/boilerplate/boilerplate.Makefile.txt b/hack/boilerplate/boilerplate.Makefile.txt new file mode 100644 index 0000000..16845c7 --- /dev/null +++ b/hack/boilerplate/boilerplate.Makefile.txt @@ -0,0 +1,14 @@ +# Copyright YEAR The KCP Authors. +# +# 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. + diff --git a/hack/boilerplate/boilerplate.generatego.txt b/hack/boilerplate/boilerplate.generatego.txt new file mode 100644 index 0000000..2d3aa51 --- /dev/null +++ b/hack/boilerplate/boilerplate.generatego.txt @@ -0,0 +1,16 @@ +/* +Copyright The KCP Authors. + +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. +*/ + diff --git a/hack/boilerplate/boilerplate.go.txt b/hack/boilerplate/boilerplate.go.txt new file mode 100644 index 0000000..f6d7ed8 --- /dev/null +++ b/hack/boilerplate/boilerplate.go.txt @@ -0,0 +1,16 @@ +/* +Copyright YEAR The KCP Authors. + +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. +*/ + diff --git a/hack/boilerplate/boilerplate.py.txt b/hack/boilerplate/boilerplate.py.txt new file mode 100644 index 0000000..16845c7 --- /dev/null +++ b/hack/boilerplate/boilerplate.py.txt @@ -0,0 +1,14 @@ +# Copyright YEAR The KCP Authors. +# +# 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. + diff --git a/hack/boilerplate/boilerplate.sh.txt b/hack/boilerplate/boilerplate.sh.txt new file mode 100644 index 0000000..16845c7 --- /dev/null +++ b/hack/boilerplate/boilerplate.sh.txt @@ -0,0 +1,14 @@ +# Copyright YEAR The KCP Authors. +# +# 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. + diff --git a/hack/build-image.sh b/hack/build-image.sh new file mode 100755 index 0000000..fa4df3e --- /dev/null +++ b/hack/build-image.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +# Copyright 2023 The KCP Authors. +# +# 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. + +set -euo pipefail + +# make git available +if ! [ -x "$(command -v git)" ]; then + echo "Installing git ..." + yum install -y git +fi + +# in CI, make use of the registry mirror to avoid getting rate limited +if [ -n "${DOCKER_REGISTRY_MIRROR_ADDR:-}" ]; then + # remove "http://" or "https://" prefix + mirror="$(echo "$DOCKER_REGISTRY_MIRROR_ADDR" | awk -F// '{print $NF}')" + + echo "Configuring registry mirror for docker.io ..." + + cat < /etc/containers/registries.conf.d/mirror.conf +[[registry]] +prefix = "docker.io" +insecure = true +location = "$mirror" +EOF +fi + +repository=ghcr.io/kcp-dev/kcp +architectures="amd64 arm64 ppc64le" + +# when building locally, just tag with the current HEAD hash +version="$(git rev-parse --short HEAD)" +branchName="" + +# deduce the tag from the Prow job metadata +if [ -n "${PULL_BASE_REF:-}" ]; then + version="$(git tag --list "$PULL_BASE_REF")" + + if [ -z "$version" ]; then + # if the base ref did not point to a tag, it's a branch name + version="$(git rev-parse --short "$PULL_BASE_REF")" + branchName="$PULL_BASE_REF" + else + # If PULL_BASE_REF is a tag, there is no branch availabe locally, plus + # there is no guarantee that vX.Y.Z is tagged _only_ in the release-X.Y + # branch; because of this we have to deduce the branch name from the tag + branchName="$(echo "$version" | sed -E 's/^v([0-9]+)\.([0-9]+)\..*/release-\1.\2/')" + fi +fi + +image="$repository:$version" +echo "Building container image $image ..." + +# build image for all architectures +for arch in $architectures; do + fullTag="$image-$arch" + + echo "Building $version-$arch ..." + buildah build-using-dockerfile \ + --file Dockerfile \ + --tag "$fullTag" \ + --arch "$arch" \ + --override-arch "$arch" \ + --build-arg "TARGETOS=linux" \ + --build-arg "TARGETARCH=$arch" \ + --format=docker \ + . +done + +echo "Creating manifest $image ..." +buildah manifest create "$image" +for arch in $architectures; do + buildah manifest add "$image" "$image-$arch" +done + +# Additionally to an image tagged with the Git tag, we also +# release images tagged with the current branch name, which +# is somewhere between a blanket "latest" tag and a specific +# tag. +if [ -n "$branchName" ]; then + branchImage="$repository:$branchName" + + echo "Creating manifest $branchImage ..." + buildah manifest create "$branchImage" + for arch in $architectures; do + buildah manifest add "$branchImage" "$image-$arch" + done +fi + +# push manifest, except in presubmits +if [ -z "${DRY_RUN:-}" ]; then + echo "Logging into GHCR ..." + buildah login --username "$KCP_GHCR_USERNAME" --password "$KCP_GHCR_PASSWORD" ghcr.io + + echo "Pushing manifest and images ..." + buildah manifest push --all "$image" "docker://$image" + + if [ -n "${branchImage:-}" ]; then + buildah manifest push --all "$branchImage" "docker://$branchImage" + fi +else + echo "Not pushing images because \$DRY_RUN is set." +fi + +echo "Done." diff --git a/hack/bump-k8s.sh b/hack/bump-k8s.sh new file mode 100755 index 0000000..da405ea --- /dev/null +++ b/hack/bump-k8s.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +# Copyright 2021 The KCP Authors. +# +# 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. + +set -o errexit +set -o nounset +set -o pipefail +set -o xtrace + +# The normal flow for updating a replaced dependency would look like: +# $ go mod edit -replace old=new@branch +# $ go mod tidy +# However, we don't know all of the specific packages that we pull in from the staging repos, +# nor do we want to update this script when that set changes. Therefore, we just look up the +# version of the k8s.io/kubernetes replacement and replace all modules at that version, since +# we know we will always want to use a self-consistent set of modules from our fork. +# Note: setting GOPROXY=direct allows us to bump very quickly after the fork has been committed to. +GITHUB_USER=${GITHUB_USER:-kcp-dev} +GITHUB_REPO=${GITHUB_REPO:-kubernetes} +BRANCH=${BRANCH:-kcp-feature-logical-clusters-1.24-v3} + +current_version="$( GOPROXY=direct go mod edit -json | jq '.Replace[] | select(.Old.Path=="k8s.io/kubernetes") | .New.Version' --raw-output )" + +# equivalent to go mod edit -replace +is_gnu_sed() { sed --version >/dev/null 2>&1; } +if is_gnu_sed; then + SED="sed -i" +else + SED="sed -i ''" +fi +${SED} -e "s|${current_version}|${BRANCH}|g" -E -e "s,=> github.com/kcp-dev/kubernetes,=> github.com/${GITHUB_USER}/${GITHUB_REPO},g" go.mod + +GOPROXY=direct go mod tidy diff --git a/hack/go-install.sh b/hack/go-install.sh new file mode 100755 index 0000000..ef6f8af --- /dev/null +++ b/hack/go-install.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# Copyright 2021 The KCP Authors. +# +# 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. + +# Originally copied from +# https://github.com/kubernetes-sigs/cluster-api-provider-gcp/blob/c26a68b23e9317323d5d37660fe9d29b3d2ff40c/scripts/go_install.sh + +set -o errexit +set -o nounset +set -o pipefail + +if [[ -z "${1:-}" ]]; then + echo "must provide module as first parameter" + exit 1 +fi + +if [[ -z "${2:-}" ]]; then + echo "must provide binary name as second parameter" + exit 1 +fi + +if [[ -z "${3:-}" ]]; then + echo "must provide version as third parameter" + exit 1 +fi + +if [[ -z "${GOBIN:-}" ]]; then + echo "GOBIN is not set. Must set GOBIN to install the bin in a specified directory." + exit 1 +fi + +mkdir -p "${GOBIN}" + +tmp_dir=$(mktemp -d -t goinstall_XXXXXXXXXX) +function clean { + rm -rf "${tmp_dir}" +} +trap clean EXIT + +rm "${GOBIN}/${2}"* > /dev/null 2>&1 || true + +cd "${tmp_dir}" + +# create a new module in the tmp directory +go mod init fake/mod + +# install the golang module specified as the first argument +go install -tags kcptools "${1}@${3}" +mv "${GOBIN}/${2}" "${GOBIN}/${2}-${3}" +ln -sf "${GOBIN}/${2}-${3}" "${GOBIN}/${2}" \ No newline at end of file diff --git a/hack/logcheck.out b/hack/logcheck.out new file mode 100644 index 0000000..e69de29 diff --git a/hack/update-go-modules.sh b/hack/update-go-modules.sh new file mode 100755 index 0000000..0a719a2 --- /dev/null +++ b/hack/update-go-modules.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# Copyright 2023 The KCP Authors. +# +# 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 tidies all go modules in the repository. + +set -o errexit +set -o nounset +set -o pipefail + +REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) + +mapfile -t DIRS < <(find "${REPO_ROOT}" -name go.mod -print0 | xargs -0 dirname) + +for dir in "${DIRS[@]}"; do + echo "Tidying ${dir}" + go mod tidy +done diff --git a/hack/verify-go-modules.sh b/hack/verify-go-modules.sh new file mode 100755 index 0000000..401b811 --- /dev/null +++ b/hack/verify-go-modules.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Copyright 2023 The KCP Authors. +# +# 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 verifies all go modules in the repository. + +set -o errexit +set -o nounset +set -o pipefail + +REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) + +mapfile -t DIRS < <(find "${REPO_ROOT}" -name go.mod -print0 | xargs -0 dirname) + +for dir in "${DIRS[@]}"; do + ( + cd "$dir" + echo "Verifying ${dir}" + if ! git diff --quiet HEAD -- go.mod go.sum; then + echo "go module files are out of date" + git diff HEAD -- go.mod go.sum + exit 1 + fi + ) +done diff --git a/hack/verify-go-versions.sh b/hack/verify-go-versions.sh new file mode 100755 index 0000000..5ec8a1a --- /dev/null +++ b/hack/verify-go-versions.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +# Copyright 2022 The KCP Authors. +# +# 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. + +set -e +set -o pipefail + +VERSION=$(grep "go 1." go.mod | sed 's/go //') + +grep "FROM .* docker.io/golang:" Dockerfile | { ! grep -v "${VERSION}"; } || { echo "Wrong go version in Dockerfile, expected ${VERSION}"; exit 1; } + +# Check prow config +grep "ghcr.io/kcp-dev/infra/build" ".prow.yaml" | { ! grep -v "${VERSION}"; } || { echo "Wrong go version in .prow.yaml; expected ${VERSION}"; exit 1; } + +if [ -z "${IGNORE_GO_VERSION}" ]; then + go version | { ! grep -v go${VERSION}; } || { echo "Unexpected go version installed, expected ${VERSION}. Use IGNORE_GO_VERSION=1 to skip this check."; exit 1; } +fi diff --git a/hack/verify-imports.sh b/hack/verify-imports.sh new file mode 100755 index 0000000..e9dbf06 --- /dev/null +++ b/hack/verify-imports.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Copyright 2022 The KCP Authors. +# +# 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 ensures that the generated client code checked into git is up-to-date +# with the generator. If it is not, re-generate the configuration to update it. + +set -o errexit +set -o nounset +set -o pipefail + +make -C "$( dirname "${BASH_SOURCE[0]}")/../" imports +if ! git diff --quiet --exit-code ; then + cat << EOF +ERROR: This check enforces that import statements are ordered correctly. +ERROR: The import statements are out of order. Run the following command +ERROR: to regenerate the statements: +ERROR: $ make imports +ERROR: The following differences were found: +EOF + git diff + exit 1 +fi \ No newline at end of file diff --git a/minimal-control-plane/main.go b/minimal-control-plane/main.go deleted file mode 100644 index 0f90bc9..0000000 --- a/minimal-control-plane/main.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -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. -*/ - -// sample-minimal-controlplane is a kube-like generic control plane -// It is compatible to kube-apiserver, but lacks the container domain -// specific APIs. -package main - -import ( - "os" - - "k8s.io/component-base/cli" - _ "k8s.io/component-base/logs/json/register" - _ "k8s.io/component-base/metrics/prometheus/clientgo" - _ "k8s.io/component-base/metrics/prometheus/version" - - "k8s.io/kubernetes/cmd/sample-minimal-controlplane/server" -) - -func main() { - command := server.NewCommand() - code := cli.Run(command) - os.Exit(code) -} diff --git a/server/admission/plugins.go b/server/admission/plugins.go new file mode 100644 index 0000000..5f7ce64 --- /dev/null +++ b/server/admission/plugins.go @@ -0,0 +1,106 @@ +/* +Copyright 2024 The KCP Authors. + +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 admission + +import ( + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle" + validatingadmissionpolicy "k8s.io/apiserver/pkg/admission/plugin/policy/validating" + "k8s.io/apiserver/pkg/admission/plugin/resourcequota" + mutatingwebhook "k8s.io/apiserver/pkg/admission/plugin/webhook/mutating" + validatingwebhook "k8s.io/apiserver/pkg/admission/plugin/webhook/validating" + "k8s.io/kubernetes/plugin/pkg/admission/admit" + certapproval "k8s.io/kubernetes/plugin/pkg/admission/certificates/approval" + "k8s.io/kubernetes/plugin/pkg/admission/certificates/ctbattest" + certsigning "k8s.io/kubernetes/plugin/pkg/admission/certificates/signing" + certsubjectrestriction "k8s.io/kubernetes/plugin/pkg/admission/certificates/subjectrestriction" + "k8s.io/kubernetes/plugin/pkg/admission/defaulttolerationseconds" + "k8s.io/kubernetes/plugin/pkg/admission/deny" + "k8s.io/kubernetes/plugin/pkg/admission/eventratelimit" + "k8s.io/kubernetes/plugin/pkg/admission/gc" + "k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision" + "k8s.io/kubernetes/plugin/pkg/admission/namespace/exists" + "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount" + // Admission policies +) + +// AllOrderedPlugins is the list of all the plugins in order. +var AllOrderedPlugins = []string{ + admit.PluginName, // AlwaysAdmit + autoprovision.PluginName, // NamespaceAutoProvision + lifecycle.PluginName, // NamespaceLifecycle + exists.PluginName, // NamespaceExists + //limitranger.PluginName, // LimitRanger + serviceaccount.PluginName, // ServiceAccount + eventratelimit.PluginName, // EventRateLimit + gc.PluginName, // OwnerReferencesPermissionEnforcement + certapproval.PluginName, // CertificateApproval + certsigning.PluginName, // CertificateSigning + ctbattest.PluginName, // ClusterTrustBundleAttest + certsubjectrestriction.PluginName, // CertificateSubjectRestriction + + // new admission plugins should generally be inserted above here + // webhook, resourcequota, and deny plugins must go at the end + mutatingwebhook.PluginName, // MutatingAdmissionWebhook + validatingadmissionpolicy.PluginName, // ValidatingAdmissionPolicy + validatingwebhook.PluginName, // ValidatingAdmissionWebhook + resourcequota.PluginName, // ResourceQuota + deny.PluginName, // AlwaysDeny +} + +// RegisterAllAdmissionPlugins registers all admission plugins. +// The order of registration is irrelevant, see AllOrderedPlugins for execution order. +func RegisterAllAdmissionPlugins(plugins *admission.Plugins) { + admit.Register(plugins) // DEPRECATED as no real meaning + autoprovision.Register(plugins) + lifecycle.Register(plugins) + exists.Register(plugins) + //limitranger.Register(plugins) + serviceaccount.Register(plugins) + eventratelimit.Register(plugins) + gc.Register(plugins) + certapproval.Register(plugins) + certsigning.Register(plugins) + ctbattest.Register(plugins) + certsubjectrestriction.Register(plugins) + mutatingwebhook.Register(plugins) + validatingadmissionpolicy.Register(plugins) + validatingwebhook.Register(plugins) + resourcequota.Register(plugins) + deny.Register(plugins) +} + +// DefaultOffAdmissionPlugins get admission plugins off by default for kube-apiserver. +func DefaultOffAdmissionPlugins() sets.Set[string] { + defaultOnPlugins := sets.New( + lifecycle.PluginName, // NamespaceLifecycle + //limitranger.PluginName, // LimitRanger + serviceaccount.PluginName, // ServiceAccount + defaulttolerationseconds.PluginName, // DefaultTolerationSeconds + mutatingwebhook.PluginName, // MutatingAdmissionWebhook + validatingwebhook.PluginName, // ValidatingAdmissionWebhook + resourcequota.PluginName, // ResourceQuota + certapproval.PluginName, // CertificateApproval + certsigning.PluginName, // CertificateSigning + ctbattest.PluginName, // ClusterTrustBundleAttest + certsubjectrestriction.PluginName, // CertificateSubjectRestriction + validatingadmissionpolicy.PluginName, // ValidatingAdmissionPolicy, only active when feature gate ValidatingAdmissionPolicy is enabled + ) + + return sets.New[string](AllOrderedPlugins...).Difference(defaultOnPlugins) +} diff --git a/server/cmd/help.go b/server/cmd/help.go new file mode 100644 index 0000000..d477138 --- /dev/null +++ b/server/cmd/help.go @@ -0,0 +1,69 @@ +/* +Copyright 2022 The KCP Authors. + +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 server + +import ( + "fmt" + "io" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + "k8s.io/apimachinery/pkg/util/sets" + cliflag "k8s.io/component-base/cli/flag" +) + +const ( + usageFmt = "Usage:\n %s\n" +) + +// setPartialUsageAndHelpFunc set both usage and help function. +// Print the flag sets we need instead of all of them. +func setPartialUsageAndHelpFunc(cmd *cobra.Command, fss cliflag.NamedFlagSets, cols int, flags []string) { + cmd.SetUsageFunc(func(cmd *cobra.Command) error { + fmt.Fprintf(cmd.OutOrStderr(), usageFmt, cmd.UseLine()) + printMostImportantFlags(cmd.OutOrStderr(), fss, cols, flags) + fmt.Fprintf(cmd.OutOrStderr(), "\nUse \"%s\" for a list of all flags available.\n", cmd.CommandPath()) + return nil + }) + cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { + fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n"+usageFmt, cmd.Long, cmd.UseLine()) + printMostImportantFlags(cmd.OutOrStdout(), fss, cols, flags) + fmt.Fprintf(cmd.OutOrStderr(), "\nUse \"%s options\" for a list of all flags available.\n", cmd.CommandPath()) + }) +} + +func printMostImportantFlags(w io.Writer, fss cliflag.NamedFlagSets, cols int, visibleFlags []string) { + visibleFlagsSet := sets.New[string](visibleFlags...) + filteredFFS := cliflag.NamedFlagSets{} + filteredFS := filteredFFS.FlagSet("Most important") + + for _, name := range fss.Order { + fs := fss.FlagSets[name] + if !fs.HasFlags() { + continue + } + + fs.VisitAll(func(f *pflag.Flag) { + if visibleFlagsSet.Has(f.Name) { + filteredFS.AddFlag(f) + } + }) + } + + cliflag.PrintSections(w, filteredFFS, cols) +} diff --git a/server/cmd/options/authentication.go b/server/cmd/options/authentication.go new file mode 100644 index 0000000..e475015 --- /dev/null +++ b/server/cmd/options/authentication.go @@ -0,0 +1,153 @@ +/* +Copyright 2022 The KCP Authors. + +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 options + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/google/uuid" + "github.com/spf13/pflag" + + "k8s.io/apiserver/pkg/authentication/authenticator" + "k8s.io/apiserver/pkg/authentication/group" + "k8s.io/apiserver/pkg/authentication/request/bearertoken" + authenticatorunion "k8s.io/apiserver/pkg/authentication/request/union" + "k8s.io/apiserver/pkg/authentication/user" + genericapiserver "k8s.io/apiserver/pkg/server" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" +) + +const ( + // A kcp admin being member of system-admin + gcpAdminUserName = "system-admin" + // A non-admin user part of the "user" battery. + gcpUserUserName = "user" +) + +type AdminAuthentication struct { + KubeConfigPath string + + // TODO: move into Secret in-cluster, maybe by using an "in-cluster" string as value + ShardAdminTokenHashFilePath string +} + +func NewAdminAuthentication(rootDir string) *AdminAuthentication { + return &AdminAuthentication{ + KubeConfigPath: filepath.Join(rootDir, "admin.kubeconfig"), + ShardAdminTokenHashFilePath: filepath.Join(rootDir, ".admin-token-store"), + } +} + +func (s *AdminAuthentication) Validate() []error { + if s == nil { + return nil + } + + errs := []error{} + + if s.ShardAdminTokenHashFilePath == "" && s.KubeConfigPath != "" { + errs = append(errs, fmt.Errorf("--admin-kubeconfig requires --admin-token-hash-file-path")) + } + + return errs +} + +func (s *AdminAuthentication) AddFlags(fs *pflag.FlagSet) { + if s == nil { + return + } + + fs.StringVar(&s.KubeConfigPath, "kubeconfig-path", s.KubeConfigPath, + "Path to which the administrative kubeconfig should be written at startup. If this is relative, it is relative to --root-directory.") + fs.StringVar(&s.ShardAdminTokenHashFilePath, "authentication-admin-token-path", s.ShardAdminTokenHashFilePath, + "Path to which the administrative token hash should be written at startup. If this is relative, it is relative to --root-directory.") +} + +// ApplyTo returns a new volatile gcp admin token. +// It also returns a new shard admin token and its hash if the configured shard admin hash file is not present. +// If the shard admin hash file is present only the shard admin hash is returned and the returned shard admin token is empty. +func (s *AdminAuthentication) ApplyTo(config *genericapiserver.Config) (volatileGcpAdminToken, volatileUserToken string, err error) { + volatileUserToken = uuid.New().String() + volatileGcpAdminToken = uuid.New().String() + + gcpAdminUser := &user.DefaultInfo{ + Name: gcpAdminUserName, + UID: uuid.New().String(), + Groups: []string{ + "system:masters", + }, + } + + nonAdminUser := &user.DefaultInfo{ + Name: gcpUserUserName, + UID: uuid.New().String(), + Groups: []string{}, + } + + newAuthenticator := group.NewAuthenticatedGroupAdder(bearertoken.New(authenticator.WrapAudienceAgnosticToken(config.Authentication.APIAudiences, authenticator.TokenFunc(func(ctx context.Context, requestToken string) (*authenticator.Response, bool, error) { + if requestToken == volatileGcpAdminToken { + return &authenticator.Response{User: gcpAdminUser}, true, nil + } + + if requestToken == volatileUserToken { + return &authenticator.Response{User: nonAdminUser}, true, nil + } + + return nil, false, nil + })))) + + config.Authentication.Authenticator = authenticatorunion.New(newAuthenticator, config.Authentication.Authenticator) + + return volatileGcpAdminToken, volatileUserToken, nil +} + +func (s *AdminAuthentication) WriteKubeConfig(config genericapiserver.CompletedConfig, gcpAdminToken, userToken string) error { + externalCACert, _ := config.SecureServing.Cert.CurrentCertKeyContent() + externalKubeConfigHost := fmt.Sprintf("https://%s", config.ExternalAddress) + + externalKubeConfig := createKubeConfig(gcpAdminToken, userToken, externalKubeConfigHost, "", externalCACert) + return clientcmd.WriteToFile(*externalKubeConfig, s.KubeConfigPath) +} + +func createKubeConfig(gcpAdminToken, userToken, baseHost, tlsServerName string, caData []byte) *clientcmdapi.Config { + var kubeConfig clientcmdapi.Config + // Create Client and Shared + kubeConfig.AuthInfos = map[string]*clientcmdapi.AuthInfo{ + gcpAdminUserName: {Token: gcpAdminToken}, + } + kubeConfig.Clusters = map[string]*clientcmdapi.Cluster{ + "root": { + Server: baseHost, + CertificateAuthorityData: caData, + TLSServerName: tlsServerName, + }, + } + kubeConfig.Contexts = map[string]*clientcmdapi.Context{ + "root": {Cluster: "root", AuthInfo: gcpAdminUserName}, + } + kubeConfig.CurrentContext = "root" + + if len(userToken) > 0 { + kubeConfig.AuthInfos[gcpUserUserName] = &clientcmdapi.AuthInfo{Token: userToken} + kubeConfig.Contexts[gcpUserUserName] = &clientcmdapi.Context{Cluster: "root", AuthInfo: gcpUserUserName} + } + + return &kubeConfig +} diff --git a/server/cmd/options/config.go b/server/cmd/options/config.go new file mode 100644 index 0000000..25bbb1f --- /dev/null +++ b/server/cmd/options/config.go @@ -0,0 +1,131 @@ +/* +Copyright 2024 The KCP Authors. + +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 options + +import ( + "github.com/kcp-dev/kcp/pkg/embeddedetcd" + + apiextensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/util/webhook" + aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver" + aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme" + "k8s.io/kubernetes/pkg/api/legacyscheme" + "k8s.io/kubernetes/pkg/controlplane" + controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver" + generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi" +) + +type Config struct { + Options CompletedOptions + + EmbeddedEtcd *embeddedetcd.Config + Aggregator *aggregatorapiserver.Config + ControlPlane *controlplaneapiserver.Config + APIExtensions *apiextensionsapiserver.Config + + ExtraConfig +} + +type ExtraConfig struct { + // authentication + GcpAdminToken, UserToken string +} + +type completedConfig struct { + Options CompletedOptions + + EmbeddedEtcd embeddedetcd.CompletedConfig + + Aggregator aggregatorapiserver.CompletedConfig + ControlPlane controlplaneapiserver.CompletedConfig + APIExtensions apiextensionsapiserver.CompletedConfig + + ExtraConfig +} + +type CompletedConfig struct { + // Embed a private pointer that cannot be instantiated outside of this package. + *completedConfig +} + +func (c *Config) Complete() (CompletedConfig, error) { + return CompletedConfig{&completedConfig{ + Options: c.Options, + + EmbeddedEtcd: c.EmbeddedEtcd.Complete(), + ControlPlane: c.ControlPlane.Complete(), + Aggregator: c.Aggregator.Complete(), + APIExtensions: c.APIExtensions.Complete(), + + ExtraConfig: c.ExtraConfig, + }}, nil +} + +// NewConfig creates all the self-contained pieces making up an +// generic controlplane server. +func NewConfig(opts CompletedOptions) (*Config, error) { + c := &Config{ + Options: opts, + } + + if opts.EmbeddedEtcd.Enabled { + var err error + c.EmbeddedEtcd, err = embeddedetcd.NewConfig(opts.EmbeddedEtcd, opts.GenericControlPlane.Etcd.EnableWatchCache) + if err != nil { + return nil, err + } + } + + genericConfig, versionedInformers, storageFactory, err := controlplaneapiserver.BuildGenericConfig( + opts.GenericControlPlane, + []*runtime.Scheme{legacyscheme.Scheme, apiextensionsapiserver.Scheme, aggregatorscheme.Scheme}, + controlplane.DefaultAPIResourceConfigSource(), + generatedopenapi.GetOpenAPIDefinitions, + ) + if err != nil { + return nil, err + } + + // set standalone config + c.GcpAdminToken, c.UserToken, err = opts.AdminAuthentication.ApplyTo(genericConfig) + if err != nil { + return nil, err + } + + serviceResolver := webhook.NewDefaultServiceResolver() + kubeAPIs, pluginInitializer, err := controlplaneapiserver.CreateConfig(opts.GenericControlPlane, genericConfig, versionedInformers, storageFactory, serviceResolver, nil) + if err != nil { + return nil, err + } + c.ControlPlane = kubeAPIs + + authInfoResolver := webhook.NewDefaultAuthenticationInfoResolverWrapper(kubeAPIs.ProxyTransport, kubeAPIs.Generic.EgressSelector, kubeAPIs.Generic.LoopbackClientConfig, kubeAPIs.Generic.TracerProvider) + apiExtensions, err := controlplaneapiserver.CreateAPIExtensionsConfig(*kubeAPIs.Generic, kubeAPIs.VersionedInformers, pluginInitializer, opts.GenericControlPlane, 3, serviceResolver, authInfoResolver) + if err != nil { + return nil, err + } + c.APIExtensions = apiExtensions + + aggregator, err := controlplaneapiserver.CreateAggregatorConfig(*kubeAPIs.Generic, opts.GenericControlPlane, kubeAPIs.VersionedInformers, serviceResolver, kubeAPIs.ProxyTransport, kubeAPIs.Extra.PeerProxy, pluginInitializer) + if err != nil { + return nil, err + } + c.Aggregator = aggregator + + return c, nil +} diff --git a/server/cmd/options/options.go b/server/cmd/options/options.go new file mode 100644 index 0000000..d89749a --- /dev/null +++ b/server/cmd/options/options.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 The KCP Authors. + +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 options + +import ( + cryptorand "crypto/rand" + "crypto/rsa" + "fmt" + "os" + "path/filepath" + + etcdoptions "github.com/kcp-dev/kcp/pkg/embeddedetcd/options" + + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/admission" + "k8s.io/client-go/util/keyutil" + cliflag "k8s.io/component-base/cli/flag" + "k8s.io/klog/v2" + controlplaneapiserveroptions "k8s.io/kubernetes/pkg/controlplane/apiserver/options" + kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options" + + gcpadmission "github.com/kcp-dev/generic-controlplane/server/admission" +) + +type Options struct { + GenericControlPlane controlplaneapiserveroptions.Options + EmbeddedEtcd etcdoptions.Options + + AdminAuthentication AdminAuthentication + + Extra ExtraOptions +} + +type ExtraOptions struct { + RootDir string +} + +type completedOptions struct { + GenericControlPlane controlplaneapiserveroptions.CompletedOptions + EmbeddedEtcd etcdoptions.CompletedOptions + + AdminAuthentication AdminAuthentication + + Extra ExtraOptions +} + +type CompletedOptions struct { + *completedOptions +} + +// NewOptions creates a new Options with default parameters. +func NewOptions(rootDir string) *Options { + o := &Options{ + GenericControlPlane: *controlplaneapiserveroptions.NewOptions(), + EmbeddedEtcd: *etcdoptions.NewOptions(rootDir), + AdminAuthentication: *NewAdminAuthentication(rootDir), + Extra: ExtraOptions{ + RootDir: rootDir, + }, + } + + // override for standalone mode + o.GenericControlPlane.SecureServing.ServerCert.CertDirectory = rootDir + // We use KCP form of the authentication options as it does not contain nodes and pods + // informers. + o.GenericControlPlane.Authentication = kubeoptions.NewBuiltInAuthenticationOptions(). + WithAnonymous(). + WithBootstrapToken(). + WithClientCert(). + WithOIDC(). + WithRequestHeader(). + WithServiceAccounts(). + WithTokenFile(). + WithWebHook() + o.GenericControlPlane.Authentication.ServiceAccounts.Issuers = []string{"https://gcp.default.svc"} + o.GenericControlPlane.Etcd.StorageConfig.Transport.ServerList = []string{"embedded"} + o.GenericControlPlane.Features.EnablePriorityAndFairness = false + // turn on the watch cache + o.GenericControlPlane.Etcd.EnableWatchCache = true + + // Flush out the default admission plugins and set the ones we want bellow. + // TODO: Generic control plane should come with a default set of plugins working out of the box. + o.GenericControlPlane.Admission.GenericAdmission.Plugins = admission.NewPlugins() + + return o +} + +func (o *Options) AddFlags(fss *cliflag.NamedFlagSets) { + o.GenericControlPlane.AddFlags(fss) + + etcdServers := fss.FlagSet("etcd").Lookup("etcd-servers") + etcdServers.Usage += " By default an embedded etcd server is started." + + o.EmbeddedEtcd.AddFlags(fss.FlagSet("Embedded etcd")) + o.AdminAuthentication.AddFlags(fss.FlagSet("GCP Standalone Authentication")) + + // fs := fss.FlagSet("GCP") + // Placeholders for future flags. +} + +func (o *Options) Complete() (*CompletedOptions, error) { + if servers := o.GenericControlPlane.Etcd.StorageConfig.Transport.ServerList; len(servers) == 1 && servers[0] == "embedded" { + klog.Background().Info("enabling embedded etcd server") + o.EmbeddedEtcd.Enabled = true + } + + var serviceAccountFile string + if len(o.GenericControlPlane.Authentication.ServiceAccounts.KeyFiles) == 0 { + // use sa.key and auto-generate if not existing + serviceAccountFile = filepath.Join(o.Extra.RootDir, "sa.key") + if _, err := os.Stat(serviceAccountFile); os.IsNotExist(err) { + klog.Background().WithValues("file", serviceAccountFile).Info("generating service account key file") + key, err := rsa.GenerateKey(cryptorand.Reader, 4096) + if err != nil { + return nil, fmt.Errorf("error generating service account private key: %w", err) + } + + encoded, err := keyutil.MarshalPrivateKeyToPEM(key) + if err != nil { + return nil, fmt.Errorf("error converting service account private key to PEM format: %w", err) + } + if err := keyutil.WriteKey(serviceAccountFile, encoded); err != nil { + return nil, fmt.Errorf("error writing service account private key file %q: %w", serviceAccountFile, err) + } + } else if err != nil { + return nil, fmt.Errorf("error checking service account key file %q: %w", serviceAccountFile, err) + } + + // set the key file to generic-controlplane server + o.GenericControlPlane.Authentication.ServiceAccounts.KeyFiles = []string{serviceAccountFile} + + if o.GenericControlPlane.ServiceAccountSigningKeyFile == "" { + o.GenericControlPlane.ServiceAccountSigningKeyFile = serviceAccountFile + } + } + + // override set of admission plugins + //spew.Dump(o.GenericControlPlane.Admission.GenericAdmission.Plugins) + gcpadmission.RegisterAllAdmissionPlugins(o.GenericControlPlane.Admission.GenericAdmission.Plugins) + o.GenericControlPlane.Admission.GenericAdmission.DisablePlugins = sets.List[string](gcpadmission.DefaultOffAdmissionPlugins()) + o.GenericControlPlane.Admission.GenericAdmission.RecommendedPluginOrder = gcpadmission.AllOrderedPlugins + + var err error + if !filepath.IsAbs(o.EmbeddedEtcd.Directory) { + o.EmbeddedEtcd.Directory, err = filepath.Abs(o.EmbeddedEtcd.Directory) + if err != nil { + return nil, err + } + } + if !filepath.IsAbs(o.GenericControlPlane.SecureServing.ServerCert.CertDirectory) { + o.GenericControlPlane.SecureServing.ServerCert.CertDirectory, err = filepath.Abs(o.GenericControlPlane.SecureServing.ServerCert.CertDirectory) + if err != nil { + return nil, err + } + } + if !filepath.IsAbs(o.AdminAuthentication.ShardAdminTokenHashFilePath) { + o.AdminAuthentication.ShardAdminTokenHashFilePath, err = filepath.Abs(o.AdminAuthentication.ShardAdminTokenHashFilePath) + if err != nil { + return nil, err + } + } + if !filepath.IsAbs(o.AdminAuthentication.KubeConfigPath) { + o.AdminAuthentication.KubeConfigPath, err = filepath.Abs(o.AdminAuthentication.KubeConfigPath) + if err != nil { + return nil, err + } + } + + completedGenericServerRunOptions, err := o.GenericControlPlane.Complete(nil, nil) + if err != nil { + return nil, err + } + + completedEmbeddedEtcd := o.EmbeddedEtcd.Complete(o.GenericControlPlane.Etcd) + + return &CompletedOptions{ + completedOptions: &completedOptions{ + GenericControlPlane: completedGenericServerRunOptions, + EmbeddedEtcd: completedEmbeddedEtcd, + AdminAuthentication: o.AdminAuthentication, + Extra: o.Extra, + }, + }, nil +} + +func (o *CompletedOptions) Validate() []error { + var errs []error + + errs = append(errs, o.GenericControlPlane.Validate()...) + errs = append(errs, o.EmbeddedEtcd.Validate()...) + errs = append(errs, o.AdminAuthentication.Validate()...) + + return errs +} diff --git a/server/cmd/server.go b/server/cmd/server.go new file mode 100644 index 0000000..9d45eb5 --- /dev/null +++ b/server/cmd/server.go @@ -0,0 +1,253 @@ +/* +Copyright 2024 The KCP Authors. + +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 server + +import ( + "context" + "fmt" + "os" + "strings" + + "github.com/davecgh/go-spew/spew" + "github.com/kcp-dev/kcp/cli/pkg/help" + "github.com/kcp-dev/kcp/pkg/embeddedetcd" + "github.com/spf13/cobra" + + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + _ "k8s.io/apiserver/pkg/admission" + genericapifilters "k8s.io/apiserver/pkg/endpoints/filters" + genericapiserver "k8s.io/apiserver/pkg/server" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/apiserver/pkg/util/notfoundhandler" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + cliflag "k8s.io/component-base/cli/flag" + "k8s.io/component-base/cli/globalflag" + "k8s.io/component-base/logs" + logsapi "k8s.io/component-base/logs/api/v1" + _ "k8s.io/component-base/metrics/prometheus/workqueue" + "k8s.io/component-base/term" + "k8s.io/component-base/version" + "k8s.io/component-base/version/verflag" + "k8s.io/klog/v2" + aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver" + controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver" + _ "k8s.io/kubernetes/pkg/features" + + options "github.com/kcp-dev/generic-controlplane/server/cmd/options" + // add the kubernetes feature gates +) + +// Order for settings: +// Options -> CompletedOptions -> Config -> CompletedOptions -> Server -> Prepared -> Run + +func init() { + utilruntime.Must(logsapi.AddFeatureGates(utilfeature.DefaultMutableFeatureGate)) +} + +// NewCommand creates a *cobra.Command object with default parameters +func NewCommand() *cobra.Command { + // manually extract root directory from flags first as it influence all other flags + rootDir := ".gcp" + for i, f := range os.Args { + if f == "--root-directory" { + if i < len(os.Args)-1 { + rootDir = os.Args[i+1] + } // else let normal flag processing fail + } else if strings.HasPrefix(f, "--root-directory=") { + rootDir = strings.TrimPrefix(f, "--root-directory=") + } + } + + s := options.NewOptions(rootDir) + + cmdStart := &cobra.Command{ + Use: "start", + Long: `The generic controlplane is a generic controlplane server, +a system serving APIs like Kubernetes, but without the container domain specific +APIs.`, + + // stop printing usage when the command errors + SilenceUsage: true, + PersistentPreRunE: func(*cobra.Command, []string) error { + // silence client-go warnings. + // kube-apiserver loopback clients should not log self-issued warnings. + rest.SetDefaultWarningHandler(rest.NoWarnings{}) + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + verflag.PrintAndExitIfRequested() + fs := cmd.Flags() + + // Activate logging as soon as possible, after that + // show flags with the final logging configuration. + if err := logsapi.ValidateAndApply(s.GenericControlPlane.Logs, utilfeature.DefaultFeatureGate); err != nil { + return err + } + cliflag.PrintFlags(fs) + + completedOptions, err := s.Complete() + if err != nil { + return err + } + + if errs := completedOptions.Validate(); len(errs) != 0 { + return utilerrors.NewAggregate(errs) + } + + // add feature enablement metrics + utilfeature.DefaultMutableFeatureGate.AddMetrics() + ctx := genericapiserver.SetupSignalContext() + + return Run(ctx, *completedOptions) + }, + Args: func(cmd *cobra.Command, args []string) error { + for _, arg := range args { + if len(arg) > 0 { + return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args) + } + } + return nil + }, + } + + var namedFlagSets cliflag.NamedFlagSets + s.AddFlags(&namedFlagSets) + verflag.AddFlags(namedFlagSets.FlagSet("global")) + globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmdStart.Name(), logs.SkipLoggingConfigurationFlags()) + + fs := cmdStart.Flags() + for _, f := range namedFlagSets.FlagSets { + fs.AddFlagSet(f) + } + + cols, _, _ := term.TerminalSize(cmdStart.OutOrStdout()) + cliflag.SetUsageAndHelpFunc(cmdStart, namedFlagSets, cols) + + startOptionsCmd := &cobra.Command{ + Use: "options", + Short: "Show all start command options", + Long: help.Doc(` + Show all start command options + + "gcp start"" has a large number of options. This command shows all of them. + `), + PersistentPreRunE: func(*cobra.Command, []string) error { + // silence client-go warnings. + // apiserver loopback clients should not log self-issued warnings. + rest.SetDefaultWarningHandler(rest.NoWarnings{}) + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Fprintf(cmd.OutOrStderr(), usageFmt, cmdStart.UseLine()) + cliflag.PrintSections(cmd.OutOrStderr(), namedFlagSets, cols) + return nil + }, + } + cmdStart.AddCommand(startOptionsCmd) + + setPartialUsageAndHelpFunc(cmdStart, namedFlagSets, cols, []string{ + "etcd-servers", + }) + + help.FitTerminal(cmdStart.OutOrStdout()) + + return cmdStart +} + +// Run runs the specified APIServer. This should never exit. +func Run(ctx context.Context, opts options.CompletedOptions) error { + // To help debugging, immediately log version + klog.Infof("Version: %+v", version.Get()) + + klog.InfoS("Golang settings", "GOGC", os.Getenv("GOGC"), "GOMAXPROCS", os.Getenv("GOMAXPROCS"), "GOTRACEBACK", os.Getenv("GOTRACEBACK")) + + config, err := options.NewConfig(opts) + if err != nil { + return err + } + completed, err := config.Complete() + if err != nil { + return err + } + + // the etcd server must be up before NewServer because storage decorators access it right away + if completed.EmbeddedEtcd.Config != nil { + klog.Info("Starting embedded etcd server") + if err := embeddedetcd.NewServer(completed.EmbeddedEtcd).Run(ctx); err != nil { + return err + } + } + + server, err := createServerChain(completed) + if err != nil { + return err + } + + prepared, err := server.PrepareRun() + if err != nil { + return err + } + + // write the kubeconfig file as close to the start of the server as possible + spew.Dump(completed.ExtraConfig) + err = completed.Options.AdminAuthentication.WriteKubeConfig(completed.ControlPlane.Generic, completed.ExtraConfig.GcpAdminToken, completed.ExtraConfig.UserToken) + if err != nil { + return err + } + + return prepared.Run(ctx) +} + +// createServerChain creates the apiservers connected via delegation. +func createServerChain(config options.CompletedConfig) (*aggregatorapiserver.APIAggregator, error) { + // 1. CRDs + notFoundHandler := notfoundhandler.New(config.ControlPlane.Generic.Serializer, genericapifilters.NoMuxAndDiscoveryIncompleteKey) + apiExtensionsServer, err := config.APIExtensions.New(genericapiserver.NewEmptyDelegateWithCustomHandler(notFoundHandler)) + if err != nil { + return nil, fmt.Errorf("failed to create apiextensions-apiserver: %w", err) + } + crdAPIEnabled := config.APIExtensions.GenericConfig.MergedResourceConfig.ResourceEnabled(apiextensionsv1.SchemeGroupVersion.WithResource("customresourcedefinitions")) + + // 2. Natively implemented resources + nativeAPIs, err := config.ControlPlane.New("generic-controlplane", apiExtensionsServer.GenericAPIServer) + if err != nil { + return nil, fmt.Errorf("failed to create generic controlplane apiserver: %w", err) + } + client, err := kubernetes.NewForConfig(config.ControlPlane.Generic.LoopbackClientConfig) + if err != nil { + return nil, err + } + storageProviders, err := config.ControlPlane.GenericStorageProviders(client.Discovery()) + if err != nil { + return nil, fmt.Errorf("failed to create storage providers: %w", err) + } + if err := nativeAPIs.InstallAPIs(storageProviders...); err != nil { + return nil, fmt.Errorf("failed to install APIs: %w", err) + } + + // 3. Aggregator for APIServices, discovery and OpenAPI + aggregatorServer, err := controlplaneapiserver.CreateAggregatorServer(config.Aggregator, nativeAPIs.GenericAPIServer, apiExtensionsServer.Informers.Apiextensions().V1().CustomResourceDefinitions(), crdAPIEnabled, controlplaneapiserver.DefaultGenericAPIServicePriorities()) + if err != nil { + // we don't need special handling for innerStopCh because the aggregator server doesn't create any go routines + return nil, fmt.Errorf("failed to create kube-aggregator: %w", err) + } + + return aggregatorServer, nil +}