├── codecov.yml ├── config ├── prometheus │ ├── kustomization.yaml │ └── monitor.yaml ├── certmanager │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ └── certificate.yaml ├── webhook │ ├── kustomization.yaml │ ├── service.yaml │ ├── kustomizeconfig.yaml │ └── manifests.yaml ├── rbac │ ├── service_account.yaml │ ├── auth_proxy_client_clusterrole.yaml │ ├── role_binding.yaml │ ├── auth_proxy_role_binding.yaml │ ├── aggregated_role_binding.yaml │ ├── leader_election_role_binding.yaml │ ├── auth_proxy_role.yaml │ ├── auth_proxy_service.yaml │ ├── role_with_aggregation_rule.yaml │ ├── servicebinding_viewer_role.yaml │ ├── servicebinding_editor_role.yaml │ ├── clusterworkloadresourcemapping_viewer_role.yaml │ ├── clusterworkloadresourcemapping_editor_role.yaml │ ├── leader_election_role.yaml │ ├── kustomization.yaml │ ├── aggregated_role.yaml │ └── role.yaml ├── manager │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ └── manager.yaml ├── samples │ ├── servicebinding.io_v1_servicebinding.yaml │ └── servicebinding.io_v1_clusterworkloadresourcemapping.yaml ├── crd │ ├── patches │ │ ├── cainjection_in_servicebindings.yaml │ │ ├── cainjection_in_clusterworkloadresourcemappings.yaml │ │ ├── webhook_in_servicebindings.yaml │ │ └── webhook_in_clusterworkloadresourcemappings.yaml │ ├── kustomizeconfig.yaml │ └── kustomization.yaml ├── default │ ├── manager_config_patch.yaml │ ├── manager_webhook_patch.yaml │ ├── webhookcainjection_patch.yaml │ ├── manager_auth_proxy_patch.yaml │ └── kustomization.yaml ├── kapp │ └── config.yaml └── servicebinding-workloadresourcemappings.yaml ├── OWNERS ├── .ko.yaml ├── SECURITY.md ├── .github ├── tls │ ├── server-csr.json │ ├── root-csr.json │ ├── intermediate-csr.json │ └── config.json └── dependabot.yml ├── hack ├── goimports │ ├── go.mod │ ├── tools.go │ └── go.sum ├── kube-rbac-proxy │ ├── README.md │ ├── main.go │ └── go.mod ├── diegen │ ├── go.mod │ ├── tools.go │ └── go.sum ├── boilerplate.go.txt ├── boilerplate.yaml.txt ├── ko │ └── tools.go ├── kapp │ ├── tools.go │ └── go.mod ├── kustomize │ ├── tools.go │ └── go.mod ├── kbld │ ├── tools.go │ └── go.mod ├── imgpkg │ ├── tools.go │ └── go.mod └── controller-gen │ ├── tools.go │ └── go.mod ├── .gitignore ├── SECURITY_CONTACTS ├── apis ├── duck │ ├── groupversion_info.go │ ├── podspecable_types.go │ └── zz_generated.deepcopy.go ├── v1 │ ├── servicebinding_conversion.go │ ├── clusterworkloadresourcemapping_conversion.go │ ├── groupversion_info.go │ ├── servicebinding_lifecycle.go │ ├── clusterworkloadresourcemapping_types.go │ └── servicebinding_types.go ├── v1beta1 │ ├── groupversion_info.go │ ├── servicebinding_conversion.go │ ├── clusterworkloadresourcemapping_conversion.go │ ├── clusterworkloadresourcemapping_types.go │ ├── servicebinding_types.go │ └── zz_generated.deepcopy.go └── v1alpha3 │ ├── groupversion_info.go │ ├── servicebinding_conversion.go │ ├── clusterworkloadresourcemapping_conversion.go │ ├── clusterworkloadresourcemapping_types.go │ ├── servicebinding_types.go │ └── zz_generated.deepcopy.go ├── samples ├── controlled-resource │ ├── service.yaml │ ├── workload.yaml │ ├── rbac.yaml │ ├── service-binding.yaml │ └── README.md ├── overridden-type-provider │ ├── service.yaml │ ├── workload.yaml │ ├── service-binding.yaml │ └── README.md ├── multi-binding │ ├── service.yaml │ ├── workload.yaml │ ├── service-binding.yaml │ └── README.md ├── spring-petclinic │ ├── kapp-config.yaml │ ├── service-binding.yaml │ ├── workload.yaml │ └── service.yaml └── external-secrets │ ├── service-binding.yaml │ ├── secret.yaml │ ├── kapp-config.yaml │ ├── workload.yaml │ ├── service.yaml │ └── README.md ├── controllers └── client.go ├── dies ├── v1 │ ├── clusterworkloadresourcemapping.go │ ├── servicebinding.go │ └── zz_generated.die_test.go └── v1beta1 │ ├── clusterworkloadresourcemapping.go │ └── servicebinding.go ├── PROJECT ├── projector ├── interface.go └── mapping.go ├── CONTRIBUTING.md ├── resolver ├── interface.go └── cluster.go ├── lifecycle └── hooks.go ├── rbac └── cani.go ├── go.mod └── Makefile /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "**/zz_generated.*.go" 3 | -------------------------------------------------------------------------------- /config/prometheus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - monitor.yaml 3 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - arthurdm 3 | - nebhale 4 | - scothis 5 | reviewers: 6 | - baijum 7 | - sbose78 8 | -------------------------------------------------------------------------------- /config/certmanager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - certificate.yaml 3 | 4 | configurations: 5 | - kustomizeconfig.yaml 6 | -------------------------------------------------------------------------------- /.ko.yaml: -------------------------------------------------------------------------------- 1 | builds: 2 | - id: controller 3 | dir: . 4 | main: . 5 | - id: kube-rbac-proxy 6 | dir: ./hack/kube-rbac-proxy 7 | main: . -------------------------------------------------------------------------------- /config/webhook/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manifests.yaml 3 | - service.yaml 4 | 5 | configurations: 6 | - kustomizeconfig.yaml 7 | -------------------------------------------------------------------------------- /config/rbac/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | Please report security vulnerabilities to: security@servicebinding.io 6 | -------------------------------------------------------------------------------- /config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manager.yaml 3 | 4 | configurations: 5 | - kustomizeconfig.yaml 6 | 7 | generatorOptions: 8 | disableNameSuffixHash: true 9 | -------------------------------------------------------------------------------- /config/samples/servicebinding.io_v1_servicebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: servicebinding.io/v1 2 | kind: ServiceBinding 3 | metadata: 4 | name: servicebinding-sample 5 | spec: 6 | # TODO(user): Add fields here 7 | -------------------------------------------------------------------------------- /.github/tls/server-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": { 3 | "algo": "rsa", 4 | "size": 2048 5 | }, 6 | "names": [ 7 | { 8 | "O": "Service Binding CI" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /config/rbac/auth_proxy_client_clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: metrics-reader 5 | rules: 6 | - nonResourceURLs: 7 | - "/metrics" 8 | verbs: 9 | - get 10 | -------------------------------------------------------------------------------- /config/samples/servicebinding.io_v1_clusterworkloadresourcemapping.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: servicebinding.io/v1 2 | kind: ClusterWorkloadResourceMapping 3 | metadata: 4 | name: clusterworkloadresourcemapping-sample 5 | spec: 6 | # TODO(user): Add fields here 7 | -------------------------------------------------------------------------------- /.github/tls/root-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "CI Root CA", 3 | "hosts": [], 4 | "key": { 5 | "algo": "rsa", 6 | "size": 2048 7 | }, 8 | "names": [ 9 | { 10 | "O": "Service Binding CI" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /config/webhook/service.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: webhook-service 6 | namespace: system 7 | spec: 8 | ports: 9 | - port: 443 10 | targetPort: 9443 11 | selector: 12 | control-plane: controller-manager 13 | -------------------------------------------------------------------------------- /.github/tls/intermediate-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "CI Intermediate CA", 3 | "hosts": [ 4 | "" 5 | ], 6 | "key": { 7 | "algo": "rsa", 8 | "size": 2048 9 | }, 10 | "names": [ 11 | { 12 | "O": "Service Binding CI" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: manager-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: manager-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_servicebindings.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: servicebindings.servicebinding.io 8 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: proxy-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: proxy-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/rbac/aggregated_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: aggregate-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: aggregate-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: leader-election-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: leader-election-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /hack/goimports/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/runtime/hack/goimports 2 | 3 | go 1.24.0 4 | 5 | require golang.org/x/tools v0.40.0 6 | 7 | require ( 8 | golang.org/x/mod v0.31.0 // indirect 9 | golang.org/x/sync v0.19.0 // indirect 10 | golang.org/x/sys v0.39.0 // indirect 11 | golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_clusterworkloadresourcemappings.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: clusterworkloadresourcemappings.servicebinding.io 8 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: proxy-role 5 | rules: 6 | - apiGroups: 7 | - authentication.k8s.io 8 | resources: 9 | - tokenreviews 10 | verbs: 11 | - create 12 | - apiGroups: 13 | - authorization.k8s.io 14 | resources: 15 | - subjectaccessreviews 16 | verbs: 17 | - create 18 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: controller-manager-metrics-service 7 | namespace: system 8 | spec: 9 | ports: 10 | - name: https 11 | port: 8443 12 | protocol: TCP 13 | targetPort: https 14 | selector: 15 | control-plane: controller-manager 16 | -------------------------------------------------------------------------------- /config/rbac/role_with_aggregation_rule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | creationTimestamp: null 5 | name: manager-role-with-aggregation-rule 6 | aggregationRule: 7 | clusterRoleSelectors: 8 | - matchLabels: 9 | servicebinding.io/controller: "true" 10 | # legacy support 11 | - matchLabels: 12 | service.binding/controller: "true" 13 | rules: [] 14 | -------------------------------------------------------------------------------- /config/manager/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This configuration is for teaching kustomize how to update name ref and var substitution 2 | varReference: 3 | - kind: MutatingWebhookConfiguration 4 | group: admissionregistration.k8s.io 5 | path: webhooks/namespaceSelector/matchExpressions/values 6 | - kind: ValidatingWebhookConfiguration 7 | group: admissionregistration.k8s.io 8 | path: webhooks/namespaceSelector/matchExpressions/values 9 | 10 | -------------------------------------------------------------------------------- /hack/kube-rbac-proxy/README.md: -------------------------------------------------------------------------------- 1 | # kube-rbac-proxy 2 | 3 | This directory is a hack to provide a main module for ko to build the kube-rbac-proxy image. Dependabot will check for new releases in the upstream repository and PR updated version. 4 | 5 | main.go is directly from https://github.com/brancz/kube-rbac-proxy/blob/v0.19.1/cmd/kube-rbac-proxy/main.go. While it is minimal and unlikely to change, if/when it does change we will need to update the content here. 6 | -------------------------------------------------------------------------------- /config/rbac/servicebinding_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view servicebindings. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: servicebinding-viewer-role 6 | rules: 7 | - apiGroups: 8 | - servicebinding.io 9 | resources: 10 | - servicebindings 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - servicebinding.io 17 | resources: 18 | - servicebindings/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/certmanager/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This configuration is for teaching kustomize how to update name ref and var substitution 2 | nameReference: 3 | - kind: Issuer 4 | group: cert-manager.io 5 | fieldSpecs: 6 | - kind: Certificate 7 | group: cert-manager.io 8 | path: spec/issuerRef/name 9 | 10 | varReference: 11 | - kind: Certificate 12 | group: cert-manager.io 13 | path: spec/commonName 14 | - kind: Certificate 15 | group: cert-manager.io 16 | path: spec/dnsNames 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | bin 9 | testbin/* 10 | 11 | # Test binary, build with `go test -c` 12 | *.test 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Kubernetes Generated files - skip generated files, except for vendored files 18 | 19 | !vendor/**/zz_generated.* 20 | 21 | # editor and IDE paraphernalia 22 | .idea 23 | *.swp 24 | *.swo 25 | *~ 26 | .vscode 27 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_servicebindings.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: servicebindings.servicebinding.io 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_clusterworkloadresourcemappings.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: clusterworkloadresourcemappings.servicebinding.io 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/rbac/servicebinding_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit servicebindings. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: servicebinding-editor-role 6 | rules: 7 | - apiGroups: 8 | - servicebinding.io 9 | resources: 10 | - servicebindings 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - servicebinding.io 21 | resources: 22 | - servicebindings/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /hack/diegen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/runtime/hack/controller-gen 2 | 3 | go 1.24.0 4 | 5 | require reconciler.io/dies/diegen v0.17.0 6 | 7 | require ( 8 | github.com/kr/text v0.2.0 // indirect 9 | golang.org/x/mod v0.28.0 // indirect 10 | golang.org/x/sync v0.17.0 // indirect 11 | golang.org/x/tools v0.37.0 // indirect 12 | gopkg.in/yaml.v2 v2.4.0 // indirect 13 | k8s.io/apimachinery v0.34.1 // indirect 14 | k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d // indirect 15 | sigs.k8s.io/controller-tools v0.19.0 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /config/rbac/clusterworkloadresourcemapping_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view clusterworkloadresourcemappings. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: clusterworkloadresourcemapping-viewer-role 6 | rules: 7 | - apiGroups: 8 | - servicebinding.io 9 | resources: 10 | - clusterworkloadresourcemappings 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - servicebinding.io 17 | resources: 18 | - clusterworkloadresourcemappings/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /SECURITY_CONTACTS: -------------------------------------------------------------------------------- 1 | # Defined below are the security contacts for this repo. 2 | # 3 | # They are the contact point for the Product Security Committee to reach out 4 | # to for triaging and handling of incoming issues. 5 | # 6 | # The below names agree to abide by the 7 | # [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy) 8 | # and will be removed and replaced if they violate that agreement. 9 | # 10 | # DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE 11 | # INSTRUCTIONS AT https://kubernetes.io/security/ 12 | 13 | arthurdm 14 | nebhale 15 | -------------------------------------------------------------------------------- /config/default/manager_config_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | args: 12 | - "--config=controller_manager_config.yaml" 13 | volumeMounts: 14 | - name: manager-config 15 | mountPath: /controller_manager_config.yaml 16 | subPath: controller_manager_config.yaml 17 | volumes: 18 | - name: manager-config 19 | configMap: 20 | name: manager-config 21 | -------------------------------------------------------------------------------- /config/prometheus/monitor.yaml: -------------------------------------------------------------------------------- 1 | 2 | # Prometheus Monitor Service (Metrics) 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | labels: 7 | control-plane: controller-manager 8 | name: controller-manager-metrics-monitor 9 | namespace: system 10 | spec: 11 | endpoints: 12 | - path: /metrics 13 | port: https 14 | scheme: https 15 | bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token 16 | tlsConfig: 17 | insecureSkipVerify: true 18 | selector: 19 | matchLabels: 20 | control-plane: controller-manager 21 | -------------------------------------------------------------------------------- /config/crd/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This file is for teaching kustomize how to substitute name and namespace reference in CRD 2 | nameReference: 3 | - kind: Service 4 | version: v1 5 | fieldSpecs: 6 | - kind: CustomResourceDefinition 7 | version: v1 8 | group: apiextensions.k8s.io 9 | path: spec/conversion/webhook/clientConfig/service/name 10 | 11 | namespace: 12 | - kind: CustomResourceDefinition 13 | version: v1 14 | group: apiextensions.k8s.io 15 | path: spec/conversion/webhook/clientConfig/service/namespace 16 | create: false 17 | 18 | varReference: 19 | - path: metadata/annotations 20 | -------------------------------------------------------------------------------- /config/rbac/clusterworkloadresourcemapping_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit clusterworkloadresourcemappings. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: clusterworkloadresourcemapping-editor-role 6 | rules: 7 | - apiGroups: 8 | - servicebinding.io 9 | resources: 10 | - clusterworkloadresourcemappings 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - servicebinding.io 21 | resources: 22 | - clusterworkloadresourcemappings/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/default/manager_webhook_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | ports: 12 | - containerPort: 9443 13 | name: webhook-server 14 | protocol: TCP 15 | volumeMounts: 16 | - mountPath: /tmp/k8s-webhook-server/serving-certs 17 | name: cert 18 | readOnly: true 19 | volumes: 20 | - name: cert 21 | secret: 22 | defaultMode: 420 23 | secretName: webhook-server-cert 24 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ -------------------------------------------------------------------------------- /hack/boilerplate.yaml.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2022 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions to do leader election. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: leader-election-role 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - configmaps 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - create 16 | - update 17 | - patch 18 | - delete 19 | - apiGroups: 20 | - coordination.k8s.io 21 | resources: 22 | - leases 23 | verbs: 24 | - get 25 | - list 26 | - watch 27 | - create 28 | - update 29 | - patch 30 | - delete 31 | - apiGroups: 32 | - "" 33 | resources: 34 | - events 35 | verbs: 36 | - create 37 | - patch 38 | -------------------------------------------------------------------------------- /config/default/webhookcainjection_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch add annotation to admission webhook config and 2 | # the variables $(NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. 3 | # apiVersion: admissionregistration.k8s.io/v1 4 | # kind: MutatingWebhookConfiguration 5 | # metadata: 6 | # name: mutating-webhook-configuration 7 | # annotations: 8 | # cert-manager.io/inject-ca-from: $(NAMESPACE)/$(CERTIFICATE_NAME) 9 | --- 10 | apiVersion: admissionregistration.k8s.io/v1 11 | kind: ValidatingWebhookConfiguration 12 | metadata: 13 | name: validating-webhook-configuration 14 | annotations: 15 | cert-manager.io/inject-ca-from: $(NAMESPACE)/$(CERTIFICATE_NAME) 16 | -------------------------------------------------------------------------------- /apis/duck/groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // +kubebuilder:object:generate=true 18 | package duck 19 | -------------------------------------------------------------------------------- /samples/controlled-resource/service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: v1 17 | kind: Secret 18 | metadata: 19 | name: controlled-resource 20 | type: Opaque 21 | stringData: 22 | target: "service binding" 23 | -------------------------------------------------------------------------------- /config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | # All RBAC will be applied under this service account in 3 | # the deployment namespace. You may comment out this resource 4 | # if your manager will use a service account that exists at 5 | # runtime. Be sure to update RoleBinding and ClusterRoleBinding 6 | # subjects if changing service account names. 7 | - service_account.yaml 8 | - role.yaml 9 | - role_binding.yaml 10 | - aggregated_role.yaml 11 | - aggregated_role_binding.yaml 12 | - leader_election_role.yaml 13 | - leader_election_role_binding.yaml 14 | # Comment the following 4 lines if you want to disable 15 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 16 | # which protects your /metrics endpoint. 17 | - auth_proxy_service.yaml 18 | - auth_proxy_role.yaml 19 | - auth_proxy_role_binding.yaml 20 | - auth_proxy_client_clusterrole.yaml 21 | -------------------------------------------------------------------------------- /hack/ko/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2022 the original author or authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import ( 24 | _ "github.com/google/ko" 25 | ) 26 | -------------------------------------------------------------------------------- /samples/overridden-type-provider/service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: v1 17 | kind: Secret 18 | metadata: 19 | name: overridden-type-provider 20 | type: Opaque 21 | stringData: 22 | type: original-type 23 | provider: original-provider 24 | -------------------------------------------------------------------------------- /hack/diegen/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2022 the original author or authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import ( 24 | _ "reconciler.io/dies/diegen" 25 | ) 26 | -------------------------------------------------------------------------------- /hack/kapp/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2022 the original author or authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import ( 24 | _ "github.com/k14s/kapp/cmd/kapp" 25 | ) 26 | -------------------------------------------------------------------------------- /hack/goimports/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2022 the original author or authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import ( 24 | _ "golang.org/x/tools/cmd/goimports" 25 | ) 26 | -------------------------------------------------------------------------------- /hack/kustomize/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2022 the original author or authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import ( 24 | _ "sigs.k8s.io/kustomize/kustomize/v4" 25 | ) 26 | -------------------------------------------------------------------------------- /hack/kbld/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2022 the original author or authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import ( 24 | _ "github.com/vmware-tanzu/carvel-kbld/cmd/kbld" 25 | ) 26 | -------------------------------------------------------------------------------- /hack/imgpkg/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2022 the original author or authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import ( 24 | _ "github.com/vmware-tanzu/carvel-imgpkg/cmd/imgpkg" 25 | ) 26 | -------------------------------------------------------------------------------- /apis/v1/servicebinding_conversion.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Original Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1 18 | 19 | import ( 20 | "sigs.k8s.io/controller-runtime/pkg/conversion" 21 | ) 22 | 23 | var _ conversion.Hub = (*ServiceBinding)(nil) 24 | 25 | // Hub for conversion 26 | func (r *ServiceBinding) Hub() {} 27 | -------------------------------------------------------------------------------- /config/webhook/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # the following config is for teaching kustomize where to look at when substituting vars. 2 | # It requires kustomize v2.1.0 or newer to work properly. 3 | nameReference: 4 | - kind: Service 5 | version: v1 6 | fieldSpecs: 7 | - kind: MutatingWebhookConfiguration 8 | group: admissionregistration.k8s.io 9 | path: webhooks/clientConfig/service/name 10 | - kind: ValidatingWebhookConfiguration 11 | group: admissionregistration.k8s.io 12 | path: webhooks/clientConfig/service/name 13 | 14 | namespace: 15 | - kind: MutatingWebhookConfiguration 16 | group: admissionregistration.k8s.io 17 | path: webhooks/clientConfig/service/namespace 18 | create: true 19 | - kind: ValidatingWebhookConfiguration 20 | group: admissionregistration.k8s.io 21 | path: webhooks/clientConfig/service/namespace 22 | create: true 23 | 24 | varReference: 25 | - path: metadata/annotations 26 | -------------------------------------------------------------------------------- /hack/controller-gen/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2022 the original author or authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import ( 24 | _ "sigs.k8s.io/controller-tools/cmd/controller-gen" 25 | ) 26 | -------------------------------------------------------------------------------- /apis/v1/clusterworkloadresourcemapping_conversion.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Original Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1 18 | 19 | import "sigs.k8s.io/controller-runtime/pkg/conversion" 20 | 21 | var _ conversion.Hub = (*ClusterWorkloadResourceMapping)(nil) 22 | 23 | // Hub for conversion 24 | func (r *ClusterWorkloadResourceMapping) Hub() {} 25 | -------------------------------------------------------------------------------- /samples/multi-binding/service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: v1 17 | kind: Secret 18 | metadata: 19 | name: multi-binding-1 20 | type: Opaque 21 | stringData: 22 | number: "1" 23 | 24 | --- 25 | apiVersion: v1 26 | kind: Secret 27 | metadata: 28 | name: multi-binding-2 29 | type: Opaque 30 | stringData: 31 | number: "2" 32 | -------------------------------------------------------------------------------- /hack/kube-rbac-proxy/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the kube-rbac-proxy maintainers. All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | 22 | "k8s.io/component-base/cli" 23 | 24 | "github.com/brancz/kube-rbac-proxy/cmd/kube-rbac-proxy/app" 25 | ) 26 | 27 | func main() { 28 | command := app.NewKubeRBACProxyCommand() 29 | code := cli.Run(command) 30 | os.Exit(code) 31 | } 32 | -------------------------------------------------------------------------------- /samples/multi-binding/workload.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: batch/v1 17 | kind: Job 18 | metadata: 19 | name: multi-binding 20 | spec: 21 | template: 22 | spec: 23 | containers: 24 | - name: workload 25 | image: ubuntu:bionic 26 | command: ["env"] 27 | enableServiceLinks: false 28 | restartPolicy: OnFailure 29 | -------------------------------------------------------------------------------- /samples/controlled-resource/workload.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: serving.knative.dev/v1 17 | kind: Service 18 | metadata: 19 | name: controlled-resource 20 | spec: 21 | template: 22 | spec: 23 | containers: 24 | # from https://knative.dev/docs/serving/samples/hello-world/helloworld-go/ 25 | - image: gcr.io/knative-samples/helloworld-go 26 | -------------------------------------------------------------------------------- /samples/overridden-type-provider/workload.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: batch/v1 17 | kind: Job 18 | metadata: 19 | name: overridden-type-provider 20 | spec: 21 | template: 22 | spec: 23 | containers: 24 | - name: workload 25 | image: ubuntu:bionic 26 | command: ["env"] 27 | enableServiceLinks: false 28 | restartPolicy: OnFailure 29 | -------------------------------------------------------------------------------- /config/certmanager/certificate.yaml: -------------------------------------------------------------------------------- 1 | # The following manifests contain a self-signed issuer CR and a certificate CR. 2 | # More document can be found at https://docs.cert-manager.io 3 | # WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. 4 | apiVersion: cert-manager.io/v1 5 | kind: Issuer 6 | metadata: 7 | name: selfsigned-issuer 8 | namespace: system 9 | spec: 10 | selfSigned: {} 11 | --- 12 | apiVersion: cert-manager.io/v1 13 | kind: Certificate 14 | metadata: 15 | name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml 16 | namespace: system 17 | spec: 18 | # $(SERVICE_NAME) and $(NAMESPACE) will be substituted by kustomize 19 | dnsNames: 20 | - $(SERVICE_NAME).$(NAMESPACE).svc 21 | - $(SERVICE_NAME).$(NAMESPACE).svc.cluster.local 22 | issuerRef: 23 | kind: Issuer 24 | name: selfsigned-issuer 25 | secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize 26 | -------------------------------------------------------------------------------- /hack/goimports/go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 2 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= 4 | golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= 5 | golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= 6 | golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 7 | golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= 8 | golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 9 | golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA= 10 | golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= 11 | golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= 12 | golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= 13 | -------------------------------------------------------------------------------- /config/kapp/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kapp.k14s.io/v1alpha1 2 | kind: Config 3 | rebaseRules: 4 | - path: [rules] 5 | type: copy 6 | sources: [existing] 7 | resourceMatchers: 8 | - andMatcher: 9 | matchers: 10 | - apiVersionKindMatcher: {apiVersion: rbac.authorization.k8s.io/v1, kind: ClusterRole} 11 | - notMatcher: 12 | matcher: 13 | emptyFieldMatcher: 14 | path: [aggregationRule] 15 | 16 | - path: [webhooks, {index: 0}, rules] 17 | type: copy 18 | sources: [existing] 19 | resourceMatchers: 20 | - andMatcher: 21 | matchers: 22 | - apiVersionKindMatcher: {apiVersion: admissionregistration.k8s.io/v1, kind: MutatingWebhookConfiguration} 23 | - hasAnnotationMatcher: 24 | keys: 25 | - webhook.servicebinding.io/dynamic-rules 26 | - andMatcher: 27 | matchers: 28 | - apiVersionKindMatcher: {apiVersion: admissionregistration.k8s.io/v1, kind: ValidatingWebhookConfiguration} 29 | - hasAnnotationMatcher: 30 | keys: 31 | - webhook.servicebinding.io/dynamic-rules -------------------------------------------------------------------------------- /config/rbac/aggregated_role.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: aggregate-role 6 | aggregationRule: 7 | clusterRoleSelectors: 8 | - matchLabels: 9 | servicebinding.io/controller: "true" 10 | # pre-v1alpha3 support 11 | - matchLabels: 12 | service.binding/controller: "true" 13 | 14 | --- 15 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: ClusterRole 17 | metadata: 18 | name: k8s-workloads-role 19 | labels: 20 | servicebinding.io/controller: "true" 21 | rules: 22 | - apiGroups: 23 | - "" 24 | resources: 25 | - replicationcontrollers 26 | verbs: 27 | - get 28 | - list 29 | - watch 30 | - update 31 | - patch 32 | - apiGroups: 33 | - apps 34 | resources: 35 | - daemonsets 36 | - deployments 37 | - replicasets 38 | - statefulsets 39 | verbs: 40 | - get 41 | - list 42 | - watch 43 | - update 44 | - patch 45 | - apiGroups: 46 | - batch 47 | resources: 48 | - cronjobs 49 | - jobs 50 | verbs: 51 | - get 52 | - list 53 | - watch 54 | - update 55 | - patch -------------------------------------------------------------------------------- /samples/controlled-resource/rbac.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | --- 17 | apiVersion: rbac.authorization.k8s.io/v1 18 | kind: ClusterRole 19 | metadata: 20 | name: servicebinding-knative-serving 21 | labels: 22 | servicebinding.io/controller: "true" 23 | rules: 24 | - apiGroups: 25 | - serving.knative.dev 26 | resources: 27 | - configurations 28 | - revisions 29 | - services 30 | verbs: 31 | - get 32 | - list 33 | - watch 34 | - update 35 | - patch 36 | -------------------------------------------------------------------------------- /config/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch inject a sidecar container which is a HTTP proxy for the 2 | # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: controller-manager 7 | namespace: system 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: kube-rbac-proxy 13 | image: ko://github.com/servicebinding/runtime/hack/kube-rbac-proxy 14 | args: 15 | - "--secure-listen-address=0.0.0.0:8443" 16 | - "--upstream=http://127.0.0.1:8080/" 17 | - "--logtostderr=true" 18 | - "--v=0" 19 | ports: 20 | - containerPort: 8443 21 | protocol: TCP 22 | name: https 23 | resources: 24 | limits: 25 | cpu: 500m 26 | memory: 128Mi 27 | requests: 28 | cpu: 5m 29 | memory: 64Mi 30 | - name: manager 31 | args: 32 | - "--health-probe-bind-address=:8081" 33 | - "--metrics-bind-address=127.0.0.1:8080" 34 | - "--leader-elect" 35 | -------------------------------------------------------------------------------- /config/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: manager-role 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - events 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - admissionregistration.k8s.io 21 | resources: 22 | - mutatingwebhookconfigurations 23 | - validatingwebhookconfigurations 24 | verbs: 25 | - create 26 | - get 27 | - list 28 | - patch 29 | - update 30 | - watch 31 | - apiGroups: 32 | - servicebinding.io 33 | resources: 34 | - clusterworkloadresourcemappings 35 | verbs: 36 | - get 37 | - list 38 | - watch 39 | - apiGroups: 40 | - servicebinding.io 41 | resources: 42 | - servicebindings 43 | verbs: 44 | - create 45 | - delete 46 | - get 47 | - list 48 | - patch 49 | - update 50 | - watch 51 | - apiGroups: 52 | - servicebinding.io 53 | resources: 54 | - servicebindings/finalizers 55 | verbs: 56 | - update 57 | - apiGroups: 58 | - servicebinding.io 59 | resources: 60 | - servicebindings/status 61 | verbs: 62 | - get 63 | - patch 64 | - update 65 | -------------------------------------------------------------------------------- /config/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # This kustomization.yaml is not intended to be run by itself, 2 | # since it depends on service name and namespace that are out of this kustomize package. 3 | # It should be run by config/default 4 | resources: 5 | - bases/servicebinding.io_servicebindings.yaml 6 | - bases/servicebinding.io_clusterworkloadresourcemappings.yaml 7 | #+kubebuilder:scaffold:crdkustomizeresource 8 | 9 | patchesStrategicMerge: 10 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. 11 | # patches here are for enabling the conversion webhook for each CRD 12 | #- patches/webhook_in_servicebindings.yaml 13 | #- patches/webhook_in_clusterworkloadresourcemappings.yaml 14 | #+kubebuilder:scaffold:crdkustomizewebhookpatch 15 | 16 | # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. 17 | # patches here are for enabling the CA injection for each CRD 18 | #- patches/cainjection_in_servicebindings.yaml 19 | #- patches/cainjection_in_clusterworkloadresourcemappings.yaml 20 | #+kubebuilder:scaffold:crdkustomizecainjectionpatch 21 | 22 | # the following config is for teaching kustomize how to do kustomization for CRDs. 23 | configurations: 24 | - kustomizeconfig.yaml 25 | -------------------------------------------------------------------------------- /config/webhook/manifests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: admissionregistration.k8s.io/v1 3 | kind: ValidatingWebhookConfiguration 4 | metadata: 5 | name: validating-webhook-configuration 6 | webhooks: 7 | - admissionReviewVersions: 8 | - v1 9 | - v1beta1 10 | clientConfig: 11 | service: 12 | name: webhook-service 13 | namespace: system 14 | path: /validate-servicebinding-io-v1-clusterworkloadresourcemapping 15 | failurePolicy: Fail 16 | name: v1.clusterworkloadresourcemappings.servicebinding.io 17 | rules: 18 | - apiGroups: 19 | - servicebinding.io 20 | apiVersions: 21 | - v1 22 | operations: 23 | - CREATE 24 | - UPDATE 25 | resources: 26 | - clusterworkloadresourcemappings 27 | sideEffects: None 28 | - admissionReviewVersions: 29 | - v1 30 | - v1beta1 31 | clientConfig: 32 | service: 33 | name: webhook-service 34 | namespace: system 35 | path: /validate-servicebinding-io-v1-servicebinding 36 | failurePolicy: Fail 37 | name: v1.servicebindings.servicebinding.io 38 | rules: 39 | - apiGroups: 40 | - servicebinding.io 41 | apiVersions: 42 | - v1 43 | operations: 44 | - CREATE 45 | - UPDATE 46 | resources: 47 | - servicebindings 48 | sideEffects: None 49 | -------------------------------------------------------------------------------- /config/servicebinding-workloadresourcemappings.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # mappings for built-in k8s types that are almost PodSpecable 16 | # see https://servicebinding.io/spec/core/1.0.0/#workload-resource-mapping 17 | 18 | --- 19 | apiVersion: servicebinding.io/v1 20 | kind: ClusterWorkloadResourceMapping 21 | metadata: 22 | name: cronjobs.batch 23 | spec: 24 | versions: 25 | - version: "*" 26 | annotations: .spec.jobTemplate.spec.template.metadata.annotations 27 | containers: 28 | - path: .spec.jobTemplate.spec.template.spec.containers[*] 29 | name: .name 30 | - path: .spec.jobTemplate.spec.template.spec.initContainers[*] 31 | name: .name 32 | volumes: .spec.jobTemplate.spec.template.spec.volumes 33 | -------------------------------------------------------------------------------- /samples/controlled-resource/service-binding.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: servicebinding.io/v1 17 | kind: ServiceBinding 18 | metadata: 19 | name: controlled-resource 20 | spec: 21 | # direct Secret reference is used for compatibility, but not recommended for dynamically provisioned services 22 | service: 23 | apiVersion: v1 24 | kind: Secret 25 | name: controlled-resource 26 | workload: 27 | apiVersion: serving.knative.dev/v1 28 | kind: Configuration 29 | # use a label selector since we may not know the name of the controlled resource 30 | selector: 31 | matchLabels: 32 | serving.knative.dev/service: controlled-resource 33 | env: 34 | - name: TARGET 35 | key: target 36 | -------------------------------------------------------------------------------- /samples/spring-petclinic/kapp-config.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | kind: ConfigMap 17 | metadata: 18 | name: kapp-config 19 | labels: 20 | kapp.k14s.io/config: "" 21 | data: 22 | config.yml: | 23 | apiVersion: kapp.k14s.io/v1alpha1 24 | kind: Config 25 | waitRules: 26 | - supportsObservedGeneration: true 27 | conditionMatchers: 28 | - type: ServiceAvailable 29 | status: "True" 30 | unblockChanges: true 31 | - type: Ready 32 | status: "False" 33 | failure: true 34 | - type: Ready 35 | status: "True" 36 | success: true 37 | resourceMatchers: 38 | - apiVersionKindMatcher: {apiVersion: servicebinding.io/v1, kind: ServiceBinding} 39 | -------------------------------------------------------------------------------- /samples/overridden-type-provider/service-binding.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: servicebinding.io/v1 17 | kind: ServiceBinding 18 | metadata: 19 | name: overridden-type-provider 20 | labels: 21 | sample: overridden-type-provider 22 | spec: 23 | type: overridden-type 24 | provider: overridden-provider 25 | # direct Secret reference is used for compatibility, but not recommended for dynamically provisioned services 26 | service: 27 | apiVersion: v1 28 | kind: Secret 29 | name: overridden-type-provider 30 | workload: 31 | apiVersion: batch/v1 32 | kind: Job 33 | name: overridden-type-provider 34 | env: 35 | - name: BOUND_TYPE 36 | key: type 37 | - name: BOUND_PROVIDER 38 | key: provider 39 | -------------------------------------------------------------------------------- /controllers/client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package controllers 18 | 19 | import ( 20 | "context" 21 | 22 | "reconciler.io/runtime/reconcilers" 23 | "sigs.k8s.io/controller-runtime/pkg/client" 24 | ) 25 | 26 | func TrackingClient(config reconcilers.Config) client.Client { 27 | return &trackingClient{config} 28 | } 29 | 30 | type trackingClient struct { 31 | reconcilers.Config 32 | } 33 | 34 | func (c *trackingClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { 35 | return c.Config.TrackAndGet(ctx, key, obj, opts...) 36 | } 37 | 38 | func (c *trackingClient) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { 39 | return c.Config.TrackAndList(ctx, list, opts...) 40 | } 41 | -------------------------------------------------------------------------------- /apis/duck/podspecable_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package duck 18 | 19 | import ( 20 | corev1 "k8s.io/api/core/v1" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | runtime "k8s.io/apimachinery/pkg/runtime" 23 | ) 24 | 25 | type PodSpecable struct { 26 | metav1.TypeMeta `json:",inline"` 27 | metav1.ObjectMeta `json:"metadata,omitempty"` 28 | 29 | Spec PodSpecableSpec `json:"spec,omitempty"` 30 | } 31 | 32 | type PodSpecableSpec struct { 33 | Template corev1.PodTemplateSpec `json:"template,omitempty"` 34 | } 35 | 36 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 37 | func (in *PodSpecable) DeepCopyObject() runtime.Object { 38 | if c := in.DeepCopy(); c != nil { 39 | return c 40 | } 41 | return nil 42 | } 43 | -------------------------------------------------------------------------------- /samples/external-secrets/service-binding.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: servicebinding.io/v1 17 | kind: ServiceBinding 18 | metadata: 19 | name: eso-example 20 | annotations: 21 | kapp.k14s.io/change-group: binding 22 | kapp.k14s.io/change-rule.service: "upsert after upserting service" 23 | kapp.k14s.io/change-rule.service-delete: "delete before deleting service" 24 | kapp.k14s.io/change-rule.workload: "upsert before upserting workload" 25 | kapp.k14s.io/change-rule.workload-delete: "delete after deleting workload" 26 | spec: 27 | service: 28 | apiVersion: external-secrets.io/v1beta1 29 | kind: ExternalSecret 30 | name: eso-example-db 31 | workload: 32 | apiVersion: apps/v1 33 | kind: Deployment 34 | name: eso-example 35 | -------------------------------------------------------------------------------- /apis/v1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package v1 contains API Schema definitions for the servicebinding.io v1 API group 18 | // +kubebuilder:object:generate=true 19 | // +groupName=servicebinding.io 20 | package v1 21 | 22 | import ( 23 | "k8s.io/apimachinery/pkg/runtime/schema" 24 | "sigs.k8s.io/controller-runtime/pkg/scheme" 25 | ) 26 | 27 | var ( 28 | // GroupVersion is group version used to register these objects 29 | GroupVersion = schema.GroupVersion{Group: "servicebinding.io", Version: "v1"} 30 | 31 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 32 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 33 | 34 | // AddToScheme adds the types in this group-version to the given scheme. 35 | AddToScheme = SchemeBuilder.AddToScheme 36 | ) 37 | -------------------------------------------------------------------------------- /apis/v1beta1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package v1beta1 contains API Schema definitions for the v1beta1 API group 18 | // +kubebuilder:object:generate=false 19 | // +groupName=servicebinding.io 20 | package v1beta1 21 | 22 | import ( 23 | "k8s.io/apimachinery/pkg/runtime/schema" 24 | "sigs.k8s.io/controller-runtime/pkg/scheme" 25 | ) 26 | 27 | var ( 28 | // GroupVersion is group version used to register these objects 29 | GroupVersion = schema.GroupVersion{Group: "servicebinding.io", Version: "v1beta1"} 30 | 31 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 32 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 33 | 34 | // AddToScheme adds the types in this group-version to the given scheme. 35 | AddToScheme = SchemeBuilder.AddToScheme 36 | ) 37 | -------------------------------------------------------------------------------- /apis/v1alpha3/groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package v1alpha3 contains API Schema definitions for the v1alpha3 API group 18 | // +kubebuilder:object:generate=false 19 | // +groupName=servicebinding.io 20 | package v1alpha3 21 | 22 | import ( 23 | "k8s.io/apimachinery/pkg/runtime/schema" 24 | "sigs.k8s.io/controller-runtime/pkg/scheme" 25 | ) 26 | 27 | var ( 28 | // GroupVersion is group version used to register these objects 29 | GroupVersion = schema.GroupVersion{Group: "servicebinding.io", Version: "v1alpha3"} 30 | 31 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 32 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 33 | 34 | // AddToScheme adds the types in this group-version to the given scheme. 35 | AddToScheme = SchemeBuilder.AddToScheme 36 | ) 37 | -------------------------------------------------------------------------------- /apis/v1alpha3/servicebinding_conversion.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1alpha3 18 | 19 | import ( 20 | "sigs.k8s.io/controller-runtime/pkg/conversion" 21 | 22 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 23 | ) 24 | 25 | var _ conversion.Convertible = (*ServiceBinding)(nil) 26 | 27 | func (src *ServiceBinding) ConvertTo(dstRaw conversion.Hub) error { 28 | dst := dstRaw.(*servicebindingv1.ServiceBinding) 29 | 30 | dst.ObjectMeta = src.ObjectMeta 31 | dst.Spec = src.Spec 32 | dst.Status = src.Status 33 | 34 | return nil 35 | } 36 | 37 | func (dst *ServiceBinding) ConvertFrom(srcRaw conversion.Hub) error { 38 | src := srcRaw.(*servicebindingv1.ServiceBinding) 39 | 40 | dst.ObjectMeta = src.ObjectMeta 41 | dst.Spec = src.Spec 42 | dst.Status = src.Status 43 | 44 | return nil 45 | } 46 | -------------------------------------------------------------------------------- /apis/v1beta1/servicebinding_conversion.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1beta1 18 | 19 | import ( 20 | "sigs.k8s.io/controller-runtime/pkg/conversion" 21 | 22 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 23 | ) 24 | 25 | var _ conversion.Convertible = (*ServiceBinding)(nil) 26 | 27 | func (src *ServiceBinding) ConvertTo(dstRaw conversion.Hub) error { 28 | dst := dstRaw.(*servicebindingv1.ServiceBinding) 29 | 30 | dst.ObjectMeta = src.ObjectMeta 31 | dst.Spec = src.Spec 32 | dst.Status = src.Status 33 | 34 | return nil 35 | } 36 | 37 | func (dst *ServiceBinding) ConvertFrom(srcRaw conversion.Hub) error { 38 | src := srcRaw.(*servicebindingv1.ServiceBinding) 39 | 40 | dst.ObjectMeta = src.ObjectMeta 41 | dst.Spec = src.Spec 42 | dst.Status = src.Status 43 | 44 | return nil 45 | } 46 | -------------------------------------------------------------------------------- /.github/tls/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "signing": { 3 | "default": { 4 | "expiry": "24h" 5 | }, 6 | "profiles": { 7 | "intermediate": { 8 | "usages": [ 9 | "cert sign", 10 | "crl sign" 11 | ], 12 | "ca_constraint": { 13 | "is_ca": true, 14 | "max_path_len": 0, 15 | "max_path_len_zero": true 16 | }, 17 | "expiry": "24h" 18 | }, 19 | "server": { 20 | "usages": [ 21 | "signing", 22 | "key encipherment", 23 | "server auth" 24 | ], 25 | "expiry": "24h" 26 | }, 27 | "client": { 28 | "usages": [ 29 | "signing", 30 | "digital signature", 31 | "key encipherment", 32 | "client auth" 33 | ], 34 | "expiry": "24h" 35 | }, 36 | "peer": { 37 | "usages": [ 38 | "signing", 39 | "digital signature", 40 | "key encipherment", 41 | "client auth", 42 | "server auth" 43 | ], 44 | "expiry": "24h" 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /apis/v1alpha3/clusterworkloadresourcemapping_conversion.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1alpha3 18 | 19 | import ( 20 | "sigs.k8s.io/controller-runtime/pkg/conversion" 21 | 22 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 23 | ) 24 | 25 | var _ conversion.Convertible = (*ClusterWorkloadResourceMapping)(nil) 26 | 27 | func (src *ClusterWorkloadResourceMapping) ConvertTo(dstRaw conversion.Hub) error { 28 | dst := dstRaw.(*servicebindingv1.ClusterWorkloadResourceMapping) 29 | 30 | dst.ObjectMeta = src.ObjectMeta 31 | dst.Spec = src.Spec 32 | 33 | return nil 34 | } 35 | 36 | func (dst *ClusterWorkloadResourceMapping) ConvertFrom(srcRaw conversion.Hub) error { 37 | src := srcRaw.(*servicebindingv1.ClusterWorkloadResourceMapping) 38 | 39 | dst.ObjectMeta = src.ObjectMeta 40 | dst.Spec = src.Spec 41 | 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /apis/v1beta1/clusterworkloadresourcemapping_conversion.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1beta1 18 | 19 | import ( 20 | "sigs.k8s.io/controller-runtime/pkg/conversion" 21 | 22 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 23 | ) 24 | 25 | var _ conversion.Convertible = (*ClusterWorkloadResourceMapping)(nil) 26 | 27 | func (src *ClusterWorkloadResourceMapping) ConvertTo(dstRaw conversion.Hub) error { 28 | dst := dstRaw.(*servicebindingv1.ClusterWorkloadResourceMapping) 29 | 30 | dst.ObjectMeta = src.ObjectMeta 31 | dst.Spec = src.Spec 32 | 33 | return nil 34 | } 35 | 36 | func (dst *ClusterWorkloadResourceMapping) ConvertFrom(srcRaw conversion.Hub) error { 37 | src := srcRaw.(*servicebindingv1.ClusterWorkloadResourceMapping) 38 | 39 | dst.ObjectMeta = src.ObjectMeta 40 | dst.Spec = src.Spec 41 | 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /samples/spring-petclinic/service-binding.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: servicebinding.io/v1 17 | kind: ServiceBinding 18 | metadata: 19 | name: spring-petclinic-db 20 | annotations: 21 | kapp.k14s.io/change-group: binding 22 | kapp.k14s.io/change-rule.service: "upsert after upserting service" 23 | kapp.k14s.io/change-rule.service-delete: "delete before deleting service" 24 | kapp.k14s.io/change-rule.workload: "upsert before upserting workload" 25 | kapp.k14s.io/change-rule.workload-delete: "delete after deleting workload" 26 | spec: 27 | # direct Secret reference is used for compatibility, but not recommended for dynamically provisioned services 28 | service: 29 | apiVersion: v1 30 | kind: Secret 31 | name: spring-petclinic-db 32 | workload: 33 | apiVersion: apps/v1 34 | kind: Deployment 35 | name: spring-petclinic 36 | -------------------------------------------------------------------------------- /dies/v1/clusterworkloadresourcemapping.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1 18 | 19 | import ( 20 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 21 | ) 22 | 23 | // +die:object=true 24 | type _ = servicebindingv1.ClusterWorkloadResourceMapping 25 | 26 | // +die 27 | // +die:field:name=Versions,die=ClusterWorkloadResourceMappingTemplateDie,listMapKey=Version 28 | type _ = servicebindingv1.ClusterWorkloadResourceMappingSpec 29 | 30 | // deprecated use VersionDie 31 | func (d *ClusterWorkloadResourceMappingSpecDie) VersionsDie(version string, fn func(d *ClusterWorkloadResourceMappingTemplateDie)) *ClusterWorkloadResourceMappingSpecDie { 32 | return d.VersionDie(version, fn) 33 | } 34 | 35 | // +die 36 | // +die:field:name=Containers,die=ClusterWorkloadResourceMappingContainerDie,listType=atomic 37 | type _ = servicebindingv1.ClusterWorkloadResourceMappingTemplate 38 | 39 | // +die 40 | type _ = servicebindingv1.ClusterWorkloadResourceMappingContainer 41 | -------------------------------------------------------------------------------- /samples/external-secrets/secret.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | --- 17 | apiVersion: external-secrets.io/v1beta1 18 | kind: ExternalSecret 19 | metadata: 20 | name: eso-example-db 21 | annotations: 22 | kapp.k14s.io/change-group: secret 23 | spec: 24 | refreshInterval: 1h 25 | secretStoreRef: 26 | name: mysql 27 | kind: SecretStore 28 | target: 29 | template: 30 | mergePolicy: Merge 31 | type: servicebinding.io/mysql 32 | dataFrom: 33 | - extract: 34 | key: /petclinic 35 | 36 | --- 37 | apiVersion: external-secrets.io/v1beta1 38 | kind: SecretStore 39 | metadata: 40 | name: mysql 41 | annotations: 42 | kapp.k14s.io/change-group: secret 43 | spec: 44 | provider: 45 | fake: 46 | data: 47 | - key: "/petclinic" 48 | valueMap: 49 | type: mysql 50 | provider: mariadb 51 | host: eso-example-db 52 | port: "3306" 53 | database: default 54 | # demo credentials 55 | username: user 56 | password: pass 57 | -------------------------------------------------------------------------------- /dies/v1beta1/clusterworkloadresourcemapping.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1beta1 18 | 19 | import ( 20 | dieservicebindingv1 "github.com/servicebinding/runtime/dies/v1" 21 | ) 22 | 23 | var ClusterWorkloadResourceMappingBlank = dieservicebindingv1.ClusterWorkloadResourceMappingBlank 24 | 25 | type ClusterWorkloadResourceMappingDie = dieservicebindingv1.ClusterWorkloadResourceMappingDie 26 | 27 | var ClusterWorkloadResourceMappingSpecBlank = dieservicebindingv1.ClusterWorkloadResourceMappingSpecBlank 28 | 29 | type ClusterWorkloadResourceMappingSpecDie = dieservicebindingv1.ClusterWorkloadResourceMappingSpecDie 30 | 31 | var ClusterWorkloadResourceMappingTemplateBlank = dieservicebindingv1.ClusterWorkloadResourceMappingTemplateBlank 32 | 33 | type ClusterWorkloadResourceMappingTemplateDie = dieservicebindingv1.ClusterWorkloadResourceMappingTemplateDie 34 | 35 | var ClusterWorkloadResourceMappingContainerBlank = dieservicebindingv1.ClusterWorkloadResourceMappingContainerBlank 36 | 37 | type ClusterWorkloadResourceMappingContainerDie = dieservicebindingv1.ClusterWorkloadResourceMappingContainerDie 38 | -------------------------------------------------------------------------------- /PROJECT: -------------------------------------------------------------------------------- 1 | domain: servicebinding.io 2 | layout: 3 | - go.kubebuilder.io/v3 4 | multigroup: true 5 | projectName: servicebinding-runtime 6 | repo: github.com/servicebinding/runtime 7 | resources: 8 | - api: 9 | crdVersion: v1 10 | namespaced: true 11 | controller: true 12 | domain: servicebinding.io 13 | kind: ServiceBinding 14 | path: github.com/servicebinding/runtime/apis/v1alpha3 15 | version: v1alpha3 16 | - api: 17 | crdVersion: v1 18 | namespaced: true 19 | controller: true 20 | domain: servicebinding.io 21 | kind: ServiceBinding 22 | path: github.com/servicebinding/runtime/apis/v1beta1 23 | version: v1beta1 24 | webhooks: 25 | validation: true 26 | webhookVersion: v1 27 | - api: 28 | crdVersion: v1 29 | namespaced: true 30 | controller: true 31 | domain: servicebinding.io 32 | kind: ServiceBinding 33 | path: github.com/servicebinding/runtime/apis/v1 34 | version: v1 35 | webhooks: 36 | validation: true 37 | webhookVersion: v1 38 | - api: 39 | crdVersion: v1 40 | domain: servicebinding.io 41 | kind: ClusterWorkloadResourceMapping 42 | path: github.com/servicebinding/runtime/apis/v1alpha3 43 | version: v1alpha3 44 | - api: 45 | crdVersion: v1 46 | domain: servicebinding.io 47 | kind: ClusterWorkloadResourceMapping 48 | path: github.com/servicebinding/runtime/apis/v1beta1 49 | version: v1beta1 50 | webhooks: 51 | validation: true 52 | webhookVersion: v1 53 | - api: 54 | crdVersion: v1 55 | domain: servicebinding.io 56 | kind: ClusterWorkloadResourceMapping 57 | path: github.com/servicebinding/runtime/apis/v1 58 | version: v1 59 | webhooks: 60 | validation: true 61 | webhookVersion: v1 62 | version: "3" 63 | -------------------------------------------------------------------------------- /samples/multi-binding/service-binding.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: servicebinding.io/v1 17 | kind: ServiceBinding 18 | metadata: 19 | name: multi-binding-1 20 | labels: 21 | multi-binding: "true" 22 | spec: 23 | # direct Secret reference is used for compatibility, but not recommended for dynamically provisioned services 24 | service: 25 | apiVersion: v1 26 | kind: Secret 27 | name: multi-binding-1 28 | workload: 29 | apiVersion: batch/v1 30 | kind: Job 31 | name: multi-binding 32 | env: 33 | - name: MULTI_BINDING_1 34 | key: number 35 | 36 | --- 37 | apiVersion: servicebinding.io/v1 38 | kind: ServiceBinding 39 | metadata: 40 | name: multi-binding-2 41 | labels: 42 | multi-binding: "true" 43 | spec: 44 | # direct Secret reference is used for compatibility, but not recommended for dynamically provisioned services 45 | service: 46 | apiVersion: v1 47 | kind: Secret 48 | name: multi-binding-2 49 | workload: 50 | apiVersion: batch/v1 51 | kind: Job 52 | name: multi-binding 53 | env: 54 | - name: MULTI_BINDING_2 55 | key: number 56 | -------------------------------------------------------------------------------- /apis/duck/zz_generated.deepcopy.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | 3 | /* 4 | Copyright 2022 the original author or authors. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | // Code generated by controller-gen. DO NOT EDIT. 20 | 21 | package duck 22 | 23 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 24 | func (in *PodSpecable) DeepCopyInto(out *PodSpecable) { 25 | *out = *in 26 | out.TypeMeta = in.TypeMeta 27 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 28 | in.Spec.DeepCopyInto(&out.Spec) 29 | } 30 | 31 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSpecable. 32 | func (in *PodSpecable) DeepCopy() *PodSpecable { 33 | if in == nil { 34 | return nil 35 | } 36 | out := new(PodSpecable) 37 | in.DeepCopyInto(out) 38 | return out 39 | } 40 | 41 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 42 | func (in *PodSpecableSpec) DeepCopyInto(out *PodSpecableSpec) { 43 | *out = *in 44 | in.Template.DeepCopyInto(&out.Template) 45 | } 46 | 47 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSpecableSpec. 48 | func (in *PodSpecableSpec) DeepCopy() *PodSpecableSpec { 49 | if in == nil { 50 | return nil 51 | } 52 | out := new(PodSpecableSpec) 53 | in.DeepCopyInto(out) 54 | return out 55 | } 56 | -------------------------------------------------------------------------------- /samples/external-secrets/kapp-config.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | kind: ConfigMap 17 | metadata: 18 | name: kapp-config 19 | labels: 20 | kapp.k14s.io/config: "" 21 | data: 22 | config.yml: | 23 | apiVersion: kapp.k14s.io/v1alpha1 24 | kind: Config 25 | waitRules: 26 | - supportsObservedGeneration: true 27 | conditionMatchers: 28 | - type: ServiceAvailable 29 | status: "True" 30 | unblockChanges: true 31 | - type: Ready 32 | status: "False" 33 | failure: true 34 | - type: Ready 35 | status: "True" 36 | success: true 37 | resourceMatchers: 38 | - apiVersionKindMatcher: {apiVersion: servicebinding.io/v1, kind: ServiceBinding} 39 | - supportsObservedGeneration: false 40 | conditionMatchers: 41 | - type: Ready 42 | status: "False" 43 | failure: true 44 | - type: Ready 45 | status: "True" 46 | success: true 47 | resourceMatchers: 48 | - apiVersionKindMatcher: {apiVersion: external-secrets.io/v1beta1, kind: ExternalSecret} 49 | - supportsObservedGeneration: false 50 | conditionMatchers: 51 | - type: Ready 52 | status: "False" 53 | failure: true 54 | - type: Ready 55 | status: "True" 56 | success: true 57 | resourceMatchers: 58 | - apiVersionKindMatcher: {apiVersion: external-secrets.io/v1beta1, kind: SecretStore} 59 | -------------------------------------------------------------------------------- /projector/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package projector 18 | 19 | import ( 20 | "context" 21 | 22 | "k8s.io/apimachinery/pkg/api/meta" 23 | "k8s.io/apimachinery/pkg/runtime" 24 | "k8s.io/apimachinery/pkg/runtime/schema" 25 | 26 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 27 | ) 28 | 29 | type ServiceBindingProjector interface { 30 | // Project the service into the workload as defined by the ServiceBinding. 31 | Project(ctx context.Context, binding *servicebindingv1.ServiceBinding, workload runtime.Object) error 32 | // Unproject the service from the workload as defined by the ServiceBinding. 33 | Unproject(ctx context.Context, binding *servicebindingv1.ServiceBinding, workload runtime.Object) error 34 | // IsProjected returns true when the workload has been projected into by the binding 35 | IsProjected(ctx context.Context, binding *servicebindingv1.ServiceBinding, workload runtime.Object) bool 36 | } 37 | 38 | type MappingSource interface { 39 | // LookupRESTMapping returns the RESTMapping for the workload type. The rest mapping contains a GroupVersionResource which can 40 | // be used to fetch the workload mapping. 41 | LookupRESTMapping(ctx context.Context, obj runtime.Object) (*meta.RESTMapping, error) 42 | 43 | // LookupWorkloadMapping the mapping template for the workload. Typically a ClusterWorkloadResourceMapping is defined for the 44 | // workload's fully qualified resource `{resource}.{group}`. 45 | LookupWorkloadMapping(ctx context.Context, gvr schema.GroupVersionResource) (*servicebindingv1.ClusterWorkloadResourceMappingSpec, error) 46 | } 47 | -------------------------------------------------------------------------------- /dies/v1/servicebinding.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1 18 | 19 | import ( 20 | diemetav1 "reconciler.io/dies/apis/meta/v1" 21 | 22 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 23 | ) 24 | 25 | // +die:object=true 26 | type _ = servicebindingv1.ServiceBinding 27 | 28 | // +die 29 | // +die:field:name=Workload,die=ServiceBindingWorkloadReferenceDie 30 | // +die:field:name=Service,die=ServiceBindingServiceReferenceDie 31 | // +die:field:name=Env,die=EnvMappingDie,listType=map 32 | type _ = servicebindingv1.ServiceBindingSpec 33 | 34 | // +die 35 | // +die:field:name=Selector,package=_/meta/v1,die=LabelSelectorDie,pointer=true 36 | type _ = servicebindingv1.ServiceBindingWorkloadReference 37 | 38 | // +die 39 | type _ = servicebindingv1.ServiceBindingServiceReference 40 | 41 | // +die 42 | type _ = servicebindingv1.EnvMapping 43 | 44 | // +die 45 | // +die:field:name=Conditions,package=_/meta/v1,die=ConditionDie,listType=atomic 46 | // +die:field:name=Binding,die=ServiceBindingSecretReferenceDie,pointer=true 47 | type _ = servicebindingv1.ServiceBindingStatus 48 | 49 | var ServiceBindingConditionReady = diemetav1.ConditionBlank.Type(servicebindingv1.ServiceBindingConditionReady).Unknown().Reason("Initializing") 50 | var ServiceBindingConditionServiceAvailable = diemetav1.ConditionBlank.Type(servicebindingv1.ServiceBindingConditionServiceAvailable).Unknown().Reason("Initializing") 51 | var ServiceBindingConditionWorkloadProjected = diemetav1.ConditionBlank.Type(servicebindingv1.ServiceBindingConditionWorkloadProjected).Unknown().Reason("Initializing") 52 | 53 | // +die 54 | type _ = servicebindingv1.ServiceBindingSecretReference 55 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://git.k8s.io/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt: 4 | 5 | _As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._ 6 | 7 | ## Getting Started 8 | 9 | We have full documentation on how to get started contributing here: 10 | 11 | 14 | 15 | - [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests 16 | - [Kubernetes Contributor Guide](https://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](https://git.k8s.io/community/contributors/guide#contributing) 17 | - [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet) - Common resources for existing developers 18 | 19 | ## Mentorship 20 | 21 | - [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers! 22 | 23 | ## Working Group 24 | 25 | The Service Binding Specification for Kubernetes project is a community lead effort. 26 | A bi-weekly [working group call][working-group] is open to the public. 27 | Discussions occur here on GitHub and on the [#bindings-discuss channel in the Kubernetes Slack][slack]. 28 | 29 | [working-group]: https://docs.google.com/document/d/1rR0qLpsjU38nRXxeich7F5QUy73RHJ90hnZiFIQ-JJ8/edit#heading=h.ar8ibc31ux6f 30 | [slack]: https://kubernetes.slack.com/archives/C012F2GPMTQ 31 | 32 | ## Issues 33 | 34 | If you catch an error in the implementation, please let us know by opening an issue or pull request at our 35 | [GitHub repository][repo]. 36 | 37 | [repo]: https://github.com/servicebinding/runtime 38 | -------------------------------------------------------------------------------- /dies/v1beta1/servicebinding.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1beta1 18 | 19 | import ( 20 | dieservicebindingv1 "github.com/servicebinding/runtime/dies/v1" 21 | ) 22 | 23 | var ServiceBindingBlank = dieservicebindingv1.ServiceBindingBlank 24 | 25 | type ServiceBindingDie = dieservicebindingv1.ServiceBindingDie 26 | 27 | var ServiceBindingSpecBlank = dieservicebindingv1.ServiceBindingSpecBlank 28 | 29 | type ServiceBindingSpecDie = dieservicebindingv1.ServiceBindingSpecDie 30 | 31 | var ServiceBindingWorkloadReferenceBlank = dieservicebindingv1.ServiceBindingWorkloadReferenceBlank 32 | 33 | type ServiceBindingWorkloadReferenceDie = dieservicebindingv1.ServiceBindingWorkloadReferenceDie 34 | 35 | var ServiceBindingServiceReferenceBlank = dieservicebindingv1.ServiceBindingServiceReferenceBlank 36 | 37 | type ServiceBindingServiceReferenceDie = dieservicebindingv1.ServiceBindingServiceReferenceDie 38 | 39 | var EnvMappingBlank = dieservicebindingv1.EnvMappingBlank 40 | 41 | type EnvMappingDie = dieservicebindingv1.EnvMappingDie 42 | 43 | var ServiceBindingStatusBlank = dieservicebindingv1.ServiceBindingStatusBlank 44 | 45 | type ServiceBindingStatusDie = dieservicebindingv1.ServiceBindingStatusDie 46 | 47 | var ServiceBindingConditionReady = dieservicebindingv1.ServiceBindingConditionReady 48 | var ServiceBindingConditionServiceAvailable = dieservicebindingv1.ServiceBindingConditionServiceAvailable 49 | var ServiceBindingConditionWorkloadProjected = dieservicebindingv1.ServiceBindingConditionWorkloadProjected 50 | 51 | var ServiceBindingSecretReferenceBlank = dieservicebindingv1.ServiceBindingSecretReferenceBlank 52 | 53 | type ServiceBindingSecretReferenceDie = dieservicebindingv1.ServiceBindingSecretReferenceDie 54 | -------------------------------------------------------------------------------- /hack/kustomize/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/runtime/hack/kustomize 2 | 3 | go 1.21 4 | 5 | require sigs.k8s.io/kustomize/kustomize/v4 v4.5.7 6 | 7 | require ( 8 | github.com/PuerkitoBio/purell v1.1.1 // indirect 9 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect 10 | github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect 11 | github.com/davecgh/go-spew v1.1.1 // indirect 12 | github.com/evanphx/json-patch v4.11.0+incompatible // indirect 13 | github.com/go-errors/errors v1.0.1 // indirect 14 | github.com/go-openapi/jsonpointer v0.19.5 // indirect 15 | github.com/go-openapi/jsonreference v0.19.5 // indirect 16 | github.com/go-openapi/swag v0.19.14 // indirect 17 | github.com/golang/protobuf v1.5.2 // indirect 18 | github.com/google/gnostic v0.5.7-v3refs // indirect 19 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect 20 | github.com/imdario/mergo v0.3.6 // indirect 21 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 22 | github.com/josharian/intern v1.0.0 // indirect 23 | github.com/mailru/easyjson v0.7.6 // indirect 24 | github.com/mattn/go-runewidth v0.0.7 // indirect 25 | github.com/mitchellh/mapstructure v1.4.1 // indirect 26 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect 27 | github.com/olekukonko/tablewriter v0.0.4 // indirect 28 | github.com/pkg/errors v0.9.1 // indirect 29 | github.com/spf13/cobra v1.4.0 // indirect 30 | github.com/spf13/pflag v1.0.5 // indirect 31 | github.com/xlab/treeprint v1.1.0 // indirect 32 | go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect 33 | golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect 34 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect 35 | golang.org/x/text v0.3.7 // indirect 36 | google.golang.org/protobuf v1.28.0 // indirect 37 | gopkg.in/inf.v0 v0.9.1 // indirect 38 | gopkg.in/yaml.v2 v2.4.0 // indirect 39 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect 40 | k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661 // indirect 41 | k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect 42 | sigs.k8s.io/kustomize/api v0.12.1 // indirect 43 | sigs.k8s.io/kustomize/cmd/config v0.10.9 // indirect 44 | sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect 45 | sigs.k8s.io/yaml v1.2.0 // indirect 46 | ) 47 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | reviewers: 9 | - servicebinding/reference-implementation 10 | - package-ecosystem: gomod 11 | directory: "/" 12 | groups: 13 | kubernetes: 14 | patterns: 15 | - "k8s.io/*" 16 | schedule: 17 | interval: daily 18 | open-pull-requests-limit: 10 19 | reviewers: 20 | - servicebinding/reference-implementation 21 | - package-ecosystem: gomod 22 | directory: "/hack/controller-gen" 23 | schedule: 24 | interval: daily 25 | open-pull-requests-limit: 10 26 | reviewers: 27 | - servicebinding/reference-implementation 28 | - package-ecosystem: gomod 29 | directory: "/hack/diegen" 30 | schedule: 31 | interval: daily 32 | open-pull-requests-limit: 10 33 | reviewers: 34 | - servicebinding/reference-implementation 35 | - package-ecosystem: gomod 36 | directory: "/hack/goimports" 37 | schedule: 38 | interval: daily 39 | open-pull-requests-limit: 10 40 | reviewers: 41 | - servicebinding/reference-implementation 42 | - package-ecosystem: gomod 43 | directory: "/hack/imgpkg" 44 | schedule: 45 | interval: daily 46 | open-pull-requests-limit: 10 47 | reviewers: 48 | - servicebinding/reference-implementation 49 | - package-ecosystem: gomod 50 | directory: "/hack/kapp" 51 | schedule: 52 | interval: daily 53 | open-pull-requests-limit: 10 54 | reviewers: 55 | - servicebinding/reference-implementation 56 | - package-ecosystem: gomod 57 | directory: "/hack/kbld" 58 | schedule: 59 | interval: daily 60 | open-pull-requests-limit: 10 61 | reviewers: 62 | - servicebinding/reference-implementation 63 | - package-ecosystem: gomod 64 | directory: "/hack/ko" 65 | schedule: 66 | interval: daily 67 | open-pull-requests-limit: 10 68 | reviewers: 69 | - servicebinding/reference-implementation 70 | - package-ecosystem: gomod 71 | directory: "/hack/kube-rbac-proxy" 72 | schedule: 73 | interval: daily 74 | open-pull-requests-limit: 10 75 | reviewers: 76 | - servicebinding/reference-implementation 77 | - package-ecosystem: gomod 78 | directory: "/hack/kustomize" 79 | schedule: 80 | interval: daily 81 | open-pull-requests-limit: 10 82 | reviewers: 83 | - servicebinding/reference-implementation 84 | -------------------------------------------------------------------------------- /hack/controller-gen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/runtime/hack/controller-gen 2 | 3 | go 1.24.0 4 | 5 | require sigs.k8s.io/controller-tools v0.19.0 6 | 7 | require ( 8 | github.com/fatih/color v1.18.0 // indirect 9 | github.com/fxamacker/cbor/v2 v2.9.0 // indirect 10 | github.com/go-logr/logr v1.4.3 // indirect 11 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 12 | github.com/go-openapi/jsonreference v0.20.2 // indirect 13 | github.com/go-openapi/swag v0.23.0 // indirect 14 | github.com/gobuffalo/flect v1.0.3 // indirect 15 | github.com/gogo/protobuf v1.3.2 // indirect 16 | github.com/google/gnostic-models v0.7.0 // indirect 17 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 18 | github.com/josharian/intern v1.0.0 // indirect 19 | github.com/json-iterator/go v1.1.12 // indirect 20 | github.com/mailru/easyjson v0.7.7 // indirect 21 | github.com/mattn/go-colorable v0.1.13 // indirect 22 | github.com/mattn/go-isatty v0.0.20 // indirect 23 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 24 | github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect 25 | github.com/spf13/cobra v1.9.1 // indirect 26 | github.com/spf13/pflag v1.0.7 // indirect 27 | github.com/x448/float16 v0.8.4 // indirect 28 | go.yaml.in/yaml/v2 v2.4.2 // indirect 29 | go.yaml.in/yaml/v3 v3.0.4 // indirect 30 | golang.org/x/mod v0.27.0 // indirect 31 | golang.org/x/net v0.43.0 // indirect 32 | golang.org/x/sync v0.16.0 // indirect 33 | golang.org/x/sys v0.35.0 // indirect 34 | golang.org/x/text v0.28.0 // indirect 35 | golang.org/x/tools v0.36.0 // indirect 36 | google.golang.org/protobuf v1.36.7 // indirect 37 | gopkg.in/inf.v0 v0.9.1 // indirect 38 | gopkg.in/yaml.v2 v2.4.0 // indirect 39 | gopkg.in/yaml.v3 v3.0.1 // indirect 40 | k8s.io/api v0.34.0 // indirect 41 | k8s.io/apiextensions-apiserver v0.34.0 // indirect 42 | k8s.io/apimachinery v0.34.0 // indirect 43 | k8s.io/code-generator v0.34.0 // indirect 44 | k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect 45 | k8s.io/klog/v2 v2.130.1 // indirect 46 | k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect 47 | k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect 48 | sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect 49 | sigs.k8s.io/randfill v1.0.0 // indirect 50 | sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect 51 | sigs.k8s.io/yaml v1.6.0 // indirect 52 | ) 53 | -------------------------------------------------------------------------------- /resolver/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resolver 18 | 19 | import ( 20 | "context" 21 | 22 | "k8s.io/apimachinery/pkg/api/meta" 23 | "k8s.io/apimachinery/pkg/runtime" 24 | "k8s.io/apimachinery/pkg/runtime/schema" 25 | 26 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 27 | ) 28 | 29 | type Resolver interface { 30 | // LookupRESTMapping returns the RESTMapping for the workload type. The rest mapping contains a GroupVersionResource which can 31 | // be used to fetch the workload mapping. 32 | LookupRESTMapping(ctx context.Context, obj runtime.Object) (*meta.RESTMapping, error) 33 | 34 | // LookupWorkloadMapping the mapping template for the workload. Typically a ClusterWorkloadResourceMapping is defined for the 35 | // workload's fully qualified resource `{resource}.{group}`. 36 | LookupWorkloadMapping(ctx context.Context, gvr schema.GroupVersionResource) (*servicebindingv1.ClusterWorkloadResourceMappingSpec, error) 37 | 38 | // LookupBindingSecret returns the binding secret name exposed by the service following the Provisioned Service duck-type 39 | // (`.status.binding.name`). If a direction binding is used (where the referenced service is itself a Secret) the referenced Secret is 40 | // returned without a lookup. 41 | LookupBindingSecret(ctx context.Context, serviceBinding *servicebindingv1.ServiceBinding) (string, error) 42 | 43 | // LookupWorkloads returns the referenced objects. Often a unstructured Object is used to sidestep issues with schemes and registered 44 | // types. The selector is mutually exclusive with the reference name. The UID of the ServiceBinding is used to find resources that 45 | // may have been previously bound but no longer match the query. 46 | LookupWorkloads(ctx context.Context, serviceBinding *servicebindingv1.ServiceBinding) ([]runtime.Object, error) 47 | } 48 | -------------------------------------------------------------------------------- /config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: servicebinding-system 3 | 4 | # Value of this field is prepended to the 5 | # names of all resources, e.g. a deployment named 6 | # "wordpress" becomes "alices-wordpress". 7 | # Note that it should also match with the prefix (text before '-') of the namespace 8 | # field above. 9 | namePrefix: servicebinding- 10 | 11 | # Labels to add to all resources and selectors. 12 | #commonLabels: 13 | # someName: someValue 14 | 15 | bases: 16 | - ../crd 17 | - ../rbac 18 | - ../manager 19 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 20 | # crd/kustomization.yaml 21 | - ../webhook 22 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. 23 | - ../certmanager 24 | # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. 25 | #- ../prometheus 26 | 27 | patchesStrategicMerge: 28 | # Protect the /metrics endpoint by putting it behind auth. 29 | # If you want your controller-manager to expose the /metrics 30 | # endpoint w/o any authn/z, please comment the following line. 31 | - manager_auth_proxy_patch.yaml 32 | 33 | # Mount the controller config file for loading manager configurations 34 | # through a ComponentConfig type 35 | #- manager_config_patch.yaml 36 | 37 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 38 | # crd/kustomization.yaml 39 | - manager_webhook_patch.yaml 40 | 41 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 42 | # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. 43 | # 'CERTMANAGER' needs to be enabled to use ca injection 44 | - webhookcainjection_patch.yaml 45 | 46 | # the following config is for teaching kustomize how to do var substitution 47 | vars: 48 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. 49 | - name: CERTIFICATE_NAME 50 | objref: 51 | kind: Certificate 52 | group: cert-manager.io 53 | version: v1 54 | name: serving-cert # this name should match the one in certificate.yaml 55 | - name: SERVICE_NAME 56 | objref: 57 | kind: Service 58 | version: v1 59 | name: webhook-service 60 | - name: NAMESPACE 61 | objref: 62 | kind: Namespace 63 | version: v1 64 | name: system 65 | fieldref: 66 | fieldpath: metadata.name 67 | -------------------------------------------------------------------------------- /samples/external-secrets/workload.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: v1 17 | kind: Service 18 | metadata: 19 | name: eso-example 20 | annotations: 21 | kapp.k14s.io/change-group: workload 22 | spec: 23 | ports: 24 | - port: 80 25 | targetPort: 8080 26 | selector: 27 | app: eso-example 28 | 29 | --- 30 | apiVersion: apps/v1 31 | kind: Deployment 32 | metadata: 33 | name: eso-example 34 | annotations: 35 | kapp.k14s.io/change-group: workload 36 | labels: 37 | app: eso-example 38 | spec: 39 | replicas: 1 40 | selector: 41 | matchLabels: 42 | app: eso-example 43 | template: 44 | metadata: 45 | annotations: 46 | kapp.k14s.io/deploy-logs: "for-new" 47 | kapp.k14s.io/deploy-logs-container-names: "workload" 48 | labels: 49 | app: eso-example 50 | spec: 51 | containers: 52 | - name: workload 53 | # built with CNB Paketo builder from https://github.com/spring-projects/spring-petclinic 54 | image: ghcr.io/servicebinding/runtime/samples/spring-petclinic@sha256:83ab44832a1db6c03d34e758199b0d9cbf29ce5beeaac4fbf96443a63342b3d4 55 | env: 56 | # tell the workload to use mysql instead of the default embedded database 57 | - name: SPRING_PROFILES_ACTIVE 58 | value: mysql 59 | ports: 60 | - name: http 61 | containerPort: 8080 62 | livenessProbe: 63 | httpGet: 64 | path: /actuator/health/liveness 65 | port: http 66 | readinessProbe: 67 | httpGet: 68 | path: /actuator/health/readiness 69 | port: http 70 | startupProbe: 71 | httpGet: 72 | path: /actuator/health/liveness 73 | port: http 74 | failureThreshold: 20 75 | periodSeconds: 5 76 | -------------------------------------------------------------------------------- /samples/spring-petclinic/workload.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: v1 17 | kind: Service 18 | metadata: 19 | name: spring-petclinic 20 | annotations: 21 | kapp.k14s.io/change-group: workload 22 | spec: 23 | ports: 24 | - port: 80 25 | targetPort: 8080 26 | selector: 27 | app: spring-petclinic 28 | 29 | --- 30 | apiVersion: apps/v1 31 | kind: Deployment 32 | metadata: 33 | name: spring-petclinic 34 | annotations: 35 | kapp.k14s.io/change-group: workload 36 | labels: 37 | app: spring-petclinic 38 | spec: 39 | replicas: 1 40 | selector: 41 | matchLabels: 42 | app: spring-petclinic 43 | template: 44 | metadata: 45 | annotations: 46 | kapp.k14s.io/deploy-logs: "for-new" 47 | kapp.k14s.io/deploy-logs-container-names: "workload" 48 | labels: 49 | app: spring-petclinic 50 | spec: 51 | containers: 52 | - name: workload 53 | # built with CNB Paketo builder from https://github.com/spring-projects/spring-petclinic 54 | image: ghcr.io/servicebinding/runtime/samples/spring-petclinic@sha256:83ab44832a1db6c03d34e758199b0d9cbf29ce5beeaac4fbf96443a63342b3d4 55 | env: 56 | # tell the workload to use mysql instead of the default embedded database 57 | - name: SPRING_PROFILES_ACTIVE 58 | value: mysql 59 | ports: 60 | - name: http 61 | containerPort: 8080 62 | livenessProbe: 63 | httpGet: 64 | path: /actuator/health/liveness 65 | port: http 66 | readinessProbe: 67 | httpGet: 68 | path: /actuator/health/readiness 69 | port: http 70 | startupProbe: 71 | httpGet: 72 | path: /actuator/health/liveness 73 | port: http 74 | failureThreshold: 20 75 | periodSeconds: 5 76 | -------------------------------------------------------------------------------- /samples/external-secrets/service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: servicebinding.io/v1 17 | kind: ServiceBinding 18 | metadata: 19 | name: eso-example-db 20 | annotations: 21 | kapp.k14s.io/change-group: service 22 | kapp.k14s.io/change-rule.service: "upsert after upserting secret" 23 | kapp.k14s.io/change-rule.service-delete: "delete before deleting secret" 24 | spec: 25 | service: 26 | apiVersion: external-secrets.io/v1beta1 27 | kind: ExternalSecret 28 | name: eso-example-db 29 | workload: 30 | apiVersion: apps/v1 31 | kind: Deployment 32 | name: eso-example-db 33 | env: 34 | - name: MYSQL_USER 35 | key: username 36 | - name: MYSQL_PASSWORD 37 | key: password 38 | - name: MYSQL_DATABASE 39 | key: database 40 | 41 | --- 42 | apiVersion: v1 43 | kind: Service 44 | metadata: 45 | name: eso-example-db 46 | annotations: 47 | kapp.k14s.io/change-group: service 48 | spec: 49 | ports: 50 | - port: 3306 51 | selector: 52 | app: eso-example-db 53 | 54 | --- 55 | apiVersion: apps/v1 56 | kind: Deployment 57 | metadata: 58 | name: eso-example-db 59 | annotations: 60 | kapp.k14s.io/change-group: service 61 | labels: 62 | app: eso-example-db 63 | spec: 64 | selector: 65 | matchLabels: 66 | app: eso-example-db 67 | template: 68 | metadata: 69 | labels: 70 | app: eso-example-db 71 | spec: 72 | # no persistance configured, the database will be reset when the pod terminates 73 | containers: 74 | - image: mariadb:10.5 75 | name: mysql 76 | env: 77 | - name: MYSQL_ROOT_PASSWORD 78 | value: root 79 | ports: 80 | - containerPort: 3306 81 | name: mysql 82 | livenessProbe: 83 | tcpSocket: 84 | port: mysql 85 | readinessProbe: 86 | tcpSocket: 87 | port: mysql 88 | startupProbe: 89 | tcpSocket: 90 | port: mysql 91 | -------------------------------------------------------------------------------- /hack/kbld/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/runtime/hack/kbld 2 | 3 | go 1.21 4 | 5 | require github.com/vmware-tanzu/carvel-kbld v0.39.0 6 | 7 | require ( 8 | carvel.dev/imgpkg v0.40.0 // indirect 9 | carvel.dev/vendir v0.39.0 // indirect 10 | github.com/carvel-dev/semver/v4 v4.0.1-0.20230221220520-8090ce423695 // indirect 11 | github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect 12 | github.com/cppforlife/cobrautil v0.0.0-20221021151949-d60711905d65 // indirect 13 | github.com/cppforlife/color v1.9.1-0.20200716202919-6706ac40b835 // indirect 14 | github.com/cppforlife/go-cli-ui v0.0.0-20220428182907-73db60c7611a // indirect 15 | github.com/docker/cli v24.0.0+incompatible // indirect 16 | github.com/docker/distribution v2.8.2+incompatible // indirect 17 | github.com/docker/docker v24.0.7+incompatible // indirect 18 | github.com/docker/docker-credential-helpers v0.7.0 // indirect 19 | github.com/go-logr/logr v1.2.4 // indirect 20 | github.com/gogo/protobuf v1.3.2 // indirect 21 | github.com/google/go-containerregistry v0.16.1 // indirect 22 | github.com/google/gofuzz v1.2.0 // indirect 23 | github.com/hashicorp/go-version v1.6.0 // indirect 24 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 25 | github.com/json-iterator/go v1.1.12 // indirect 26 | github.com/klauspost/compress v1.16.5 // indirect 27 | github.com/mattn/go-colorable v0.1.13 // indirect 28 | github.com/mattn/go-isatty v0.0.20 // indirect 29 | github.com/mitchellh/go-homedir v1.1.0 // indirect 30 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 31 | github.com/modern-go/reflect2 v1.0.2 // indirect 32 | github.com/opencontainers/go-digest v1.0.0 // indirect 33 | github.com/opencontainers/image-spec v1.1.0-rc3 // indirect 34 | github.com/pkg/errors v0.9.1 // indirect 35 | github.com/sirupsen/logrus v1.9.1 // indirect 36 | github.com/spf13/cobra v1.7.0 // indirect 37 | github.com/spf13/pflag v1.0.5 // indirect 38 | github.com/vbatts/tar-split v0.11.3 // indirect 39 | github.com/vito/go-interact v1.0.1 // indirect 40 | golang.org/x/net v0.17.0 // indirect 41 | golang.org/x/sync v0.3.0 // indirect 42 | golang.org/x/sys v0.15.0 // indirect 43 | golang.org/x/term v0.15.0 // indirect 44 | golang.org/x/text v0.14.0 // indirect 45 | gopkg.in/inf.v0 v0.9.1 // indirect 46 | gopkg.in/yaml.v2 v2.4.0 // indirect 47 | k8s.io/apimachinery v0.28.1 // indirect 48 | k8s.io/klog/v2 v2.100.1 // indirect 49 | k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect 50 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect 51 | sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect 52 | sigs.k8s.io/yaml v1.4.0 // indirect 53 | ) 54 | -------------------------------------------------------------------------------- /samples/spring-petclinic/service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 the original author or authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: v1 17 | kind: Secret 18 | metadata: 19 | name: spring-petclinic-db 20 | annotations: 21 | kapp.k14s.io/change-group: service 22 | type: servicebinding.io/mysql 23 | stringData: 24 | type: mysql 25 | provider: mariadb 26 | host: spring-petclinic-db 27 | port: "3306" 28 | database: default 29 | # demo credentials 30 | username: user 31 | password: pass 32 | 33 | --- 34 | apiVersion: v1 35 | kind: Service 36 | metadata: 37 | name: spring-petclinic-db 38 | annotations: 39 | kapp.k14s.io/change-group: service 40 | spec: 41 | ports: 42 | - port: 3306 43 | selector: 44 | app: spring-petclinic-db 45 | 46 | --- 47 | apiVersion: apps/v1 48 | kind: Deployment 49 | metadata: 50 | name: spring-petclinic-db 51 | annotations: 52 | kapp.k14s.io/change-group: service 53 | labels: 54 | app: spring-petclinic-db 55 | spec: 56 | selector: 57 | matchLabels: 58 | app: spring-petclinic-db 59 | template: 60 | metadata: 61 | labels: 62 | app: spring-petclinic-db 63 | spec: 64 | # no persistance configured, the database will be reset when the pod terminates 65 | containers: 66 | - image: mariadb:10.5 67 | name: mysql 68 | env: 69 | - name: MYSQL_USER 70 | valueFrom: 71 | secretKeyRef: 72 | name: spring-petclinic-db 73 | key: username 74 | - name: MYSQL_PASSWORD 75 | valueFrom: 76 | secretKeyRef: 77 | name: spring-petclinic-db 78 | key: password 79 | - name: MYSQL_DATABASE 80 | valueFrom: 81 | secretKeyRef: 82 | name: spring-petclinic-db 83 | key: database 84 | - name: MYSQL_ROOT_PASSWORD 85 | value: root 86 | ports: 87 | - containerPort: 3306 88 | name: mysql 89 | livenessProbe: 90 | tcpSocket: 91 | port: mysql 92 | readinessProbe: 93 | tcpSocket: 94 | port: mysql 95 | startupProbe: 96 | tcpSocket: 97 | port: mysql 98 | -------------------------------------------------------------------------------- /lifecycle/hooks.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package lifecycle 18 | 19 | import ( 20 | "context" 21 | 22 | "k8s.io/apimachinery/pkg/runtime" 23 | "sigs.k8s.io/controller-runtime/pkg/client" 24 | 25 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 26 | "github.com/servicebinding/runtime/projector" 27 | "github.com/servicebinding/runtime/resolver" 28 | ) 29 | 30 | type ServiceBindingHooks struct { 31 | // ResolverFactory returns a resolver which is used to lookup binding 32 | // related values. 33 | // 34 | // +optional 35 | ResolverFactory func(client.Client) resolver.Resolver 36 | 37 | // ProjectorFactory returns a projector which is used to bind/unbind the 38 | // service to/from the workload. 39 | // 40 | // +optional 41 | ProjectorFactory func(projector.MappingSource) projector.ServiceBindingProjector 42 | 43 | // ServiceBindingPreProjection can be used to alter the resolved 44 | // ServiceBinding before the projection. 45 | // 46 | // +optional 47 | ServiceBindingPreProjection func(ctx context.Context, binding *servicebindingv1.ServiceBinding) error 48 | 49 | // ServiceBindingPostProjection can be used to alter the projected 50 | // ServiceBinding before mutations are persisted. 51 | // 52 | // +optional 53 | ServiceBindingPostProjection func(ctx context.Context, binding *servicebindingv1.ServiceBinding) error 54 | 55 | // WorkloadPreProjection can be used to alter the resolved workload before 56 | // the projection. 57 | // 58 | // +optional 59 | WorkloadPreProjection func(ctx context.Context, workload runtime.Object) error 60 | 61 | // WorkloadPostProjection can be used to alter the projected workload 62 | // before mutations are persisted. 63 | // 64 | // +optional 65 | WorkloadPostProjection func(ctx context.Context, workload runtime.Object) error 66 | } 67 | 68 | func (h *ServiceBindingHooks) GetResolver(c client.Client) resolver.Resolver { 69 | if h.ResolverFactory == nil { 70 | return resolver.New(c) 71 | } 72 | return h.ResolverFactory(c) 73 | } 74 | 75 | func (h *ServiceBindingHooks) GetProjector(r projector.MappingSource) projector.ServiceBindingProjector { 76 | if h.ProjectorFactory == nil { 77 | return projector.New(r) 78 | } 79 | return h.ProjectorFactory(r) 80 | } 81 | -------------------------------------------------------------------------------- /apis/v1beta1/clusterworkloadresourcemapping_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1beta1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | 22 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 23 | ) 24 | 25 | // ClusterWorkloadResourceMappingTemplate defines the mapping for a specific version of an workload resource to a 26 | // logical PodTemplateSpec-like structure. 27 | type ClusterWorkloadResourceMappingTemplate = servicebindingv1.ClusterWorkloadResourceMappingTemplate 28 | 29 | // ClusterWorkloadResourceMappingContainer defines the mapping for a specific fragment of an workload resource 30 | // to a Container-like structure. 31 | // 32 | // Each mapping defines exactly one path that may match multiple container-like fragments within the workload 33 | // resource. For each object matching the path the name, env and volumeMounts expressions are resolved to find those 34 | // structures. 35 | type ClusterWorkloadResourceMappingContainer = servicebindingv1.ClusterWorkloadResourceMappingContainer 36 | 37 | // ClusterWorkloadResourceMappingSpec defines the desired state of ClusterWorkloadResourceMapping 38 | type ClusterWorkloadResourceMappingSpec = servicebindingv1.ClusterWorkloadResourceMappingSpec 39 | 40 | // +kubebuilder:object:root=true 41 | // +kubebuilder:resource:scope=Cluster 42 | // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 43 | 44 | // ClusterWorkloadResourceMapping is the Schema for the clusterworkloadresourcemappings API 45 | type ClusterWorkloadResourceMapping struct { 46 | metav1.TypeMeta `json:",inline"` 47 | metav1.ObjectMeta `json:"metadata,omitempty"` 48 | 49 | Spec ClusterWorkloadResourceMappingSpec `json:"spec,omitempty"` 50 | } 51 | 52 | // +kubebuilder:object:root=true 53 | 54 | // ClusterWorkloadResourceMappingList contains a list of ClusterWorkloadResourceMapping 55 | type ClusterWorkloadResourceMappingList struct { 56 | metav1.TypeMeta `json:",inline"` 57 | metav1.ListMeta `json:"metadata,omitempty"` 58 | 59 | Items []ClusterWorkloadResourceMapping `json:"items"` 60 | } 61 | 62 | func init() { 63 | SchemeBuilder.Register(&ClusterWorkloadResourceMapping{}, &ClusterWorkloadResourceMappingList{}) 64 | } 65 | -------------------------------------------------------------------------------- /rbac/cani.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rbac 18 | 19 | import ( 20 | "context" 21 | "sync" 22 | "time" 23 | 24 | "github.com/go-logr/logr" 25 | authorizationv1 "k8s.io/api/authorization/v1" 26 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 | "sigs.k8s.io/controller-runtime/pkg/client" 28 | ) 29 | 30 | type AccessChecker interface { 31 | CanI(ctx context.Context, group string, resource string) bool 32 | WithVerb(operation string) AccessChecker 33 | } 34 | 35 | func NewAccessChecker(client client.Client, ttl time.Duration) AccessChecker { 36 | return &accessChecker{ 37 | client: client, 38 | verb: "*", 39 | ttl: ttl, 40 | cache: map[authorizationv1.ResourceAttributes]authorizationv1.SelfSubjectAccessReview{}, 41 | } 42 | } 43 | 44 | type accessChecker struct { 45 | client client.Client 46 | verb string 47 | ttl time.Duration 48 | cache map[authorizationv1.ResourceAttributes]authorizationv1.SelfSubjectAccessReview 49 | m sync.Mutex 50 | } 51 | 52 | func (ac *accessChecker) WithVerb(verb string) AccessChecker { 53 | return &accessChecker{ 54 | client: ac.client, 55 | verb: verb, 56 | ttl: ac.ttl, 57 | cache: map[authorizationv1.ResourceAttributes]authorizationv1.SelfSubjectAccessReview{}, 58 | } 59 | } 60 | 61 | func (ac *accessChecker) CanI(ctx context.Context, group string, resource string) bool { 62 | key := authorizationv1.ResourceAttributes{ 63 | Namespace: "", 64 | Verb: ac.verb, 65 | Group: group, 66 | Resource: resource, 67 | } 68 | 69 | ac.m.Lock() 70 | defer ac.m.Unlock() 71 | 72 | ssar, ok := ac.cache[key] 73 | if ok { 74 | // ensure cached value is sufficiently recent 75 | if ssar.GetCreationTimestamp().Add(ac.ttl).After(time.Now()) { 76 | return ssar.Status.Allowed 77 | } 78 | delete(ac.cache, key) 79 | ssar = authorizationv1.SelfSubjectAccessReview{} 80 | } 81 | 82 | ssar.Spec = authorizationv1.SelfSubjectAccessReviewSpec{ 83 | ResourceAttributes: &key, 84 | } 85 | if err := ac.client.Create(ctx, &ssar); err != nil { 86 | logr.FromContextOrDiscard(ctx).Error(err, "unable to check access", "resource", key) 87 | // treat errors as not allowed 88 | ssar.SetCreationTimestamp(metav1.Now()) 89 | } 90 | ac.cache[key] = ssar 91 | return ssar.Status.Allowed 92 | } 93 | -------------------------------------------------------------------------------- /apis/v1alpha3/clusterworkloadresourcemapping_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1alpha3 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | 22 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 23 | ) 24 | 25 | // ClusterWorkloadResourceMappingTemplate defines the mapping for a specific version of an workload resource to a 26 | // logical PodTemplateSpec-like structure. 27 | type ClusterWorkloadResourceMappingTemplate = servicebindingv1.ClusterWorkloadResourceMappingTemplate 28 | 29 | // ClusterWorkloadResourceMappingContainer defines the mapping for a specific fragment of an workload resource 30 | // to a Container-like structure. 31 | // 32 | // Each mapping defines exactly one path that may match multiple container-like fragments within the workload 33 | // resource. For each object matching the path the name, env and volumeMounts expressions are resolved to find those 34 | // structures. 35 | type ClusterWorkloadResourceMappingContainer = servicebindingv1.ClusterWorkloadResourceMappingContainer 36 | 37 | // ClusterWorkloadResourceMappingSpec defines the desired state of ClusterWorkloadResourceMapping 38 | type ClusterWorkloadResourceMappingSpec = servicebindingv1.ClusterWorkloadResourceMappingSpec 39 | 40 | // +kubebuilder:deprecatedversion:warning="servicebinding.io/v1alpha3 is deprecated and will be removed in a future release, use v1 instead" 41 | // +kubebuilder:object:root=true 42 | // +kubebuilder:resource:scope=Cluster 43 | // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 44 | 45 | // ClusterWorkloadResourceMapping is the Schema for the clusterworkloadresourcemappings API 46 | type ClusterWorkloadResourceMapping struct { 47 | metav1.TypeMeta `json:",inline"` 48 | metav1.ObjectMeta `json:"metadata,omitempty"` 49 | 50 | Spec ClusterWorkloadResourceMappingSpec `json:"spec,omitempty"` 51 | } 52 | 53 | // +kubebuilder:object:root=true 54 | 55 | // ClusterWorkloadResourceMappingList contains a list of ClusterWorkloadResourceMapping 56 | type ClusterWorkloadResourceMappingList struct { 57 | metav1.TypeMeta `json:",inline"` 58 | metav1.ListMeta `json:"metadata,omitempty"` 59 | 60 | Items []ClusterWorkloadResourceMapping `json:"items"` 61 | } 62 | 63 | func init() { 64 | SchemeBuilder.Register(&ClusterWorkloadResourceMapping{}, &ClusterWorkloadResourceMappingList{}) 65 | } 66 | -------------------------------------------------------------------------------- /projector/mapping.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package projector 18 | 19 | import ( 20 | "context" 21 | 22 | "k8s.io/apimachinery/pkg/api/meta" 23 | "k8s.io/apimachinery/pkg/runtime" 24 | "k8s.io/apimachinery/pkg/runtime/schema" 25 | 26 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 27 | ) 28 | 29 | // The workload's version is either directly matched, or the wildcard version `*` 30 | // mapping template is returned. If no explicit mapping is found, a mapping appropriate for a PodSpecable resource may be used. 31 | func MappingVersion(version string, mappings *servicebindingv1.ClusterWorkloadResourceMappingSpec) *servicebindingv1.ClusterWorkloadResourceMappingTemplate { 32 | wildcardMapping := servicebindingv1.ClusterWorkloadResourceMappingTemplate{Version: "*"} 33 | var mapping *servicebindingv1.ClusterWorkloadResourceMappingTemplate 34 | for _, v := range mappings.Versions { 35 | switch v.Version { 36 | case version: 37 | mapping = &v 38 | case "*": 39 | wildcardMapping = v 40 | } 41 | } 42 | if mapping == nil { 43 | // use wildcard version by default 44 | mapping = &wildcardMapping 45 | } 46 | 47 | mapping = mapping.DeepCopy() 48 | mapping.Default() 49 | 50 | return mapping 51 | } 52 | 53 | var _ MappingSource = (*staticMapping)(nil) 54 | 55 | type staticMapping struct { 56 | workloadMapping *servicebindingv1.ClusterWorkloadResourceMappingSpec 57 | restMapping *meta.RESTMapping 58 | } 59 | 60 | // NewStaticMapping returns a single ClusterWorkloadResourceMappingSpec for each lookup. It is useful for 61 | // testing. 62 | func NewStaticMapping(wm *servicebindingv1.ClusterWorkloadResourceMappingSpec, rm *meta.RESTMapping) MappingSource { 63 | if len(wm.Versions) == 0 { 64 | wm.Versions = []servicebindingv1.ClusterWorkloadResourceMappingTemplate{ 65 | { 66 | Version: "*", 67 | }, 68 | } 69 | } 70 | for i := range wm.Versions { 71 | wm.Versions[i].Default() 72 | } 73 | 74 | return &staticMapping{ 75 | workloadMapping: wm, 76 | restMapping: rm, 77 | } 78 | } 79 | 80 | func (m *staticMapping) LookupRESTMapping(ctx context.Context, obj runtime.Object) (*meta.RESTMapping, error) { 81 | return m.restMapping, nil 82 | } 83 | 84 | func (m *staticMapping) LookupWorkloadMapping(ctx context.Context, gvr schema.GroupVersionResource) (*servicebindingv1.ClusterWorkloadResourceMappingSpec, error) { 85 | return m.workloadMapping, nil 86 | } 87 | -------------------------------------------------------------------------------- /samples/multi-binding/README.md: -------------------------------------------------------------------------------- 1 | # Multi-bindings 2 | 3 | Often an workload needs to consume more than one service. 4 | In that case, multiple service binding resources can each bind a distinct service to the same workload. 5 | 6 | In this sample, we'll use a [Kubernetes Job][kubernetes-jobs] to dump the environment to the logs and exit. 7 | 8 | ## Setup 9 | 10 | If not already installed, [install the ServiceBinding CRD and controller][install]. 11 | 12 | ## Deploy 13 | 14 | Like Pods, Kubernetes Jobs are immutable after they are created. 15 | We need to make sure the `ServiceBinding`s are fully configured before the workload is created. 16 | 17 | Apply the services and `ServiceBinding`s: 18 | 19 | ```sh 20 | kubectl apply -f ./samples/multi-binding/service.yaml -f ./samples/multi-binding/service-binding.yaml 21 | ``` 22 | 23 | Check on the status of the `ServiceBinding`: 24 | 25 | ```sh 26 | kubectl get servicebinding -l multi-binding=true -oyaml 27 | ``` 28 | 29 | For each service binding, the `ServiceAvailable` condition should be `True` and the `Ready` condition `False`. 30 | 31 | ``` 32 | ... 33 | conditions: 34 | - lastTransitionTime: "2022-08-02T21:28:45Z" 35 | message: the workload was not found 36 | reason: WorkloadNotFound 37 | status: Unknown 38 | type: Ready 39 | - lastTransitionTime: "2022-08-02T21:28:45Z" 40 | message: "" 41 | reason: ResolvedBindingSecret 42 | status: "True" 43 | type: ServiceAvailable 44 | ``` 45 | 46 | Create the workload `Job`: 47 | 48 | ```sh 49 | kubectl apply -f ./samples/multi-binding/workload.yaml 50 | ``` 51 | 52 | ## Understand 53 | 54 | Each `ServiceBinding` resource defines an environment variable that is projected into the workload in addition to the binding volume mount. 55 | 56 | ```sh 57 | kubectl describe job multi-binding 58 | ``` 59 | 60 | ``` 61 | ... 62 | Environment: 63 | SERVICE_BINDING_ROOT: /bindings 64 | MULTI_BINDING_1: Optional: false 65 | MULTI_BINDING_2: Optional: false 66 | ... 67 | ``` 68 | 69 | The job dumps the environment to the log and then exits. 70 | We should see our injected environment variable as well as other variable commonly found in Kubernetes containers. 71 | 72 | Inspect the logs from the job: 73 | 74 | ```sh 75 | kubectl logs -l job-name=multi-binding --tail 100 76 | ``` 77 | 78 | ``` 79 | ... 80 | SERVICE_BINDING_ROOT=/bindings 81 | MULTI_BINDING_1=1 82 | MULTI_BINDING_2=2 83 | ... 84 | ``` 85 | 86 | ## Play 87 | 88 | Try adding yet another binding targeting the same Job. 89 | Remember that Jobs are immutable after they are created, so you'll need to delete and recreate the Job to see the additional binding. 90 | 91 | Alternatively, define a `Deployment` and update each binding to target the new Deployment. 92 | Since Deployments are mutable, each service binding that is added or removed will be reflected on the Deployment and trigger the rollout of a new `ReplicaSet`. 93 | 94 | [install]: ../../README.md#getting-started 95 | [kubernetes-jobs]: https://kubernetes.io/docs/concepts/workloads/controllers/job/ 96 | -------------------------------------------------------------------------------- /config/manager/manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: system 7 | --- 8 | apiVersion: apps/v1 9 | kind: Deployment 10 | metadata: 11 | name: controller-manager 12 | namespace: system 13 | labels: 14 | control-plane: controller-manager 15 | spec: 16 | selector: 17 | matchLabels: 18 | control-plane: controller-manager 19 | replicas: 1 20 | template: 21 | metadata: 22 | annotations: 23 | kubectl.kubernetes.io/default-container: manager 24 | labels: 25 | control-plane: controller-manager 26 | spec: 27 | securityContext: 28 | runAsNonRoot: true 29 | containers: 30 | - args: 31 | - --leader-elect 32 | image: ko://github.com/servicebinding/runtime 33 | name: manager 34 | securityContext: 35 | allowPrivilegeEscalation: false 36 | livenessProbe: 37 | httpGet: 38 | path: /healthz 39 | port: 8081 40 | initialDelaySeconds: 15 41 | periodSeconds: 20 42 | readinessProbe: 43 | httpGet: 44 | path: /readyz 45 | port: 8081 46 | initialDelaySeconds: 5 47 | periodSeconds: 10 48 | # TODO(user): Configure the resources accordingly based on the project requirements. 49 | # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ 50 | resources: 51 | limits: 52 | cpu: 500m 53 | memory: 128Mi 54 | requests: 55 | cpu: 10m 56 | memory: 64Mi 57 | serviceAccountName: controller-manager 58 | terminationGracePeriodSeconds: 10 59 | 60 | --- 61 | apiVersion: admissionregistration.k8s.io/v1 62 | kind: MutatingWebhookConfiguration 63 | metadata: 64 | name: admission-projector 65 | annotations: 66 | cert-manager.io/inject-ca-from: $(NAMESPACE)/$(CERTIFICATE_NAME) 67 | webhook.servicebinding.io/dynamic-rules: "" 68 | webhooks: 69 | - name: interceptor.servicebinding.io 70 | namespaceSelector: 71 | matchExpressions: 72 | - key: kubernetes.io/metadata.name 73 | operator: NotIn 74 | values: 75 | - $(NAMESPACE) 76 | - kube-system 77 | admissionReviewVersions: ["v1"] 78 | clientConfig: 79 | service: 80 | name: webhook-service 81 | namespace: system 82 | path: /interceptor 83 | failurePolicy: Fail 84 | reinvocationPolicy: IfNeeded 85 | sideEffects: None 86 | 87 | --- 88 | apiVersion: admissionregistration.k8s.io/v1 89 | kind: ValidatingWebhookConfiguration 90 | metadata: 91 | name: trigger 92 | annotations: 93 | cert-manager.io/inject-ca-from: $(NAMESPACE)/$(CERTIFICATE_NAME) 94 | webhook.servicebinding.io/dynamic-rules: "" 95 | webhooks: 96 | - name: trigger.servicebinding.io 97 | namespaceSelector: 98 | matchExpressions: 99 | - key: kubernetes.io/metadata.name 100 | operator: NotIn 101 | values: 102 | - $(NAMESPACE) 103 | - kube-system 104 | admissionReviewVersions: ["v1"] 105 | clientConfig: 106 | service: 107 | name: webhook-service 108 | namespace: system 109 | path: /trigger 110 | failurePolicy: Ignore 111 | sideEffects: None 112 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/runtime 2 | 3 | go 1.24.0 4 | 5 | require ( 6 | github.com/go-logr/logr v1.4.3 7 | github.com/google/go-cmp v0.7.0 8 | github.com/stretchr/testify v1.11.1 9 | gomodules.xyz/jsonpatch/v2 v2.5.0 10 | k8s.io/api v0.34.3 11 | k8s.io/apimachinery v0.34.3 12 | k8s.io/client-go v0.34.3 13 | k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d 14 | reconciler.io/dies v0.17.0 15 | reconciler.io/runtime v0.24.1 16 | sigs.k8s.io/controller-runtime v0.22.4 17 | sigs.k8s.io/yaml v1.6.0 18 | ) 19 | 20 | require ( 21 | github.com/beorn7/perks v1.0.1 // indirect 22 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 23 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 24 | github.com/emicklei/go-restful/v3 v3.12.2 // indirect 25 | github.com/evanphx/json-patch/v5 v5.9.11 // indirect 26 | github.com/fatih/color v1.18.0 // indirect 27 | github.com/fsnotify/fsnotify v1.9.0 // indirect 28 | github.com/fxamacker/cbor/v2 v2.9.0 // indirect 29 | github.com/go-logr/zapr v1.3.0 // indirect 30 | github.com/go-openapi/jsonpointer v0.21.2 // indirect 31 | github.com/go-openapi/jsonreference v0.21.0 // indirect 32 | github.com/go-openapi/swag v0.23.1 // indirect 33 | github.com/gogo/protobuf v1.3.2 // indirect 34 | github.com/google/btree v1.1.3 // indirect 35 | github.com/google/gnostic-models v0.7.0 // indirect 36 | github.com/google/uuid v1.6.0 // indirect 37 | github.com/josharian/intern v1.0.0 // indirect 38 | github.com/json-iterator/go v1.1.12 // indirect 39 | github.com/mailru/easyjson v0.9.0 // indirect 40 | github.com/mattn/go-colorable v0.1.13 // indirect 41 | github.com/mattn/go-isatty v0.0.20 // indirect 42 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 43 | github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect 44 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 45 | github.com/pkg/errors v0.9.1 // indirect 46 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect 47 | github.com/prometheus/client_golang v1.22.0 // indirect 48 | github.com/prometheus/client_model v0.6.1 // indirect 49 | github.com/prometheus/common v0.62.0 // indirect 50 | github.com/prometheus/procfs v0.15.1 // indirect 51 | github.com/spf13/pflag v1.0.6 // indirect 52 | github.com/stretchr/objx v0.5.2 // indirect 53 | github.com/x448/float16 v0.8.4 // indirect 54 | go.uber.org/multierr v1.11.0 // indirect 55 | go.uber.org/zap v1.27.0 // indirect 56 | go.yaml.in/yaml/v2 v2.4.2 // indirect 57 | go.yaml.in/yaml/v3 v3.0.4 // indirect 58 | golang.org/x/net v0.44.0 // indirect 59 | golang.org/x/oauth2 v0.27.0 // indirect 60 | golang.org/x/sync v0.17.0 // indirect 61 | golang.org/x/sys v0.36.0 // indirect 62 | golang.org/x/term v0.35.0 // indirect 63 | golang.org/x/text v0.29.0 // indirect 64 | golang.org/x/time v0.9.0 // indirect 65 | gomodules.xyz/jsonpatch/v3 v3.0.1 // indirect 66 | gomodules.xyz/orderedmap v0.1.0 // indirect 67 | google.golang.org/protobuf v1.36.8 // indirect 68 | gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect 69 | gopkg.in/inf.v0 v0.9.1 // indirect 70 | gopkg.in/yaml.v3 v3.0.1 // indirect 71 | k8s.io/apiextensions-apiserver v0.34.1 // indirect 72 | k8s.io/klog/v2 v2.130.1 // indirect 73 | k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3 // indirect 74 | sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect 75 | sigs.k8s.io/randfill v1.0.0 // indirect 76 | sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect 77 | ) 78 | -------------------------------------------------------------------------------- /samples/overridden-type-provider/README.md: -------------------------------------------------------------------------------- 1 | # Overridden Type and Provider 2 | 3 | When projected into the workload, the binding must contain a `type` entry and should contain a `provider` entry. 4 | If the Secret doesn't contain a type or provider, or contains the wrong values, they can be overridden for the binding. 5 | 6 | In this sample, we'll use a [Kubernetes Job][kubernetes-jobs] to dump the environment to the logs and exit. 7 | 8 | ## Setup 9 | 10 | If not already installed, [install the ServiceBinding CRD and controller][install]. 11 | 12 | ## Deploy 13 | 14 | Like Pods, Kubernetes Jobs are immutable after they are created. 15 | We need to make sure the `ServiceBinding`s are fully configured before the workload is created. 16 | 17 | Apply the service and `ServiceBinding`: 18 | 19 | ```sh 20 | kubectl apply -f ./samples/overridden-type-provider/service.yaml -f ./samples/overridden-type-provider/service-binding.yaml 21 | ``` 22 | 23 | Check on the status of the `ServiceBinding`: 24 | 25 | ```sh 26 | kubectl get servicebinding -l sample=overridden-type-provider -oyaml 27 | ``` 28 | 29 | For each service binding, the `ServiceAvailable` condition should be `True` and the `ProjectionReady` condition `False`. 30 | 31 | ``` 32 | ... 33 | conditions: 34 | - lastTransitionTime: "2022-08-02T21:32:29Z" 35 | message: the workload was not found 36 | reason: WorkloadNotFound 37 | status: Unknown 38 | type: Ready 39 | - lastTransitionTime: "2022-08-02T21:32:29Z" 40 | message: "" 41 | reason: ResolvedBindingSecret 42 | status: "True" 43 | type: ServiceAvailable 44 | ``` 45 | 46 | Create the workload `Job`: 47 | 48 | ```sh 49 | kubectl apply -f ./samples/overridden-type-provider/workload.yaml 50 | ``` 51 | 52 | ## Understand 53 | 54 | Each `ServiceBinding` resource defines an environment variable that is projected into the workload in addition to the binding volume mount. 55 | 56 | ```sh 57 | kubectl describe job overridden-type-provider 58 | ``` 59 | 60 | ``` 61 | ... 62 | Environment: 63 | SERVICE_BINDING_ROOT: /bindings 64 | BOUND_PROVIDER: (v1:metadata.annotations['projector.servicebinding.io/provider-7b561828-a00b-4075-9ea5-64c69535230c']) 65 | BOUND_TYPE: (v1:metadata.annotations['projector.servicebinding.io/type-7b561828-a00b-4075-9ea5-64c69535230c']) 66 | ... 67 | ``` 68 | 69 | The job dumps the environment to the log and then exits. 70 | We should see our injected environment variable as well as other variable commonly found in Kubernetes containers. 71 | 72 | Inspect the logs from the job: 73 | 74 | ```sh 75 | kubectl logs -l job-name=overridden-type-provider --tail 100 76 | ``` 77 | 78 | ``` 79 | ... 80 | SERVICE_BINDING_ROOT=/bindings 81 | BOUND_PROVIDER=overridden-provider 82 | BOUND_TYPE=overridden-type 83 | ... 84 | ``` 85 | 86 | The order of variables may vary. 87 | 88 | ## Play 89 | 90 | Try changing the `.spec.type` or `.spec.provider` fields on the ServiceBinding, or return them to the original values (empty string). 91 | Remember that Jobs are immutable after they are created, so you'll need to delete and recreate the Job to see the additional binding. 92 | 93 | Alternatively, define a `Deployment` and update each binding to target the new Deployment. 94 | Since Deployments are mutable, each service binding that is added or removed will be reflected on the Deployment and trigger the rollout of a new `ReplicaSet`. 95 | 96 | [install]: ../../README.md#getting-started 97 | [kubernetes-jobs]: https://kubernetes.io/docs/concepts/workloads/controllers/job/ 98 | -------------------------------------------------------------------------------- /apis/v1/servicebinding_lifecycle.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package v1 contains API Schema definitions for the servicebinding.io v1 API group 18 | // +kubebuilder:object:generate=true 19 | // +groupName=servicebinding.io 20 | package v1 21 | 22 | import ( 23 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 | "reconciler.io/runtime/apis" 25 | ) 26 | 27 | // These are valid conditions of ServiceBinding. 28 | const ( 29 | // ServiceBindingReady means the ServiceBinding has projected the ProvisionedService 30 | // secret and the Workload is ready to start. It does not indicate the condition 31 | // of either the Service or the Workload resources referenced. 32 | ServiceBindingConditionReady = apis.ConditionReady 33 | // ServiceBindingConditionServiceAvailable means the ServiceBinding's service 34 | // reference resolved to a ProvisionedService and found a secret. It does not 35 | // indicate the condition of the Service. 36 | ServiceBindingConditionServiceAvailable = "ServiceAvailable" 37 | // ServiceBindingConditionWorkloadProjected means the ServiceBinding has projected 38 | // the ProvisionedService secret and the Workload is ready to start. It does not 39 | // indicate the condition of the Workload resources referenced. 40 | // 41 | // Not a standardized condition. 42 | ServiceBindingConditionWorkloadProjected = "WorkloadProjected" 43 | ) 44 | 45 | var servicebindingCondSet = apis.NewLivingConditionSetWithHappyReason( 46 | "ServiceBound", 47 | ServiceBindingConditionServiceAvailable, 48 | ServiceBindingConditionWorkloadProjected, 49 | ) 50 | 51 | func (s *ServiceBinding) GetConditionsAccessor() apis.ConditionsAccessor { 52 | return &s.Status 53 | } 54 | 55 | func (s *ServiceBinding) GetConditionSet() apis.ConditionSet { 56 | return servicebindingCondSet 57 | } 58 | 59 | func (s *ServiceBinding) GetConditionManager() apis.ConditionManager { 60 | return servicebindingCondSet.Manage(&s.Status) 61 | } 62 | 63 | func (s *ServiceBindingStatus) InitializeConditions() { 64 | conditionManager := servicebindingCondSet.Manage(s) 65 | conditionManager.InitializeConditions() 66 | // reset existing managed conditions 67 | conditionManager.MarkUnknown(ServiceBindingConditionServiceAvailable, "Initializing", "") 68 | conditionManager.MarkUnknown(ServiceBindingConditionWorkloadProjected, "Initializing", "") 69 | } 70 | 71 | var _ apis.ConditionsAccessor = (*ServiceBindingStatus)(nil) 72 | 73 | // GetConditions implements ConditionsAccessor 74 | func (s *ServiceBindingStatus) GetConditions() []metav1.Condition { 75 | return s.Conditions 76 | } 77 | 78 | // SetConditions implements ConditionsAccessor 79 | func (s *ServiceBindingStatus) SetConditions(c []metav1.Condition) { 80 | s.Conditions = c 81 | } 82 | 83 | // GetCondition fetches the condition of the specified type. 84 | func (s *ServiceBindingStatus) GetCondition(t string) *metav1.Condition { 85 | for _, cond := range s.Conditions { 86 | if cond.Type == t { 87 | return &cond 88 | } 89 | } 90 | return nil 91 | } 92 | -------------------------------------------------------------------------------- /apis/v1alpha3/servicebinding_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1alpha3 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | 22 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 23 | ) 24 | 25 | // ServiceBindingWorkloadReference defines a subset of corev1.ObjectReference with extensions 26 | type ServiceBindingWorkloadReference = servicebindingv1.ServiceBindingWorkloadReference 27 | 28 | // ServiceBindingServiceReference defines a subset of corev1.ObjectReference 29 | type ServiceBindingServiceReference = servicebindingv1.ServiceBindingServiceReference 30 | 31 | // ServiceBindingSecretReference defines a mirror of corev1.LocalObjectReference 32 | type ServiceBindingSecretReference = servicebindingv1.ServiceBindingSecretReference 33 | 34 | // EnvMapping defines a mapping from the value of a Secret entry to an environment variable 35 | type EnvMapping = servicebindingv1.EnvMapping 36 | 37 | // ServiceBindingSpec defines the desired state of ServiceBinding 38 | type ServiceBindingSpec = servicebindingv1.ServiceBindingSpec 39 | 40 | // These are valid conditions of ServiceBinding. 41 | const ( 42 | // ServiceBindingReady means the ServiceBinding has projected the ProvisionedService 43 | // secret and the Workload is ready to start. It does not indicate the condition 44 | // of either the Service or the Workload resources referenced. 45 | ServiceBindingConditionReady = servicebindingv1.ServiceBindingConditionReady 46 | ) 47 | 48 | // ServiceBindingStatus defines the observed state of ServiceBinding 49 | type ServiceBindingStatus = servicebindingv1.ServiceBindingStatus 50 | 51 | // +kubebuilder:deprecatedversion:warning="servicebinding.io/v1alpha3 is deprecated and will be removed in a future release, use v1 instead" 52 | // +kubebuilder:object:root=true 53 | // +kubebuilder:subresource:status 54 | // +kubebuilder:printcolumn:name="Secret",type=string,JSONPath=`.status.binding.name` 55 | // +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status` 56 | // +kubebuilder:printcolumn:name="Reason",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].reason` 57 | // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 58 | 59 | // ServiceBinding is the Schema for the servicebindings API 60 | type ServiceBinding struct { 61 | metav1.TypeMeta `json:",inline"` 62 | metav1.ObjectMeta `json:"metadata,omitempty"` 63 | 64 | Spec ServiceBindingSpec `json:"spec,omitempty"` 65 | Status ServiceBindingStatus `json:"status,omitempty"` 66 | } 67 | 68 | // +kubebuilder:object:root=true 69 | 70 | // ServiceBindingList contains a list of ServiceBinding 71 | type ServiceBindingList struct { 72 | metav1.TypeMeta `json:",inline"` 73 | metav1.ListMeta `json:"metadata,omitempty"` 74 | 75 | Items []ServiceBinding `json:"items"` 76 | } 77 | 78 | func init() { 79 | SchemeBuilder.Register(&ServiceBinding{}, &ServiceBindingList{}) 80 | } 81 | -------------------------------------------------------------------------------- /hack/kapp/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/runtime/hack/kapp 2 | 3 | go 1.21 4 | 5 | require github.com/k14s/kapp v0.52.0 6 | 7 | require ( 8 | cloud.google.com/go v0.97.0 // indirect 9 | github.com/Azure/go-autorest v14.2.0+incompatible // indirect 10 | github.com/Azure/go-autorest/autorest v0.11.18 // indirect 11 | github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect 12 | github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect 13 | github.com/Azure/go-autorest/logger v0.2.1 // indirect 14 | github.com/Azure/go-autorest/tracing v0.6.0 // indirect 15 | github.com/PuerkitoBio/purell v1.1.1 // indirect 16 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect 17 | github.com/cppforlife/cobrautil v0.0.0-20200514214827-bb86e6965d72 // indirect 18 | github.com/cppforlife/color v1.9.1-0.20200716202919-6706ac40b835 // indirect 19 | github.com/cppforlife/go-cli-ui v0.0.0-20200716203538-1e47f820817f // indirect 20 | github.com/cppforlife/go-patch v0.2.0 // indirect 21 | github.com/davecgh/go-spew v1.1.1 // indirect 22 | github.com/emicklei/go-restful/v3 v3.8.0 // indirect 23 | github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect 24 | github.com/ghodss/yaml v1.0.0 // indirect 25 | github.com/go-logr/logr v1.2.0 // indirect 26 | github.com/go-openapi/jsonpointer v0.19.5 // indirect 27 | github.com/go-openapi/jsonreference v0.19.6 // indirect 28 | github.com/go-openapi/swag v0.19.15 // indirect 29 | github.com/gogo/protobuf v1.3.2 // indirect 30 | github.com/golang/protobuf v1.5.2 // indirect 31 | github.com/google/gnostic v0.5.7-v3refs // indirect 32 | github.com/google/gofuzz v1.2.0 // indirect 33 | github.com/hashicorp/go-version v1.3.0 // indirect 34 | github.com/imdario/mergo v0.3.12 // indirect 35 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 36 | github.com/josharian/intern v1.0.0 // indirect 37 | github.com/json-iterator/go v1.1.12 // indirect 38 | github.com/k14s/difflib v0.0.0-20201117154628-0c031775bf57 // indirect 39 | github.com/k14s/starlark-go v0.0.0-20200720175618-3a5c849cc368 // indirect 40 | github.com/k14s/ytt v0.36.0 // indirect 41 | github.com/mailru/easyjson v0.7.6 // indirect 42 | github.com/mattn/go-colorable v0.1.8 // indirect 43 | github.com/mattn/go-isatty v0.0.12 // indirect 44 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect 45 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 46 | github.com/modern-go/reflect2 v1.0.2 // indirect 47 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 48 | github.com/spf13/cobra v1.2.1 // indirect 49 | github.com/spf13/pflag v1.0.5 // indirect 50 | github.com/vito/go-interact v0.0.0-20171111012221-fa338ed9e9ec // indirect 51 | github.com/vmware-tanzu/carvel-kapp-controller v0.38.4 // indirect 52 | github.com/vmware-tanzu/carvel-vendir v0.24.0 // indirect 53 | golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect 54 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect 55 | golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect 56 | golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect 57 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect 58 | golang.org/x/text v0.3.7 // indirect 59 | golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect 60 | google.golang.org/appengine v1.6.7 // indirect 61 | google.golang.org/protobuf v1.27.1 // indirect 62 | gopkg.in/inf.v0 v0.9.1 // indirect 63 | gopkg.in/yaml.v2 v2.4.0 // indirect 64 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect 65 | k8s.io/api v0.24.3 // indirect 66 | k8s.io/apimachinery v0.24.3 // indirect 67 | k8s.io/client-go v0.24.3 // indirect 68 | k8s.io/klog/v2 v2.60.1 // indirect 69 | k8s.io/kube-openapi v0.0.0-20220803164354-a70c9af30aea // indirect 70 | k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect 71 | sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect 72 | sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect 73 | sigs.k8s.io/yaml v1.3.0 // indirect 74 | ) 75 | -------------------------------------------------------------------------------- /hack/imgpkg/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/runtime/hack/imgpkg 2 | 3 | go 1.21 4 | 5 | require github.com/vmware-tanzu/carvel-imgpkg v0.38.0 6 | 7 | require ( 8 | cloud.google.com/go/compute v1.19.3 // indirect 9 | cloud.google.com/go/compute/metadata v0.2.3 // indirect 10 | github.com/Azure/azure-sdk-for-go v55.0.0+incompatible // indirect 11 | github.com/Azure/go-autorest v14.2.0+incompatible // indirect 12 | github.com/Azure/go-autorest/autorest v0.11.18 // indirect 13 | github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect 14 | github.com/Azure/go-autorest/autorest/azure/auth v0.5.2 // indirect 15 | github.com/Azure/go-autorest/autorest/azure/cli v0.4.1 // indirect 16 | github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect 17 | github.com/Azure/go-autorest/logger v0.2.1 // indirect 18 | github.com/Azure/go-autorest/tracing v0.6.0 // indirect 19 | github.com/VividCortex/ewma v1.2.0 // indirect 20 | github.com/aws/aws-sdk-go-v2 v1.7.1 // indirect 21 | github.com/aws/aws-sdk-go-v2/config v1.5.0 // indirect 22 | github.com/aws/aws-sdk-go-v2/credentials v1.3.1 // indirect 23 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.3.0 // indirect 24 | github.com/aws/aws-sdk-go-v2/internal/ini v1.1.1 // indirect 25 | github.com/aws/aws-sdk-go-v2/service/ecr v1.4.1 // indirect 26 | github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.4.1 // indirect 27 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.1 // indirect 28 | github.com/aws/aws-sdk-go-v2/service/sso v1.3.1 // indirect 29 | github.com/aws/aws-sdk-go-v2/service/sts v1.6.0 // indirect 30 | github.com/aws/smithy-go v1.6.0 // indirect 31 | github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220517224237-e6f29200ae04 // indirect 32 | github.com/cheggaaa/pb/v3 v3.1.4 // indirect 33 | github.com/chrismellard/docker-credential-acr-env v0.0.0-20220327082430-c57b701bfc08 // indirect 34 | github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect 35 | github.com/cppforlife/cobrautil v0.0.0-20221021151949-d60711905d65 // indirect 36 | github.com/cppforlife/color v1.9.1-0.20200716202919-6706ac40b835 // indirect 37 | github.com/cppforlife/go-cli-ui v0.0.0-20220425131040-94f26b16bc14 // indirect 38 | github.com/dimchansky/utfbom v1.1.0 // indirect 39 | github.com/docker/cli v24.0.0+incompatible // indirect 40 | github.com/docker/distribution v2.8.2+incompatible // indirect 41 | github.com/docker/docker v24.0.0+incompatible // indirect 42 | github.com/docker/docker-credential-helpers v0.7.0 // indirect 43 | github.com/fatih/color v1.15.0 // indirect 44 | github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect 45 | github.com/golang/protobuf v1.5.3 // indirect 46 | github.com/google/go-containerregistry v0.16.1 // indirect 47 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 48 | github.com/jmespath/go-jmespath v0.4.0 // indirect 49 | github.com/klauspost/compress v1.16.5 // indirect 50 | github.com/kr/pretty v0.3.1 // indirect 51 | github.com/mattn/go-colorable v0.1.13 // indirect 52 | github.com/mattn/go-isatty v0.0.19 // indirect 53 | github.com/mattn/go-runewidth v0.0.14 // indirect 54 | github.com/mitchellh/go-homedir v1.1.0 // indirect 55 | github.com/opencontainers/go-digest v1.0.0 // indirect 56 | github.com/opencontainers/image-spec v1.1.0-rc3 // indirect 57 | github.com/pkg/errors v0.9.1 // indirect 58 | github.com/rivo/uniseg v0.2.0 // indirect 59 | github.com/sirupsen/logrus v1.9.1 // indirect 60 | github.com/spf13/cobra v1.7.0 // indirect 61 | github.com/spf13/pflag v1.0.5 // indirect 62 | github.com/vbatts/tar-split v0.11.3 // indirect 63 | github.com/vito/go-interact v1.0.1 // indirect 64 | golang.org/x/crypto v0.12.0 // indirect 65 | golang.org/x/net v0.14.0 // indirect 66 | golang.org/x/oauth2 v0.8.0 // indirect 67 | golang.org/x/sync v0.3.0 // indirect 68 | golang.org/x/sys v0.12.0 // indirect 69 | golang.org/x/term v0.11.0 // indirect 70 | google.golang.org/appengine v1.6.7 // indirect 71 | google.golang.org/protobuf v1.30.0 // indirect 72 | gopkg.in/yaml.v2 v2.4.0 // indirect 73 | sigs.k8s.io/yaml v1.3.0 // indirect 74 | ) 75 | -------------------------------------------------------------------------------- /apis/v1beta1/servicebinding_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1beta1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | 22 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 23 | ) 24 | 25 | // ServiceBindingWorkloadReference defines a subset of corev1.ObjectReference with extensions 26 | type ServiceBindingWorkloadReference = servicebindingv1.ServiceBindingWorkloadReference 27 | 28 | // ServiceBindingServiceReference defines a subset of corev1.ObjectReference 29 | type ServiceBindingServiceReference = servicebindingv1.ServiceBindingServiceReference 30 | 31 | // ServiceBindingSecretReference defines a mirror of corev1.LocalObjectReference 32 | type ServiceBindingSecretReference = servicebindingv1.ServiceBindingSecretReference 33 | 34 | // EnvMapping defines a mapping from the value of a Secret entry to an environment variable 35 | type EnvMapping = servicebindingv1.EnvMapping 36 | 37 | // ServiceBindingSpec defines the desired state of ServiceBinding 38 | type ServiceBindingSpec = servicebindingv1.ServiceBindingSpec 39 | 40 | // These are valid conditions of ServiceBinding. 41 | const ( 42 | // ServiceBindingReady means the ServiceBinding has projected the ProvisionedService 43 | // secret and the Workload is ready to start. It does not indicate the condition 44 | // of either the Service or the Workload resources referenced. 45 | ServiceBindingConditionReady = servicebindingv1.ServiceBindingConditionReady 46 | // ServiceBindingConditionServiceAvailable means the ServiceBinding's service 47 | // reference resolved to a ProvisionedService and found a secret. It does not 48 | // indicate the condition of the Service. 49 | ServiceBindingConditionServiceAvailable = servicebindingv1.ServiceBindingConditionServiceAvailable 50 | // ServiceBindingConditionWorkloadProjected means the ServiceBinding has projected 51 | // the ProvisionedService secret and the Workload is ready to start. It does not 52 | // indicate the condition of the Workload resources referenced. 53 | // 54 | // Not a standardized condition. 55 | ServiceBindingConditionWorkloadProjected = servicebindingv1.ServiceBindingConditionWorkloadProjected 56 | ) 57 | 58 | // ServiceBindingStatus defines the observed state of ServiceBinding 59 | type ServiceBindingStatus = servicebindingv1.ServiceBindingStatus 60 | 61 | // +kubebuilder:object:root=true 62 | // +kubebuilder:subresource:status 63 | // +kubebuilder:printcolumn:name="Secret",type=string,JSONPath=`.status.binding.name` 64 | // +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status` 65 | // +kubebuilder:printcolumn:name="Reason",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].reason` 66 | // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 67 | 68 | // ServiceBinding is the Schema for the servicebindings API 69 | type ServiceBinding struct { 70 | metav1.TypeMeta `json:",inline"` 71 | metav1.ObjectMeta `json:"metadata,omitempty"` 72 | 73 | Spec ServiceBindingSpec `json:"spec,omitempty"` 74 | Status ServiceBindingStatus `json:"status,omitempty"` 75 | } 76 | 77 | // +kubebuilder:object:root=true 78 | 79 | // ServiceBindingList contains a list of ServiceBinding 80 | type ServiceBindingList struct { 81 | metav1.TypeMeta `json:",inline"` 82 | metav1.ListMeta `json:"metadata,omitempty"` 83 | 84 | Items []ServiceBinding `json:"items"` 85 | } 86 | 87 | func init() { 88 | SchemeBuilder.Register(&ServiceBinding{}, &ServiceBindingList{}) 89 | } 90 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) 2 | ifeq (,$(shell go env GOBIN)) 3 | GOBIN=$(shell go env GOPATH)/bin 4 | else 5 | GOBIN=$(shell go env GOBIN) 6 | endif 7 | 8 | # Tools 9 | CONTROLLER_GEN ?= go run -modfile hack/controller-gen/go.mod sigs.k8s.io/controller-tools/cmd/controller-gen 10 | DIEGEN ?= go run -modfile hack/diegen/go.mod reconciler.io/dies/diegen 11 | GOIMPORTS ?= go run -modfile hack/goimports/go.mod golang.org/x/tools/cmd/goimports 12 | KAPP ?= go run -modfile hack/kapp/go.mod github.com/k14s/kapp/cmd/kapp 13 | KO ?= go run -modfile hack/ko/go.mod github.com/google/ko 14 | KUSTOMIZE ?= go run -modfile hack/kustomize/go.mod sigs.k8s.io/kustomize/kustomize/v4 15 | 16 | KAPP_APP ?= servicebinding-runtime 17 | KAPP_APP_NAMESPACE ?= default 18 | 19 | ifeq (${KO_DOCKER_REPO},kind.local) 20 | # kind isn't multi-arch aware, default to the current arch 21 | KO_PLATFORMS ?= linux/$(shell go env GOARCH) 22 | else 23 | KO_PLATFORMS ?= linux/arm64,linux/amd64 24 | endif 25 | 26 | # Setting SHELL to bash allows bash commands to be executed by recipes. 27 | # Options are set to exit when a recipe line exits non-zero or a piped command fails. 28 | SHELL = /usr/bin/env bash -o pipefail 29 | .SHELLFLAGS = -ec 30 | 31 | .PHONY: all 32 | all: test 33 | 34 | ##@ General 35 | 36 | # The help target prints out all targets with their descriptions organized 37 | # beneath their categories. The categories are represented by '##@' and the 38 | # target descriptions by '##'. The awk commands is responsible for reading the 39 | # entire set of makefiles included in this invocation, looking for lines of the 40 | # file as xyz: ## something, and then pretty-format the target and help. Then, 41 | # if there's a line with ##@ something, that gets pretty-printed as a category. 42 | # More info on the usage of ANSI control characters for terminal formatting: 43 | # https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters 44 | # More info on the awk command: 45 | # http://linuxcommand.org/lc3_adv_awk.php 46 | 47 | .PHONY: help 48 | help: ## Display this help. 49 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 50 | 51 | ##@ Development 52 | 53 | .PHONY: manifests 54 | manifests: ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. 55 | $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases 56 | @rm -rf config/crd/bases/_*.yaml 57 | cat hack/boilerplate.yaml.txt > config/servicebinding-runtime.yaml 58 | $(KUSTOMIZE) build config/default >> config/servicebinding-runtime.yaml 59 | 60 | .PHONY: generate 61 | generate: ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. 62 | $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." 63 | $(DIEGEN) die:headerFile="hack/boilerplate.go.txt" paths="./..." 64 | 65 | .PHONY: fmt 66 | fmt: ## Run go fmt against code. 67 | $(GOIMPORTS) --local github.com/servicebinding/runtime -w . 68 | 69 | .PHONY: vet 70 | vet: ## Run go vet against code. 71 | go vet ./... 72 | 73 | .PHONY: test 74 | test: manifests generate fmt vet ## Run tests. 75 | go test ./... -coverprofile cover.out 76 | 77 | ##@ Deployment 78 | 79 | .PHONY: deploy 80 | deploy: manifests ## Deploy controller to the K8s cluster specified in ~/.kube/config. 81 | $(KAPP) deploy -a $(KAPP_APP) -n $(KAPP_APP_NAMESPACE) -c \ 82 | -f config/kapp \ 83 | -f config/servicebinding-workloadresourcemappings.yaml \ 84 | -f <($(KO) resolve --platform $(KO_PLATFORMS) -f config/servicebinding-runtime.yaml) 85 | 86 | .PHONY: deploy-cert-manager 87 | deploy-cert-manager: ## Deploy cert-manager to the K8s cluster specified in ~/.kube/config. 88 | $(KAPP) deploy -a cert-manager -n $(KAPP_APP_NAMESPACE) --wait-timeout 5m -c -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml 89 | 90 | .PHONY: undeploy-cert-manager 91 | undeploy-cert-manager: ## Undeploy cert-manager from the K8s cluster specified in ~/.kube/config. 92 | $(KAPP) delete -a cert-manager -n $(KAPP_APP_NAMESPACE) 93 | 94 | .PHONY: undeploy 95 | undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. 96 | $(KAPP) delete -a $(KAPP_APP) -n $(KAPP_APP_NAMESPACE) 97 | -------------------------------------------------------------------------------- /hack/diegen/go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= 3 | github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= 4 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 5 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 6 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 7 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 8 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 9 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 10 | github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= 11 | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 12 | github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= 13 | github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= 14 | github.com/onsi/gomega v1.38.1 h1:FaLA8GlcpXDwsb7m0h2A9ew2aTk3vnZMlzFgg5tz/pk= 15 | github.com/onsi/gomega v1.38.1/go.mod h1:LfcV8wZLvwcYRwPiJysphKAEsmcFnLMK/9c+PjvlX8g= 16 | github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= 17 | github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= 18 | go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= 19 | go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= 20 | golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= 21 | golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= 22 | golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= 23 | golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= 24 | golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= 25 | golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 26 | golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= 27 | golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 28 | golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= 29 | golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= 30 | golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= 31 | golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 32 | golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY= 33 | golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= 34 | golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= 35 | golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= 36 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 37 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 38 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 39 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 40 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 41 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 42 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 43 | k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4= 44 | k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= 45 | k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0= 46 | k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= 47 | reconciler.io/dies/diegen v0.17.0 h1:O7ujxx6yzjIfL1iGZeTxhyl6x7515r9RLNQ+PHXciW8= 48 | reconciler.io/dies/diegen v0.17.0/go.mod h1:GTB/AT7lpaRSu88CrpnNin745qjWjMHPtTvMbscEkec= 49 | sigs.k8s.io/controller-tools v0.19.0 h1:OU7jrPPiZusryu6YK0jYSjPqg8Vhf8cAzluP9XGI5uk= 50 | sigs.k8s.io/controller-tools v0.19.0/go.mod h1:y5HY/iNDFkmFla2CfQoVb2AQXMsBk4ad84iR1PLANB0= 51 | -------------------------------------------------------------------------------- /samples/external-secrets/README.md: -------------------------------------------------------------------------------- 1 | # External Secrets 2 | 3 | [External Secrets][eso] is an operator to fetch content from secure stores and synthesize that state into a Kubernetes `Secret`. 4 | 5 | This sample uses a fake `SecretStore` (to avoid external infrastructure) and `ExternalSecret` to create a binding Secret. The [Spring PetClinic][petclinic] workload and MySQL database are independently bound to the `ExternalSecret`. 6 | 7 | ## Setup 8 | 9 | If not already installed, [install the ServiceBinding CRD and controller][install], and the [External Secrets Operator][eso-install]. 10 | 11 | > NOTE: Provisioned Service support was added to External Secrets in the v0.8.2 release, prior versions are not compatible. 12 | 13 | This sample uses [Carvel Kapp][kapp-install], rather than `kubectl` to install and watch the sample become ready. 14 | 15 | ## Deploy 16 | 17 | Apply the `ExternalSecret`, `SecretStore`, PetClinic workload, MySQL service and connect them with `ServiceBinding`s: 18 | 19 | ```sh 20 | kapp deploy --app servicebinding-sample-external-secrets -f samples/external-secrets 21 | ``` 22 | 23 | When you are done with this sample, all resources in the deploy can be removed by running: 24 | 25 | ```sh 26 | kapp delete --app servicebinding-sample-external-secrets 27 | ``` 28 | 29 | When prompted, you can review the resource about to be created (updated or deleted) and approve them, or add `--yes` to the above commands. Resources are [tracked between deploys](https://carvel.dev/kapp/docs/latest/diff/), if a resource is removed from the file it will be removed from the cluster on the next deploy. 30 | 31 | Kapp will monitor the [health of the resources](https://carvel.dev/kapp/docs/latest/apply-waiting/) it creates and exit when they become ready, or fail to become ready. The startup [logs from our workload](https://carvel.dev/kapp/docs/latest/apply/#kappk14siodeploy-logs) will also be displayed. 32 | 33 | ## Understand 34 | 35 | Inspect the `ExternalSecret`: 36 | 37 | ```sh 38 | kubectl describe externalsecrets.external-secrets.io eso-example 39 | ``` 40 | 41 | If the `ExternalSecret` is working, a new `Secret` is created and the name of that `Secret` is reflected on the status. 42 | The describe output will contain: 43 | 44 | ```txt 45 | ... 46 | Status: 47 | Binding: 48 | Name: eso-example-db 49 | ... 50 | ``` 51 | 52 | The `ServiceBinding` for the PetClinic workload references the `ExternalSecret` resource to discover the binding `Secret` exposed. The [Spring PetClinic sample](../spring-petclinic/) goes into deeper detail for how a Spring Boot workload can consume service bindings at runtime. 53 | 54 | ```sh 55 | kubectl describe servicebindings.servicebinding.io eso-example 56 | ``` 57 | 58 | ```txt 59 | Spec: 60 | Service: 61 | API Version: external-secrets.io/v1beta1 62 | Kind: ExternalSecret 63 | Name: eso-example-db 64 | ``` 65 | 66 | Additional, the `ServiceBinding` for the MySQL database projects environment variables since the MySQL image is not natively aware of service bindings. 67 | 68 | ```sh 69 | kubectl describe servicebindings.servicebinding.io eso-example-db 70 | ``` 71 | 72 | ```txt 73 | ... 74 | Spec: 75 | Env: 76 | - Key: username 77 | Name: MYSQL_USER 78 | - Key: password 79 | Name: MYSQL_PASSWORD 80 | - Key: database 81 | Name: MYSQL_DATABASE 82 | ... 83 | ``` 84 | 85 | ## Play 86 | 87 | A key advantage of referencing a Provisioned Service resources over directly referencing the binding `Secret`, is that the name of the `Secret` referenced can be updated at any time, bound workloads will automatically receive the updated `Secret`. 88 | 89 | Try updating the `ExternalSecret` to manage the `Secret` under a different name. 90 | 91 | ```sh 92 | kubectl patch externalsecrets.external-secrets.io eso-example-db --type json --patch '[{"op": "replace", "path": "/spec/target/name", "value":"my-new-super-duper-secret"}]' 93 | ``` 94 | 95 | Look at the `ExternalSecret` status and the `Deployment`s to see that they have been updated to use the `my-new-super-duper-secret` secret. 96 | 97 | [eso]: https://external-secrets.io/ 98 | [eso-install]: https://external-secrets.io/v0.8.2/introduction/getting-started/ 99 | [install]: ../../README.md#getting-started 100 | [kapp-install]: https://carvel.dev/kapp/ 101 | [petclinic]: https://github.com/spring-projects/spring-petclinic 102 | -------------------------------------------------------------------------------- /samples/controlled-resource/README.md: -------------------------------------------------------------------------------- 1 | # Controlled Resource 2 | 3 | Sometimes a the workload resource you create is not PodSpec-able, but it creates a child resource that is. In cases like this, we can inject into the child resource. Normally, it is not possible to mutate a controlled resource, as the controller should see the mutation and undo the change, however, `ServiceBinding`s are able to inject into controlled resources and keep the injected values in sync. 4 | 5 | This behavior may not be portable across other service binding implementations. 6 | 7 | ## Setup 8 | 9 | If not already installed, [install the ServiceBinding CRD and controller][install]. 10 | 11 | For this sample, we'll also need [Knative Serving][knative-install]. 12 | 13 | ## Deploy 14 | 15 | Apply the custom workload, service and connect them with a `ServiceBinding`: 16 | 17 | ```sh 18 | kubectl apply -f ./samples/controlled-resource 19 | ``` 20 | 21 | ## Understand 22 | 23 | The workload.yaml defines a Knative `Service`, which in turn controls a Knative `Configuration`. 24 | The `ServiceBinding`'s workload reference targets the `Configuration`, instead of the `Service`. 25 | 26 | > Note: the Knative `Service` and `Configuration` resources are both PodSpec-able, and can both be the target of a service binding. Typically, a binding would target the service instead of the configuration resource. We're targeting the configuration in this sample to demonstrate targeting a controlled resource. 27 | 28 | The workload reference is using a label selector to match the target configuration. Label selectors are useful when a binding needs to target multiple resources, or the name of the target resource is not known. Controllers may generate multiple child resources, or use a generated name which will not be known in advance. 29 | 30 | We can see the binding applied to the Knative `Configuration`. 31 | 32 | ```sh 33 | kubectl describe configurations.serving.knative.dev -l serving.knative.dev/service=controlled-resource 34 | ``` 35 | 36 | It will contain an environment variable `TARGET` provided by the binding. 37 | 38 | ``` 39 | ... 40 | Env: 41 | Name: SERVICE_BINDING_ROOT 42 | Value: /bindings 43 | Name: TARGET 44 | Value From: 45 | Secret Key Ref: 46 | Key: target 47 | Name: controlled-resource 48 | ... 49 | ``` 50 | 51 | Try manually editing the configuration to add a new environment variable. 52 | 53 | ```sh 54 | kubectl edit configurations.serving.knative.dev controlled-resource 55 | ``` 56 | 57 | The new value will be removed by the Knative controller. 58 | This is normal for controlled resources. 59 | The service binding is able to inject into controlled resources because it hooks directly into the cluster's API server via a mutating webhook. 60 | The webhook is able to intercept requests from the Knative controller and transparently reapplies the binding, preventing the controller from removing the injected values. 61 | 62 | Knative resources are not exposed by default for binding, This sample includes a ClusterRole that grants the controller access to project the service into Knative Serving resources. ClusterRoles that include the `servicebinding.io/controller: "true"` label are automatically available to the Service Binding Runtime. 63 | 64 | ## Play 65 | 66 | Try invoking the Knative Service to view the message injected by the service binding 67 | 68 | ```sh 69 | kubectl get ksvc controlled-resource --output=custom-columns=NAME:.metadata.name,URL:.status.url 70 | ``` 71 | 72 | Assuming ingress is properly configured, an invocable URL will be returned for the controlled-resource service. 73 | 74 | ``` 75 | NAME URL 76 | controlled-resource http://controlled-resource.default.{YOUR_CLUSTERS_HOSTNAME} 77 | ``` 78 | 79 | Make a request to the service. 80 | 81 | ```sh 82 | curl http://controlled-resource.default.{YOUR_CLUSTERS_HOSTNAME} 83 | Hello service binding! 84 | ``` 85 | 86 | Going further, try changing the message in the controlled-resource `Secret`. 87 | While values in the volume are updated in a running container, an environment variable will only be updated when a new Pod is created. 88 | Because Knative will auto-scale workloads based on requests, new Pods will be created over time, but exactly when is highly dependant on the load. 89 | 90 | 91 | [knative-install]: https://knative.dev/docs/install/yaml-install/serving/install-serving-with-yaml/ 92 | [install]: ../../README.md#getting-started 93 | -------------------------------------------------------------------------------- /apis/v1/clusterworkloadresourcemapping_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Original Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1 18 | 19 | import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 20 | 21 | // ClusterWorkloadResourceMappingTemplate defines the mapping for a specific version of an workload resource to a 22 | // logical PodTemplateSpec-like structure. 23 | type ClusterWorkloadResourceMappingTemplate struct { 24 | // Version is the version of the workload resource that this mapping is for. 25 | Version string `json:"version"` 26 | // Annotations is a Restricted JSONPath that references the annotations map within the workload resource. These 27 | // annotations must end up in the resulting Pod, and are generally not the workload resource's annotations. 28 | // Defaults to `.spec.template.metadata.annotations`. 29 | Annotations string `json:"annotations,omitempty"` 30 | // Containers is the collection of mappings to container-like fragments of the workload resource. Defaults to 31 | // mappings appropriate for a PodSpecable resource. 32 | Containers []ClusterWorkloadResourceMappingContainer `json:"containers,omitempty"` 33 | // Volumes is a Restricted JSONPath that references the slice of volumes within the workload resource. Defaults to 34 | // `.spec.template.spec.volumes`. 35 | Volumes string `json:"volumes,omitempty"` 36 | } 37 | 38 | // ClusterWorkloadResourceMappingContainer defines the mapping for a specific fragment of an workload resource 39 | // to a Container-like structure. 40 | // 41 | // Each mapping defines exactly one path that may match multiple container-like fragments within the workload 42 | // resource. For each object matching the path the name, env and volumeMounts expressions are resolved to find those 43 | // structures. 44 | type ClusterWorkloadResourceMappingContainer struct { 45 | // Path is the JSONPath within the workload resource that matches an existing fragment that is container-like. 46 | Path string `json:"path"` 47 | // Name is a Restricted JSONPath that references the name of the container with the container-like workload resource 48 | // fragment. If not defined, container name filtering is ignored. 49 | Name string `json:"name,omitempty"` 50 | // Env is a Restricted JSONPath that references the slice of environment variables for the container with the 51 | // container-like workload resource fragment. The referenced location is created if it does not exist. Defaults 52 | // to `.envs`. 53 | Env string `json:"env,omitempty"` 54 | // VolumeMounts is a Restricted JSONPath that references the slice of volume mounts for the container with the 55 | // container-like workload resource fragment. The referenced location is created if it does not exist. Defaults 56 | // to `.volumeMounts`. 57 | VolumeMounts string `json:"volumeMounts,omitempty"` 58 | } 59 | 60 | // ClusterWorkloadResourceMappingSpec defines the desired state of ClusterWorkloadResourceMapping 61 | type ClusterWorkloadResourceMappingSpec struct { 62 | // Versions is the collection of versions for a given resource, with mappings. 63 | Versions []ClusterWorkloadResourceMappingTemplate `json:"versions,omitempty"` 64 | } 65 | 66 | // +kubebuilder:object:root=true 67 | // +kubebuilder:resource:scope=Cluster 68 | // +kubebuilder:storageversion 69 | // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 70 | 71 | // ClusterWorkloadResourceMapping is the Schema for the clusterworkloadresourcemappings API 72 | type ClusterWorkloadResourceMapping struct { 73 | metav1.TypeMeta `json:",inline"` 74 | metav1.ObjectMeta `json:"metadata,omitempty"` 75 | 76 | Spec ClusterWorkloadResourceMappingSpec `json:"spec,omitempty"` 77 | } 78 | 79 | // +kubebuilder:object:root=true 80 | 81 | // ClusterWorkloadResourceMappingList contains a list of ClusterWorkloadResourceMapping 82 | type ClusterWorkloadResourceMappingList struct { 83 | metav1.TypeMeta `json:",inline"` 84 | metav1.ListMeta `json:"metadata,omitempty"` 85 | 86 | Items []ClusterWorkloadResourceMapping `json:"items"` 87 | } 88 | 89 | func init() { 90 | SchemeBuilder.Register(&ClusterWorkloadResourceMapping{}, &ClusterWorkloadResourceMappingList{}) 91 | } 92 | -------------------------------------------------------------------------------- /dies/v1/zz_generated.die_test.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | Copyright 2022 the original author or authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by diegen. DO NOT EDIT. 21 | 22 | package v1 23 | 24 | import ( 25 | testingx "testing" 26 | 27 | testing "reconciler.io/dies/testing" 28 | ) 29 | 30 | func TestClusterWorkloadResourceMappingDie_MissingMethods(t *testingx.T) { 31 | die := ClusterWorkloadResourceMappingBlank 32 | ignore := []string{"TypeMeta", "ObjectMeta"} 33 | diff := testing.DieFieldDiff(die).Delete(ignore...) 34 | if diff.Len() != 0 { 35 | t.Errorf("found missing fields for ClusterWorkloadResourceMappingDie: %s", diff.List()) 36 | } 37 | } 38 | 39 | func TestClusterWorkloadResourceMappingSpecDie_MissingMethods(t *testingx.T) { 40 | die := ClusterWorkloadResourceMappingSpecBlank 41 | ignore := []string{} 42 | diff := testing.DieFieldDiff(die).Delete(ignore...) 43 | if diff.Len() != 0 { 44 | t.Errorf("found missing fields for ClusterWorkloadResourceMappingSpecDie: %s", diff.List()) 45 | } 46 | } 47 | 48 | func TestClusterWorkloadResourceMappingTemplateDie_MissingMethods(t *testingx.T) { 49 | die := ClusterWorkloadResourceMappingTemplateBlank 50 | ignore := []string{} 51 | diff := testing.DieFieldDiff(die).Delete(ignore...) 52 | if diff.Len() != 0 { 53 | t.Errorf("found missing fields for ClusterWorkloadResourceMappingTemplateDie: %s", diff.List()) 54 | } 55 | } 56 | 57 | func TestClusterWorkloadResourceMappingContainerDie_MissingMethods(t *testingx.T) { 58 | die := ClusterWorkloadResourceMappingContainerBlank 59 | ignore := []string{} 60 | diff := testing.DieFieldDiff(die).Delete(ignore...) 61 | if diff.Len() != 0 { 62 | t.Errorf("found missing fields for ClusterWorkloadResourceMappingContainerDie: %s", diff.List()) 63 | } 64 | } 65 | 66 | func TestServiceBindingDie_MissingMethods(t *testingx.T) { 67 | die := ServiceBindingBlank 68 | ignore := []string{"TypeMeta", "ObjectMeta"} 69 | diff := testing.DieFieldDiff(die).Delete(ignore...) 70 | if diff.Len() != 0 { 71 | t.Errorf("found missing fields for ServiceBindingDie: %s", diff.List()) 72 | } 73 | } 74 | 75 | func TestServiceBindingSpecDie_MissingMethods(t *testingx.T) { 76 | die := ServiceBindingSpecBlank 77 | ignore := []string{} 78 | diff := testing.DieFieldDiff(die).Delete(ignore...) 79 | if diff.Len() != 0 { 80 | t.Errorf("found missing fields for ServiceBindingSpecDie: %s", diff.List()) 81 | } 82 | } 83 | 84 | func TestServiceBindingWorkloadReferenceDie_MissingMethods(t *testingx.T) { 85 | die := ServiceBindingWorkloadReferenceBlank 86 | ignore := []string{} 87 | diff := testing.DieFieldDiff(die).Delete(ignore...) 88 | if diff.Len() != 0 { 89 | t.Errorf("found missing fields for ServiceBindingWorkloadReferenceDie: %s", diff.List()) 90 | } 91 | } 92 | 93 | func TestServiceBindingServiceReferenceDie_MissingMethods(t *testingx.T) { 94 | die := ServiceBindingServiceReferenceBlank 95 | ignore := []string{} 96 | diff := testing.DieFieldDiff(die).Delete(ignore...) 97 | if diff.Len() != 0 { 98 | t.Errorf("found missing fields for ServiceBindingServiceReferenceDie: %s", diff.List()) 99 | } 100 | } 101 | 102 | func TestEnvMappingDie_MissingMethods(t *testingx.T) { 103 | die := EnvMappingBlank 104 | ignore := []string{} 105 | diff := testing.DieFieldDiff(die).Delete(ignore...) 106 | if diff.Len() != 0 { 107 | t.Errorf("found missing fields for EnvMappingDie: %s", diff.List()) 108 | } 109 | } 110 | 111 | func TestServiceBindingStatusDie_MissingMethods(t *testingx.T) { 112 | die := ServiceBindingStatusBlank 113 | ignore := []string{} 114 | diff := testing.DieFieldDiff(die).Delete(ignore...) 115 | if diff.Len() != 0 { 116 | t.Errorf("found missing fields for ServiceBindingStatusDie: %s", diff.List()) 117 | } 118 | } 119 | 120 | func TestServiceBindingSecretReferenceDie_MissingMethods(t *testingx.T) { 121 | die := ServiceBindingSecretReferenceBlank 122 | ignore := []string{} 123 | diff := testing.DieFieldDiff(die).Delete(ignore...) 124 | if diff.Len() != 0 { 125 | t.Errorf("found missing fields for ServiceBindingSecretReferenceDie: %s", diff.List()) 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /apis/v1alpha3/zz_generated.deepcopy.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | 3 | /* 4 | Copyright 2022 the original author or authors. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | // Code generated by controller-gen. DO NOT EDIT. 20 | 21 | package v1alpha3 22 | 23 | import ( 24 | runtime "k8s.io/apimachinery/pkg/runtime" 25 | ) 26 | 27 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 28 | func (in *ClusterWorkloadResourceMapping) DeepCopyInto(out *ClusterWorkloadResourceMapping) { 29 | *out = *in 30 | out.TypeMeta = in.TypeMeta 31 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 32 | in.Spec.DeepCopyInto(&out.Spec) 33 | } 34 | 35 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterWorkloadResourceMapping. 36 | func (in *ClusterWorkloadResourceMapping) DeepCopy() *ClusterWorkloadResourceMapping { 37 | if in == nil { 38 | return nil 39 | } 40 | out := new(ClusterWorkloadResourceMapping) 41 | in.DeepCopyInto(out) 42 | return out 43 | } 44 | 45 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 46 | func (in *ClusterWorkloadResourceMapping) DeepCopyObject() runtime.Object { 47 | if c := in.DeepCopy(); c != nil { 48 | return c 49 | } 50 | return nil 51 | } 52 | 53 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 54 | func (in *ClusterWorkloadResourceMappingList) DeepCopyInto(out *ClusterWorkloadResourceMappingList) { 55 | *out = *in 56 | out.TypeMeta = in.TypeMeta 57 | in.ListMeta.DeepCopyInto(&out.ListMeta) 58 | if in.Items != nil { 59 | in, out := &in.Items, &out.Items 60 | *out = make([]ClusterWorkloadResourceMapping, len(*in)) 61 | for i := range *in { 62 | (*in)[i].DeepCopyInto(&(*out)[i]) 63 | } 64 | } 65 | } 66 | 67 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterWorkloadResourceMappingList. 68 | func (in *ClusterWorkloadResourceMappingList) DeepCopy() *ClusterWorkloadResourceMappingList { 69 | if in == nil { 70 | return nil 71 | } 72 | out := new(ClusterWorkloadResourceMappingList) 73 | in.DeepCopyInto(out) 74 | return out 75 | } 76 | 77 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 78 | func (in *ClusterWorkloadResourceMappingList) DeepCopyObject() runtime.Object { 79 | if c := in.DeepCopy(); c != nil { 80 | return c 81 | } 82 | return nil 83 | } 84 | 85 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 86 | func (in *ServiceBinding) DeepCopyInto(out *ServiceBinding) { 87 | *out = *in 88 | out.TypeMeta = in.TypeMeta 89 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 90 | in.Spec.DeepCopyInto(&out.Spec) 91 | in.Status.DeepCopyInto(&out.Status) 92 | } 93 | 94 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceBinding. 95 | func (in *ServiceBinding) DeepCopy() *ServiceBinding { 96 | if in == nil { 97 | return nil 98 | } 99 | out := new(ServiceBinding) 100 | in.DeepCopyInto(out) 101 | return out 102 | } 103 | 104 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 105 | func (in *ServiceBinding) DeepCopyObject() runtime.Object { 106 | if c := in.DeepCopy(); c != nil { 107 | return c 108 | } 109 | return nil 110 | } 111 | 112 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 113 | func (in *ServiceBindingList) DeepCopyInto(out *ServiceBindingList) { 114 | *out = *in 115 | out.TypeMeta = in.TypeMeta 116 | in.ListMeta.DeepCopyInto(&out.ListMeta) 117 | if in.Items != nil { 118 | in, out := &in.Items, &out.Items 119 | *out = make([]ServiceBinding, len(*in)) 120 | for i := range *in { 121 | (*in)[i].DeepCopyInto(&(*out)[i]) 122 | } 123 | } 124 | } 125 | 126 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceBindingList. 127 | func (in *ServiceBindingList) DeepCopy() *ServiceBindingList { 128 | if in == nil { 129 | return nil 130 | } 131 | out := new(ServiceBindingList) 132 | in.DeepCopyInto(out) 133 | return out 134 | } 135 | 136 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 137 | func (in *ServiceBindingList) DeepCopyObject() runtime.Object { 138 | if c := in.DeepCopy(); c != nil { 139 | return c 140 | } 141 | return nil 142 | } 143 | -------------------------------------------------------------------------------- /apis/v1beta1/zz_generated.deepcopy.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | 3 | /* 4 | Copyright 2022 the original author or authors. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | // Code generated by controller-gen. DO NOT EDIT. 20 | 21 | package v1beta1 22 | 23 | import ( 24 | runtime "k8s.io/apimachinery/pkg/runtime" 25 | ) 26 | 27 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 28 | func (in *ClusterWorkloadResourceMapping) DeepCopyInto(out *ClusterWorkloadResourceMapping) { 29 | *out = *in 30 | out.TypeMeta = in.TypeMeta 31 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 32 | in.Spec.DeepCopyInto(&out.Spec) 33 | } 34 | 35 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterWorkloadResourceMapping. 36 | func (in *ClusterWorkloadResourceMapping) DeepCopy() *ClusterWorkloadResourceMapping { 37 | if in == nil { 38 | return nil 39 | } 40 | out := new(ClusterWorkloadResourceMapping) 41 | in.DeepCopyInto(out) 42 | return out 43 | } 44 | 45 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 46 | func (in *ClusterWorkloadResourceMapping) DeepCopyObject() runtime.Object { 47 | if c := in.DeepCopy(); c != nil { 48 | return c 49 | } 50 | return nil 51 | } 52 | 53 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 54 | func (in *ClusterWorkloadResourceMappingList) DeepCopyInto(out *ClusterWorkloadResourceMappingList) { 55 | *out = *in 56 | out.TypeMeta = in.TypeMeta 57 | in.ListMeta.DeepCopyInto(&out.ListMeta) 58 | if in.Items != nil { 59 | in, out := &in.Items, &out.Items 60 | *out = make([]ClusterWorkloadResourceMapping, len(*in)) 61 | for i := range *in { 62 | (*in)[i].DeepCopyInto(&(*out)[i]) 63 | } 64 | } 65 | } 66 | 67 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterWorkloadResourceMappingList. 68 | func (in *ClusterWorkloadResourceMappingList) DeepCopy() *ClusterWorkloadResourceMappingList { 69 | if in == nil { 70 | return nil 71 | } 72 | out := new(ClusterWorkloadResourceMappingList) 73 | in.DeepCopyInto(out) 74 | return out 75 | } 76 | 77 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 78 | func (in *ClusterWorkloadResourceMappingList) DeepCopyObject() runtime.Object { 79 | if c := in.DeepCopy(); c != nil { 80 | return c 81 | } 82 | return nil 83 | } 84 | 85 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 86 | func (in *ServiceBinding) DeepCopyInto(out *ServiceBinding) { 87 | *out = *in 88 | out.TypeMeta = in.TypeMeta 89 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 90 | in.Spec.DeepCopyInto(&out.Spec) 91 | in.Status.DeepCopyInto(&out.Status) 92 | } 93 | 94 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceBinding. 95 | func (in *ServiceBinding) DeepCopy() *ServiceBinding { 96 | if in == nil { 97 | return nil 98 | } 99 | out := new(ServiceBinding) 100 | in.DeepCopyInto(out) 101 | return out 102 | } 103 | 104 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 105 | func (in *ServiceBinding) DeepCopyObject() runtime.Object { 106 | if c := in.DeepCopy(); c != nil { 107 | return c 108 | } 109 | return nil 110 | } 111 | 112 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 113 | func (in *ServiceBindingList) DeepCopyInto(out *ServiceBindingList) { 114 | *out = *in 115 | out.TypeMeta = in.TypeMeta 116 | in.ListMeta.DeepCopyInto(&out.ListMeta) 117 | if in.Items != nil { 118 | in, out := &in.Items, &out.Items 119 | *out = make([]ServiceBinding, len(*in)) 120 | for i := range *in { 121 | (*in)[i].DeepCopyInto(&(*out)[i]) 122 | } 123 | } 124 | } 125 | 126 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceBindingList. 127 | func (in *ServiceBindingList) DeepCopy() *ServiceBindingList { 128 | if in == nil { 129 | return nil 130 | } 131 | out := new(ServiceBindingList) 132 | in.DeepCopyInto(out) 133 | return out 134 | } 135 | 136 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 137 | func (in *ServiceBindingList) DeepCopyObject() runtime.Object { 138 | if c := in.DeepCopy(); c != nil { 139 | return c 140 | } 141 | return nil 142 | } 143 | -------------------------------------------------------------------------------- /resolver/cluster.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 the original author or authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resolver 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | 23 | apierrs "k8s.io/apimachinery/pkg/api/errors" 24 | "k8s.io/apimachinery/pkg/api/meta" 25 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 27 | "k8s.io/apimachinery/pkg/labels" 28 | "k8s.io/apimachinery/pkg/runtime" 29 | "k8s.io/apimachinery/pkg/runtime/schema" 30 | "k8s.io/apimachinery/pkg/types" 31 | "sigs.k8s.io/controller-runtime/pkg/client" 32 | "sigs.k8s.io/controller-runtime/pkg/client/apiutil" 33 | 34 | servicebindingv1 "github.com/servicebinding/runtime/apis/v1" 35 | ) 36 | 37 | // New creates a new resolver backed by a controller-runtime client 38 | func New(client client.Client) Resolver { 39 | return &clusterResolver{ 40 | client: client, 41 | } 42 | } 43 | 44 | type clusterResolver struct { 45 | client client.Client 46 | } 47 | 48 | func (m *clusterResolver) LookupRESTMapping(ctx context.Context, obj runtime.Object) (*meta.RESTMapping, error) { 49 | gvk, err := apiutil.GVKForObject(obj, m.client.Scheme()) 50 | if err != nil { 51 | return nil, err 52 | } 53 | rm, err := m.client.RESTMapper().RESTMapping(gvk.GroupKind(), gvk.Version) 54 | if err != nil { 55 | return nil, err 56 | } 57 | return rm, nil 58 | } 59 | 60 | func (m *clusterResolver) LookupWorkloadMapping(ctx context.Context, gvr schema.GroupVersionResource) (*servicebindingv1.ClusterWorkloadResourceMappingSpec, error) { 61 | wrm := &servicebindingv1.ClusterWorkloadResourceMapping{} 62 | 63 | if err := m.client.Get(ctx, types.NamespacedName{Name: fmt.Sprintf("%s.%s", gvr.Resource, gvr.Group)}, wrm); err != nil { 64 | if !apierrs.IsNotFound(err) { 65 | return nil, err 66 | } 67 | wrm.Spec = servicebindingv1.ClusterWorkloadResourceMappingSpec{ 68 | Versions: []servicebindingv1.ClusterWorkloadResourceMappingTemplate{ 69 | { 70 | Version: "*", 71 | }, 72 | }, 73 | } 74 | } 75 | 76 | for i := range wrm.Spec.Versions { 77 | wrm.Spec.Versions[i].Default() 78 | } 79 | 80 | return &wrm.Spec, nil 81 | } 82 | 83 | func (r *clusterResolver) LookupBindingSecret(ctx context.Context, serviceBinding *servicebindingv1.ServiceBinding) (string, error) { 84 | serviceRef := serviceBinding.Spec.Service 85 | if serviceRef.APIVersion == "v1" && serviceRef.Kind == "Secret" { 86 | // direct secret reference 87 | return serviceRef.Name, nil 88 | } 89 | service := &unstructured.Unstructured{} 90 | service.SetAPIVersion(serviceRef.APIVersion) 91 | service.SetKind(serviceRef.Kind) 92 | if err := r.client.Get(ctx, client.ObjectKey{Namespace: serviceBinding.Namespace, Name: serviceRef.Name}, service); err != nil { 93 | return "", err 94 | } 95 | secretName, exists, err := unstructured.NestedString(service.UnstructuredContent(), "status", "binding", "name") 96 | // treat missing values as empty 97 | _ = exists 98 | return secretName, err 99 | } 100 | 101 | const ( 102 | mappingAnnotationPrefix = "projector.servicebinding.io/mapping-" 103 | ) 104 | 105 | func (r *clusterResolver) LookupWorkloads(ctx context.Context, serviceBinding *servicebindingv1.ServiceBinding) ([]runtime.Object, error) { 106 | workloadRef := serviceBinding.Spec.Workload 107 | 108 | list := &unstructured.UnstructuredList{} 109 | list.SetAPIVersion(workloadRef.APIVersion) 110 | // TODO this is unsafe if the ListKind doesn't follow this convention 111 | list.SetKind(fmt.Sprintf("%sList", workloadRef.Kind)) 112 | 113 | var ls labels.Selector 114 | if workloadRef.Selector != nil { 115 | var err error 116 | ls, err = metav1.LabelSelectorAsSelector(workloadRef.Selector) 117 | if err != nil { 118 | return nil, err 119 | } 120 | } 121 | 122 | if err := r.client.List(ctx, list, client.InNamespace(serviceBinding.Namespace)); err != nil { 123 | return nil, err 124 | } 125 | workloads := []runtime.Object{} 126 | for i := range list.Items { 127 | workload := &list.Items[i] 128 | if annotations := workload.GetAnnotations(); annotations != nil { 129 | if _, ok := annotations[fmt.Sprintf("%s%s", mappingAnnotationPrefix, serviceBinding.UID)]; ok { 130 | workloads = append(workloads, workload) 131 | continue 132 | } 133 | } 134 | if workloadRef.Name != "" { 135 | if workload.GetName() == workloadRef.Name { 136 | workloads = append(workloads, workload) 137 | } 138 | continue 139 | } 140 | if ls.Matches(labels.Set(workload.GetLabels())) { 141 | workloads = append(workloads, workload) 142 | } 143 | } 144 | 145 | return workloads, nil 146 | } 147 | -------------------------------------------------------------------------------- /apis/v1/servicebinding_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Original Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package v1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // ServiceBindingWorkloadReference defines a subset of corev1.ObjectReference with extensions 24 | type ServiceBindingWorkloadReference struct { 25 | // API version of the referent. 26 | APIVersion string `json:"apiVersion"` 27 | // Kind of the referent. 28 | // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 29 | Kind string `json:"kind"` 30 | // Name of the referent. 31 | // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 32 | Name string `json:"name,omitempty"` 33 | // Selector is a query that selects the workload or workloads to bind the service to 34 | Selector *metav1.LabelSelector `json:"selector,omitempty"` 35 | // Containers describes which containers in a Pod should be bound to 36 | Containers []string `json:"containers,omitempty"` 37 | } 38 | 39 | // ServiceBindingServiceReference defines a subset of corev1.ObjectReference 40 | type ServiceBindingServiceReference struct { 41 | // API version of the referent. 42 | APIVersion string `json:"apiVersion"` 43 | // Kind of the referent. 44 | // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 45 | Kind string `json:"kind"` 46 | // Name of the referent. 47 | // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 48 | Name string `json:"name"` 49 | } 50 | 51 | // ServiceBindingSecretReference defines a mirror of corev1.LocalObjectReference 52 | type ServiceBindingSecretReference struct { 53 | // Name of the referent secret. 54 | // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 55 | Name string `json:"name"` 56 | } 57 | 58 | // EnvMapping defines a mapping from the value of a Secret entry to an environment variable 59 | type EnvMapping struct { 60 | // Name is the name of the environment variable 61 | Name string `json:"name"` 62 | // Key is the key in the Secret that will be exposed 63 | Key string `json:"key"` 64 | } 65 | 66 | // ServiceBindingSpec defines the desired state of ServiceBinding 67 | type ServiceBindingSpec struct { 68 | // Name is the name of the service as projected into the workload container. Defaults to .metadata.name. 69 | Name string `json:"name,omitempty"` 70 | // Type is the type of the service as projected into the workload container 71 | Type string `json:"type,omitempty"` 72 | // Provider is the provider of the service as projected into the workload container 73 | Provider string `json:"provider,omitempty"` 74 | // Workload is a reference to an object 75 | Workload ServiceBindingWorkloadReference `json:"workload"` 76 | // Service is a reference to an object that fulfills the ProvisionedService duck type 77 | Service ServiceBindingServiceReference `json:"service"` 78 | // Env is the collection of mappings from Secret entries to environment variables 79 | Env []EnvMapping `json:"env,omitempty"` 80 | } 81 | 82 | // ServiceBindingStatus defines the observed state of ServiceBinding 83 | type ServiceBindingStatus struct { 84 | // ObservedGeneration is the 'Generation' of the ServiceBinding that 85 | // was last processed by the controller. 86 | ObservedGeneration int64 `json:"observedGeneration,omitempty"` 87 | 88 | // Conditions are the conditions of this ServiceBinding 89 | Conditions []metav1.Condition `json:"conditions,omitempty"` 90 | 91 | // Binding exposes the projected secret for this ServiceBinding 92 | Binding *ServiceBindingSecretReference `json:"binding,omitempty"` 93 | } 94 | 95 | // +kubebuilder:object:root=true 96 | // +kubebuilder:storageversion 97 | // +kubebuilder:subresource:status 98 | // +kubebuilder:printcolumn:name="Secret",type=string,JSONPath=`.status.binding.name` 99 | // +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status` 100 | // +kubebuilder:printcolumn:name="Reason",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].reason` 101 | // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 102 | 103 | // ServiceBinding is the Schema for the servicebindings API 104 | type ServiceBinding struct { 105 | metav1.TypeMeta `json:",inline"` 106 | metav1.ObjectMeta `json:"metadata,omitempty"` 107 | 108 | Spec ServiceBindingSpec `json:"spec,omitempty"` 109 | Status ServiceBindingStatus `json:"status,omitempty"` 110 | } 111 | 112 | // +kubebuilder:object:root=true 113 | 114 | // ServiceBindingList contains a list of ServiceBinding 115 | type ServiceBindingList struct { 116 | metav1.TypeMeta `json:",inline"` 117 | metav1.ListMeta `json:"metadata,omitempty"` 118 | 119 | Items []ServiceBinding `json:"items"` 120 | } 121 | 122 | func init() { 123 | SchemeBuilder.Register(&ServiceBinding{}, &ServiceBindingList{}) 124 | } 125 | -------------------------------------------------------------------------------- /hack/kube-rbac-proxy/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/runtime/hack/kube-rbac-proxy 2 | 3 | go 1.24.9 4 | 5 | require ( 6 | github.com/brancz/kube-rbac-proxy v0.20.1 7 | k8s.io/component-base v0.34.3 8 | ) 9 | 10 | require ( 11 | cel.dev/expr v0.24.0 // indirect 12 | github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect 13 | github.com/NYTimes/gziphandler v1.1.1 // indirect 14 | github.com/antlr4-go/antlr/v4 v4.13.0 // indirect 15 | github.com/beorn7/perks v1.0.1 // indirect 16 | github.com/blang/semver/v4 v4.0.0 // indirect 17 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect 18 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 19 | github.com/coreos/go-oidc v2.3.0+incompatible // indirect 20 | github.com/coreos/go-semver v0.3.1 // indirect 21 | github.com/coreos/go-systemd/v22 v22.5.0 // indirect 22 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 23 | github.com/emicklei/go-restful/v3 v3.12.2 // indirect 24 | github.com/felixge/httpsnoop v1.0.4 // indirect 25 | github.com/fsnotify/fsnotify v1.9.0 // indirect 26 | github.com/fxamacker/cbor/v2 v2.9.0 // indirect 27 | github.com/ghodss/yaml v1.0.0 // indirect 28 | github.com/go-logr/logr v1.4.3 // indirect 29 | github.com/go-logr/stdr v1.2.2 // indirect 30 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 31 | github.com/go-openapi/jsonreference v0.20.2 // indirect 32 | github.com/go-openapi/swag v0.23.0 // indirect 33 | github.com/gogo/protobuf v1.3.2 // indirect 34 | github.com/golang/protobuf v1.5.4 // indirect 35 | github.com/google/btree v1.1.3 // indirect 36 | github.com/google/cel-go v0.26.0 // indirect 37 | github.com/google/gnostic-models v0.7.0 // indirect 38 | github.com/google/go-cmp v0.7.0 // indirect 39 | github.com/google/uuid v1.6.0 // indirect 40 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect 41 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect 42 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 43 | github.com/josharian/intern v1.0.0 // indirect 44 | github.com/json-iterator/go v1.1.12 // indirect 45 | github.com/kylelemons/godebug v1.1.0 // indirect 46 | github.com/mailru/easyjson v0.7.7 // indirect 47 | github.com/moby/term v0.5.0 // indirect 48 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 49 | github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect 50 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 51 | github.com/oklog/run v1.2.0 // indirect 52 | github.com/pkg/errors v0.9.1 // indirect 53 | github.com/pmezard/go-difflib v1.0.0 // indirect 54 | github.com/pquerna/cachecontrol v0.1.0 // indirect 55 | github.com/prometheus/client_golang v1.22.0 // indirect 56 | github.com/prometheus/client_model v0.6.1 // indirect 57 | github.com/prometheus/common v0.62.0 // indirect 58 | github.com/prometheus/procfs v0.15.1 // indirect 59 | github.com/spf13/cobra v1.10.1 // indirect 60 | github.com/spf13/pflag v1.0.10 // indirect 61 | github.com/stoewer/go-strcase v1.3.0 // indirect 62 | github.com/x448/float16 v0.8.4 // indirect 63 | go.etcd.io/etcd/api/v3 v3.6.4 // indirect 64 | go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect 65 | go.etcd.io/etcd/client/v3 v3.6.4 // indirect 66 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect 67 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect 68 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect 69 | go.opentelemetry.io/otel v1.35.0 // indirect 70 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect 71 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect 72 | go.opentelemetry.io/otel/metric v1.35.0 // indirect 73 | go.opentelemetry.io/otel/sdk v1.34.0 // indirect 74 | go.opentelemetry.io/otel/trace v1.35.0 // indirect 75 | go.opentelemetry.io/proto/otlp v1.5.0 // indirect 76 | go.uber.org/multierr v1.11.0 // indirect 77 | go.uber.org/zap v1.27.0 // indirect 78 | go.yaml.in/yaml/v2 v2.4.2 // indirect 79 | go.yaml.in/yaml/v3 v3.0.4 // indirect 80 | golang.org/x/crypto v0.45.0 // indirect 81 | golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect 82 | golang.org/x/net v0.47.0 // indirect 83 | golang.org/x/oauth2 v0.27.0 // indirect 84 | golang.org/x/sync v0.18.0 // indirect 85 | golang.org/x/sys v0.38.0 // indirect 86 | golang.org/x/term v0.37.0 // indirect 87 | golang.org/x/text v0.31.0 // indirect 88 | golang.org/x/time v0.9.0 // indirect 89 | google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect 90 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect 91 | google.golang.org/grpc v1.72.1 // indirect 92 | google.golang.org/protobuf v1.36.5 // indirect 93 | gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect 94 | gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect 95 | gopkg.in/inf.v0 v0.9.1 // indirect 96 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect 97 | gopkg.in/yaml.v2 v2.4.0 // indirect 98 | gopkg.in/yaml.v3 v3.0.1 // indirect 99 | k8s.io/api v0.34.3 // indirect 100 | k8s.io/apimachinery v0.34.3 // indirect 101 | k8s.io/apiserver v0.34.2 // indirect 102 | k8s.io/client-go v0.34.3 // indirect 103 | k8s.io/klog/v2 v2.130.1 // indirect 104 | k8s.io/kms v0.34.2 // indirect 105 | k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect 106 | k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect 107 | sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect 108 | sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect 109 | sigs.k8s.io/randfill v1.0.0 // indirect 110 | sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect 111 | sigs.k8s.io/yaml v1.6.0 // indirect 112 | ) 113 | --------------------------------------------------------------------------------