{"id":18637351,"url":"https://github.com/openshift/api","last_synced_at":"2025-05-13T00:15:12.536Z","repository":{"id":37445070,"uuid":"108446737","full_name":"openshift/api","owner":"openshift","description":"Canonical location of the OpenShift API definition.","archived":false,"fork":false,"pushed_at":"2025-05-10T01:09:00.000Z","size":196449,"stargazers_count":100,"open_issues_count":65,"forks_count":541,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-05-13T00:14:41.132Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.openshift.org","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openshift.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"security/install.go","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-10-26T17:54:59.000Z","updated_at":"2025-05-10T23:36:37.000Z","dependencies_parsed_at":"2025-04-11T20:34:48.614Z","dependency_job_id":"210d4767-38fe-46d3-b610-81494635f31a","html_url":"https://github.com/openshift/api","commit_stats":{"total_commits":1845,"total_committers":243,"mean_commits":7.592592592592593,"dds":0.8623306233062331,"last_synced_commit":"1957a8d7445bf2332f027f93a24d7573f77a0dc0"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openshift%2Fapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openshift%2Fapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openshift%2Fapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openshift%2Fapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openshift","download_url":"https://codeload.github.com/openshift/api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253843225,"owners_count":21972874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T05:35:25.499Z","updated_at":"2025-05-13T00:15:07.522Z","avatar_url":"https://github.com/openshift.png","language":"Go","readme":"# api\nThe canonical location of the OpenShift API definition.\nThis repo holds the API type definitions and serialization code used by [openshift/client-go](https://github.com/openshift/client-go)\nAPIs in this repo ship inside OCP payloads.\n\n## Adding new FeatureGates\nAdd your FeatureGate to `features.go`.\nThe threshold for merging a fully disabled or TechPreview FeatureGate is an open enhancement.\nTo promote to Default on any ClusterProfile, the threshold is 99% passing tests on all platforms or QE sign off.\n\n### Adding new TechPreview FeatureGate to all ClusterProfiles (Hypershift and SelfManaged)\n```go\nFeatureGateMyFeatureName = newFeatureGate(\"MyFeatureName\").\n\t\t\treportProblemsToJiraComponent(\"my-jira-component\").\n\t\t\tcontactPerson(\"my-team-lead\").\n\t\t\tproductScope(ocpSpecific).\n\t\t\tenableIn(TechPreviewNoUpgrade).\n\t\t\tmustRegister()\n```\n\n### Adding new TechPreview FeatureGate to all only Hypershift\nThis will be enabled in TechPreview on Hypershift, but never enabled on SelfManaged\n```go\nFeatureGateMyFeatureName = newFeatureGate(\"MyFeatureName\").\n\t\t\treportProblemsToJiraComponent(\"my-jira-component\").\n\t\t\tcontactPerson(\"my-team-lead\").\n\t\t\tproductScope(ocpSpecific).\n\t\t\tenableForClusterProfile(Hypershift, TechPreviewNoUpgrade).\n\t\t\tmustRegister()\n```\n\n### Promoting to Default, but only on Hypershift\nThis will be enabled in TechPreview on all ClusterProfiles and also by Default on Hypershift.\nIt will be disabled in Default on SelfManaged.\n```go\nFeatureGateMyFeatureName = newFeatureGate(\"MyFeatureName\").\n\t\t\treportProblemsToJiraComponent(\"my-jira-component\").\n\t\t\tcontactPerson(\"my-team-lead\").\n\t\t\tproductScope([ocpSpecific|kubernetes]).\n\t\t\tenableIn(TechPreviewNoUpgrade).\n\t\t\tenableForClusterProfile(Hypershift, Default).\n\t\t\tmustRegister()\n```\n\n### Promoting to Default on all ClusterProfiles\n```go\nFeatureGateMyFeatureName = newFeatureGate(\"MyFeatureName\").\n\t\t\treportProblemsToJiraComponent(\"my-jira-component\").\n\t\t\tcontactPerson(\"my-team-lead\").\n\t\t\tproductScope([ocpSpecific|kubernetes]).\n            enableIn(Default, TechPreviewNoUpgrade).\n\t\t\tmustRegister()\n```\n\n### defining API validation tests\nTests are logically associated with FeatureGates.\nWhen adding any FeatureGated functionality a new test file is required.\nThe test files are located in `\u003cgroup\u003e/\u003cversion\u003e/tests/\u003ccrd-name\u003e/FeatureGate.yaml`:\n```\nroute/\n  v1/\n    tests/\n      routes.route.openshift.io/\n        AAA_ungated.yaml\n        RouteExternalCertificate.yaml\n```\nHere's an `AAA_ungated.yaml` example:\n```yaml\napiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this.\nname: Route\ncrdName: routes.route.openshift.io\ntests:\n```\n\nHere's an `RouteExternalCertificate.yaml` example:\n```yaml\napiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this.\nname: Route\ncrdName: routes.route.openshift.io\nfeatureGate: RouteExternalCertificate\ntests:\n```\n\nThe integration tests use the crdName and featureGate to determine which tests apply to which manifests and automatically\nreact to changes when the FeatureGates are enabled/disabled on various FeatureSets and ClusterProfiles.\n\n[`gen-minimal-test.sh`](tests/hack/gen-minimal-test.sh) can still function to stub out files if you don't want to\ncopy/paste an existing one.\n\n### defining FeatureGate e2e tests\n\nIn order to move an API into the `Default` FeatureSet, it is necessary to demonstrate completeness and reliability.\nE2E tests are the ONLY category of test that automatically prevents regression over time: repository presubmits do NOT provide equivalent protection.\nTo confirm this, there is an automated verify script that runs every time a FeatureGate is added to the `Default` FeatureSet.\nThe script queries our CI system (sippy/component readiness) to retrieve a list of all automated tests for a given FeatureGate\nand then enforces the following rules.\n1. Tests must contain either `[OCPFeatureGate:\u003cFeatureGateName\u003e]` or the standard upstream `[FeatureGate:\u003cFeatureGateName\u003e]`.\n2. There must be at least five tests for each FeatureGate.\n3. Every test must be run on every TechPreview platform we have jobs for.  (Ask for an exception if your feature doesn't support a variant.)\n4. Every test must run at least 14 times on every platform/variant.\n5. Every test must pass at least 95% of the time on every platform/variant.\n\nIf your FeatureGate lacks automated testing, there is an exception process that allows QE to sign off on the promotion by \ncommenting on the PR.\n\n\n## defining new APIs\n\nWhen defining a new API, please follow [the OpenShift API\nconventions](https://github.com/openshift/enhancements/blob/master/CONVENTIONS.md#api),\nand then follow the instructions below to regenerate CRDs (if necessary) and\nsubmit a pull request with your new API definitions and generated files.\n\nNew APIs (new CRDs) must be added first as an unstable API (v1alpha1).\nOnce the feature is more developed, and ready to be promoted to stable, the API can be promoted to v1.\n\n### Why do we start with v1alpha1?\n\nBy starting an API as a v1alpha1, we can iterate on the API with the ability to make breaking changes.\nWe can make changes to the schema, change validations, change entire types and even serialization without worry.\n\nWhen changes are made to an API, any existing client code will need to be updated to match.\nIf there are breaking changes (such as changing the serialization), then this requires a new version of the API.\n\nIf we did not bump the API version for each breaking change, a client, generated prior to the breaking change,\nwould panic when it tried to deserialize the new serialization of the API.\n\nIf, during development of a feature, we need to make a breaking change, we should move the feature to v1alpha2 (or v1alpha3, etc),\nuntil we reach a version that we are happy to promote to v1.\n\nDo not make changes to the API when promoting the feature to v1.\n\n### Adding a new stable API (v1)\nWhen copying, it matters which `// +foo` markers are two comments blocks up and which are one comment block up.\n\n```go\n// +genclient\n// +genclient:nonNamespaced\n// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object\n// the next line of whitespace matters\n\n// MyAPI is amazing, let me describe it!\n//\n// Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).\n// +openshift:compatibility-gen:level=1\n// +openshift:file-pattern=cvoRunLevel=0000_50,operatorName=my-operator,operatorOrdering=01\n// +kubebuilder:object:root=true\n// +kubebuilder:subresource:status\n// +kubebuilder:resource:path=myapis,scope=Cluster\n// +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/\u003cthis PR number\u003e\n// +openshift:capability=IfYouHaveOne\n// +kubebuilder:printcolumn:name=Column Name,JSONPath=.status.something,type=string,description=how users should interpret this.\n// +kubebuilder:metadata:annotations=key=value\n// +kubebuilder:metadata:labels=key=value\n// +kubebuilder:validation:XValidation:rule=\ntype MyAPI struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\n\t// metadata is the standard object's metadata.\n\t// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata\n\tmetav1.ObjectMeta `json:\"metadata,omitempty\"`\n\n\t// spec is the desired state of the cluster version - the operator will work\n\t// to ensure that the desired version is applied to the cluster.\n\t// +kubebuilder:validation:Required\n\tSpec MyAPISpec `json:\"spec\"`\n\t// status contains information about the available updates and any in-progress\n\t// updates.\n\t// +optional\n\tStatus MyAPIStatus `json:\"status\"`\n}\n\n```\n\n### Adding a new unstable API (v1alpha) \nFirst, add a FeatureGate as described above.\n\nLike above, but there's an additional\n\n```go\n// +kubebuilder:validation:XValidation:rule=\n// +openshift:enable:FeatureGate=MyFeatureGate\ntype MyAPI struct {\n\t...\n}\n```\n\n### Adding new fields\nHere are few other use-cases for convenience, but have a look in `./example` for other possibilities. \n\n\n```go\n// +openshift:validation:FeatureGateAwareXValidation:featureGate=MyFeatureGate,rule=\"has(oldSelf.coolNewField) ? has(self.coolNewField) : true\",message=\"coolNewField may not be removed once set\"\ntype MyAPI struct {\n    // +openshift:enable:FeatureGate=MyFeatureGate\n    // +optional\n    CoolNewField string `json:\"coolNewField\"`\n}\n\n// EvolvingDiscriminator defines the audit policy profile type.\n// +openshift:validation:FeatureGateAwareEnum:featureGate=\"\",enum=\"\";StableValue\n// +openshift:validation:FeatureGateAwareEnum:featureGate=MyFeatureGate,enum=\"\";StableValue;TechPreviewOnlyValue\ntype EvolvingDiscriminator string\n\nconst (\n  // \"StableValue\" is always present.\n  StableValue EvolvingDiscriminator = \"StableValue\"\n\n  // \"TechPreviewOnlyValue\" should only be allowed when TechPreviewNoUpgrade is set in the cluster\n  TechPreviewOnlyValue EvolvingDiscriminator = \"TechPreviewOnlyValue\"\n)\n\n```\n\n\n### required labels\n\nIn addition to the standard `lgtm` and `approved` labels this repository requires either:\n\n`bugzilla/valid-bug` - applied if your PR references a valid bugzilla bug\n\nOR\n\n`qe-approved`, `docs-approved`, and `px-approved` - these labels can be applied by anyone in the openshift org via the `/label` command.\n\nWho should apply these qe/docs/px labels?\n- For a no-FF team who is merging a feature before code freeze, they need to get those labels applied to their api repo PR by the appropriate teams (i.e. qe, docs, px)\n- For a FF(traditional) team who is merging a feature before FF, they can self-apply the labels(via /label commands), they are basically irrelevant for those teams\n- For a FF team who is merging a feature after FF, the PR should be rejected barring an exception\n\nWhy are these labels needed?\n\nWe need a way for no-FF teams to be able to merge post-FF that does not require a BZ.  For non-shared repos that mechanism is the \nqe/docs/px-approved labels.  We are expanding that mechanism to shared repos because the alternative would be that no-FF teams would\nput a dummy `bugzilla/valid-bug` label on their feature PRs in order to be able to merge them after feature freeze.  Since most\nindividuals can't apply a `bugzilla/valid-bug` label to a PR, this introduces additional obstacles on those PRs.  Conversely, anyone\ncan apply the docs/qe/px-approved labels, so \"FF\" teams that need to apply these labels to merge can do so w/o needing to involve\nanyone additional.\n\nDoes this mean feature-freeze teams can use the no-FF process to merge code?\n\nNo, signing a team up to be a no-FF team includes some basic education on the process and includes ensuring the associated QE+Docs\nparticipants are aware the team is moving to that model.  If you'd like to sign your team up, please speak with Gina Hargan who will\nbe happy to help on-board your team.\n\n## vendoring generated manifests into other repositories\nIf your repository relies on vendoring and copying CRD manifests (good job!), you'll need have an import line that\ndepends on the package that contains the CRD manifests.\nFor example, adding\n```go\nimport (\n\t_ \"github.com/openshift/api/operatoringress/v1/zz_generated.crd-manifests\"\n)\n```\nto any .go file will work, but some commonly chosen files are `tools/tools.go` or `pkg/dependencymagnet/doc.go`.\nOnce added, a `go mod vendor` will pick up the package containing the manifests for you to copy.\n\n## generating CRD schemas\n\nSince Kubernetes 1.16, every CRD created in `apiextensions.k8s.io/v1` is required to have a [structural OpenAPIV3 schema](https://kubernetes.io/blog/2019/06/20/crd-structural-schema/). The schemas provide server-side validation for fields, as well as providing the descriptions for `oc explain`. Moreover, schemas ensure structural consistency of data in etcd. Without it anything can be stored in a resource which can have security implications. As we host many of our CRDs in this repo along with their corresponding Go types we also require them to have schemas. However, the following instructions apply for CRDs that are not hosted here as well.\n\nThese schemas are often very long and complex, and should not be written by hand. For OpenShift, we provide Makefile targets in [build-machinery-go](https://github.com/openshift/build-machinery-go/) which generate the schema, built on upstream's [controller-gen](https://github.com/kubernetes-sigs/controller-tools) tool.\n\nIf you make a change to a CRD type in this repo, simply calling `make update-codegen-crds` should regenerate all CRDs and update the manifests. If yours is not updated, ensure that the path to its API is included in our [calls to the Makefile targets](https://github.com/openshift/api/blob/release-4.5/Makefile#L17-L29), if this doesn't help try calling `make generate-with-container` for executing the generators in a controlled environment.\n\nTo add this generator to another repo:\n1. Vendor `github.com/openshift/build-machinery-go`\n\n2. Update your `Makefile` to include the following:\n```\ninclude $(addprefix ./vendor/github.com/openshift/build-machinery-go/make/, \\\n  targets/openshift/crd-schema-gen.mk \\\n)\n\n$(call add-crd-gen,\u003cTARGET_NAME\u003e,\u003cAPI_DIRECTORY\u003e,\u003cCRD_MANIFESTS\u003e,\u003cMANIFEST_OUTPUT\u003e)\n```\nThe parameters for the call are:\n\n1. `TARGET_NAME`: The name of your generated Make target. This can be anything, as long as it does not conflict with another make target. Recommended to be your api name.\n2. `API_DIRECTORY`: The location of your API. For example if your Go types are located under `pkg/apis/myoperator/v1/types.go`, this should be `./pkg/apis/myoperator/v1`.\n3. `CRD_MANIFESTS`: The directory your CRDs are located in. For example, if that is `manifests/my_operator.crd.yaml` then it should be `./manifests`\n4. `MANIFEST_OUTPUT`: This should most likely be the same as `CRD_MANIFESTS`, and is only provided for flexibility to output generated code to a different directory.\n\nYou can include as many calls to different APIs as necessary, or if you have multiple APIs under the same directory (eg, `v1` and `v2beta1`) you can use 1 call to the parent directory pointing to your API.\n\nAfter this, calling `make update-codegen-crds` should generate a new structural OpenAPIV3 schema for your CRDs.\n\n**Notes** \n- This will not generate entire CRDs, only their OpenAPIV3 schemas. If you do not already have a CRD, you will get no output from the generator.\n- Ensure that your API is correctly declared for the generator to pick it up. That means, in your `doc.go`, include the following:\n  1. `// +groupName=\u003cAPI_GROUP_NAME\u003e`, this should match the `group` in your CRD `spec`\n  2. `// +kubebuilder:validation:Optional`, this tells the operator that fields should be optional unless explicitly marked with `// +kubebuilder:validation:Required`\n  \nFor more information on the API markers to add to your Go types, see the [Kubebuilder book](https://book.kubebuilder.io/reference/markers.html)\n\n### Order of generation\n`make update-codegen-crds` does roughly this:\n\n1. Run the `empty-partial-schema` tool.  This creates empty CRD manifests in `zz_generated.featuregated-crd-manifests` for each FeatureGate.\n2. Run the `schemapatch` tool.  This fills in the schema for each per-FeatureGate CRD manifest.\n3. Run the `manifest-merge` tool.  This combines all the per-FeatureGate CRD manifests and `manual-overrides`\n\n#### empty-partial-schema\nThis tool is gengo based and scans all types for a `// +kubebuilder:object:root=true` marker.\nFor each type match, the type is navigated and all tags that include a `featureGate`\n(`// +openshift:enable:FeatureGate`, `// +openshift:validation:FeatureGateAwareEnum`, and `// +openshift:validation:FeatureGateAwareXValidation`)\nare tracked.\nFor each type, for each FeatureGate, a file CRD manifest is created in `zz_generated.featuregated-crd-manifests`.\nThe most common kube-builder tags are re-implemented in this stage to fill in the non-schema portion of the CRD manifests.\nThis includes things like metadata, resource, and some custom openshift tags as well.\n\nThe generator ignores the schema when doing verify, so it doesn't fail on needing to run `schemapatch`.\nThe generator should clean up old FeatureGated manifests when the gate is removed.\nUngated files are created for resources that are sometimes ungated.\nAnnotations are injected to indicate which FeatureGate a manifest is for: this is later read by `schemapatch` and `manifest-merge`.\n\n#### schemapatch\nThis tool is kubebuilder based with patches to handle FeatureGated types, members, and validation.\nIt reads the injected annotation from `empty-partial-schema` to decide which FeatureGate should be considered enabled when\ncreating the schema that needs to be injected.\nIt has no knowledge of whether the FeatureGate is enabled or disabled in particular ClusterProfile,FeatureSet tuples.\nIt only needs a single pass over all the FeatureGated partial manifests.\n\nIf the schema generation isn't doing what you want, `manual-override-crd-manifests` allows partially overlaying bits of the CRD manifest.\n`yamlpatch` is no longer supported.\nThe format is just \"write the CRD you want and delete the stuff the generator sets properly\".\nMore specifically, it is the partial manifest that server-side-apply (structured merge diff) would properly merge on top of\nthe CRD that is generated otherwise.\nCaveat, you cannot test this with a kube-apiserver because the CRD schema uses atomic lists and we had to patch that\nschema to indicate map lists keyed by version.\n\n#### manifest-merge\nThis tool is gengo based and it combines the files in `zz_generated.featuregated-crd-manifests` and `manual-override-crd-manifests`\non a per ClusterProfile,FeatureSet tuple.\nThis tool takes as input all possible ClusterProfiles and all possible FeatureSets.\nIt then maps from ClusterProfile,FeatureSet tuple to the set of enabled and disabled FeatureGates.\nThen for each CRD,ClusterProfile,Feature tuple, it merges the pertinent input using structured-merge-diff (SSA) logic\nbased on the CRD schema plus a patch to make atomic fields map-lists.\nPertinence is determined based on\n1. does this manifest have preferred ClusterProfile annotations: if so, honor them; if not, include everywhere.\n2. does this manifest have FeatureGate annotations: if so, match against the enabled set for the ClusterProfile,FeatureSet tuple.\n   Note that CustomNoUpgrade selects everything\n\nOnce we have CRD for each ClusterProfile,FeatureSet tuple we choose what to serialize.\nThis roughly follows:\n1. if all the CRDs are the same, write a single file and annotate with no FeatureSet and every ClusterProfile. Done.\n2. if all the CRDs are the same across all ClusterProfiles for each FeatureSet, create one file per FeatureSet and\n   annotate with one FeatureSet and all ClusterProfiles. Done.\n3. if all the CRDs are the same across all FeatureSets for one ClusterProfile, create one file and annotate\n   with no FeatureSet and one ClusterProfile. Continue to 4.\n4. for all remaining ClusterProfile,FeatureSet tuples, serialize a file with one FeatureSet and one ClusterProfile.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenshift%2Fapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenshift%2Fapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenshift%2Fapi/lists"}