├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── extensions ├── README.md └── secret-generation.md ├── internal ├── .gitignore ├── Makefile ├── go.mod ├── go.sum ├── servicebinding.io │ └── v1 │ │ ├── cluster_workload_resource_mapping.go │ │ ├── group_version.go │ │ └── service_binding.go └── tools.go ├── servicebinding.io_clusterworkloadresourcemappings.yaml └── servicebinding.io_servicebindings.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, caste, color, religion, or sexual 10 | identity and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or advances of 31 | any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email address, 35 | without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | bhale@vmware.com or arthurdm@ca.ibm.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series of 86 | actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or permanent 93 | ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within the 113 | community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.1, available at 119 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 120 | 121 | Community Impact Guidelines were inspired by 122 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 123 | 124 | For answers to common questions about this code of conduct, see the FAQ at 125 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 126 | [https://www.contributor-covenant.org/translations][translations]. 127 | 128 | [homepage]: https://www.contributor-covenant.org 129 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 130 | [Mozilla CoC]: https://github.com/mozilla/diversity 131 | [FAQ]: https://www.contributor-covenant.org/faq 132 | [translations]: https://www.contributor-covenant.org/translations 133 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | :+1::tada: First off, thanks for taking the time to contribute! :tada::+1: 4 | 5 | The Service Binding project is a community lead effort. A bi-weekly [working group call][working-group] is open to the public. Discussions occur here on GitHub and on the [#bindings-discuss channel in the Kubernetes Slack][slack]. 6 | 7 | [working-group]: https://docs.google.com/document/d/1rR0qLpsjU38nRXxeich7F5QUy73RHJ90hnZiFIQ-JJ8/edit#heading=h.ar8ibc31ux6f 8 | [slack]: https://kubernetes.slack.com/archives/C012F2GPMTQ 9 | 10 | There are multiple Git repositories under the [`servicebinding` GitHub organization](https://github.com/servicebinding). 11 | 12 | - [spec](https://github.com/servicebinding/spec) - The latest actively developing working copy of the spec. 13 | - [service-binding-controller](https://github.com/servicebinding/service-binding-controller) - The reference implementation of the spec. 14 | - [website](https://github.com/servicebinding/website) - The [servicebinding.io](https://servicebinding.io) website content. 15 | - [conformance](https://github.com/servicebinding/conformance) - The conformace test suite. 16 | 17 | 18 | If you catch an error, please let us know by opening an issue or pull request in the related GitHub repository. 19 | 20 | Please note we have a [code of conduct][conduct], please follow it in all your interactions with the project. 21 | 22 | Contributions to this project should conform to the [Developer Certificate of Origin][dco]. See the [next section](#sign-your-work) for more details. 23 | 24 | ## Sign Your Work 25 | 26 | Contributions to this project should conform to the [Developer Certificate of Origin][dco]. You need to sign-off your git commits before sending the pull requests. The sign-off is a single line of text at the end of the commit message. The signature consists of your official name and email address. These two details should match with the name and email address used in the Git commit. All your commits need to be signed. Your signature certifies that you wrote the patch or otherwise have the right to contribute the material. The rules are pretty simple, if you can certify the below (from 27 | [developercertificate.org][dco]): 28 | 29 | ``` 30 | Developer Certificate of Origin 31 | Version 1.1 32 | 33 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 34 | 1 Letterman Drive 35 | Suite D4700 36 | San Francisco, CA, 94129 37 | 38 | Everyone is permitted to copy and distribute verbatim copies of this 39 | license document, but changing it is not allowed. 40 | 41 | 42 | Developer's Certificate of Origin 1.1 43 | 44 | By making a contribution to this project, I certify that: 45 | 46 | (a) The contribution was created in whole or in part by me and I 47 | have the right to submit it under the open source license 48 | indicated in the file; or 49 | 50 | (b) The contribution is based upon previous work that, to the best 51 | of my knowledge, is covered under an appropriate open source 52 | license and I have the right under that license to submit that 53 | work with modifications, whether created in whole or in part 54 | by me, under the same open source license (unless I am 55 | permitted to submit under a different license), as indicated 56 | in the file; or 57 | 58 | (c) The contribution was provided directly to me by some other 59 | person who certified (a), (b) or (c) and I have not modified 60 | it. 61 | 62 | (d) I understand and agree that this project and the contribution 63 | are public and that a record of the contribution (including all 64 | personal information I submit with it, including my sign-off) is 65 | maintained indefinitely and may be redistributed consistent with 66 | this project or the open source license(s) involved. 67 | ``` 68 | 69 | Then you just add a line to every git commit message: 70 | 71 | Signed-off-by: Joe Smith 72 | 73 | Use your real name (sorry, no pseudonyms or anonymous contributions.) 74 | 75 | If you set your `user.name` and `user.email` git configs, you can sign your commit automatically with `git commit -s`. 76 | 77 | Note: If your git config information is set properly then viewing the `git log` information for your commit will look something like this: 78 | 79 | ``` 80 | Author: Joe Smith 81 | Date: Thu Feb 2 11:41:15 2018 -0800 82 | 83 | Update README 84 | 85 | Signed-off-by: Joe Smith 86 | ``` 87 | 88 | Notice the `Author` and `Signed-off-by` lines match. If they don't your PR will be rejected by the automated DCO check. 89 | 90 | ## Pull Request Workflow 91 | 92 | - Fork the repository and clone it your work directory 93 | - Create a topic branch from where you want to base your work 94 | - This is usually the `main` branch. 95 | - Only target release branches if you are certain your fix must be on that 96 | branch. 97 | - To quickly create a topic branch based on `main`; ``git checkout -b 98 | my-bug-fix upstream/main`` (Here `upstream` is alias for the remote repo) 99 | - Make commits of logical units 100 | - Make sure your commit messages are in [the proper format][commit-message]. 101 | Also include any related GitHub issue references in the commit message. 102 | - Push your changes to a topic branch in your fork of the repository 103 | - Submit a pull request 104 | 105 | Example: 106 | 107 | ```shell 108 | git remote add upstream https://github.com/servicebinding/.git 109 | git fetch upstream 110 | git checkout -b my-bug-fix upstream/main 111 | git commit -a 112 | git push origin my-bug-fix 113 | ``` 114 | 115 | ### Staying in sync with upstream 116 | 117 | When your branch gets out of sync with the `upstream/main` branch, use the 118 | following to update: 119 | 120 | ``` shell 121 | git checkout my-bug-fix 122 | git fetch upstream 123 | git rebase upstream/main 124 | git push --force-with-lease origin my-bug-fix 125 | ``` 126 | 127 | ### Updating pull requests 128 | 129 | If your PR fails to pass CI or needs changes based on code review, you'll most 130 | likely want to squash these changes into existing commits. 131 | 132 | If your pull request contains a single commit or your changes are related to the 133 | most recent commit, you can simply amend the commit. 134 | 135 | ``` 136 | git add . 137 | git commit --amend 138 | git push --force-with-lease origin my-bug-fix 139 | ``` 140 | 141 | If you need to squash changes into an earlier commit, you can use: 142 | 143 | ``` 144 | git add . 145 | git commit --fixup 146 | git rebase -i --autosquash main 147 | git push --force-with-lease origin my-bug-fix 148 | ``` 149 | 150 | Please add a comment in the PR indicating your new changes are ready to review. 151 | 152 | [conduct]: https://github.com/servicebinding/spec/blob/main/CODE_OF_CONDUCT.md 153 | [dco]: http://developercertificate.org 154 | [commit-message]: https://cbea.ms/git-commit/ 155 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Service Binding Specification for Kubernetes 2 | 3 | Today in Kubernetes, the exposure of secrets for connecting application workloads to external services such as REST APIs, databases, event buses, and many more is manual and bespoke. Each service provider suggests a different way to access their secrets, and application developers consume these secrets in a way specific to each workload. While there is a good deal of value to this flexibility, large development teams lose overall velocity dealing with each unique solution. To combat this, we see teams adopting internal patterns for how to achieve this workload-to-service linkage. 4 | 5 | This specification aims to create a Kubernetes-wide specification for communicating service secrets to workloads in a consistent way. It aims to create a widely applicable mechanism _without_ excluding other strategies for systems that it does not fit easily. The benefit of Kubernetes-wide specification is that all of the actors in an ecosystem can work towards a clearly defined abstraction at the edge of their expertise and depend on other parties to complete the chain. 6 | 7 | * Application Developers expect their secrets to be presented consistently and predictably within a container. 8 | * Service Providers expect their secrets to be collected and exposed to consumers consistently and predictably. 9 | * Platforms expect to retrieve secrets from Service Providers and expose them to Application Developers consistently and predictably. 10 | 11 | The pattern of Service Binding has prior art in non-Kubernetes platforms. Heroku pioneered this model with [Add-ons][h], and Cloud Foundry adopted similar ideas with their [Services][cf]. Other open source projects like the [Open Service Broker][osb] aim to help with this pattern on those non-Kubernetes platforms. In the Kubernetes ecosystem, the CNCF Sandbox Cloud Native Buildpacks project has proposed a [buildpack-specific specification][cnb] exclusively addressing the application developer portion of this pattern. 12 | 13 | [h]: https://devcenter.heroku.com/articles/add-ons 14 | [cf]: https://docs.cloudfoundry.org/devguide/services/ 15 | [osb]: https://www.openservicebrokerapi.org 16 | [cnb]: https://github.com/buildpacks/spec/blob/master/extensions/bindings.md 17 | 18 | 19 | ## Community, discussion, contribution, and support 20 | 21 | The Service Binding Specification for Kubernetes project is a community lead effort. 22 | A bi-weekly [working group call][working-group] is open to the public. 23 | Discussions occur here on GitHub and on the [#bindings-discuss channel in the Kubernetes Slack][slack]. 24 | 25 | If you catch an error in the specification’s text, or if you write an 26 | implementation, please let us know by opening an issue or pull request at our 27 | [GitHub repository][repo]. 28 | 29 | 30 | ### Code of conduct 31 | 32 | Participation in the Service Binding community is governed by the [Contributor Covenant][code-of-conduct]. 33 | 34 | [working-group]: https://docs.google.com/document/d/1rR0qLpsjU38nRXxeich7F5QUy73RHJ90hnZiFIQ-JJ8/edit#heading=h.ar8ibc31ux6f 35 | [slack]: https://kubernetes.slack.com/archives/C012F2GPMTQ 36 | [repo]: https://github.com/servicebinding/spec 37 | [code-of-conduct]: ./CODE_OF_CONDUCT.md 38 | 39 | --- 40 | 41 | 42 | - [Service Binding Specification for Kubernetes](#service-binding-specification-for-kubernetes) 43 | - [Status](#status) 44 | - [Notational Conventions](#notational-conventions) 45 | - [Terminology definition](#terminology-definition) 46 | - [Provisioned Service](#provisioned-service) 47 | - [Resource Type Schema](#resource-type-schema) 48 | - [Example Resource](#example-resource) 49 | - [Well-known Secret Entries](#well-known-secret-entries) 50 | - [Example Secret](#example-secret) 51 | - [Considerations for Role-Based Access Control (RBAC)](#considerations-for-role-based-access-control-rbac) 52 | - [Example Resource](#example-resource-1) 53 | - [Workload Projection](#workload-projection) 54 | - [Example Directory Structure](#example-directory-structure) 55 | - [Considerations for Role-Based Access Control (RBAC)](#considerations-for-role-based-access-control-rbac-1) 56 | - [Example Resource](#example-resource-2) 57 | - [Service Binding](#service-binding) 58 | - [Resource Type Schema](#resource-type-schema-1) 59 | - [Minimal Example Resource](#minimal-example-resource) 60 | - [Label Selector Example Resource](#label-selector-example-resource) 61 | - [Environment Variables Example Resource](#environment-variables-example-resource) 62 | - [Reconciler Implementation](#reconciler-implementation) 63 | - [Ready Condition Status](#ready-condition-status) 64 | - [ServiceAvailable Condition Status](#serviceavailable-condition-status) 65 | - [Direct Secret Reference](#direct-secret-reference) 66 | - [Direct Secret Reference Example Resource](#direct-secret-reference-example-resource) 67 | - [Workload Resource Mapping](#workload-resource-mapping) 68 | - [Fixed JSONPath](#fixed-jsonpath) 69 | - [Resource Type Schema](#resource-type-schema-2) 70 | - [Example Resource](#example-resource-3) 71 | - [`PodSpec`-able (Default) Example Resource](#podspec-able-default-example-resource) 72 | - [Runtime Behavior](#runtime-behavior) 73 | - [Role-Based Access Control (RBAC)](#role-based-access-control-rbac) 74 | - [Example Resource](#example-resource-4) 75 | 76 | --- 77 | 78 | ## Status 79 | 80 | This document is a working draft of the Service Bindings for Kubernetes specification, representing the collective efforts of the [community](#community). It is published for early implementors and users to provide feedback. [Releases of the specification][releases] are published on the main website. 81 | 82 | [releases]: https://servicebinding.io/#specification 83 | 84 | ## Notational Conventions 85 | 86 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14](https://tools.ietf.org/html/bcp14) [RFC2119](https://tools.ietf.org/html/rfc2119) [RFC8174](https://tools.ietf.org/html/rfc8174) when, and only when, they appear in all capitals, as shown here. 87 | 88 | The key words "unspecified", "undefined", and "implementation-defined" are to be interpreted as described in the [rationale for the C99 standard](http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf#page=18). 89 | 90 | An implementation is not compliant if it fails to satisfy one or more of the MUST, MUST NOT, REQUIRED, SHALL, or SHALL NOT requirements for the protocols it implements. An implementation is compliant if it satisfies all the MUST, MUST NOT, REQUIRED, SHALL, and SHALL NOT requirements for the protocols it implements. 91 | 92 | ## Terminology definition 93 | 94 |
95 |
Duck Type
96 |
Any type that meets the contract defined in a specification, without being an instance of a specific concrete type. For example, for a specification that requires a given key on status, any resource that has that key on its status regardless of its apiVersion or kind would be considered to implement that duck type.
97 | 98 |
Service
99 |
Any software that exposes functionality. Examples include a database, a message broker, a workload with REST endpoints, an event stream, an Application Performance Monitor, or a Hardware Security Module.
100 | 101 |
Workload
102 |
A workload is an application running on Kubernetes. Examples include processing using a framework like Spring Boot, NodeJS Express, or Ruby on Rails. Workloads are the part of an application that runs. Workloads may colloquially be referred to as an application.
103 | 104 |
Service Binding
105 |
The act of or representation of the action of providing information about a Service to a Workload
106 | 107 |
Secret
108 |
A Kubernetes Secret
109 | 110 |
PodSpec-able Duck Type
111 |
A Kubernetes resource where .spec.template attribute conforms to a Kubernetes Pod's spec. Examples of resources include DaemonSet, Deployment, Job, and StatefulSet.
112 |
113 | 114 | # Provisioned Service 115 | 116 | A Provisioned Service resource **MUST** define a `.status.binding` field which is a `LocalObjectReference`-able (containing a single field `name`) to a `Secret`. The `Secret` **MUST** exist in the same namespace as the resource. The `Secret` data **SHOULD** contain a `type` entry with a value that identifies the abstract classification of the binding. The `Secret` type (`.type` verses `.data.type` fields) **SHOULD** reflect this value as `servicebinding.io/{type}`, substituting `{type}` with the `Secret` data type. It is **RECOMMENDED** that the `Secret` data also contain a `provider` entry with a value that identifies the provider of the binding. The `Secret` data **MAY** contain any other entry. To facilitate discoverability, it is **RECOMMENDED** that a `CustomResourceDefinition` exposing a Provisioned Service add `servicebinding.io/provisioned-service: "true"` as a label. 117 | 118 | > Note: While the Provisioned Service referenced `Secret` data should contain a `type` entry, the `type` must be defined as it is projected to a workload. The relaxation of the requirement for provisioned services allows for a mapping to enrich an existing secret. For example, `ServiceBinding` has fields to override `type` and `provider` values. 119 | 120 | Extensions and implementations **MAY** define additional mechanisms to consume a Provisioned Service that does not conform to the duck type. 121 | 122 | ## Resource Type Schema 123 | 124 | ```yaml 125 | status: 126 | binding: 127 | name: # string 128 | ``` 129 | 130 | ## Example Resource 131 | 132 | ```yaml 133 | ... 134 | status: 135 | ... 136 | binding: 137 | name: production-db-secret 138 | ``` 139 | 140 | ## Well-known Secret Entries 141 | 142 | Other than the recommended `type` and `provider` entries, there are no other reserved `Secret` entries. In the interests of consistency, if a `Secret` includes any of the following entry names, the entry value **MUST** meet the specified requirements: 143 | 144 | | Name | Requirements 145 | | ---- | ------------ 146 | | `host` | A DNS-resolvable host name or IP address 147 | | `port` | A valid port number 148 | | `uri` | A valid URI as defined by [RFC3986](https://tools.ietf.org/html/rfc3986) 149 | | `username` | A string-based username credential 150 | | `password` | A string-based password credential 151 | | `certificates` | A collection of PEM-encoded X.509 public certificates, representing a certificate chain used to trust TLS connections 152 | | `private-key` | A PEM-encoded private key used in mTLS client authentication 153 | 154 | `Secret` entries that do not meet these requirements **MUST** use different entry names. 155 | 156 | ## Example Secret 157 | 158 | ```yaml 159 | apiVersion: v1 160 | kind: Secret 161 | metadata: 162 | name: production-db-secret 163 | type: servicebinding.io/mysql 164 | stringData: 165 | type: mysql 166 | provider: bitnami 167 | host: localhost 168 | port: 3306 169 | username: root 170 | password: root 171 | ``` 172 | 173 | ## Considerations for Role-Based Access Control (RBAC) 174 | 175 | Cluster operators and CRD authors **SHOULD** opt-in resources to expose provisioned services by defining a `ClusterRole` with a label matching `servicebinding.io/controller=true`. The `get`, `list`, and `watch` verbs **MUST** be granted in the `ClusterRole`. 176 | 177 | See [Role-Based Access Control (RBAC)](#role-based-access-control-rbac) for how the `ClusterRole` is consumed. 178 | 179 | ### Example Resource 180 | 181 | ```yaml 182 | apiVersion: rbac.authorization.k8s.io/v1 183 | kind: ClusterRole 184 | metadata: 185 | name: awesome-service-bindings 186 | labels: 187 | servicebinding.io/controller: "true" # matches the aggregation rule selector 188 | rules: 189 | - apiGroups: 190 | - awesome.example.com 191 | resources: 192 | - awesomeservices 193 | verbs: 194 | - get 195 | - list 196 | - watch 197 | ``` 198 | 199 | # Workload Projection 200 | 201 | A projected binding **MUST** be volume mounted into a container at `$SERVICE_BINDING_ROOT/` with directory names matching the name of the binding. Binding names **MUST** match `[a-z0-9\-\.]{1,253}`. The `$SERVICE_BINDING_ROOT` environment variable **MUST** be declared and can point to any valid file system location. 202 | 203 | The projected binding **MUST** contain a `type` entry with a value that identifies the abstract classification of the binding. It is **RECOMMENDED** that the projected binding also contain a `provider` entry with a value that identifies the provider of the binding. The projected binding data **MAY** contain any other entry. Directories under `$SERVICE_BINDING_ROOT` that do not contain a `type` entry **SHOULD** be ignored by the workload process at runtime. 204 | 205 | The name of a binding entry file name **SHOULD** match `[a-z0-9\-\.]{1,253}`. The contents of a binding entry may be anything representable as bytes on the file system including, but not limited to, a literal string value (e.g. `db-password`), a language-specific binary (e.g. a Java `KeyStore` with a private key and X.509 certificate), or an indirect pointer to another system for value resolution (e.g. `vault://production-database/password`). 206 | 207 | The collection of files within the directory **MAY** change during the lifetime of the container or between container launches. 208 | 209 | Users **SHOULD** ensure each binding has a unique name. The behavior for name collisions is undefined. Implementations **MAY** attempt a good faith check for collisions to provide a meaningful error message. 210 | 211 | ## Example Directory Structure 212 | 213 | ```plain 214 | $SERVICE_BINDING_ROOT 215 | ├── account-database 216 | │ ├── type 217 | │ ├── provider 218 | │ ├── uri 219 | │ ├── username 220 | │ └── password 221 | └── transaction-event-stream 222 | ├── type 223 | ├── connection-count 224 | ├── uri 225 | ├── certificates 226 | └── private-key 227 | ``` 228 | 229 | ## Considerations for Role-Based Access Control (RBAC) 230 | 231 | Cluster operators and CRD authors **SHOULD** opt-in resources to binding projection by defining a `ClusterRole` with a label matching `servicebinding.io/controller=true`. The `get`, `list`, `watch`, `update`, and `patch` verbs **MUST** be granted in the `ClusterRole`. 232 | 233 | See [Role-Based Access Control (RBAC)](#role-based-access-control-rbac) for how the `ClusterRole` is consumed. 234 | 235 | ### Example Resource 236 | 237 | ```yaml 238 | apiVersion: rbac.authorization.k8s.io/v1 239 | kind: ClusterRole 240 | metadata: 241 | name: awesome-service-bindings 242 | labels: 243 | servicebinding.io/controller: "true" # matches the aggregation rule selector 244 | rules: 245 | - apiGroups: 246 | - awesome.example.com 247 | resources: 248 | - awesomeworkloads 249 | verbs: 250 | - get 251 | - list 252 | - watch 253 | - update 254 | - patch 255 | ``` 256 | 257 | # Service Binding 258 | 259 | A Service Binding describes the connection between a [Provisioned Service](#provisioned-service) and a [Workload Projection](#workload-projection). It **MUST** be codified as a concrete resource type with API version `servicebinding.io/v1` and kind `ServiceBinding`. An implementation **MAY** support other versions of this specification which define additional API versions. Multiple `ServiceBinding` objects can refer to the same service. Multiple `ServiceBinding` objects can refer to the same workload. For portability, the schema **MUST** comply to the exemplar CRD found [here][sb-crd]. 260 | 261 | > Note: Restricting service binding to resources within the same namespace is strongly recommended. Implementations that choose to support cross-namespace service binding must provide a security model that prevents attacks like privilege escalation and secret enumeration, as well as a deterministic way to declare target namespaces. 262 | 263 | A `ServiceBinding` **MUST** define a `.spec.workload` which is an `ObjectReference`-like declaration. A `ServiceBinding` **MAY** define the workload reference by-name or by-[label selector][ls]. A name and selector **MUST NOT** be defined in the same reference. A `ServiceBinding` **MUST** define a `.spec.service` which is an `ObjectReference`-like declaration to a Provisioned Service-able resource. Extensions and implementations **MAY** allow additional kinds of workloads and services to be referenced. 264 | 265 | The `ServiceBinding` **MAY** define `.spec.workload.containers`, to limit which containers in the workload are bound. If `.spec.workload.containers` is defined, the value **MUST** be a list of strings. Binding to a container is opt-in, unless `.spec.workload.containers` is undefined then all containers **MUST** be bound. For each item in the containers list: 266 | - a container matched by name **MUST** be bound 267 | - values that do not match a container **SHOULD** be ignored 268 | 269 | A `ServiceBinding` **MAY** define a `.spec.env` which is an array of `EnvMapping`. An `EnvMapping` object **MUST** define `name` and `key` entries. The `key` of an `EnvMapping` **MUST** refer to a binding `Secret` key name. The value of this `Secret` entry **MUST** be configured as an environment variable on the resource represented by `workload`. 270 | 271 | A `ServiceBinding` **MUST** define `.status.conditions` which is an array of `Condition` objects as defined in [meta/v1 Condition][mv1c]. At least one condition containing a `type` of `Ready` **MUST** be defined by the implementation. The `Ready` condition **SHOULD** contain appropriate values. As label selectors are inherently queries that return zero-to-many resources, it is **RECOMMENDED** that `ServiceBinding` authors use a combination of labels that yield a single resource, but implementors **MUST** handle each matching resource as if it was specified by name in a distinct `ServiceBinding`. Partial failures **MUST** be aggregated and reported on the binding status's `Ready` condition. A `ServiceBinding` **SHOULD** reflect the secret projected into the workload as `.status.binding.name`. 272 | 273 | When updating the status of the `ServiceBinding`, the controller **MUST** set the value of `.status.observedGeneration` to the value of `.metadata.generation`. The `.metadata.generation` field is always the current generation of the `ServiceBinding`, which is incremented by the API server when writes are made to the `ServiceBinding` spec field. Therefore, consumers **SHOULD** compare the value of the observed and current generations to know if the status reflects the current resource definition. 274 | 275 | [sb-crd]: servicebinding.io_servicebindings.yaml 276 | [ls]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors 277 | [gt]: https://golang.org/pkg/text/template/#pkg-overview 278 | [mv1c]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#condition-v1-meta 279 | 280 | ## Resource Type Schema 281 | 282 | ```yaml 283 | apiVersion: servicebinding.io/v1 284 | kind: ServiceBinding 285 | metadata: 286 | name: # string 287 | generation: # int64, defined by the Kubernetes control plane 288 | ... 289 | spec: 290 | name: # string, optional, default: .metadata.name 291 | type: # string, optional 292 | provider: # string, optional 293 | service: # Provisioned Service resource ObjectReference-like 294 | apiVersion: # string 295 | kind: # string 296 | name: # string 297 | workload: # ObjectReference-like 298 | apiVersion: # string 299 | kind: # string 300 | name: # string, mutually exclusive with selector 301 | selector: # metav1.LabelSelector, mutually exclusive with name 302 | containers: # []string, optional 303 | env: # []EnvMapping, optional 304 | - name: # string 305 | key: # string 306 | 307 | status: 308 | binding: # LocalObjectReference, optional 309 | name: # string 310 | conditions: # []metav1.Condition containing at least one entry for `Ready` 311 | observedGeneration: # int64 312 | ``` 313 | 314 | ## Minimal Example Resource 315 | 316 | ```yaml 317 | apiVersion: servicebinding.io/v1 318 | kind: ServiceBinding 319 | metadata: 320 | name: account-service 321 | spec: 322 | service: 323 | apiVersion: com.example/v1alpha1 324 | kind: AccountService 325 | name: prod-account-service 326 | workload: 327 | apiVersion: apps/v1 328 | kind: Deployment 329 | name: online-banking 330 | status: 331 | conditions: 332 | - type: Ready 333 | status: 'True' 334 | reason: 'Projected' 335 | message: '' 336 | lastTransitionTime: '2021-01-20T17:00:00Z' 337 | ``` 338 | 339 | ## Label Selector Example Resource 340 | 341 | ```yaml 342 | apiVersion: servicebinding.io/v1 343 | kind: ServiceBinding 344 | metadata: 345 | name: online-banking-frontend-to-account-service 346 | spec: 347 | name: account-service 348 | service: 349 | apiVersion: com.example/v1alpha1 350 | kind: AccountService 351 | name: prod-account-service 352 | workload: 353 | apiVersion: apps/v1 354 | kind: Deployment 355 | selector: 356 | matchLabels: 357 | app.kubernetes.io/part-of: online-banking 358 | app.kubernetes.io/component: frontend 359 | status: 360 | conditions: 361 | - type: Ready 362 | status: 'True' 363 | reason: 'Projected' 364 | message: '' 365 | lastTransitionTime: '2021-01-20T17:00:00Z' 366 | ``` 367 | 368 | ## Environment Variables Example Resource 369 | 370 | ```yaml 371 | apiVersion: servicebinding.io/v1 372 | kind: ServiceBinding 373 | metadata: 374 | name: account-service 375 | spec: 376 | service: 377 | apiVersion: com.example/v1alpha1 378 | kind: AccountService 379 | name: prod-account-service 380 | workload: 381 | apiVersion: apps/v1 382 | kind: Deployment 383 | name: online-banking 384 | env: 385 | - name: ACCOUNT_SERVICE_HOST 386 | key: host 387 | - name: ACCOUNT_SERVICE_USERNAME 388 | key: username 389 | - name: ACCOUNT_SERVICE_PASSWORD 390 | key: password 391 | status: 392 | binding: 393 | name: prod-account-service-projection 394 | conditions: 395 | - type: Ready 396 | status: 'True' 397 | reason: 'Projected' 398 | message: '' 399 | lastTransitionTime: '2021-01-20T17:00:00Z' 400 | ``` 401 | 402 | ## Reconciler Implementation 403 | 404 | A Reconciler implementation for the `ServiceBinding` type is responsible for binding the Provisioned Service binding `Secret` into a workload. The `Secret` referred to by `.status.binding` on the resource represented by `service` **MUST** be mounted as a volume on the resource represented by `workload`. 405 | 406 | If a `.spec.name` is set, the directory name of the volume mount **MUST** be its value. If a `.spec.name` is not set, the directory name of the volume mount **SHOULD** be the value of `.metadata.name`. 407 | 408 | For each container to be bound, if the `$SERVICE_BINDING_ROOT` environment variable has already been configured on the resource represented by `workload`, the Provisioned Service binding `Secret` **MUST** be mounted relative to that location. If the `$SERVICE_BINDING_ROOT` environment variable has not been configured on the resource represented by `workload`, the `$SERVICE_BINDING_ROOT` environment variable **MUST** be set and the Provisioned Service binding `Secret` **MUST** be mounted relative to that location. A **RECOMMENDED** value to use is `/bindings`. 409 | 410 | The `$SERVICE_BINDING_ROOT` environment variable **MUST NOT** be reset if it is already configured on the resource represented by `workload`. 411 | 412 | If a `.spec.type` is set, the `type` entry in the workload projection **MUST** be set to its value overriding any existing value. If a `.spec.provider` is set, the `provider` entry in the workload projection **MUST** be set to its value overriding any existing value. 413 | 414 | The `ServiceBinding` status **MUST** be updated for the result of an error when the implementation is unable to retry the binding, or user interaction is required to recover from the error. For example, when updating a workload resource to project a binding a conflict **SHOULD NOT** be reflected because retrying may allow the update to succeed. A not found error fetching the workload resource **SHOULD** be reflected as the error is not recoverable until the target workload resource is created. An implementation **MAY** record an event as a result of any error. 415 | 416 | ### Ready Condition Status 417 | 418 | If the service binding is completed successfully, the `Ready` condition status **MUST** be set to `True`. If the service binding cannot be completed, including cases where the service or workload resource are not found or do not conform to the specification requirements, the `Ready` condition status **MUST** be set to `False`. If the `Ready` condition status is neither actively `True` nor `False` it **SHOULD** be set to `Unknown`. 419 | 420 | ### ServiceAvailable Condition Status 421 | 422 | If the referenced Provisioned Service exists and exposes a binding secret, the `ServiceAvailable` condition status **MUST** be set to `True`. If the referenced Provisioned Service either does not exist, or it cannot be determined if the resource exists, the `ServiceAvailable` condition status **MUST** be set to `False` with a meaningful message. If the `ServiceAvailable` condition status is neither actively `True` nor `False` it **SHOULD** be set to `Unknown`. 423 | 424 | # Direct Secret Reference 425 | 426 | There are scenarios where an appropriate resource conforming to the Provisioned Service duck-type does not exist, but there is a `Secret` available for binding. This feature allows a `ServiceBinding` to directly reference a `Secret`. 427 | 428 | When the `.spec.service.kind` attribute is `Secret` and `.spec.service.apiVersion` is `v1`, the `.spec.service.name` attribute **MUST** be treated as `.status.binding.name` for a Provisioned Service. 429 | 430 | ## Direct Secret Reference Example Resource 431 | 432 | ```yaml 433 | apiVersion: servicebinding.io/v1 434 | kind: ServiceBinding 435 | metadata: 436 | name: account-service 437 | 438 | spec: 439 | service: 440 | apiVersion: v1 441 | kind: Secret 442 | name: prod-account-service-secret 443 | workload: 444 | apiVersion: apps/v1 445 | kind: Deployment 446 | name: online-banking 447 | status: 448 | binding: 449 | name: prod-account-service-reference 450 | conditions: 451 | - type: Ready 452 | status: 'True' 453 | reason: 'Projected' 454 | message: '' 455 | lastTransitionTime: '2021-01-20T17:00:00Z' 456 | ``` 457 | 458 | # Workload Resource Mapping 459 | 460 | A workload resource mapping describes how to apply [service binding](#service-binding) transformations to a [workload projection](#workload-projection). It **MUST** be codified as a concrete resource type (cluster scoped resource) with API version `servicebinding.io/v1` and kind `ClusterWorkloadResourceMapping`. An implementation **MAY** support other versions of this specification which define additional API versions. For portability, the schema **MUST** comply to the exemplar CRD found [here][cwrm-crd]. 461 | 462 | A workload resource mapping **MUST** define its name using [CRD syntax][crd-syntax] (`.`) for the resource that it defines a mapping for. A workload resource mapping **MUST** define a `.spec.versions` which is an array of `MappingTemplate` fragments. 463 | 464 | A `MappingTemplate` fragment **MUST** define at least one `version` entry that represents a version of the mapped resource. The `version` entry **MAY** contain a `*` wildcard which indicates that this mapping should be used for any version that does not have a mapping explicitly defined for it. A `MappingTemplate` fragment **MAY** define `annotations`, as a string containing a [Fixed JSONPath](#fixed-jsonpath) that describes the location of a map of annotations in the target resource. If not specified, the default `annotations` expression **MUST** be appropriate for mapping to a `PodSpec`-able resource (`.spec.template.metadata.annotations`). A `MappingTemplate` fragment **MAY** define `containers`, as an array of `MappingContainer` fragments. If not specified, the default `MappingContainer` **MUST** be appropriate for mapping to a `PodSpec`-able resource. A `MappingTemplate` fragment **MAY** define `volumes`, as a string containing a [Fixed JSONPath](#fixed-jsonpath) that describes the location of [`[]Volume`][volume] arrays in the target resource. If not specified, the default `volumes` expression **MUST** be appropriate for mapping to a `PodSpec`-able resource (`.spec.template.spec.volumes`). 465 | 466 | A `MappingContainer` fragment **MUST** define a `path` entry which is a string containing a [JSONPath][jsonpath] that references container like locations in the target resource. The following expressions **MUST** be applied to each object matched by the path. A `MappingTemplate` object **MAY** define `name`, as a string containing a [Fixed JSONPath](#fixed-jsonpath) that describes the location of a string in the target resource that names the container. A `MappingTemplate` object **MAY** define `env`, as a string containing a [Fixed JSONPath](#fixed-jsonpath) that describes the location of [`[]EnvVar`][envvar] array in the target resource. If not specified, the default `env` expression **MUST** be appropriate for mapping within an actual `Container` object (`.env`). A `MappingTemplate` object **MAY** define `volumeMounts`, as a string containing a [Fixed JSONPath](#fixed-jsonpath) that describes the location of [`[]VolumeMount`][volumemount] array in the target resource. If not specified, the default `env` expression **MUST** be appropriate for mapping within an actual `Container` object (`.volumeMounts`). 467 | 468 | [cwrm-crd]: servicebinding.io_clusterworkloadresourcemappings.yaml 469 | [container]: https://kubernetes.io/docs/reference/kubernetes-api/workloads-resources/container/ 470 | [crd-syntax]: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#create-a-customresourcedefinition 471 | [envvar]: https://kubernetes.io/docs/reference/kubernetes-api/workloads-resources/container/#environment-variables 472 | [jsonpath]: http://goessner.net/articles/JsonPath/ 473 | [volume]: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/volume 474 | [volumemount]: https://kubernetes.io/docs/reference/kubernetes-api/workloads-resources/container/#volumes 475 | 476 | ## Fixed JSONPath 477 | 478 | > Note: Only expressions labeled as 'Fixed JSONPath' **MUST** conform to this requirement. Other expressions **MAY** use the full JSONPath syntax. 479 | 480 | A Fixed JSONPath is a subset of [JSONPath][jsonpath] expressions that **MUST NOT** use type and operators other than fields separated by the child operator. This grammar allows accessing nested fields via a single, fixed path. 481 | 482 | For example, these expressions are allowed: 483 | 484 | - `.name` 485 | - `['name']` 486 | - `.spec.template.spec.volumes` 487 | - `.spec['template'].spec['volumes']` 488 | 489 | All other types and operators are disallowed, including but not limited to: 490 | 491 | - texts 492 | - identifiers 493 | - filters 494 | - ints 495 | - floats 496 | - wildcards 497 | - recursives 498 | - unions 499 | - bools 500 | 501 | ## Resource Type Schema 502 | 503 | ```yaml 504 | apiVersion: servicebinding.io/v1 505 | kind: ClusterWorkloadResourceMapping 506 | metadata: 507 | name: # string 508 | generation: # int64, defined by the Kubernetes control plane 509 | ... 510 | spec: 511 | versions: # []MappingTemplate 512 | - version: # string 513 | annotations: # string (Fixed JSONPath), optional 514 | containers: # []MappingContainer, optional 515 | - path: # string (JSONPath) 516 | name: # string (Fixed JSONPath), optional 517 | env: # string (Fixed JSONPath), optional 518 | volumeMounts: # string (Fixed JSONPath), optional 519 | volumes: # string (Fixed JSONPath), optional 520 | ``` 521 | 522 | ## Example Resource 523 | 524 | ```yaml 525 | apiVersion: servicebinding.io/v1 526 | kind: ClusterWorkloadResourceMapping 527 | metadata: 528 | name: cronjobs.batch 529 | spec: 530 | versions: 531 | - version: "*" 532 | annotations: .spec.jobTemplate.spec.template.metadata.annotations 533 | containers: 534 | - path: .spec.jobTemplate.spec.template.spec.containers[*] 535 | name: .name 536 | env: .env # this is the default value 537 | volumeMounts: .volumeMounts # this is the default value 538 | - path: .spec.jobTemplate.spec.template.spec.initContainers[*] 539 | name: .name 540 | env: .env # this is the default value 541 | volumeMounts: .volumeMounts # this is the default value 542 | volumes: .spec.jobTemplate.spec.template.spec.volumes 543 | ``` 544 | 545 | ## `PodSpec`-able (Default) Example Resource 546 | 547 | ```yaml 548 | apiVersion: servicebinding.io/v1 549 | kind: ClusterWorkloadResourceMapping 550 | metadata: 551 | name: deployments.apps 552 | spec: 553 | versions: 554 | - version: "*" 555 | annotations: .spec.template.metadata.annotations 556 | containers: 557 | - path: .spec.template.spec.containers[*] 558 | name: .name 559 | env: .env 560 | volumeMounts: .volumeMounts 561 | - path: .spec.template.spec.initContainers[*] 562 | name: .name 563 | env: .env 564 | volumeMounts: .volumeMounts 565 | volumes: .spec.template.spec.volumes 566 | ``` 567 | 568 | > Note: This example is equivalent to not specifying a mapping or specifying an empty mapping. 569 | 570 | ## Runtime Behavior 571 | 572 | When a `ClusterWorkloadResourceMapping` is defined in the cluster matching a workload resource it **MUST** be used to map the binding that type. If no mapping is available for the type, the implementation **MUST** treat the workload resource as a `PodSpec`-able type. 573 | 574 | When a service binding projection is removed, the controller **MUST** use the same mappings from the projection creation. After a `ClusterWorkloadResourceMapping` resource is modified, each binding targeting the mapped workload type **MUST** be removed, then reattempted with the latest mapping. 575 | 576 | If a `ServiceBinding` specifies `.spec.workload.containers` and a `MappingContainer` specifies a `name` expression, the resolved name **MUST** limit which containers in the workload are bound. If either key is not defined, the container **SHOULD** be bound. 577 | 578 | An implementation **MUST** create empty values at locations referenced by [Fixed JSONPaths](#fixed-jsonpath) that do not exist on the workload resource. Values referenced by JSONPaths in both the `MappingTemplate` and `MappingContainer` fragments **MUST** be mutated by a `ServiceBinding` reconciler as if they were defined directly by a [`corev1.PodTemplateSpec`][cv1pts]. A reconciler **MUST** preserve fields on the workload resource that fall outside the specific fragments and types defined by the mapping. 579 | 580 | [cv1pts]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#podtemplatespec-v1-core 581 | 582 | # Role-Based Access Control (RBAC) 583 | 584 | Kubernetes clusters often utilize [Role-based access control (RBAC)][rbac] to authorize subjects to perform specific actions on resources. When operating in a cluster with RBAC enabled, the service binding reconciler needs permission to read resources that provisioned a service and write resources that services are projected into. This section defines a means for third-party CRD authors and cluster operators to expose resources to the service binding reconciler. Cluster operators **MAY** impose additional access controls beyond RBAC. 585 | 586 | If a service binding reconciler implementation is using Role-Based Access Control (RBAC) it **MUST** define an [aggregated `ClusterRole`][acr] with a label selector matching the label `servicebinding.io/controller=true`. This `ClusterRole` **MUST** be bound (`RoleBinding` for a single namespace or `ClusterRoleBinding` if cluster-wide) to the subject the service binding reconciler runs as, typically a `ServiceAccount`. 587 | 588 | [rbac]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/ 589 | [acr]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles 590 | 591 | ## Example Resource 592 | 593 | ```yaml 594 | apiVersion: rbac.authorization.k8s.io/v1 595 | kind: ClusterRole 596 | metadata: 597 | name: ... 598 | aggregationRule: 599 | clusterRoleSelectors: 600 | - matchLabels: 601 | servicebinding.io/controller: "true" 602 | rules: [] # The control plane automatically fills in the rules 603 | ``` 604 | -------------------------------------------------------------------------------- /extensions/README.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | This directory contains extensions to the [Service Binding Specification for Kubernetes](https://github.com/servicebinding/spec). Extensions are optional additions to the core specification. Implementation and support of these specifications are not required in order for a platform to be considered compliant. However, if the features addressed by these specifications are supported, a platform must be in compliance with the specification that governs that feature. Both the core spec and the extensions are going to have their independent release cycles. 4 | 5 | | No. | Title | Status | 6 | | --- | ---------------------------------------------------- | ------ | 7 | | 1 | [Secret Generation Extension](./secret-generation.md) | Draft | 8 | -------------------------------------------------------------------------------- /extensions/secret-generation.md: -------------------------------------------------------------------------------- 1 | # Secret Generation Extension 2 | 3 | This document defines an extension to the [Service Binding Specification for Kubernetes](https://github.com/servicebinding/spec) ("Service Binding spec" for short henceforth). This extension specifies generating a Kubernetes Secret resource that can be consumed by any Service Binding spec compliant implementation. The Secret resource is generated from one of these sources: 4 | 5 | - Operator Lifecycle Manager Descriptors 6 | - Custom Resource Definition Annotations 7 | - Custom Resource Annotations 8 | 9 | ## Status 10 | 11 | This document is a pre-release, working draft of the Secret Generation extension for Service Binding, representing the collective efforts of the community. It is published for early implementors and users to provide feedback. Any part of this document may change before the extension reaches 1.0 with no promise of backwards compatibility. 12 | 13 | ## Specification 14 | 15 | Many services, especially initially, will not be Provisioned Service-compliant. These services will expose the appropriate binding `Secret` information, but not in the way that the specification or applications expect. Users should have a way of describing a mapping from existing data associated with arbitrary resources and CRDs to a representation of a binding `Secret`. 16 | 17 | To handle the majority of existing resources and CRDs, `Secret` generation needs to support the following behaviors: 18 | 19 | 1. Extract a string from a resource 20 | 1. Extract an entire `ConfigMap`/`Secret` refrenced from a resource 21 | 1. Extract a specific entry in a `ConfigMap`/`Secret` referenced from a resource 22 | 1. Extract entries from a collection of objects, mapping keys and values from entries in a `ConfigMap`/`Secret` referenced from a resource 23 | 1. Exctact a collection of specific entry values in a resource's collection of objects 24 | 1. Map each value to a specific key 25 | 1. Map each value of a collection to a key with generated name 26 | 27 | While the syntax of the generation strategies are specific to the system they are annotating, they are based on a common data model. 28 | 29 | | Model | Description 30 | | ----- | ----------- 31 | | `path` | A template represention of the path to an element in a Kubernetes resource. The value of `path` is specified as [JSONPath](https://kubernetes.io/docs/reference/kubectl/jsonpath/). Required. 32 | | `objectType` | Specifies the type of the object selected by the `path`. One of `ConfigMap`, `Secret`, or `string` (default). 33 | | `elementType` | Specifies the type of object in an array selected by the `path`. One of `sliceOfMaps`, `sliceOfStrings`, `string` (default). 34 | | `sourceKey` | Specifies a particular key to select if a `ConfigMap` or `Secret` is selected by the `path`. Specifies a value to use for the key for an entry in a binding `Secret` when `elementType` is `sliceOfMaps`. 35 | | `sourceValue` | Specifies a particular value to use for the value for an entry in a binding `Secret` when `elementType` is `sliceOfMaps` or `sliceOfStrings`. 36 | 37 | 38 | ### OLM Operator Descriptors 39 | 40 | OLM Operators are configured by setting the `specDescriptor` and `statusDescriptor` entries in the [ClusterServiceVersion](https://docs.openshift.com/container-platform/4.4/operators/operator_sdk/osdk-generating-csvs.html) with mapping descriptors. 41 | 42 | ### Descriptor Examples 43 | 44 | The following examples refer to this resource definition. 45 | 46 | ```yaml 47 | apiVersion: apps.kube.io/v1beta1 48 | kind: Database 49 | metadata: 50 | name: my-cluster 51 | spec: 52 | tags: 53 | - Brno 54 | - PWR 55 | - stage 56 | ... 57 | 58 | status: 59 | bootstrap: 60 | - type: plain 61 | url: myhost2.example.com 62 | name: hostGroup1 63 | - type: tls 64 | url: myhost1.example.com:9092,myhost2.example.com:9092 65 | name: hostGroup2 66 | data: 67 | dbConfiguration: database-config # ConfigMap 68 | dbCredentials: database-cred-Secret # Secret 69 | url: db.stage.ibm.com 70 | ``` 71 | 72 | 1. Mount an entire `Secret` as the binding `Secret` 73 | 74 | ```yaml 75 | - path: data.dbCredentials 76 | x-descriptors: 77 | - urn:alm:descriptor:io.kubernetes:Secret 78 | - service.binding 79 | ``` 80 | 81 | 1. Mount an entire `ConfigMap` as the binding `Secret` 82 | 83 | ```yaml 84 | - path: data.dbConfiguration 85 | x-descriptors: 86 | - urn:alm:descriptor:io.kubernetes:ConfigMap 87 | - service.binding 88 | ``` 89 | 90 | 1. Mount an entry from a `ConfigMap` into the binding `Secret` 91 | 92 | ```yaml 93 | - path: data.dbConfiguration 94 | x-descriptors: 95 | - urn:alm:descriptor:io.kubernetes:ConfigMap 96 | - service.binding:certificate:sourceKey=certificate 97 | ``` 98 | 99 | 1. Mount an entry from a `ConfigMap` into the binding `Secret` with a different key 100 | 101 | ```yaml 102 | - path: data.dbConfiguration 103 | x-descriptors: 104 | - urn:alm:descriptor:io.kubernetes:ConfigMap 105 | - service.binding:timeout:sourceKey=db_timeout 106 | ``` 107 | 108 | 1. Mount a resource definition value into the binding `Secret` 109 | 110 | ```yaml 111 | - path: data.uri 112 | x-descriptors: 113 | - service.binding:uri 114 | ``` 115 | 116 | 1. Mount a resource definition value into the binding `Secret` with a different key 117 | 118 | ```yaml 119 | - path: data.connectionURL 120 | x-descriptors: 121 | - service.binding:uri 122 | ``` 123 | 124 | 1. Mount the entries of a collection into the binding `Secret` selecting the key and value from each entry 125 | 126 | ```yaml 127 | - path: bootstrap 128 | x-descriptors: 129 | - service.binding:endpoints:elementType=sliceOfMaps:sourceKey=type:sourceValue=url 130 | ``` 131 | 132 | 1. Mount the items of a collection into the binding `Secret` with one key per item 133 | 134 | ```yaml 135 | - path: spec.tags 136 | x-descriptors: 137 | - service.binding:tags:elementType=sliceOfStrings 138 | ``` 139 | 140 | 1. Mount the values of collection entries into the binding `Secret` with one key per entry value 141 | 142 | ```yaml 143 | - path: bootstrap 144 | x-descriptors: 145 | - service.binding:endpoints:elementType=sliceOfStrings:sourceValue=url 146 | ``` 147 | 148 | ### Non-OLM Operator and Resource Annotations 149 | 150 | Non-OLM Operators are configured by adding annotations to the Operator's CRD with mapping configuration. All Kubernetes resources are configured by adding annotations to the resource. 151 | 152 | ### Annotation Examples 153 | 154 | The following examples refer to this resource definition. 155 | 156 | ```yaml 157 | apiVersion: apps.kube.io/v1beta1 158 | kind: Database 159 | metadata: 160 | name: my-cluster 161 | spec: 162 | tags: 163 | - Brno 164 | - PWR 165 | - stage 166 | ... 167 | 168 | status: 169 | bootstrap: 170 | - type: plain 171 | url: myhost2.example.com 172 | name: hostGroup1 173 | - type: tls 174 | url: myhost1.example.com:9092,myhost2.example.com:9092 175 | name: hostGroup2 176 | data: 177 | dbConfiguration: database-config # ConfigMap 178 | dbCredentials: database-cred-Secret # Secret 179 | url: db.stage.ibm.com 180 | ``` 181 | 182 | 1. Mount an entire `Secret` as the binding `Secret` 183 | ```plain 184 | “service.binding": 185 | ”path={.status.data.dbCredentials},objectType=Secret” 186 | ``` 187 | 1. Mount an entire `ConfigMap` as the binding `Secret` 188 | ```plain 189 | service.binding”: 190 | "path={.status.data.dbConfiguration},objectType=ConfigMap” 191 | ``` 192 | 1. Mount an entry from a `ConfigMap` into the binding `Secret` 193 | ```plain 194 | “service.binding/certificate”: 195 | "path={.status.data.dbConfiguration},objectType=ConfigMap,sourceKey=certificate" 196 | ``` 197 | 1. Mount an entry from a `ConfigMap` into the binding `Secret` with a different key 198 | ```plain 199 | “service.binding/timeout”: 200 | “path={.status.data.dbConfiguration},objectType=ConfigMap,sourceKey=db_timeout” 201 | ``` 202 | 1. Mount a resource definition value into the binding `Secret` 203 | ```plain 204 | “service.binding/uri”: 205 | "path={.status.data.url}" 206 | ``` 207 | 1. Mount a resource definition value into the binding `Secret` with a different key 208 | ```plain 209 | “service.binding/uri": 210 | "path={.status.data.connectionURL}” 211 | ``` 212 | 1. Mount the entries of a collection into the binding `Secret` selecting the key and value from each entry 213 | ```plain 214 | “service.binding/endpoints”: 215 | "path={.status.bootstrap},elementType=sliceOfMaps,sourceKey=type,sourceValue=url" 216 | ``` 217 | 1. Mount the items of a collection into the binding `Secret` with one key per item 218 | ```plain 219 | "service.binding/tags": 220 | "path={.spec.tags},elementType=sliceOfStrings 221 | ``` 222 | 1. Mount the values of collection entries into the binding `Secret` with one key per entry value 223 | ```plain 224 | “service.binding/endpoints”: 225 | "path={.status.bootstrap},elementType=sliceOfStrings,sourceValue=url" 226 | ``` 227 | -------------------------------------------------------------------------------- /internal/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/go,intellij+all 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=go,intellij+all 4 | 5 | ### Go ### 6 | # Binaries for programs and plugins 7 | *.exe 8 | *.exe~ 9 | *.dll 10 | *.so 11 | *.dylib 12 | 13 | # Test binary, built with `go test -c` 14 | *.test 15 | 16 | # Output of the go coverage tool, specifically when used with LiteIDE 17 | *.out 18 | 19 | # Dependency directories (remove the comment below to include it) 20 | # vendor/ 21 | 22 | ### Go Patch ### 23 | /vendor/ 24 | /Godeps/ 25 | 26 | ### Intellij+all ### 27 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 28 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 29 | 30 | # User-specific stuff 31 | .idea/**/workspace.xml 32 | .idea/**/tasks.xml 33 | .idea/**/usage.statistics.xml 34 | .idea/**/dictionaries 35 | .idea/**/shelf 36 | 37 | # Generated files 38 | .idea/**/contentModel.xml 39 | 40 | # Sensitive or high-churn files 41 | .idea/**/dataSources/ 42 | .idea/**/dataSources.ids 43 | .idea/**/dataSources.local.xml 44 | .idea/**/sqlDataSources.xml 45 | .idea/**/dynamic.xml 46 | .idea/**/uiDesigner.xml 47 | .idea/**/dbnavigator.xml 48 | 49 | # Gradle 50 | .idea/**/gradle.xml 51 | .idea/**/libraries 52 | 53 | # Gradle and Maven with auto-import 54 | # When using Gradle or Maven with auto-import, you should exclude module files, 55 | # since they will be recreated, and may cause churn. Uncomment if using 56 | # auto-import. 57 | # .idea/artifacts 58 | # .idea/compiler.xml 59 | # .idea/jarRepositories.xml 60 | # .idea/modules.xml 61 | # .idea/*.iml 62 | # .idea/modules 63 | # *.iml 64 | # *.ipr 65 | 66 | # CMake 67 | cmake-build-*/ 68 | 69 | # Mongo Explorer plugin 70 | .idea/**/mongoSettings.xml 71 | 72 | # File-based project format 73 | *.iws 74 | 75 | # IntelliJ 76 | out/ 77 | 78 | # mpeltonen/sbt-idea plugin 79 | .idea_modules/ 80 | 81 | # JIRA plugin 82 | atlassian-ide-plugin.xml 83 | 84 | # Cursive Clojure plugin 85 | .idea/replstate.xml 86 | 87 | # Crashlytics plugin (for Android Studio and IntelliJ) 88 | com_crashlytics_export_strings.xml 89 | crashlytics.properties 90 | crashlytics-build.properties 91 | fabric.properties 92 | 93 | # Editor-based Rest Client 94 | .idea/httpRequests 95 | 96 | # Android studio 3.1+ serialized cache file 97 | .idea/caches/build_file_checksums.ser 98 | 99 | ### Intellij+all Patch ### 100 | # Ignores the whole .idea folder and all .iml files 101 | # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 102 | 103 | .idea/ 104 | 105 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 106 | 107 | *.iml 108 | modules.xml 109 | .idea/misc.xml 110 | *.ipr 111 | 112 | # Sonarlint plugin 113 | .idea/sonarlint 114 | 115 | # End of https://www.toptal.com/developers/gitignore/api/go,intellij+all 116 | -------------------------------------------------------------------------------- /internal/Makefile: -------------------------------------------------------------------------------- 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 | # https://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 | CONTROLLER_GEN ?= go run sigs.k8s.io/controller-tools/cmd/controller-gen 16 | 17 | .PHONY: generate 18 | generate: 19 | $(CONTROLLER_GEN) crd:crdVersions=v1 output:crd:artifacts:config=.. paths=./... 20 | -------------------------------------------------------------------------------- /internal/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/servicebinding/spec/internal 2 | 3 | go 1.21 4 | toolchain go1.24.1 5 | 6 | require ( 7 | k8s.io/apimachinery v0.29.1 8 | sigs.k8s.io/controller-runtime v0.17.1 9 | sigs.k8s.io/controller-tools v0.14.0 10 | ) 11 | 12 | require ( 13 | github.com/fatih/color v1.16.0 // indirect 14 | github.com/go-logr/logr v1.4.1 // indirect 15 | github.com/gobuffalo/flect v1.0.2 // indirect 16 | github.com/gogo/protobuf v1.3.2 // indirect 17 | github.com/google/gofuzz v1.2.0 // indirect 18 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 19 | github.com/json-iterator/go v1.1.12 // indirect 20 | github.com/mattn/go-colorable v0.1.13 // indirect 21 | github.com/mattn/go-isatty v0.0.20 // indirect 22 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 23 | github.com/modern-go/reflect2 v1.0.2 // indirect 24 | github.com/spf13/cobra v1.8.0 // indirect 25 | github.com/spf13/pflag v1.0.5 // indirect 26 | golang.org/x/mod v0.17.0 // indirect 27 | golang.org/x/net v0.38.0 // indirect 28 | golang.org/x/sync v0.12.0 // indirect 29 | golang.org/x/sys v0.31.0 // indirect 30 | golang.org/x/text v0.23.0 // indirect 31 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect 32 | gopkg.in/inf.v0 v0.9.1 // indirect 33 | gopkg.in/yaml.v2 v2.4.0 // indirect 34 | gopkg.in/yaml.v3 v3.0.1 // indirect 35 | k8s.io/api v0.29.0 // indirect 36 | k8s.io/apiextensions-apiserver v0.29.0 // indirect 37 | k8s.io/klog/v2 v2.110.1 // indirect 38 | k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect 39 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect 40 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect 41 | sigs.k8s.io/yaml v1.4.0 // indirect 42 | ) 43 | -------------------------------------------------------------------------------- /internal/go.sum: -------------------------------------------------------------------------------- 1 | github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= 6 | github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= 7 | github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= 8 | github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= 9 | github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 10 | github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= 11 | github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 12 | github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= 13 | github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= 14 | github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= 15 | github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= 16 | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 17 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 18 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 19 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 20 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 21 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 22 | github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= 23 | github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 24 | github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= 25 | github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 26 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 27 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 28 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 29 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 30 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 31 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 32 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 33 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 34 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 35 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 36 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 37 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 38 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 39 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 40 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 41 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 42 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 43 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 44 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 45 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 46 | github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= 47 | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 48 | github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= 49 | github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= 50 | github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= 51 | github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= 52 | github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= 53 | github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= 54 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 55 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 56 | github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= 57 | github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= 58 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 59 | github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= 60 | github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= 61 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 62 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 63 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 64 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 65 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 66 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 67 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 68 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 69 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 70 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 71 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 72 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 73 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 74 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 75 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 76 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 77 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 78 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 79 | golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= 80 | golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 81 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 82 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 83 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 84 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 85 | golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= 86 | golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= 87 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 88 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 89 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 90 | golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= 91 | golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 92 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 93 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 94 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 95 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 96 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 97 | golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= 98 | golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 99 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 100 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 101 | golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= 102 | golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 103 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 104 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 105 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 106 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 107 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= 108 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 109 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 110 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 111 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 112 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 113 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 114 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 115 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 116 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 117 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 118 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 119 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 120 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 121 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 122 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 123 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 124 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 125 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 126 | k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= 127 | k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= 128 | k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= 129 | k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= 130 | k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= 131 | k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= 132 | k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= 133 | k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= 134 | k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= 135 | k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= 136 | sigs.k8s.io/controller-runtime v0.17.1 h1:V1dQELMGVk46YVXXQUbTFujU7u4DQj6YUj9Rb6cuzz8= 137 | sigs.k8s.io/controller-runtime v0.17.1/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= 138 | sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= 139 | sigs.k8s.io/controller-tools v0.14.0/go.mod h1:TV7uOtNNnnR72SpzhStvPkoS/U5ir0nMudrkrC4M9Sc= 140 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= 141 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= 142 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= 143 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= 144 | sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= 145 | sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= 146 | -------------------------------------------------------------------------------- /internal/servicebinding.io/v1/cluster_workload_resource_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 | * 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 | -------------------------------------------------------------------------------- /internal/servicebinding.io/v1/group_version.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 v1 contains API Schema definitions for the service binding 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 | -------------------------------------------------------------------------------- /internal/servicebinding.io/v1/service_binding.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 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 | // These are valid conditions of ServiceBinding. 83 | const ( 84 | // ServiceBindingReady means the ServiceBinding has projected the ProvisionedService 85 | // secret and the Workload is ready to start. It does not indicate the condition 86 | // of either the Service or the Workload resources referenced. 87 | ServiceBindingConditionReady = "Ready" 88 | ) 89 | 90 | // ServiceBindingStatus defines the observed state of ServiceBinding 91 | type ServiceBindingStatus struct { 92 | // ObservedGeneration is the 'Generation' of the ServiceBinding that 93 | // was last processed by the controller. 94 | ObservedGeneration int64 `json:"observedGeneration,omitempty"` 95 | 96 | // Conditions are the conditions of this ServiceBinding 97 | Conditions []metav1.Condition `json:"conditions,omitempty"` 98 | 99 | // Binding exposes the projected secret for this ServiceBinding 100 | Binding *ServiceBindingSecretReference `json:"binding,omitempty"` 101 | } 102 | 103 | // +kubebuilder:object:root=true 104 | // +kubebuilder:storageversion 105 | // +kubebuilder:subresource:status 106 | // +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status` 107 | // +kubebuilder:printcolumn:name="Reason",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].reason` 108 | // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 109 | 110 | // ServiceBinding is the Schema for the servicebindings API 111 | type ServiceBinding struct { 112 | metav1.TypeMeta `json:",inline"` 113 | metav1.ObjectMeta `json:"metadata,omitempty"` 114 | 115 | Spec ServiceBindingSpec `json:"spec,omitempty"` 116 | Status ServiceBindingStatus `json:"status,omitempty"` 117 | } 118 | 119 | // +kubebuilder:object:root=true 120 | 121 | // ServiceBindingList contains a list of ServiceBinding 122 | type ServiceBindingList struct { 123 | metav1.TypeMeta `json:",inline"` 124 | metav1.ListMeta `json:"metadata,omitempty"` 125 | 126 | Items []ServiceBinding `json:"items"` 127 | } 128 | -------------------------------------------------------------------------------- /internal/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | * Copyright 2020 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 | * https://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 | package internal 21 | 22 | import ( 23 | _ "sigs.k8s.io/controller-tools/cmd/controller-gen" 24 | ) 25 | -------------------------------------------------------------------------------- /servicebinding.io_clusterworkloadresourcemappings.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.14.0 7 | name: clusterworkloadresourcemappings.servicebinding.io 8 | spec: 9 | group: servicebinding.io 10 | names: 11 | kind: ClusterWorkloadResourceMapping 12 | listKind: ClusterWorkloadResourceMappingList 13 | plural: clusterworkloadresourcemappings 14 | singular: clusterworkloadresourcemapping 15 | scope: Cluster 16 | versions: 17 | - additionalPrinterColumns: 18 | - jsonPath: .metadata.creationTimestamp 19 | name: Age 20 | type: date 21 | name: v1 22 | schema: 23 | openAPIV3Schema: 24 | description: ClusterWorkloadResourceMapping is the Schema for the clusterworkloadresourcemappings 25 | API 26 | properties: 27 | apiVersion: 28 | description: |- 29 | APIVersion defines the versioned schema of this representation of an object. 30 | Servers should convert recognized schemas to the latest internal value, and 31 | may reject unrecognized values. 32 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 33 | type: string 34 | kind: 35 | description: |- 36 | Kind is a string value representing the REST resource this object represents. 37 | Servers may infer this from the endpoint the client submits requests to. 38 | Cannot be updated. 39 | In CamelCase. 40 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 41 | type: string 42 | metadata: 43 | type: object 44 | spec: 45 | description: ClusterWorkloadResourceMappingSpec defines the desired state 46 | of ClusterWorkloadResourceMapping 47 | properties: 48 | versions: 49 | description: Versions is the collection of versions for a given resource, 50 | with mappings. 51 | items: 52 | description: |- 53 | ClusterWorkloadResourceMappingTemplate defines the mapping for a specific version of an workload resource to a 54 | logical PodTemplateSpec-like structure. 55 | properties: 56 | annotations: 57 | description: |- 58 | Annotations is a Restricted JSONPath that references the annotations map within the workload resource. These 59 | annotations must end up in the resulting Pod, and are generally not the workload resource's annotations. 60 | Defaults to `.spec.template.metadata.annotations`. 61 | type: string 62 | containers: 63 | description: |- 64 | Containers is the collection of mappings to container-like fragments of the workload resource. Defaults to 65 | mappings appropriate for a PodSpecable resource. 66 | items: 67 | description: |- 68 | ClusterWorkloadResourceMappingContainer defines the mapping for a specific fragment of an workload resource 69 | to a Container-like structure. 70 | 71 | 72 | Each mapping defines exactly one path that may match multiple container-like fragments within the workload 73 | resource. For each object matching the path the name, env and volumeMounts expressions are resolved to find those 74 | structures. 75 | properties: 76 | env: 77 | description: |- 78 | Env is a Restricted JSONPath that references the slice of environment variables for the container with the 79 | container-like workload resource fragment. The referenced location is created if it does not exist. Defaults 80 | to `.envs`. 81 | type: string 82 | name: 83 | description: |- 84 | Name is a Restricted JSONPath that references the name of the container with the container-like workload resource 85 | fragment. If not defined, container name filtering is ignored. 86 | type: string 87 | path: 88 | description: Path is the JSONPath within the workload 89 | resource that matches an existing fragment that is container-like. 90 | type: string 91 | volumeMounts: 92 | description: |- 93 | VolumeMounts is a Restricted JSONPath that references the slice of volume mounts for the container with the 94 | container-like workload resource fragment. The referenced location is created if it does not exist. Defaults 95 | to `.volumeMounts`. 96 | type: string 97 | required: 98 | - path 99 | type: object 100 | type: array 101 | version: 102 | description: Version is the version of the workload resource 103 | that this mapping is for. 104 | type: string 105 | volumes: 106 | description: |- 107 | Volumes is a Restricted JSONPath that references the slice of volumes within the workload resource. Defaults to 108 | `.spec.template.spec.volumes`. 109 | type: string 110 | required: 111 | - version 112 | type: object 113 | type: array 114 | type: object 115 | type: object 116 | served: true 117 | storage: true 118 | subresources: {} 119 | -------------------------------------------------------------------------------- /servicebinding.io_servicebindings.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.14.0 7 | name: servicebindings.servicebinding.io 8 | spec: 9 | group: servicebinding.io 10 | names: 11 | kind: ServiceBinding 12 | listKind: ServiceBindingList 13 | plural: servicebindings 14 | singular: servicebinding 15 | scope: Namespaced 16 | versions: 17 | - additionalPrinterColumns: 18 | - jsonPath: .status.conditions[?(@.type=="Ready")].status 19 | name: Ready 20 | type: string 21 | - jsonPath: .status.conditions[?(@.type=="Ready")].reason 22 | name: Reason 23 | type: string 24 | - jsonPath: .metadata.creationTimestamp 25 | name: Age 26 | type: date 27 | name: v1 28 | schema: 29 | openAPIV3Schema: 30 | description: ServiceBinding is the Schema for the servicebindings API 31 | properties: 32 | apiVersion: 33 | description: |- 34 | APIVersion defines the versioned schema of this representation of an object. 35 | Servers should convert recognized schemas to the latest internal value, and 36 | may reject unrecognized values. 37 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 38 | type: string 39 | kind: 40 | description: |- 41 | Kind is a string value representing the REST resource this object represents. 42 | Servers may infer this from the endpoint the client submits requests to. 43 | Cannot be updated. 44 | In CamelCase. 45 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 46 | type: string 47 | metadata: 48 | type: object 49 | spec: 50 | description: ServiceBindingSpec defines the desired state of ServiceBinding 51 | properties: 52 | env: 53 | description: Env is the collection of mappings from Secret entries 54 | to environment variables 55 | items: 56 | description: EnvMapping defines a mapping from the value of a Secret 57 | entry to an environment variable 58 | properties: 59 | key: 60 | description: Key is the key in the Secret that will be exposed 61 | type: string 62 | name: 63 | description: Name is the name of the environment variable 64 | type: string 65 | required: 66 | - key 67 | - name 68 | type: object 69 | type: array 70 | name: 71 | description: Name is the name of the service as projected into the 72 | workload container. Defaults to .metadata.name. 73 | type: string 74 | provider: 75 | description: Provider is the provider of the service as projected 76 | into the workload container 77 | type: string 78 | service: 79 | description: Service is a reference to an object that fulfills the 80 | ProvisionedService duck type 81 | properties: 82 | apiVersion: 83 | description: API version of the referent. 84 | type: string 85 | kind: 86 | description: |- 87 | Kind of the referent. 88 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 89 | type: string 90 | name: 91 | description: |- 92 | Name of the referent. 93 | More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 94 | type: string 95 | required: 96 | - apiVersion 97 | - kind 98 | - name 99 | type: object 100 | type: 101 | description: Type is the type of the service as projected into the 102 | workload container 103 | type: string 104 | workload: 105 | description: Workload is a reference to an object 106 | properties: 107 | apiVersion: 108 | description: API version of the referent. 109 | type: string 110 | containers: 111 | description: Containers describes which containers in a Pod should 112 | be bound to 113 | items: 114 | type: string 115 | type: array 116 | kind: 117 | description: |- 118 | Kind of the referent. 119 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 120 | type: string 121 | name: 122 | description: |- 123 | Name of the referent. 124 | More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 125 | type: string 126 | selector: 127 | description: Selector is a query that selects the workload or 128 | workloads to bind the service to 129 | properties: 130 | matchExpressions: 131 | description: matchExpressions is a list of label selector 132 | requirements. The requirements are ANDed. 133 | items: 134 | description: |- 135 | A label selector requirement is a selector that contains values, a key, and an operator that 136 | relates the key and values. 137 | properties: 138 | key: 139 | description: key is the label key that the selector 140 | applies to. 141 | type: string 142 | operator: 143 | description: |- 144 | operator represents a key's relationship to a set of values. 145 | Valid operators are In, NotIn, Exists and DoesNotExist. 146 | type: string 147 | values: 148 | description: |- 149 | values is an array of string values. If the operator is In or NotIn, 150 | the values array must be non-empty. If the operator is Exists or DoesNotExist, 151 | the values array must be empty. This array is replaced during a strategic 152 | merge patch. 153 | items: 154 | type: string 155 | type: array 156 | required: 157 | - key 158 | - operator 159 | type: object 160 | type: array 161 | matchLabels: 162 | additionalProperties: 163 | type: string 164 | description: |- 165 | matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels 166 | map is equivalent to an element of matchExpressions, whose key field is "key", the 167 | operator is "In", and the values array contains only "value". The requirements are ANDed. 168 | type: object 169 | type: object 170 | x-kubernetes-map-type: atomic 171 | required: 172 | - apiVersion 173 | - kind 174 | type: object 175 | required: 176 | - service 177 | - workload 178 | type: object 179 | status: 180 | description: ServiceBindingStatus defines the observed state of ServiceBinding 181 | properties: 182 | binding: 183 | description: Binding exposes the projected secret for this ServiceBinding 184 | properties: 185 | name: 186 | description: |- 187 | Name of the referent secret. 188 | More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 189 | type: string 190 | required: 191 | - name 192 | type: object 193 | conditions: 194 | description: Conditions are the conditions of this ServiceBinding 195 | items: 196 | description: "Condition contains details for one aspect of the current 197 | state of this API Resource.\n---\nThis struct is intended for 198 | direct use as an array at the field path .status.conditions. For 199 | example,\n\n\n\ttype FooStatus struct{\n\t // Represents the 200 | observations of a foo's current state.\n\t // Known .status.conditions.type 201 | are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // 202 | +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t 203 | \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" 204 | patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t 205 | \ // other fields\n\t}" 206 | properties: 207 | lastTransitionTime: 208 | description: |- 209 | lastTransitionTime is the last time the condition transitioned from one status to another. 210 | This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. 211 | format: date-time 212 | type: string 213 | message: 214 | description: |- 215 | message is a human readable message indicating details about the transition. 216 | This may be an empty string. 217 | maxLength: 32768 218 | type: string 219 | observedGeneration: 220 | description: |- 221 | observedGeneration represents the .metadata.generation that the condition was set based upon. 222 | For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date 223 | with respect to the current state of the instance. 224 | format: int64 225 | minimum: 0 226 | type: integer 227 | reason: 228 | description: |- 229 | reason contains a programmatic identifier indicating the reason for the condition's last transition. 230 | Producers of specific condition types may define expected values and meanings for this field, 231 | and whether the values are considered a guaranteed API. 232 | The value should be a CamelCase string. 233 | This field may not be empty. 234 | maxLength: 1024 235 | minLength: 1 236 | pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ 237 | type: string 238 | status: 239 | description: status of the condition, one of True, False, Unknown. 240 | enum: 241 | - "True" 242 | - "False" 243 | - Unknown 244 | type: string 245 | type: 246 | description: |- 247 | type of condition in CamelCase or in foo.example.com/CamelCase. 248 | --- 249 | Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be 250 | useful (see .node.status.conditions), the ability to deconflict is important. 251 | The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) 252 | maxLength: 316 253 | pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ 254 | type: string 255 | required: 256 | - lastTransitionTime 257 | - message 258 | - reason 259 | - status 260 | - type 261 | type: object 262 | type: array 263 | observedGeneration: 264 | description: |- 265 | ObservedGeneration is the 'Generation' of the ServiceBinding that 266 | was last processed by the controller. 267 | format: int64 268 | type: integer 269 | type: object 270 | type: object 271 | served: true 272 | storage: true 273 | subresources: 274 | status: {} 275 | --------------------------------------------------------------------------------