diff --git a/.yamllint.yml b/.yamllint.yml index 37489b560..70a5fd847 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -5,6 +5,7 @@ yaml-files: - '.yamllint' ignore: - 'cluster-service/deploy/helm/templates/azure-operators-managed-identities-config.configmap.yaml' + - 'acrpull/deploy/helm/acrpull/templates/deployment.yaml' rules: brackets: enable diff --git a/acrpull/Makefile b/acrpull/Makefile new file mode 100644 index 000000000..996892a2e --- /dev/null +++ b/acrpull/Makefile @@ -0,0 +1,13 @@ +-include ../setup-env.mk + +deploy: + kubectl create namespace acrpull --dry-run=client -o json | kubectl apply -f - && \ + helm upgrade --install ${HELM_DRY_RUN} acrpull \ + deploy/helm/acrpull/ \ + --set image=mcr.microsoft.com/aks/msi-acrpull@${ACRPULL_DIGEST} \ + --namespace acrpull +.PHONY: deploy + +undeploy: + helm uninstall acrpull --namespace acrpull +.PHONY: undeploy diff --git a/acrpull/deploy/helm/acrpull/Chart.yaml b/acrpull/deploy/helm/acrpull/Chart.yaml new file mode 100644 index 000000000..63420852c --- /dev/null +++ b/acrpull/deploy/helm/acrpull/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: acrpull +description: Controller for injecting pull credentials from managed identities into AKS clusters. +type: application +version: 0.1.0 +appVersion: "v0.1.5" diff --git a/acrpull/deploy/helm/acrpull/templates/acrpull.microsoft.com_acrpullbindings.yaml b/acrpull/deploy/helm/acrpull/templates/acrpull.microsoft.com_acrpullbindings.yaml new file mode 100644 index 000000000..efabf5cc3 --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/acrpull.microsoft.com_acrpullbindings.yaml @@ -0,0 +1,175 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: acrpullbindings.acrpull.microsoft.com +spec: + group: acrpull.microsoft.com + names: + kind: AcrPullBinding + listKind: AcrPullBindingList + plural: acrpullbindings + shortNames: + - apb + - apbs + singular: acrpullbinding + scope: Namespaced + versions: + - name: v1beta2 + schema: + openAPIV3Schema: + description: AcrPullBinding is the Schema for the acrpullbindings API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AcrPullBindingSpec defines the desired state of AcrPullBinding + properties: + acr: + description: ACR holds specifics of the Azure Container Registry for + which credentials are projected. + properties: + cloudConfig: + description: AirgappedCloudConfiguration configures a custom cloud + to interact with when running air-gapped. + properties: + entraAuthorityHost: + description: EntraAuthorityHost configures a custom Entra + host endpoint. + minLength: 1 + type: string + resourceManagerAudience: + description: ResourceManagerAudience configures the audience + for which tokens will be requested from Entra. + minLength: 1 + type: string + required: + - entraAuthorityHost + - resourceManagerAudience + type: object + environment: + default: PublicCloud + description: Environment specifies the Azure Cloud environment + in which the ACR is deployed. + enum: + - PublicCloud + - USGovernmentCloud + - ChinaCloud + - AirgappedCloud + example: PublicCloud + type: string + scope: + description: |- + Scope defines the scope for the access token, e.g. pull/push access for a repository. + Note: you need to pin it down to the repository level, there is no wildcard available, + however a list of space-delimited scopes is acceptable. + See docs for details: https://distribution.github.io/distribution/spec/auth/scope/ + + + Examples: + repository:my-repository:pull,push + repository:my-repository:pull repository:other-repository:push,pull + example: repository:my-repository:pull,push + minLength: 1 + type: string + server: + description: Server is the FQDN for the Azure Container Registry, + e.g. example.azurecr.io + example: example.azurecr.io + type: string + x-kubernetes-validations: + - message: server must be a fully-qualified domain name + rule: isURL('https://' + self) && url('https://' + self).getHostname() + == self + required: + - environment + - scope + - server + type: object + x-kubernetes-validations: + - message: a custom cloud configuration must be present for air-gapped + cloud environments + rule: 'self.environment == ''ArigappedCloud'' ? has(self.cloudConfig) + : !has(self.cloudConfig)' + auth: + description: Auth determines how we will authenticate to the Azure + Container Registry. Only one method may be provided. + properties: + managedIdentity: + description: ManagedIdentity uses Azure Managed Identity to authenticate + with Azure. + properties: + clientID: + description: ClientID is the client identifier for the managed + identity. Either provide the client ID or the resource ID. + example: 1b461305-28be-5271-beda-bd9fd2e24251 + type: string + resourceID: + description: ResourceID is the resource identifier for the + managed identity. Either provide the client ID or the resource + ID. + example: /subscriptions/sub-name/resourceGroups/rg-name/providers/Microsoft.ManagedIdentity/userAssignedIdentities/1b461305-28be-5271-beda-bd9fd2e24251 + type: string + type: object + x-kubernetes-validations: + - message: only client or resource ID can be set + rule: '[has(self.clientID), has(self.resourceID)].exists_one(x, + x)' + workloadIdentity: + description: WorkloadIdentity uses Azure Workload Identity to + authenticate with Azure. + properties: + serviceAccountRef: + description: |- + ServiceAccountName specifies the name of the service account + that should be used when authenticating with WorkloadIdentity. + type: string + type: object + type: object + x-kubernetes-validations: + - message: only one authentication type can be set + rule: '[has(self.managedIdentity), has(self.workloadIdentity)].exists_one(x, + x)' + serviceAccountName: + description: The name of the service account to associate the image + pull secret with. + type: string + type: object + status: + description: AcrPullBindingStatus defines the observed state of AcrPullBinding + properties: + error: + description: Error message if there was an error updating the token. + type: string + lastTokenRefreshTime: + description: Information when was the last time the ACR token was + refreshed. + format: date-time + type: string + tokenExpirationTime: + description: The expiration date of the current ACR token. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/acrpull/deploy/helm/acrpull/templates/controller_role.yaml b/acrpull/deploy/helm/acrpull/templates/controller_role.yaml new file mode 100644 index 000000000..c7919f064 --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/controller_role.yaml @@ -0,0 +1,79 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: acrpull-controller +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - '*' +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - serviceaccounts/token + verbs: + - create +- apiGroups: + - acrpull.microsoft.com + resources: + - acrpullbindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - acrpull.microsoft.com + resources: + - acrpullbindings/finalizers + verbs: + - update +- apiGroups: + - acrpull.microsoft.com + resources: + - acrpullbindings/status + verbs: + - get + - patch + - update +- apiGroups: + - msi-acrpull.microsoft.com + resources: + - acrpullbindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - msi-acrpull.microsoft.com + resources: + - acrpullbindings/finalizers + verbs: + - update +- apiGroups: + - msi-acrpull.microsoft.com + resources: + - acrpullbindings/status + verbs: + - get + - patch + - update diff --git a/acrpull/deploy/helm/acrpull/templates/controller_role_binding.yaml b/acrpull/deploy/helm/acrpull/templates/controller_role_binding.yaml new file mode 100644 index 000000000..82800ad35 --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/controller_role_binding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm + name: acrpull-controller-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: acrpull-controller +subjects: +- kind: ServiceAccount + name: acrpull + namespace: {{ .Values.namespace }} diff --git a/acrpull/deploy/helm/acrpull/templates/deployment.yaml b/acrpull/deploy/helm/acrpull/templates/deployment.yaml new file mode 100644 index 000000000..24abdc3d8 --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/deployment.yaml @@ -0,0 +1,77 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: acrpull + namespace: {{ .Values.namespace }} + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm +spec: + selector: + matchLabels: + app.kubernetes.io/name: acrpull + replicas: 2 + template: + metadata: + labels: + app.kubernetes.io/name: acrpull + spec: + securityContext: + runAsNonRoot: true + containers: + - command: + - /manager + args: + - "--health-probe-bind-address=:8081" + - "--metrics-bind-address=127.0.0.1:8080" + - "--leader-elect" + image: "{{ .Values.image }}" + name: acrpull-controller + ports: + - containerPort: 8080 + protocol: TCP + name: metrics + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + readOnlyRootFilesystem: true + runAsUser: 1000 + runAsGroup: 3000 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 100m + memory: 100Mi + requests: + cpu: 100m + memory: 20Mi + serviceAccountName: acrpull + terminationGracePeriodSeconds: 10 + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/acrpull/deploy/helm/acrpull/templates/leader_election_role.yaml b/acrpull/deploy/helm/acrpull/templates/leader_election_role.yaml new file mode 100644 index 000000000..fd0dae166 --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/leader_election_role.yaml @@ -0,0 +1,40 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm + name: acrpull-controller-leader-election + namespace: {{ .Values.namespace }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/acrpull/deploy/helm/acrpull/templates/leader_election_role_binding.yaml b/acrpull/deploy/helm/acrpull/templates/leader_election_role_binding.yaml new file mode 100644 index 000000000..a534e194f --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/leader_election_role_binding.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm + name: acrpull-controller-leader-election-binding + namespace: {{ .Values.namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: acrpull-controller-leader-election +subjects: +- kind: ServiceAccount + name: acrpull + namespace: {{ .Values.namespace }} diff --git a/acrpull/deploy/helm/acrpull/templates/msi-acrpull.microsoft.com_acrpullbindings.yaml b/acrpull/deploy/helm/acrpull/templates/msi-acrpull.microsoft.com_acrpullbindings.yaml new file mode 100644 index 000000000..938ecc25e --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/msi-acrpull.microsoft.com_acrpullbindings.yaml @@ -0,0 +1,87 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: acrpullbindings.msi-acrpull.microsoft.com +spec: + group: msi-acrpull.microsoft.com + names: + kind: AcrPullBinding + listKind: AcrPullBindingList + plural: acrpullbindings + singular: acrpullbinding + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: AcrPullBinding is the Schema for the acrpullbindings API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AcrPullBindingSpec defines the desired state of AcrPullBinding + properties: + acrServer: + description: The full server name for the ACR. For example, test.azurecr.io + minLength: 0 + type: string + managedIdentityClientID: + description: The Managed Identity client ID that is used to authenticate + with ACR (specify one of ClientID or ResourceID) + type: string + managedIdentityResourceID: + description: The Managed Identity resource ID that is used to authenticate + with ACR (if ClientID is specified, this is ignored) + type: string + scope: + description: |- + The registry scope which the pull token should have. For example, repository:my-repository:pull,push + See docs for details: https://distribution.github.io/distribution/spec/auth/scope/ + type: string + serviceAccountName: + description: |- + The Service Account to associate the image pull secret with. If this is not specified, the default Service Account + of the namespace will be used. + type: string + required: + - acrServer + type: object + status: + description: AcrPullBindingStatus defines the observed state of AcrPullBinding + properties: + error: + description: Error message if there was an error updating the token. + type: string + lastTokenRefreshTime: + description: Information when was the last time the ACR token was + refreshed. + format: date-time + type: string + tokenExpirationTime: + description: The expiration date of the current ACR token. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/acrpull/deploy/helm/acrpull/templates/namespace.yaml b/acrpull/deploy/helm/acrpull/templates/namespace.yaml new file mode 100644 index 000000000..5ffff4a27 --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/namespace.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm + name: acrpull diff --git a/acrpull/deploy/helm/acrpull/templates/podmonitor.yaml b/acrpull/deploy/helm/acrpull/templates/podmonitor.yaml new file mode 100644 index 000000000..4ced676f8 --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/podmonitor.yaml @@ -0,0 +1,14 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm + name: acrpull-monitor + namespace: {{ .Values.namespace }} +spec: + podMetricsEndpoints: + - port: metrics + selector: + matchLabels: + app.kubernetes.io/name: acrpull diff --git a/acrpull/deploy/helm/acrpull/templates/serviceaccount.yaml b/acrpull/deploy/helm/acrpull/templates/serviceaccount.yaml new file mode 100644 index 000000000..40929d970 --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/serviceaccount.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm + name: acrpull + namespace: {{ .Values.namespace }} diff --git a/acrpull/deploy/helm/acrpull/templates/validatingadmissionpolicies.yaml b/acrpull/deploy/helm/acrpull/templates/validatingadmissionpolicies.yaml new file mode 100644 index 000000000..d85324c5f --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/validatingadmissionpolicies.yaml @@ -0,0 +1,131 @@ +# This policy validates the configuration of the tokens that are created by the msi-acrpull controller. +# It requires the parameters controllerServiceAccountName, controllerNamespace, token expiration, and token audiences +# to be set in the ConfigMap admission-policies-controller-config. +# The user must configure: +# the token audiences +# the controllerServiceAccountName and controllerNamespace parameters +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicy +metadata: + name: "controller-token-request-policy" + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm +spec: + failurePolicy: Fail + paramKind: + apiVersion: v1 + kind: ConfigMap + matchConditions: + - name: 'userIsController' + expression: "request.userInfo.username == 'system:serviceaccount:'+params.data.controllerNamespace+':'+params.data.controllerServiceAccountName" + matchConstraints: + resourceRules: + - apiGroups: [""] + apiVersions: ["v1"] + operations: ["CREATE"] + resources: ["serviceaccounts/token"] + variables: + - name: requestHasOnlyOneAudience + expression: "object.spec.audiences.size() == 1" + - name: hasCorrectAudience + expression: "object.spec.audiences.exists(w, w == params.data.tokenAudience)" + validations: + - expression: "variables.hasCorrectAudience == true && variables.requestHasOnlyOneAudience == true" # if the expression evaluates to false, the validation check is enforced according to the failurePolicy + messageExpression: "string(params.data.controllerServiceAccountName) + ' has failed to ' + string(request.operation) + ' ' + string(request.name) + ' token in the ' + string(request.namespace) + ' namespace. Check the configuration.'" + reason: "Forbidden" +--- +# This policy is used to restrict the types of secrets that the controller can create or update. We only allow the controller +# to create dockerconfigjson secret types, as allowing other types would allow privilege escalations and unwanted behavior. +# (For example, service account token secret types get auto-populated with tokens.) +# We furthermore restrict the controller to creating and updating secrets with the label we use for limiting our informers. +# It requires the parameter controllerName, controllerNamespace and the list of secret types to allow to be set in the +# ConfigMap admission-policies-controller-config. +# The user must configure: +# the controllerServiceAccountName and controllerNamespace parameters +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicy +metadata: + name: "controller-secret-mutation-policy" + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm +spec: + failurePolicy: Fail + paramKind: + apiVersion: v1 + kind: ConfigMap + matchConditions: + - name: 'userIsController' + expression: "request.userInfo.username == 'system:serviceaccount:'+params.data.controllerNamespace+':'+params.data.controllerServiceAccountName" + matchConstraints: + resourceRules: + - apiGroups: [""] + apiVersions: ["v1"] + operations: ["CREATE", "UPDATE"] + resources: ["secrets"] + variables: + - name: hasOwner + expression: "has(object.metadata.ownerReferences) && (size(object.metadata.ownerReferences) == 1 && object.metadata.ownerReferences.all(o, o.kind == 'AcrPullBinding' && (o.apiVersion.startsWith('msi-acrpull.microsoft.com/') || o.apiVersion.startsWith('acrpull.microsoft.com/'))))" + - name: matchesPreviousOwner + expression: "has(oldObject.metadata) ? oldObject.metadata.ownerReferences == object.metadata.ownerReferences : true" + - name: hasSecretType + expression: "object.type == 'kubernetes.io/dockerconfigjson'" + - name: matchesPreviousSecretType + expression: "has(oldObject.metadata) ? oldObject.type == object.type : true" + - name: hasLabel + expression: "has(object.metadata.labels) && ('acr.microsoft.com/binding' in object.metadata.labels)" + - name: matchesPreviousLabel + expression: "has(oldObject.metadata) ? oldObject.metadata.labels == object.metadata.labels : true" + validations: + - expression: "variables.hasOwner == true && variables.matchesPreviousOwner == true && variables.hasSecretType == true && variables.matchesPreviousSecretType == true && variables.hasLabel == true && variables.matchesPreviousLabel == true" + messageExpression: "string(params.data.controllerServiceAccountName) + ' has failed to ' + string(request.operation) + ' secret with ' + string(object.type) + ' type ' + 'in the ' + string(request.namespace) + ' namespace. The controller can only create or update secrets that it owns, with the correct type and having the correct label.'" + reason: "Forbidden" +--- +# This policy will deny updates to serviceAccounts that do something other than changing the list of managed pull secrets. +# It requires the parameter controllerServiceAccountName and controllerNamespace to be set in the +# ConfigMap admission-policies-controller-config. +# The user must configure: +# the controllerServiceAccountName and controllerNamespace parameters +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicy +metadata: + name: "controller-service-account-mutation-policy" + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm +spec: + failurePolicy: Fail + paramKind: + apiVersion: v1 + kind: ConfigMap + matchConditions: + - name: 'userIsController' + expression: "request.userInfo.username == 'system:serviceaccount:'+params.data.controllerNamespace+':'+params.data.controllerServiceAccountName" + matchConstraints: + resourceRules: + - apiGroups: [""] + apiVersions: ["v1"] + operations: ["UPDATE"] + resources: ["serviceaccounts"] + variables: + - name: secretsUnchanged + expression: "oldObject.?secrets == object.?secrets" + - name: automountUnchanged + expression: "oldObject.?automountServiceAccountToken == object.?automountServiceAccountToken" + - name: previousPullSecretNames + expression: "oldObject.?imagePullSecrets.orValue([]).map(s, s.name)" + - name: pullSecretNames + expression: "object.?imagePullSecrets.orValue([]).map(s, s.name)" + - name: addedPullSecrets + expression: "variables.pullSecretNames.filter(s, !(s in variables.previousPullSecretNames))" + - name: removedPullSecrets + expression: "variables.previousPullSecretNames.filter(s, !(s in variables.pullSecretNames))" + - name: onlyCorrectPullSecretsAdded + expression: "variables.addedPullSecrets.all(s, s.matches('^acr-pull-.{1,44}-[a-zA-Z0-9]{10}$'))" + - name: onlyCorrectPullSecretsRemoved + expression: "variables.removedPullSecrets.all(s, s.matches('^acr-pull-.{1,44}-[a-zA-Z0-9]{10}$'))" + validations: + - expression: "variables.secretsUnchanged == true && variables.automountUnchanged == true && variables.onlyCorrectPullSecretsAdded == true && variables.onlyCorrectPullSecretsRemoved == true" + messageExpression: "string(params.data.controllerServiceAccountName) + ' has failed to ' + string(request.operation) + ' service account ' + string(request.name) + ' in the ' + string(request.namespace) + ' namespace. The controller may only update service accounts to add or remove pull secrets that the controller manages.' + string(variables.automountUnchanged == true) + string(variables.automountUnchanged == true) + string(variables.onlyCorrectPullSecretsAdded == true) + string(variables.onlyCorrectPullSecretsRemoved == true)" + reason: "Forbidden" diff --git a/acrpull/deploy/helm/acrpull/templates/validatingadmissionpolicybindings.yaml b/acrpull/deploy/helm/acrpull/templates/validatingadmissionpolicybindings.yaml new file mode 100644 index 000000000..6fe97342d --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/validatingadmissionpolicybindings.yaml @@ -0,0 +1,44 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicyBinding +metadata: + name: "controller-token-request-policy-binding" + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm +spec: + policyName: "controller-token-request-policy" + validationActions: [Deny] + paramRef: + name: "admission-policies-controller-config" + namespace: {{ .Values.namespace }} + parameterNotFoundAction: "Deny" +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicyBinding +metadata: + name: "controller-secret-mutation-policy-binding" + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm +spec: + policyName: "controller-secret-mutation-policy" + validationActions: [Deny] + paramRef: + name: "admission-policies-controller-config" + namespace: {{ .Values.namespace }} + parameterNotFoundAction: "Deny" +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicyBinding +metadata: + name: "controller-service-account-mutation-policy-binding" + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm +spec: + policyName: "controller-service-account-mutation-policy" + validationActions: [Deny] + paramRef: + name: "admission-policies-controller-config" + namespace: {{ .Values.namespace }} + parameterNotFoundAction: "Deny" diff --git a/acrpull/deploy/helm/acrpull/templates/validatingadmissionpolicyparameters.yaml b/acrpull/deploy/helm/acrpull/templates/validatingadmissionpolicyparameters.yaml new file mode 100644 index 000000000..0152ce02a --- /dev/null +++ b/acrpull/deploy/helm/acrpull/templates/validatingadmissionpolicyparameters.yaml @@ -0,0 +1,17 @@ +# This is the configuration file for the MSI-ACRPull Controller. These values will be passed to the helm chart. +# The config map is an easy way to provide an example of the configuration. +# The user must configure: +# the controllerName and controllerNamespace parameters +# the token audience: any opaque string, which the reconciler will be restricted to use +apiVersion: v1 +kind: ConfigMap +metadata: + name: "admission-policies-controller-config" + namespace: {{ .Values.namespace }} + labels: + app.kubernetes.io/name: acrpull + app.kubernetes.io/managed-by: Helm +data: + controllerServiceAccountName: 'acrpull' + controllerNamespace: '{{ .Values.namespace }}' + tokenAudience: 'api://AzureCRTokenExchange' diff --git a/acrpull/deploy/helm/acrpull/values.yaml b/acrpull/deploy/helm/acrpull/values.yaml new file mode 100644 index 000000000..e921d8fb2 --- /dev/null +++ b/acrpull/deploy/helm/acrpull/values.yaml @@ -0,0 +1,5 @@ +namespace: acrpull +image: registry/image:tag +nodeSelector: {} +tolerations: [] +affinity: {} diff --git a/acrpull/pipeline.yaml b/acrpull/pipeline.yaml new file mode 100644 index 000000000..a4ea72131 --- /dev/null +++ b/acrpull/pipeline.yaml @@ -0,0 +1,18 @@ +$schema: "pipeline.schema.v1" +serviceGroup: Microsoft.Azure.ARO.HCP.RP.Frontend +rolloutName: ACRPull Controller Rollout +resourceGroups: + - name: {{ .svc.rg }} + subscription: {{ .svc.subscription }} + aksCluster: {{ .aksName }} + steps: + - name: deploy + action: Shell + command: make deploy + dryRun: + variables: + - name: HELM_DRY_RUN + value: "--dry-run=server --debug" + variables: + - name: ACRPULL_DIGEST + configRef: acrPullImageDigest diff --git a/config/config.schema.json b/config/config.schema.json index 071ec9dab..4dc9d323c 100644 --- a/config/config.schema.json +++ b/config/config.schema.json @@ -329,6 +329,9 @@ "kubernetesVersion": { "type": "string" }, + "acrPullImageDigest": { + "type": "string" + }, "maestro": { "type": "object", "properties": { @@ -705,6 +708,7 @@ "imageSync", "istioVersion", "kubernetesVersion", + "acrPullImageDigest", "maestro", "mgmt", "mgmtKeyVault", diff --git a/config/config.yaml b/config/config.yaml index 52fd074f3..1cef26e24 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -17,6 +17,7 @@ defaults: subnetPrefix: "10.128.8.0/21" podSubnetPrefix: "10.128.64.0/18" aksName: aro-hcp-aks + acrPullImageDigest: sha256:9816561e7ee91a0814a482564d202288f2e5401ca2387a56641f144d04fa3535 #v0.1.5 # Hypershift hypershift: diff --git a/dev-infrastructure/Makefile b/dev-infrastructure/Makefile index 82bb47856..c6638f914 100644 --- a/dev-infrastructure/Makefile +++ b/dev-infrastructure/Makefile @@ -27,23 +27,18 @@ list: @grep '^[^#[:space:]].*:' Makefile .PHONY: list -fmt: - set -e; \ - FILES="$$(find . -type f -name "*.bicep*" ! -name "*.tmpl.bicepparam")"; \ - for file in $$FILES; do \ - echo "az bicep format --file $${file}"; \ - az bicep format --file $$file; \ - done -.PHONY: fmt - -lint: - set -e; \ - FILES="$$(find . -type f -name "*.bicep*" ! -name "*.tmpl.bicepparam")"; \ - for file in $$FILES; do \ - echo "az bicep lint --file $${file}"; \ - az bicep lint --file $$file; \ - done -.PHONY: lint +modules := $(wildcard ./templates/*.bicep) +parameters := $(filter-out $(wildcard ./templates/*.tmpl.bicepparam),$(wildcard ./templates/*.bicepparam)) + +fmt: $(modules:.bicep=.bicep.fmt) $(parameters:.bicepparam=.biceparam.fmt) + +lint: $(modules:.bicep=.bicep.lint) $(parameters:.bicepparam=.biceparam.lint) + +%.bicep.fmt %.bicepparam.fmt: + az bicep format --file $(basename $@) + +%.bicep.lint %.bicepparam.lint: + az bicep lint --file $(basename $@) feature-registration: # hardcoded to eastus as this is a subscription deployment, not a resource group @az deployment sub create \ diff --git a/dev-infrastructure/modules/aks-cluster-base.bicep b/dev-infrastructure/modules/aks-cluster-base.bicep index ee09f41f7..3cb37f575 100644 --- a/dev-infrastructure/modules/aks-cluster-base.bicep +++ b/dev-infrastructure/modules/aks-cluster-base.bicep @@ -469,6 +469,36 @@ resource uami_fedcred 'Microsoft.ManagedIdentity/userAssignedIdentities/federate } ] +resource pullerIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + location: location + name: 'image-puller' +} + +module acrPullerRoles 'acr/acr-permissions.bicep' = [ + for (_, i) in acrPullResourceGroups: { + name: guid(acrRg[i].id, aksCluster.id, acrPullRoleDefinitionId, 'puller-identity') + scope: acrRg[i] + params: { + principalId: pullerIdentity.properties.principalId + acrResourceGroupid: acrRg[i].id + } + } +] + +resource puller_fedcred 'Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials@2023-01-31' = [ + for i in range(0, length(workloadIdentities)): { + parent: pullerIdentity + name: '${workloadIdentities[i].value.uamiName}-${location}-puller-fedcred' + properties: { + audiences: [ + 'api://AzureCRTokenExchange' + ] + issuer: aksCluster.properties.oidcIssuerProfile.issuerURL + subject: 'system:serviceaccount:${workloadIdentities[i].value.namespace}:${workloadIdentities[i].value.serviceAccountName}' + } + } +] + // grant aroDevopsMsi the aksClusterAdmin role on the aksCluster so it can // deploy services to the cluster resource aroDevopsMSIClusterAdmin 'Microsoft.Authorization/roleAssignments@2022-04-01' = { diff --git a/frontend/Makefile b/frontend/Makefile index 27a7d5b86..4cda30f30 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -3,8 +3,9 @@ ifndef COMMIT COMMIT := $(shell git rev-parse --short=7 HEAD) endif -ARO_HCP_BASE_IMAGE ?= ${ARO_HCP_IMAGE_ACR}.azurecr.io -ARO_HCP_FRONTEND_IMAGE ?= $(ARO_HCP_BASE_IMAGE)/arohcpfrontend:$(COMMIT) +ARO_HCP_IMAGE_REGISTRY ?= ${ARO_HCP_IMAGE_ACR}.azurecr.io +ARO_HCP_IMAGE_REPOSITORY ?= arohcpfrontend +ARO_HCP_FRONTEND_IMAGE ?= $(ARO_HCP_IMAGE_REGISTRY)/$(ARO_HCP_IMAGE_REPOSITORY):$(COMMIT) .DEFAULT_GOAL := frontend @@ -43,10 +44,23 @@ deploy: -g ${RESOURCEGROUP} \ -n frontend \ --query clientId -o tsv); \ + FRONTEND_MI_TENANT_ID=$$(az identity show \ + -g ${RESOURCEGROUP} \ + -n frontend \ + --query tenantId -o tsv);\ + IMAGE_PULLER_MI_CLIENT_ID=$$(az identity show \ + -g ${RESOURCEGROUP} \ + -n image-puller \ + --query clientId -o tsv); \ + IMAGE_PULLER_MI_TENANT_ID=$$(az identity show \ + -g ${RESOURCEGROUP} \ + -n image-puller \ + --query tenantId -o tsv);\ SECRET_STORE_MI_CLIENT_ID=$$(az aks show --resource-group ${RESOURCEGROUP} \ --name ${AKS_NAME} \ --query addonProfiles.azureKeyvaultSecretsProvider.identity.clientId \ --output tsv); \ + --query clientId -o tsv);\ ISTO_VERSION=$$(az aks show -n ${AKS_NAME} -g ${RESOURCEGROUP} --query serviceMeshProfile.istio.revisions[-1] -o tsv) && \ DB_URL=$$(az cosmosdb show -n ${DB_NAME} -g ${RESOURCEGROUP} --query documentEndpoint -o tsv) && \ TENANT_ID=$(shell az account show --query tenantId --output tsv) && \ @@ -62,9 +76,14 @@ deploy: --set credsKeyVault.name=${SERVICE_KEY_VAULT} \ --set credsKeyVault.secret=${CERTIFICATE_NAME} \ --set serviceAccount.workloadIdentityClientId="$${FRONTEND_MI_CLIENT_ID}" \ + --set serviceAccount.workloadIdentityTenantId="$${FRONTEND_MI_TENANT_ID}" \ + --set pullBinding.workloadIdentityClientId="$${IMAGE_PULLER_MI_CLIENT_ID}" \ + --set pullBinding.workloadIdentityTenantId="$${IMAGE_PULLER_MI_TENANT_ID}" \ --set configMap.currentVersion=${ARO_HCP_FRONTEND_IMAGE} \ --set configMap.location=${LOCATION} \ --set deployment.imageName=${ARO_HCP_FRONTEND_IMAGE} \ + --set pullBinding.registry=${ARO_HCP_IMAGE_REGISTRY} \ + --set pullBinding.scope=repository:${ARO_HCP_IMAGE_REPOSITORY}:pull \ --namespace aro-hcp .PHONY: deploy diff --git a/frontend/deploy/helm/frontend/templates/acrpullbinding.yaml b/frontend/deploy/helm/frontend/templates/acrpullbinding.yaml new file mode 100644 index 000000000..90101407e --- /dev/null +++ b/frontend/deploy/helm/frontend/templates/acrpullbinding.yaml @@ -0,0 +1,15 @@ +apiVersion: acrpull.microsoft.com/v1beta2 +kind: AcrPullBinding +metadata: + name: pull-binding +spec: + acr: + environment: PublicCloud + scope: {{ .Values.pullBinding.registry }} + server: {{ .Values.pullBinding.scope }} + auth: + workloadIdentity: + serviceAccountRef: frontend + clientID: {{ .Values.pullBinding.workloadIdentityClientId }} + tenantID: {{ .Values.pullBinding.workloadIdentityTenantId }} + serviceAccountName: frontend diff --git a/frontend/deploy/helm/frontend/templates/serviceaccount.yaml b/frontend/deploy/helm/frontend/templates/serviceaccount.yaml index 770aea829..0e44510db 100644 --- a/frontend/deploy/helm/frontend/templates/serviceaccount.yaml +++ b/frontend/deploy/helm/frontend/templates/serviceaccount.yaml @@ -3,4 +3,5 @@ kind: ServiceAccount metadata: annotations: azure.workload.identity/client-id: '{{ .Values.serviceAccount.workloadIdentityClientId }}' + azure.workload.identity/tenant-id: '{{ .Values.serviceAccount.workloadIdentityTenantId }}' name: frontend diff --git a/frontend/deploy/helm/frontend/values.yaml b/frontend/deploy/helm/frontend/values.yaml index 220d956f1..4f606f3f4 100644 --- a/frontend/deploy/helm/frontend/values.yaml +++ b/frontend/deploy/helm/frontend/values.yaml @@ -14,3 +14,9 @@ deployment: imageName: "" serviceAccount: workloadIdentityClientId: "" + workloadIdentityTenantId: "" +pullBinding: + registry: "" + scope: "" + workloadIdentityClientId: "" + workloadIdentityTenantId: "" diff --git a/go.work.sum b/go.work.sum index 97cc576fa..edcc432a4 100644 --- a/go.work.sum +++ b/go.work.sum @@ -316,6 +316,7 @@ cloud.google.com/go/websecurityscanner v1.6.5/go.mod h1:QR+DWaxAz2pWooylsBF854/I cloud.google.com/go/workflows v1.12.4 h1:uHNmUiatTbPQ4H1pabwfzpfEYD4BBnqDHqMm2IesOh4= cloud.google.com/go/workflows v1.12.4/go.mod h1:yQ7HUqOkdJK4duVtMeBCAOPiN1ZF1E9pAMX51vpwB/w= contrib.go.opencensus.io/exporter/stackdriver v0.13.14/go.mod h1:5pSSGY0Bhuk7waTHuDf4aQ8D2DrhgETRo9fy6k3Xlzc= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= @@ -342,6 +343,7 @@ github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3k github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= @@ -384,6 +386,7 @@ github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxk github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -525,7 +528,9 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs= +github.com/cjlapao/common-go-cryptorand v0.0.4 h1:M4hBZlxXJJ4yY3itQzDCGYJH0rmXYd1nOa8T97EPPpc= github.com/cjlapao/common-go-cryptorand v0.0.4/go.mod h1:gUG7Bso/ZDD8tOoVmMvaYWMsglfAO9eg+p74OQH7Z2w= +github.com/cjlapao/common-go-identity v0.0.3 h1:0/lZ6Ke9KErhM4ZeJIfmETq+zUdf2jl0CH+Kn6v+HgQ= github.com/cjlapao/common-go-identity v0.0.3/go.mod h1:xuNepNCHVI/51Q6DQgNPYvx3HS0VaeEhGnp8YcDO/+I= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -541,6 +546,7 @@ github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 h1:DBmgJDC9dTfkVyGgipa github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM= github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw= github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go/v2 v2.3.5/go.mod h1:1wNJ45eSXW9AnOc3skntW9ZUZz6gxrQK3cOj3rK+BC8= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= @@ -574,6 +580,7 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee 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 v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -664,8 +671,10 @@ github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyN github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= @@ -674,6 +683,7 @@ github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQr github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -690,6 +700,7 @@ github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw= github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0= @@ -702,6 +713,7 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= @@ -724,6 +736,7 @@ github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -802,6 +815,7 @@ github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoG github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/licenseclassifier v0.0.0-20210722185704-3043a050f148/go.mod h1:rq9F0RSpNKlrefnf6ZYMHKUnEJBCNzf6AcCXMYBeYvE= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= @@ -815,6 +829,7 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.6.0 h1:LoQuqlw6kHRwg25n3M0xtYrW+z2pTkR0ae1xx11hRw8= github.com/google/rpmpack v0.6.0/go.mod h1:uqVAUVQLq8UY2hCDfmJ/+rtO3aw7qyhc90rCVEabEfI= @@ -925,6 +940,7 @@ github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3lUTQd+eF9HdeMo= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ionos-cloud/sdk-go/v6 v6.1.8/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= @@ -935,7 +951,9 @@ github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8 github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= @@ -955,6 +973,7 @@ github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgS github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b h1:ZGiXF8sz7PDk6RgkP+A/SFfUD0ZR/AgG6SpRNEDKZy8= @@ -984,6 +1003,7 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= @@ -1002,12 +1022,15 @@ github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= @@ -1158,6 +1181,7 @@ github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f h1:/UDgs8FGMqw github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc= github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/ovh/go-ovh v1.4.1/go.mod h1:6bL6pPyUT7tBfI0pqOegJgRjgjuO+mOo+MyXd1EEC0M= +github.com/pascaldekloe/jwt v1.12.0 h1:imQSkPOtAIBAXoKKjL9ZVJuF/rVqJ+ntiLGpLyeqMUQ= github.com/pascaldekloe/jwt v1.12.0/go.mod h1:LiIl7EwaglmH1hWThd/AmydNCnHf/mmfluBlNqHbk8U= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= @@ -1237,8 +1261,10 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rubenv/sql-migrate v1.7.0 h1:HtQq1xyTN2ISmQDggnh0c9U3JlP8apWh8YO2jzlXpTI= github.com/rubenv/sql-migrate v1.7.0/go.mod h1:S4wtDEG1CKn+0ShpTtzWhFpHHI5PvCUtiGI+C+Z2THE= @@ -1254,6 +1280,7 @@ github.com/sassoftware/relic v7.2.1+incompatible h1:Pwyh1F3I0r4clFJXkSI8bOyJINGq github.com/sassoftware/relic v7.2.1+incompatible/go.mod h1:CWfAxv73/iLZ17rbyhIEq3K9hs5w6FpNMdUT//qR+zk= github.com/sassoftware/relic/v7 v7.6.2 h1:rS44Lbv9G9eXsukknS4mSjIAuuX+lMq/FnStgmZlUv4= github.com/sassoftware/relic/v7 v7.6.2/go.mod h1:kjmP0IBVkJZ6gXeAu35/KCEfca//+PKM6vTAsyDPY+k= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= @@ -1365,6 +1392,7 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yashtewari/glob-intersection v0.1.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= +github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= @@ -1396,6 +1424,7 @@ github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97 github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= @@ -1536,6 +1565,7 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -1582,6 +1612,7 @@ golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZ golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -1596,6 +1627,7 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= @@ -2034,16 +2066,19 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= @@ -2072,6 +2107,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069z honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c= k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM= @@ -2096,8 +2132,11 @@ knative.dev/pkg v0.0.0-20230612155445-74c4be5e935e h1:koM+NopG2Yw738NlJhQF3ZwpyS knative.dev/pkg v0.0.0-20230612155445-74c4be5e935e/go.mod h1:dqC6IrvyBE7E+oZocs5PkVhq1G59pDTA7r8U17EAKMk= oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 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=