diff --git a/go.mod b/go.mod index cedfc70e44..9894c27409 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/openshift/client-go v0.0.0-20260512113608-deb4dc54551a github.com/openshift/library-go v0.0.0-20260515094948-509d00758cf2 github.com/openshift/multi-operator-manager v0.0.0-20241205181422-20aa3906b99d - github.com/openshift/oauth-apiserver v0.0.0-20260430140618-160ac7fb4ea6 + github.com/openshift/oauth-apiserver v0.0.0-20260520145010-97a820bd5412 github.com/spf13/cobra v1.10.0 github.com/spf13/pflag v1.0.9 github.com/stretchr/testify v1.11.1 @@ -133,3 +133,5 @@ require ( ) replace github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 + +replace github.com/openshift/api => github.com/everettraven/openshift-api v0.0.0-20260507192020-4affa2ac4dea diff --git a/go.sum b/go.sum index 870daddf93..bf7d504840 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/everettraven/openshift-api v0.0.0-20260507192020-4affa2ac4dea h1:2Bw06Lh1m4KaiQIvjhz5Q06cZ5OBsT1lEwT0CVrY4EE= +github.com/everettraven/openshift-api v0.0.0-20260507192020-4affa2ac4dea/go.mod h1:pyVjK0nZ4sRs4fuQVQ4rubsJdahI1PB94LnQ8sGdvxo= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/felixge/fgprof v0.9.4 h1:ocDNwMFlnA0NU0zSB3I52xkO4sFXk80VK9lXjLClu88= github.com/felixge/fgprof v0.9.4/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM= @@ -146,8 +148,6 @@ github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/openshift-eng/openshift-tests-extension v0.0.0-20260408205138-ec501c2bf4a5 h1:FJmsOMCeFpAakgnVhHUoITcHLLW9/DrJJSAY1CZaLCA= github.com/openshift-eng/openshift-tests-extension v0.0.0-20260408205138-ec501c2bf4a5/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M= -github.com/openshift/api v0.0.0-20260511191110-9b69e5fa27e9 h1:yb8ul1HPFYhO04yp0D8T/qSySZnKv210f4nE//i/Bdg= -github.com/openshift/api v0.0.0-20260511191110-9b69e5fa27e9/go.mod h1:pyVjK0nZ4sRs4fuQVQ4rubsJdahI1PB94LnQ8sGdvxo= github.com/openshift/build-machinery-go v0.0.0-20251023084048-5d77c1a5e5af h1:UiYYMi/CCV+kwWrXuXfuUSOY2yNXOpWpNVgHc6aLQlE= github.com/openshift/build-machinery-go v0.0.0-20251023084048-5d77c1a5e5af/go.mod h1:8jcm8UPtg2mCAsxfqKil1xrmRMI3a+XU2TZ9fF8A7TE= github.com/openshift/client-go v0.0.0-20260512113608-deb4dc54551a h1:EKx2XhOKehd1C5ptY7IrLl4WV35E8kP0pRPnG5BUZXk= @@ -156,8 +156,8 @@ github.com/openshift/library-go v0.0.0-20260515094948-509d00758cf2 h1:JoiqT7XZ4W github.com/openshift/library-go v0.0.0-20260515094948-509d00758cf2/go.mod h1:gKG9lctU0yEftSoT3DUyeIWz1oAgF0EHUpwI4pnCo4o= github.com/openshift/multi-operator-manager v0.0.0-20241205181422-20aa3906b99d h1:Rzx23P63JFNNz5D23ubhC0FCN5rK8CeJhKcq5QKcdyU= github.com/openshift/multi-operator-manager v0.0.0-20241205181422-20aa3906b99d/go.mod h1:iVi9Bopa5cLhjG5ie9DoZVVqkH8BGb1FQVTtecOLn4I= -github.com/openshift/oauth-apiserver v0.0.0-20260430140618-160ac7fb4ea6 h1:WvXToDt/IVTXb4NxbqEjY0cuPpVadTK6ATu75mlVM/s= -github.com/openshift/oauth-apiserver v0.0.0-20260430140618-160ac7fb4ea6/go.mod h1:VsfvQ75bRfxT1dBSh1zROlnpDHNUYuSxgUV6vTXtOqs= +github.com/openshift/oauth-apiserver v0.0.0-20260520145010-97a820bd5412 h1:oDB0GmUXLp8y85fWz+LGRE0hM5JqbXTfNPi5GjEqiX0= +github.com/openshift/oauth-apiserver v0.0.0-20260520145010-97a820bd5412/go.mod h1:qPt46oOj0jFGgpabBjMazsgQXwrJ7KYBDwAuaesJLdE= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 h1:PMTgifBcBRLJJiM+LgSzPDTk9/Rx4qS09OUrfpY6GBQ= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= diff --git a/pkg/controllers/externaloidc/generation/oauthapiserver/generate.go b/pkg/controllers/externaloidc/generation/oauthapiserver/generate.go index 83d9e10eb2..daec375073 100644 --- a/pkg/controllers/externaloidc/generation/oauthapiserver/generate.go +++ b/pkg/controllers/externaloidc/generation/oauthapiserver/generate.go @@ -9,6 +9,7 @@ import ( "io" "net/http" "net/url" + "regexp" "strings" "time" @@ -20,6 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/sets" authenticationcel "k8s.io/apiserver/pkg/authentication/cel" corev1listers "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/util/cert" @@ -128,6 +130,15 @@ func generateJWTForProvider(provider configv1.OIDCProvider, configMapLister core out.UserValidationRules = userValidationRules } + if featureGates.Enabled(features.FeatureGateExternalOIDCExternalClaimsSourcing) { + externalClaimsSources, err := generateExternalClaimsSources(configMapLister, secretLister, provider.ExternalClaimsSources...) + if err != nil { + return authenticationv1alpha1.JWTAuthenticator{}, fmt.Errorf("generating externalClaimsSources for provider %q: %v", provider.Name, err) + } + + out.ExternalClaimsSources = externalClaimsSources + } + out.Issuer = &issuer out.ClaimMappings = &claimMappings out.ClaimValidationRules = claimValidationRules @@ -752,3 +763,298 @@ func isConstField(exp *exprpb.Expr, field string) bool { c := exp.GetConstExpr() return c != nil && c.GetStringValue() == field } + +func generateExternalClaimsSources(cmLister corev1listers.ConfigMapLister, secretLister corev1listers.SecretLister, sources ...configv1.ExternalClaimsSource) ([]authenticationv1alpha1.ExternalClaimsSource, error) { + out := []authenticationv1alpha1.ExternalClaimsSource{} + seenClaimNames := sets.New[string]() + for _, source := range sources { + source, err := generateExternalClaimsSource(source, cmLister, secretLister, seenClaimNames) + if err != nil { + return nil, err + } + + if source != nil { + out = append(out, *source) + } + } + + return out, nil +} + +func generateExternalClaimsSource(source configv1.ExternalClaimsSource, cmLister corev1listers.ConfigMapLister, secretLister corev1listers.SecretLister, seenClaimNames sets.Set[string]) (*authenticationv1alpha1.ExternalClaimsSource, error) { + authentication, err := generateExternalClaimsSourceAuthentication(source.Authentication, secretLister, cmLister) + if err != nil { + return nil, err + } + + tls, err := generateExternalClaimsSourceTLS(source.TLS, cmLister) + if err != nil { + return nil, err + } + + url, err := generateExternalClaimsSourceURL(source.URL) + if err != nil { + return nil, err + } + + mappings, err := generateExternalClaimsSourceMappings(seenClaimNames, source.Mappings...) + if err != nil { + return nil, err + } + + conditions, err := generateExternalClaimsSourceConditions(source.Predicates...) + if err != nil { + return nil, err + } + + return &authenticationv1alpha1.ExternalClaimsSource{ + Authentication: authentication, + TLS: tls, + URL: url, + Mappings: mappings, + Conditions: conditions, + }, nil +} + +func generateExternalClaimsSourceAuthentication(externalSourceAuthentication configv1.ExternalSourceAuthentication, secretLister corev1listers.SecretLister, cmLister corev1listers.ConfigMapLister) (*authenticationv1alpha1.Authentication, error) { + switch externalSourceAuthentication.Type { + case "": // signals the omitted case which is valid and means to use anonymous auth. This means we should omit it as well so anonymous auth takes place. + return nil, nil + case configv1.ExternalSourceAuthenticationTypeRequestProvidedToken: + return &authenticationv1alpha1.Authentication{ + Type: ptr.To(authenticationv1alpha1.AuthenticationTypeRequestProvidedToken), + }, nil + case configv1.ExternalSourceAuthenticationTypeClientCredential: + cc, err := generateExternalClaimsSourceAuthenticationClientCredential(externalSourceAuthentication.ClientCredential, secretLister, cmLister) + if err != nil { + return nil, fmt.Errorf("generating client credentials configuration: %w", err) + } + + return &authenticationv1alpha1.Authentication{ + Type: ptr.To(authenticationv1alpha1.AuthenticationTypeClientCredential), + ClientCredential: cc, + }, nil + default: + return nil, fmt.Errorf("unknown external source authentication type %q", externalSourceAuthentication.Type) + } +} + +var printableASCIIRegexp = regexp.MustCompile(`^[[:print:]]+$`) + +func generateExternalClaimsSourceAuthenticationClientCredential(clientCredentialConfig configv1.ClientCredentialConfig, secretLister corev1listers.SecretLister, cmLister corev1listers.ConfigMapLister) (*authenticationv1alpha1.ClientCredentialConfig, error) { + // TODO: enable validation when it is possible to do so. Currently blocked + // due to oauth-apiserver not being rebased on 1.35 and the KAS library changes + // not existing in the 1.35 branch. + // The following jira tickets track the work necessary to eventually enable this validation: + // 1. https://redhat.atlassian.net/browse/CNTRLPLANE-3491 + // 2. https://redhat.atlassian.net/browse/CNTRLPLANE-3492 + // 3. https://redhat.atlassian.net/browse/CNTRLPLANE-3493 + /* + if err := validation.ValidateClientCredentialConfigClientID(clientCredentialConfig.ClientID, field.NewPath("")); err != nil { + return nil, fmt.Errorf("validating client id: %w", kubeErrorListToGoError(err)) + } + + if err := validation.ValidateTokenEndpoint(clientCredentialConfig.TokenEndpoint, field.NewPath("")); err != nil { + return nil, fmt.Errorf("validating token endpoint: %w", kubeErrorListToGoError(err)) + } + */ + + clientSecret, err := getClientSecretFromSecret(clientCredentialConfig.ClientSecret.Name, secretLister) + if err != nil { + return nil, fmt.Errorf("getting client secret: %w", err) + } + + // TODO: enable validation when it is possible to do so. Currently blocked + // due to oauth-apiserver not being rebased on 1.35 and the KAS library changes + // not existing in the 1.35 branch. + // The following jira tickets track the work necessary to eventually enable this validation: + // 1. https://redhat.atlassian.net/browse/CNTRLPLANE-3491 + // 2. https://redhat.atlassian.net/browse/CNTRLPLANE-3492 + // 3. https://redhat.atlassian.net/browse/CNTRLPLANE-3493 + /* + if err := validation.ValidateClientCredentialConfigClientSecret(clientSecret, field.NewPath("")); err != nil { + return nil, fmt.Errorf("validating client secret: %w", kubeErrorListToGoError(err)) + } + */ + + scopes, err := generateClientCredentialScopes(clientCredentialConfig.Scopes...) + if err != nil { + return nil, fmt.Errorf("generating scopes: %w", err) + } + + var certificateAuthority *string = nil + if len(clientCredentialConfig.TLS.CertificateAuthority.Name) > 0 { + ca, err := getCertificateAuthorityFromConfigMap(clientCredentialConfig.TLS.CertificateAuthority.Name, cmLister) + if err != nil { + return nil, fmt.Errorf("getting certificate authority: %w", err) + } + + certificateAuthority = &ca + } + + return &authenticationv1alpha1.ClientCredentialConfig{ + ClientID: clientCredentialConfig.ClientID, + ClientSecret: clientSecret, + TokenEndpoint: clientCredentialConfig.TokenEndpoint, + Scopes: scopes, + TLS: &authenticationv1alpha1.TLS{ + CertificateAuthority: certificateAuthority, + }, + }, nil +} + +func generateClientCredentialScopes(scopes ...configv1.OAuth2Scope) ([]string, error) { + out := make([]string, 0, len(scopes)) + errs := []error{} + for _, scope := range scopes { + // TODO: enable validation when it is possible to do so. Currently blocked + // due to oauth-apiserver not being rebased on 1.35 and the KAS library changes + // not existing in the 1.35 branch. + // The following jira tickets track the work necessary to eventually enable this validation: + // 1. https://redhat.atlassian.net/browse/CNTRLPLANE-3491 + // 2. https://redhat.atlassian.net/browse/CNTRLPLANE-3492 + // 3. https://redhat.atlassian.net/browse/CNTRLPLANE-3493 + /* + err := validation.ValidateClientCredentialConfigScope(string(scope), field.NewPath("")) + if err != nil { + errs = append(errs, fmt.Errorf("validating scopes[%s]: %w", i, kubeErrorListToGoError(err))) + continue + } + */ + + out = append(out, string(scope)) + } + + return out, errors.Join(errs...) +} + +func getClientSecretFromSecret(name string, secretLister corev1listers.SecretLister) (string, error) { + secret, err := secretLister.Secrets(configNamespace).Get(name) + if err != nil { + return "", fmt.Errorf("could not retrieve auth secret %s/%s to get client secret: %v", configNamespace, name, err) + } + + clientSecret, ok := secret.Data["client-secret"] + if !ok || len(clientSecret) == 0 { + return "", fmt.Errorf("secret %s/%s key \"client-secret\" missing or empty", configNamespace, name) + } + + return string(clientSecret), nil +} + +func generateExternalClaimsSourceTLS(externalSourceTLS configv1.ExternalSourceTLS, cmLister corev1listers.ConfigMapLister) (*authenticationv1alpha1.TLS, error) { + caData, err := getCertificateAuthorityFromConfigMap(externalSourceTLS.CertificateAuthority.Name, cmLister) + if err != nil { + return nil, fmt.Errorf("getting certificate authority for external source: %w", err) + } + + return &authenticationv1alpha1.TLS{ + CertificateAuthority: &caData, + }, nil +} + +func generateExternalClaimsSourceURL(sourceURL configv1.SourceURL) (*authenticationv1alpha1.SourceURL, error) { + // TODO: enable validation when it is possible to do so. Currently blocked + // due to oauth-apiserver not being rebased on 1.35 and the KAS library changes + // not existing in the 1.35 branch. + // The following jira tickets track the work necessary to eventually enable this validation: + // 1. https://redhat.atlassian.net/browse/CNTRLPLANE-3491 + // 2. https://redhat.atlassian.net/browse/CNTRLPLANE-3492 + // 3. https://redhat.atlassian.net/browse/CNTRLPLANE-3493 + /* + if err := validation.ValidateExternalClaimsSourceURLHostname(&sourceURL.Hostname, field.NewPath("")); err != nil { + return nil, fmt.Errorf("validating hostname: %w", kubeErrorListToGoError(err)) + } + + if err := validation.ValidateExternalClaimsSourceURLPathExpression(externaloidccel.NewCompiler(), &sourceURL.PathExpression, field.NewPath("")); err != nil { + return nil, fmt.Errorf("validating path expression: %w", kubeErrorListToGoError(err)) + } + */ + + return &authenticationv1alpha1.SourceURL{ + Hostname: &sourceURL.Hostname, + PathExpression: &sourceURL.PathExpression, + }, nil +} + +func generateExternalClaimsSourceMappings(seenClaimNames sets.Set[string], sourcedClaimMappings ...configv1.SourcedClaimMapping) ([]authenticationv1alpha1.SourcedClaimMapping, error) { + out := make([]authenticationv1alpha1.SourcedClaimMapping, 0, len(sourcedClaimMappings)) + + errs := []error{} + for _, sourcedClaimMapping := range sourcedClaimMappings { + // TODO: enable validation when it is possible to do so. Currently blocked + // due to oauth-apiserver not being rebased on 1.35 and the KAS library changes + // not existing in the 1.35 branch. + // The following jira tickets track the work necessary to eventually enable this validation: + // 1. https://redhat.atlassian.net/browse/CNTRLPLANE-3491 + // 2. https://redhat.atlassian.net/browse/CNTRLPLANE-3492 + // 3. https://redhat.atlassian.net/browse/CNTRLPLANE-3493 + /* + if err := validation.ValidateExternalClaimsSourceMappingName(&sourcedClaimMapping.Name, seenClaimNames, field.NewPath("")); err != nil { + errs = append(errs, fmt.Errorf("validating mappings[%d]: validating name %q: %w", i, sourcedClaimMapping.Name, kubeErrorListToGoError(err))) + continue + } + + if err := validation.ValidateExternalClaimsSourceMappingExpression(externaloidccel.NewCompiler(), &sourcedClaimMapping.Expression, field.NewPath("")); err != nil { + errs = append(errs, fmt.Errorf("validating mappings[%d]: validating expression %q: %w", i, sourcedClaimMapping.Expression, kubeErrorListToGoError(err))) + continue + } + */ + + out = append(out, authenticationv1alpha1.SourcedClaimMapping{ + Name: &sourcedClaimMapping.Name, + Expression: &sourcedClaimMapping.Expression, + }) + } + + return out, errors.Join(errs...) +} + +func generateExternalClaimsSourceConditions(externalSourcePredicates ...configv1.ExternalSourcePredicate) ([]authenticationv1alpha1.ExternalSourceCondition, error) { + out := make([]authenticationv1alpha1.ExternalSourceCondition, 0, len(externalSourcePredicates)) + + errs := []error{} + // seenConditions := sets.New[string]() + for _, predicate := range externalSourcePredicates { + // TODO: enable validation when it is possible to do so. Currently blocked + // due to oauth-apiserver not being rebased on 1.35 and the KAS library changes + // not existing in the 1.35 branch. + // The following jira tickets track the work necessary to eventually enable this validation: + // 1. https://redhat.atlassian.net/browse/CNTRLPLANE-3491 + // 2. https://redhat.atlassian.net/browse/CNTRLPLANE-3492 + // 3. https://redhat.atlassian.net/browse/CNTRLPLANE-3493 + /* + cond := authentication.ExternalSourceCondition{ + Expression: &predicate.Expression, + } + + if err := validation.ValidateExternalSourceCondition(externaloidccel.NewCompiler(), cond, seenConditions, field.NewPath("")); err != nil { + errs = append(errs, fmt.Errorf("validating predicates[%d]: validating expression %q: %w", i, predicate.Expression, kubeErrorListToGoError(err))) + } + */ + + out = append(out, authenticationv1alpha1.ExternalSourceCondition{ + Expression: &predicate.Expression, + }) + } + + return out, errors.Join(errs...) +} + +// TODO: enable validation when it is possible to do so. Currently blocked +// due to oauth-apiserver not being rebased on 1.35 and the KAS library changes +// not existing in the 1.35 branch. +// The following jira tickets track the work necessary to eventually enable this validation: +// 1. https://redhat.atlassian.net/browse/CNTRLPLANE-3491 +// 2. https://redhat.atlassian.net/browse/CNTRLPLANE-3492 +// 3. https://redhat.atlassian.net/browse/CNTRLPLANE-3493 +/* +func kubeErrorListToGoError(list field.ErrorList) error { + errs := make([]error, 0, len(list)) + for _, err := range list { + errs = append(errs, errors.New(fmt.Sprintf("%s: %s", err.Type.String(), err.Detail))) + } + + return errors.Join(errs...) +} +*/ diff --git a/pkg/controllers/externaloidc/generation/oauthapiserver/generate_test.go b/pkg/controllers/externaloidc/generation/oauthapiserver/generate_test.go index 9ddc7dc797..cf116718ad 100644 --- a/pkg/controllers/externaloidc/generation/oauthapiserver/generate_test.go +++ b/pkg/controllers/externaloidc/generation/oauthapiserver/generate_test.go @@ -1233,6 +1233,570 @@ func TestAuthenticationConfigurationGeneratorGenerateAuthenticationConfiguration }, ), }, + { + name: "valid auth config with external claims source using request provided token auth and conditions, success", + caBundleConfigMap: &baseCABundleConfigMap, + configMapIndexer: func() cache.Indexer { + idx := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) + idx.Add(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ext-source-ca-bundle", + Namespace: configNamespace, + }, + Data: map[string]string{ + "ca-bundle.crt": testCertData, + }, + }) + return idx + }(), + auth: *authWithUpdates(baseAuthResource, []func(auth *configv1.Authentication){ + func(auth *configv1.Authentication) { + for i := range auth.Spec.OIDCProviders { + auth.Spec.OIDCProviders[i].Issuer.URL = "https://example.com" + auth.Spec.OIDCProviders[i].ExternalClaimsSources = []configv1.ExternalClaimsSource{ + { + Authentication: configv1.ExternalSourceAuthentication{ + Type: configv1.ExternalSourceAuthenticationTypeRequestProvidedToken, + }, + TLS: configv1.ExternalSourceTLS{ + CertificateAuthority: configv1.ExternalSourceCertificateAuthorityConfigMapReference{ + Name: "ext-source-ca-bundle", + }, + }, + URL: configv1.SourceURL{ + Hostname: "claims.example.com", + PathExpression: "claims.sub", + }, + Mappings: []configv1.SourcedClaimMapping{ + { + Name: "custom_claim", + Expression: "response.custom_claim", + }, + }, + Predicates: []configv1.ExternalSourcePredicate{ + { + Expression: "has(claims.sub)", + }, + }, + }, + } + } + }, + }), + expectedAuthConfig: authConfigWithUpdates(baseAuthConfig, []func(authConfig *authenticationv1alpha1.AuthenticationConfiguration){ + func(authConfig *authenticationv1alpha1.AuthenticationConfiguration) { + for i := range authConfig.JWT { + authConfig.JWT[i].Issuer.URL = "https://example.com" + authConfig.JWT[i].ExternalClaimsSources = []authenticationv1alpha1.ExternalClaimsSource{ + { + Authentication: &authenticationv1alpha1.Authentication{ + Type: ptr.To(authenticationv1alpha1.AuthenticationTypeRequestProvidedToken), + }, + TLS: &authenticationv1alpha1.TLS{ + CertificateAuthority: ptr.To(testCertData), + }, + URL: &authenticationv1alpha1.SourceURL{ + Hostname: ptr.To("claims.example.com"), + PathExpression: ptr.To("claims.sub"), + }, + Mappings: []authenticationv1alpha1.SourcedClaimMapping{ + { + Name: ptr.To("custom_claim"), + Expression: ptr.To("response.custom_claim"), + }, + }, + Conditions: []authenticationv1alpha1.ExternalSourceCondition{ + { + Expression: ptr.To("has(claims.sub)"), + }, + }, + }, + } + } + }, + }), + expectError: false, + featureGates: featuregates.NewFeatureGate( + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCExternalClaimsSourcing, + }, + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCWithAdditionalClaimMappings, + features.FeatureGateExternalOIDCWithUpstreamParity, + }, + ), + }, + { + name: "valid auth config with external claims source using anonymous auth, success", + caBundleConfigMap: &baseCABundleConfigMap, + configMapIndexer: func() cache.Indexer { + idx := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) + idx.Add(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ext-source-ca-bundle", + Namespace: configNamespace, + }, + Data: map[string]string{ + "ca-bundle.crt": testCertData, + }, + }) + return idx + }(), + auth: *authWithUpdates(baseAuthResource, []func(auth *configv1.Authentication){ + func(auth *configv1.Authentication) { + for i := range auth.Spec.OIDCProviders { + auth.Spec.OIDCProviders[i].Issuer.URL = "https://example.com" + auth.Spec.OIDCProviders[i].ExternalClaimsSources = []configv1.ExternalClaimsSource{ + { + TLS: configv1.ExternalSourceTLS{ + CertificateAuthority: configv1.ExternalSourceCertificateAuthorityConfigMapReference{ + Name: "ext-source-ca-bundle", + }, + }, + URL: configv1.SourceURL{ + Hostname: "claims.example.com", + PathExpression: "claims.sub", + }, + Mappings: []configv1.SourcedClaimMapping{ + { + Name: "custom_claim", + Expression: "response.custom_claim", + }, + }, + }, + } + } + }, + }), + expectedAuthConfig: authConfigWithUpdates(baseAuthConfig, []func(authConfig *authenticationv1alpha1.AuthenticationConfiguration){ + func(authConfig *authenticationv1alpha1.AuthenticationConfiguration) { + for i := range authConfig.JWT { + authConfig.JWT[i].Issuer.URL = "https://example.com" + authConfig.JWT[i].ExternalClaimsSources = []authenticationv1alpha1.ExternalClaimsSource{ + { + TLS: &authenticationv1alpha1.TLS{ + CertificateAuthority: ptr.To(testCertData), + }, + URL: &authenticationv1alpha1.SourceURL{ + Hostname: ptr.To("claims.example.com"), + PathExpression: ptr.To("claims.sub"), + }, + Mappings: []authenticationv1alpha1.SourcedClaimMapping{ + { + Name: ptr.To("custom_claim"), + Expression: ptr.To("response.custom_claim"), + }, + }, + }, + } + } + }, + }), + expectError: false, + featureGates: featuregates.NewFeatureGate( + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCExternalClaimsSourcing, + }, + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCWithAdditionalClaimMappings, + features.FeatureGateExternalOIDCWithUpstreamParity, + }, + ), + }, + { + name: "valid auth config with external claims source using client credential auth", + caBundleConfigMap: &baseCABundleConfigMap, + configMapIndexer: func() cache.Indexer { + idx := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) + idx.Add(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ext-source-ca-bundle", + Namespace: configNamespace, + }, + Data: map[string]string{ + "ca-bundle.crt": testCertData, + }, + }) + idx.Add(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cc-tls-ca-bundle", + Namespace: configNamespace, + }, + Data: map[string]string{ + "ca-bundle.crt": testCertData, + }, + }) + return idx + }(), + secretIndexer: func() cache.Indexer { + idx := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) + idx.Add(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "client-secret-ref", + Namespace: configNamespace, + }, + Data: map[string][]byte{ + "client-secret": []byte("my-secret-value"), + }, + }) + return idx + }(), + auth: *authWithUpdates(baseAuthResource, []func(auth *configv1.Authentication){ + func(auth *configv1.Authentication) { + for i := range auth.Spec.OIDCProviders { + auth.Spec.OIDCProviders[i].Issuer.URL = "https://example.com" + auth.Spec.OIDCProviders[i].ExternalClaimsSources = []configv1.ExternalClaimsSource{ + { + Authentication: configv1.ExternalSourceAuthentication{ + Type: configv1.ExternalSourceAuthenticationTypeClientCredential, + ClientCredential: configv1.ClientCredentialConfig{ + ClientID: "my-client-id", + ClientSecret: configv1.ClientSecretSecretReference{ + Name: "client-secret-ref", + }, + TokenEndpoint: "https://idp.example.com/oauth2/token", + Scopes: []configv1.OAuth2Scope{"openid", "profile"}, + TLS: configv1.ExternalSourceTLS{ + CertificateAuthority: configv1.ExternalSourceCertificateAuthorityConfigMapReference{ + Name: "cc-tls-ca-bundle", + }, + }, + }, + }, + TLS: configv1.ExternalSourceTLS{ + CertificateAuthority: configv1.ExternalSourceCertificateAuthorityConfigMapReference{ + Name: "ext-source-ca-bundle", + }, + }, + URL: configv1.SourceURL{ + Hostname: "claims.example.com", + PathExpression: "claims.sub", + }, + Mappings: []configv1.SourcedClaimMapping{ + { + Name: "custom_claim", + Expression: "response.custom_claim", + }, + }, + }, + } + } + }, + }), + expectedAuthConfig: authConfigWithUpdates(baseAuthConfig, []func(authConfig *authenticationv1alpha1.AuthenticationConfiguration){ + func(authConfig *authenticationv1alpha1.AuthenticationConfiguration) { + for i := range authConfig.JWT { + authConfig.JWT[i].Issuer.URL = "https://example.com" + authConfig.JWT[i].ExternalClaimsSources = []authenticationv1alpha1.ExternalClaimsSource{ + { + Authentication: &authenticationv1alpha1.Authentication{ + Type: ptr.To(authenticationv1alpha1.AuthenticationTypeClientCredential), + ClientCredential: &authenticationv1alpha1.ClientCredentialConfig{ + ClientID: "my-client-id", + ClientSecret: "my-secret-value", + TokenEndpoint: "https://idp.example.com/oauth2/token", + Scopes: []string{"openid", "profile"}, + TLS: &authenticationv1alpha1.TLS{ + CertificateAuthority: ptr.To(testCertData), + }, + }, + }, + TLS: &authenticationv1alpha1.TLS{ + CertificateAuthority: ptr.To(testCertData), + }, + URL: &authenticationv1alpha1.SourceURL{ + Hostname: ptr.To("claims.example.com"), + PathExpression: ptr.To("claims.sub"), + }, + Mappings: []authenticationv1alpha1.SourcedClaimMapping{ + { + Name: ptr.To("custom_claim"), + Expression: ptr.To("response.custom_claim"), + }, + }, + }, + } + } + }, + }), + expectError: false, + featureGates: featuregates.NewFeatureGate( + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCExternalClaimsSourcing, + }, + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCWithAdditionalClaimMappings, + features.FeatureGateExternalOIDCWithUpstreamParity, + }, + ), + }, + { + name: "auth config with external claims source with unknown auth type, error", + caBundleConfigMap: &baseCABundleConfigMap, + auth: *authWithUpdates(baseAuthResource, []func(auth *configv1.Authentication){ + func(auth *configv1.Authentication) { + for i := range auth.Spec.OIDCProviders { + auth.Spec.OIDCProviders[i].Issuer.URL = "https://example.com" + auth.Spec.OIDCProviders[i].ExternalClaimsSources = []configv1.ExternalClaimsSource{ + { + Authentication: configv1.ExternalSourceAuthentication{ + Type: configv1.ExternalSourceAuthenticationType("UnknownType"), + }, + TLS: configv1.ExternalSourceTLS{ + CertificateAuthority: configv1.ExternalSourceCertificateAuthorityConfigMapReference{ + Name: "ext-source-ca-bundle", + }, + }, + URL: configv1.SourceURL{ + Hostname: "claims.example.com", + PathExpression: "claims.sub", + }, + Mappings: []configv1.SourcedClaimMapping{ + { + Name: "custom_claim", + Expression: "response.custom_claim", + }, + }, + }, + } + } + }, + }), + expectError: true, + featureGates: featuregates.NewFeatureGate( + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCExternalClaimsSourcing, + }, + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCWithAdditionalClaimMappings, + features.FeatureGateExternalOIDCWithUpstreamParity, + }, + ), + }, + { + name: "auth config with external claims source with missing TLS CA configmap, error", + caBundleConfigMap: &baseCABundleConfigMap, + auth: *authWithUpdates(baseAuthResource, []func(auth *configv1.Authentication){ + func(auth *configv1.Authentication) { + for i := range auth.Spec.OIDCProviders { + auth.Spec.OIDCProviders[i].Issuer.URL = "https://example.com" + auth.Spec.OIDCProviders[i].ExternalClaimsSources = []configv1.ExternalClaimsSource{ + { + Authentication: configv1.ExternalSourceAuthentication{ + Type: configv1.ExternalSourceAuthenticationTypeRequestProvidedToken, + }, + TLS: configv1.ExternalSourceTLS{ + CertificateAuthority: configv1.ExternalSourceCertificateAuthorityConfigMapReference{ + Name: "nonexistent-ca-bundle", + }, + }, + URL: configv1.SourceURL{ + Hostname: "claims.example.com", + PathExpression: "claims.sub", + }, + Mappings: []configv1.SourcedClaimMapping{ + { + Name: "custom_claim", + Expression: "response.custom_claim", + }, + }, + }, + } + } + }, + }), + expectError: true, + featureGates: featuregates.NewFeatureGate( + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCExternalClaimsSourcing, + }, + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCWithAdditionalClaimMappings, + features.FeatureGateExternalOIDCWithUpstreamParity, + }, + ), + }, + { + name: "auth config with external claims source with client secret key missing in secret, error", + caBundleConfigMap: &baseCABundleConfigMap, + secretIndexer: func() cache.Indexer { + idx := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) + idx.Add(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "client-secret-ref", + Namespace: configNamespace, + }, + Data: map[string][]byte{ + "wrong-key": []byte("my-secret-value"), + }, + }) + return idx + }(), + auth: *authWithUpdates(baseAuthResource, []func(auth *configv1.Authentication){ + func(auth *configv1.Authentication) { + for i := range auth.Spec.OIDCProviders { + auth.Spec.OIDCProviders[i].Issuer.URL = "https://example.com" + auth.Spec.OIDCProviders[i].ExternalClaimsSources = []configv1.ExternalClaimsSource{ + { + Authentication: configv1.ExternalSourceAuthentication{ + Type: configv1.ExternalSourceAuthenticationTypeClientCredential, + ClientCredential: configv1.ClientCredentialConfig{ + ClientID: "my-client-id", + ClientSecret: configv1.ClientSecretSecretReference{ + Name: "client-secret-ref", + }, + TokenEndpoint: "https://idp.example.com/oauth2/token", + }, + }, + TLS: configv1.ExternalSourceTLS{ + CertificateAuthority: configv1.ExternalSourceCertificateAuthorityConfigMapReference{ + Name: "ext-source-ca-bundle", + }, + }, + URL: configv1.SourceURL{ + Hostname: "claims.example.com", + PathExpression: "claims.sub", + }, + Mappings: []configv1.SourcedClaimMapping{ + { + Name: "custom_claim", + Expression: "response.custom_claim", + }, + }, + }, + } + } + }, + }), + expectError: true, + featureGates: featuregates.NewFeatureGate( + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCExternalClaimsSourcing, + }, + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCWithAdditionalClaimMappings, + features.FeatureGateExternalOIDCWithUpstreamParity, + }, + ), + }, + + { + name: "auth config with external claims source configured but feature gate disabled", + caBundleConfigMap: &baseCABundleConfigMap, + auth: *authWithUpdates(baseAuthResource, []func(auth *configv1.Authentication){ + func(auth *configv1.Authentication) { + for i := range auth.Spec.OIDCProviders { + auth.Spec.OIDCProviders[i].Issuer.URL = "https://example.com" + auth.Spec.OIDCProviders[i].ExternalClaimsSources = []configv1.ExternalClaimsSource{ + { + Authentication: configv1.ExternalSourceAuthentication{ + Type: configv1.ExternalSourceAuthenticationTypeRequestProvidedToken, + }, + }, + } + } + }, + }), + expectedAuthConfig: authConfigWithUpdates(baseAuthConfig, []func(authConfig *authenticationv1alpha1.AuthenticationConfiguration){ + func(authConfig *authenticationv1alpha1.AuthenticationConfiguration) { + for i := range authConfig.JWT { + authConfig.JWT[i].Issuer.URL = "https://example.com" + } + }, + }), + expectError: false, + featureGates: featuregates.NewFeatureGate( + []configv1.FeatureGateName{}, + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCWithAdditionalClaimMappings, + features.FeatureGateExternalOIDCWithUpstreamParity, + features.FeatureGateExternalOIDCExternalClaimsSourcing, + }, + ), + }, + // TODO: Add tests for validating currently unvalidated fields due to dependency issues (CEL expression validation) + // The following jira tickets track the work necessary to eventually enable this validation: + // 1. https://redhat.atlassian.net/browse/CNTRLPLANE-3491 + // 2. https://redhat.atlassian.net/browse/CNTRLPLANE-3492 + // 3. https://redhat.atlassian.net/browse/CNTRLPLANE-3493 + /* + { + name: "auth config with duplicate mapping names across external claims sources", + caBundleConfigMap: &baseCABundleConfigMap, + configMapIndexer: func() cache.Indexer { + idx := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) + idx.Add(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ext-source-ca-bundle", + Namespace: configNamespace, + }, + Data: map[string]string{ + "ca-bundle.crt": testCertData, + }, + }) + return idx + }(), + auth: *authWithUpdates(baseAuthResource, []func(auth *configv1.Authentication){ + func(auth *configv1.Authentication) { + for i := range auth.Spec.OIDCProviders { + auth.Spec.OIDCProviders[i].Issuer.URL = "https://example.com" + auth.Spec.OIDCProviders[i].ExternalClaimsSources = []configv1.ExternalClaimsSource{ + { + Authentication: configv1.ExternalSourceAuthentication{ + Type: configv1.ExternalSourceAuthenticationTypeRequestProvidedToken, + }, + TLS: configv1.ExternalSourceTLS{ + CertificateAuthority: configv1.ExternalSourceCertificateAuthorityConfigMapReference{ + Name: "ext-source-ca-bundle", + }, + }, + URL: configv1.SourceURL{ + Hostname: "source-one.example.com", + PathExpression: "claims.sub", + }, + Mappings: []configv1.SourcedClaimMapping{ + { + Name: "custom_claim", + Expression: "response.custom_claim", + }, + }, + }, + { + Authentication: configv1.ExternalSourceAuthentication{ + Type: configv1.ExternalSourceAuthenticationTypeRequestProvidedToken, + }, + TLS: configv1.ExternalSourceTLS{ + CertificateAuthority: configv1.ExternalSourceCertificateAuthorityConfigMapReference{ + Name: "ext-source-ca-bundle", + }, + }, + URL: configv1.SourceURL{ + Hostname: "source-two.example.com", + PathExpression: "claims.sub", + }, + Mappings: []configv1.SourcedClaimMapping{ + { + Name: "custom_claim", + Expression: "response.other_claim", + }, + }, + }, + } + } + }, + }), + expectError: true, + featureGates: featuregates.NewFeatureGate( + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCExternalClaimsSourcing, + }, + []configv1.FeatureGateName{ + features.FeatureGateExternalOIDCWithAdditionalClaimMappings, + features.FeatureGateExternalOIDCWithUpstreamParity, + }, + ), + }, + */ } { t.Run(tt.name, func(t *testing.T) { if tt.configMapIndexer == nil { diff --git a/vendor/github.com/openshift/api/config/v1/types_apiserver.go b/vendor/github.com/openshift/api/config/v1/types_apiserver.go index 7de714ebfb..b92a04ed06 100644 --- a/vendor/github.com/openshift/api/config/v1/types_apiserver.go +++ b/vendor/github.com/openshift/api/config/v1/types_apiserver.go @@ -209,7 +209,6 @@ type APIServerNamedServingCert struct { } // APIServerEncryption is used to encrypt sensitive resources on the cluster. -// +openshift:validation:FeatureGateAwareXValidation:featureGate=KMSEncryption,rule="has(self.type) && self.type == 'KMS' ? has(self.kms) : !has(self.kms)",message="kms config is required when encryption type is KMS, and forbidden otherwise" // +union type APIServerEncryption struct { // type defines what encryption type should be used to encrypt resources at the datastore layer. @@ -241,7 +240,7 @@ type APIServerEncryption struct { // +openshift:enable:FeatureGate=KMSEncryption // +unionMember // +optional - KMS KMSPluginConfig `json:"kms,omitempty,omitzero"` + KMS *KMSConfig `json:"kms,omitempty"` } // +openshift:validation:FeatureGateAwareEnum:featureGate="",enum="";identity;aescbc;aesgcm diff --git a/vendor/github.com/openshift/api/config/v1/types_authentication.go b/vendor/github.com/openshift/api/config/v1/types_authentication.go index 1a036bbb67..54a6d2107f 100644 --- a/vendor/github.com/openshift/api/config/v1/types_authentication.go +++ b/vendor/github.com/openshift/api/config/v1/types_authentication.go @@ -5,7 +5,7 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +genclient // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC;ExternalOIDCWithUIDAndExtraClaimMappings;ExternalOIDCWithUpstreamParity,rule="!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients) || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace == specC.componentNamespace && statusC.componentName == specC.componentName) || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP, oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC, oldC.componentNamespace == specC.componentNamespace && oldC.componentName == specC.componentName)))))",message="all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients" +// +openshift:validation:FeatureGateAwareXValidation:featureGate=ExternalOIDC;ExternalOIDCWithUIDAndExtraClaimMappings;ExternalOIDCWithUpstreamParity;ExternalOIDCExternalClaimsSourcing,rule="!has(self.spec.oidcProviders) || self.spec.oidcProviders.all(p, !has(p.oidcClients) || p.oidcClients.all(specC, self.status.oidcClients.exists(statusC, statusC.componentNamespace == specC.componentNamespace && statusC.componentName == specC.componentName) || (has(oldSelf.spec.oidcProviders) && oldSelf.spec.oidcProviders.exists(oldP, oldP.name == p.name && has(oldP.oidcClients) && oldP.oidcClients.exists(oldC, oldC.componentNamespace == specC.componentNamespace && oldC.componentName == specC.componentName)))))",message="all oidcClients in the oidcProviders must match their componentName and componentNamespace to either a previously configured oidcClient or they must exist in the status.oidcClients" // Authentication specifies cluster-wide settings for authentication (like OAuth and // webhook token authenticators). The canonical name of an instance is `cluster`. @@ -91,6 +91,7 @@ type AuthenticationSpec struct { // +openshift:enable:FeatureGate=ExternalOIDC // +openshift:enable:FeatureGate=ExternalOIDCWithUIDAndExtraClaimMappings // +openshift:enable:FeatureGate=ExternalOIDCWithUpstreamParity + // +openshift:enable:FeatureGate=ExternalOIDCExternalClaimsSourcing // +optional OIDCProviders []OIDCProvider `json:"oidcProviders,omitempty"` } @@ -245,6 +246,28 @@ type OIDCProvider struct { // +optional // +openshift:enable:FeatureGate=ExternalOIDCWithUpstreamParity UserValidationRules []TokenUserValidationRule `json:"userValidationRules,omitempty"` + + // externalClaimsSources is an optional field that can be used to configure + // sources, external to the token provided in a request, in which claims + // should be fetched from and made available to the claim mapping process + // that is used to build the identity of a token holder. + // + // For example, fetching additional user metadata from an OIDC provider's UserInfo endpoint. + // + // When not specified, only claims present in the token itself will be available + // in the claim mapping process. + // + // When specified, at least one external claim source must be specified and no more than 5 + // sources may be specified. + // + // +openshift:enable:FeatureGate=ExternalOIDCExternalClaimsSourcing + // + // +optional + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=5 + // +kubebuilder:validation:XValidation:rule="self.all(s, s.mappings.all(m, self.filter(s2, s2.mappings.exists(m2, m2.name == m.name)).size() == 1))",message="mapping names must be unique across all external claim sources." + // +listType=atomic + ExternalClaimsSources []ExternalClaimsSource `json:"externalClaimsSources,omitempty"` } // +kubebuilder:validation:MinLength=1 @@ -831,3 +854,324 @@ type TokenUserValidationRule struct { // +kubebuilder:validation:MaxLength=256 Message string `json:"message,omitempty"` } + +// ExternalClaimsSource provides the configuration for a single external claim source. +type ExternalClaimsSource struct { + // authentication is an optional field that configures how the apiserver authenticates with an external claims source. + // When not specified, anonymous authentication is used. + // + // +optional + Authentication ExternalSourceAuthentication `json:"authentication,omitzero"` + + // tls is an optional field that configures the http client TLS + // settings when fetching external claims from this source. + // + // When omitted, system default TLS settings will be used + // for fetching claims from the external source. + // + // +optional + TLS ExternalSourceTLS `json:"tls,omitzero"` + + // url is a required configuration of the URL + // for which the external claims are located. + // + // +required + URL SourceURL `json:"url,omitzero"` + + // mappings is a required list of the claim + // and response handling expression pairs + // that produces the claims from the external source. + // mappings must have at least 1 entry and must not exceed 16 entries. + // Entries must have a unique name across all external claim sources. + // + // +required + // +listType=map + // +listMapKey=name + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=16 + Mappings []SourcedClaimMapping `json:"mappings,omitempty"` + + // predicates is an optional list of constraints in + // which claims should attempt to be fetched from this + // external source. + // + // When omitted, claims are always attempted to be fetched + // from this external source. + // + // When specified, all predicates must evaluate to 'true' + // before claims are attempted to be fetched from this external source. + // predicates must have at least 1 entry and must not exceed 16 entries. + // Entries must have unique expressions. + // + // +optional + // +listType=map + // +listMapKey=expression + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=16 + Predicates []ExternalSourcePredicate `json:"predicates,omitempty"` +} + +// ExternalSourceAuthenticationType is the type of authentication that should be used +// when fetching claims from an external source. +// +// +enum +// +kubebuilder:validation:Enum=RequestProvidedToken;ClientCredential +type ExternalSourceAuthenticationType string + +const ( + // ExternalSourceAuthenticationTypeRequestProvidedToken is an ExternalSourceAuthenticationType + // that represents that the token being evaluated for authentication + // should be used for authenticating with the external claims source. + // This is useful for scenarios where a token has multiple audiences + // and scopes so that it can be used to access both the cluster and + // the UserInfo endpoint that contains additional information about the + // user not present in the token. + ExternalSourceAuthenticationTypeRequestProvidedToken ExternalSourceAuthenticationType = "RequestProvidedToken" + + // ExternalSourceAuthenticationTypeClientCredential is an ExternalSourceAuthenticationType + // that represents that the authenticator should use the OAuth2 + // client credentials grant flow to obtain an access token for + // authenticating with the external claims source. + // This is useful for scenarios such as fetching user information + // from Microsoft's Graph API where a separate client credential + // is needed to access the API. + ExternalSourceAuthenticationTypeClientCredential ExternalSourceAuthenticationType = "ClientCredential" +) + +// ExternalSourceAuthentication configures how the apiserver should attempt +// to authenticate with an external claims source. +// +// +kubebuilder:validation:XValidation:rule="self.type == 'ClientCredential' ? has(self.clientCredential) : !has(self.clientCredential)",message="clientCredential is required when type is ClientCredential, and forbidden otherwise" +type ExternalSourceAuthentication struct { + // type is a required field that sets the type of + // authentication method used by the authenticator + // when fetching external claims. + // + // Allowed values are 'RequestProvidedToken' and 'ClientCredential'. + // + // When set to 'RequestProvidedToken', the authenticator will + // use the token provided to the kube-apiserver as part of the + // request to authenticate with the external claims source. + // + // When set to 'ClientCredential', the authenticator will + // use the configured client-id, client-secret, and token endpoint + // to fetch an access token using the OAuth2 client credentials grant + // flow. The fetched access token will then be used to authenticate + // with the external claims source. + // + // +required + Type ExternalSourceAuthenticationType `json:"type,omitempty"` + + // clientCredential configures the client credentials + // and token endpoint to use to get an access token. + // clientCredential is required when type is 'ClientCredential', and forbidden otherwise. + // + // +optional + ClientCredential ClientCredentialConfig `json:"clientCredential,omitzero"` +} + +// ExternalSourceTLS configures the TLS options that the apiserver uses as a client +// when making a request to the external claim source. +type ExternalSourceTLS struct { + // certificateAuthority is a required reference to a ConfigMap in the openshift-config + // namespace that contains the CA certificate to use to validate TLS connections with the external claims source. + // + // +required + CertificateAuthority ExternalSourceCertificateAuthorityConfigMapReference `json:"certificateAuthority,omitzero"` +} + +// ClientCredentialConfig configures the client credentials and token endpoint +// to use to get an access token via the OAuth2 client credentials grant flow. +type ClientCredentialConfig struct { + // clientID is a required client identifier to use during the OAuth2 client credentials flow. + // clientID must be at least 1 character in length, must not exceed 256 characters in length, + // and must only contain printable ASCII characters. + // + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=256 + // +kubebuilder:validation:XValidation:rule="self.matches('^[[:print:]]+$')",message="clientID must only contain printable ASCII characters" + ClientID string `json:"clientID,omitempty"` + + // clientSecret is a required reference to a Secret in the openshift-config namespace to be used + // as the client secret during the OAuth2 client credentials flow. + // + // The key 'client-secret' is used to locate the client secret data in the Secret. + // + // +required + ClientSecret ClientSecretSecretReference `json:"clientSecret,omitzero"` + + // tokenEndpoint is a required URL to query for an access token using + // the client credential OAuth2 flow. + // tokenEndpoint must be at least 1 character in length and must not exceed 2048 characters in length. + // tokenEndpoint must be a valid HTTPS URL. + // tokenEndpoint must have a host and a path. + // tokenEndpoint must not contain query parameters, fragments, + // or user information (e.g., "user:password@host"). + // + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=2048 + // +kubebuilder:validation:XValidation:rule="isURL(self)",message="tokenEndpoint must be a valid HTTPS url" + // +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getScheme() == 'https'",message="tokenEndpoint must be a valid HTTPS url" + // +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getHost() != ''",message="tokenEndpoint must have a hostname" + // +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getEscapedPath() != ''",message="tokenEndpoint must have a path" + // +kubebuilder:validation:XValidation:rule="isURL(self) && url(self).getQuery() == {}",message="tokenEndpoint must not have query parameters" + // +kubebuilder:validation:XValidation:rule="isURL(self) && self.find('#(.+)$') == ''",message="tokenEndpoint must not have a fragment" + // +kubebuilder:validation:XValidation:rule="isURL(self) && !self.matches('^https://[^/]+@.+$')",message="tokenEndpoint must not have user info" + TokenEndpoint string `json:"tokenEndpoint,omitempty"` + + // scopes is an optional list of OAuth2 scopes to request when obtaining + // an access token. + // + // If not specified, the token endpoint's default scopes + // will be used. + // + // When specified, there must be at least 1 entry and must not exceed 16 entries. + // Each entry must be at least 1 character in length and must not exceed 256 characters in length. + // Each entry must only contain printable ASCII characters, excluding spaces, double quotes and backslashes. + // Entries must be unique. + // + // +optional + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=16 + // +listType=set + Scopes []OAuth2Scope `json:"scopes,omitempty"` + + // tls is an optional field that allows configuring the TLS + // settings used to interact with the identity provider + // as an OAuth2 client. + // + // When omitted, system default TLS settings will be used + // for the OAuth2 client. + // + // +optional + TLS ExternalSourceTLS `json:"tls,omitzero"` +} + +// OAuth2Scope is a string alias that represents an OAuth2 Scope as defined by https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.4 +// +// +kubebuilder:validation:XValidation:rule="self.matches('^[!#-[\\\\]-~]+$')",message="scopes must only contain printable ASCII characters excluding spaces, double quotes and backslashes" +// +kubebuilder:validation:MinLength=1 +// +kubebuilder:validation:MaxLength=256 +type OAuth2Scope string + +// SourceURL configures the options used to build the URL that is queried for external claims. +type SourceURL struct { + // hostname is a required hostname for which the external claims are located. + // + // It must be a valid DNS subdomain name as per RFC1123. + // + // This means that it must start and end with a lowercase alphanumeric character, + // must only consist of lowercase alphanumeric characters, '-', and '.'. + // hostname must be at least 1 character in length and must not exceed 253 characters in length. + // hostname may optionally specify a port in the format ':{port}'. + // If a port is specified it must not exceed 65535. + // + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=259 + // +kubebuilder:validation:XValidation:rule="isURL('https://'+self)",message="hostname must be a valid hostname" + // +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self.split(':')[0]).hasValue()",message="hostname before port must start and end with a lowercase alphanumeric character, and must only contain lowercase alphanumeric characters, '-' or '.'" + // +kubebuilder:validation:XValidation:rule="self.split(':').size() > 1 ? int(self.split(':')[1]) <= 65535 : true",message="port must not exceed 65535" + Hostname string `json:"hostname,omitempty"` + + // pathExpression is a required CEL expression that returns a list + // of string values used to construct the URL path. + // Claims from the token used for the request to the kube-apiserver + // are made available via the `claims` variable. + // expression must be at least 1 character in length and must not exceed 1024 characters in length. + // + // Values in the returned list will be joined with the hostname using a forward slash + // (`/`) as a separator. Values in the returned list do not need to include the forward slash. + // + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=1024 + PathExpression string `json:"pathExpression,omitempty"` +} + +// SourcedClaimMapping configures the mapping behavior for a single external claim +// from the response the apiserver received from the external claim source. +type SourcedClaimMapping struct { + // name is a required name of the claim that + // will be produced and made available during + // the claim-to-identity mapping process. + // name must consist of only lowercase alpha characters and underscores ('_'). + // name must be at least 1 character and must not exceed 256 characters in length. + // + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=256 + // +kubebuilder:validation:XValidation:rule="self.matches('^[a-z_]+$')",message="name must consist of only lowercase alpha characters and underscores" + Name string `json:"name,omitempty"` + + // expression is a required CEL expression that + // will produce a value to be assigned to the claim. + // The full response body from the request to the + // external claim source is provided via the + // `response` variable. + // expression must be at least 1 character and must not exceed 1024 characters in length. + // + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=1024 + Expression string `json:"expression,omitempty"` +} + +// ExternalSourcePredicate configures a singular condition +// that must return true before the external source is queried +// to retrieve external claims. +type ExternalSourcePredicate struct { + // expression is a required CEL expression that + // is used to determine whether or not an external + // source should be used to fetch external claims. + // + // The expression must return a boolean value, + // where true means that the source should be consulted + // and false means that it should not. + // + // Claims from the token used for the request to the kube-apiserver + // are made available via the `claims` variable. + // + // expression must be at least 1 character and must not exceed 1024 characters in length. + // + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=1024 + Expression string `json:"expression,omitempty"` +} + +// CertificateAuthorityConfigMapReference is a reference to a ConfigMap in the openshift-config +// namespace that should be used for configuring the certificate authority to be +// used when sourcing claims from external sources. +type ExternalSourceCertificateAuthorityConfigMapReference struct { + // name is the required name of the ConfigMap that exists in the openshift-config namespace. + // + // It must be at least 1 character in length, must not exceed 253 characters in length, + // must start and end with a lowercase alphanumeric character, and must only contain + // lowercase alphanumeric characters, '-' or '.'. + // + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="name must start and end with a lowercase alphanumeric character, and must only contain lowercase alphanumeric characters, '-' or '.'" + Name string `json:"name,omitempty"` +} + +// ClientSecretSecretReference is a reference to a Secret in the openshift-config +// namespace that should be used for configuring the client secret to be +// used when sourcing claims from external sources with the client credential authentication flow. +type ClientSecretSecretReference struct { + // name is the required name of the Secret that exists in the openshift-config namespace. + // + // It must be at least 1 character in length, must not exceed 253 characters in length, + // must start and end with a lowercase alphanumeric character, and must only contain + // lowercase alphanumeric characters, '-' or '.'. + // + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="name must start and end with a lowercase alphanumeric character, and must only contain lowercase alphanumeric characters, '-' or '.'" + Name string `json:"name,omitempty"` +} diff --git a/vendor/github.com/openshift/api/config/v1/types_cluster_operator.go b/vendor/github.com/openshift/api/config/v1/types_cluster_operator.go index e934e83550..8323040389 100644 --- a/vendor/github.com/openshift/api/config/v1/types_cluster_operator.go +++ b/vendor/github.com/openshift/api/config/v1/types_cluster_operator.go @@ -160,9 +160,8 @@ const ( // is actively rolling out new code, propagating config changes (e.g, a version change), or otherwise // moving from one steady state to another. Operators should not report // Progressing when they are reconciling (without action) a previously known - // state. Operators should not report Progressing only because resources owned by them, - // such as DaemonSets and Deployments, are adjusting to a new node from cluster scaleup - // or a node rebooting from cluster upgrade. + // state. Operators should not report Progressing only because DaemonSets owned by them + // are adjusting to a new node from cluster scaleup or a node rebooting from cluster upgrade. // If the observed cluster state has changed and the component is // reacting to it (updated proxy configuration for instance), Progressing should become true // since it is moving from one steady state to another. diff --git a/vendor/github.com/openshift/api/config/v1/types_image.go b/vendor/github.com/openshift/api/config/v1/types_image.go index 96fa349a67..82f46c8b6c 100644 --- a/vendor/github.com/openshift/api/config/v1/types_image.go +++ b/vendor/github.com/openshift/api/config/v1/types_image.go @@ -165,50 +165,20 @@ type RegistryLocation struct { // +kubebuilder:validation:XValidation:rule="has(self.blockedRegistries) ? !has(self.allowedRegistries) : true",message="Only one of blockedRegistries or allowedRegistries may be set" type RegistrySources struct { // insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections. - // Each entry must be a valid registry scope in the format hostname[:port][/path], - // optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). - // The hostname must consist of valid DNS labels separated by dots, where each label - // contains only alphanumeric characters and hyphens and does not start or end with a hyphen. - // Entries must not be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), - // and must be at most 256 characters in length. The list may contain at most 1024 entries. // +optional // +listType=atomic - // +kubebuilder:validation:MaxItems=1024 - // +kubebuilder:validation:items:MinLength=1 - // +kubebuilder:validation:items:MaxLength=256 - // +kubebuilder:validation:items:XValidation:rule="self.matches('^\\\\*(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$')",message="each registry must be a valid hostname[:port][/path] or wildcard *.hostname format without tags or digests" InsecureRegistries []string `json:"insecureRegistries,omitempty"` // blockedRegistries cannot be used for image pull and push actions. All other registries are permitted. - // Each entry must be a valid registry scope in the format hostname[:port][/path], - // optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). - // The hostname must consist of valid DNS labels separated by dots, where each label - // contains only alphanumeric characters and hyphens and does not start or end with a hyphen. - // Entries must not be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), - // and must be at most 256 characters in length. The list may contain at most 1024 entries. // // Only one of BlockedRegistries or AllowedRegistries may be set. // +optional // +listType=atomic - // +kubebuilder:validation:MaxItems=1024 - // +kubebuilder:validation:items:MinLength=1 - // +kubebuilder:validation:items:MaxLength=256 - // +kubebuilder:validation:items:XValidation:rule="self.matches('^\\\\*(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$')",message="each registry must be a valid hostname[:port][/path] or wildcard *.hostname format without tags or digests" BlockedRegistries []string `json:"blockedRegistries,omitempty"` // allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied. - // Each entry must be a valid registry scope in the format hostname[:port][/path], - // optionally prefixed with "*." for wildcard subdomains (e.g., "*.example.com"). - // The hostname must consist of valid DNS labels separated by dots, where each label - // contains only alphanumeric characters and hyphens and does not start or end with a hyphen. - // Entries must not be empty, must not include tags (e.g., ":latest") or digests (e.g., "@sha256:..."), - // and must be at most 256 characters in length. The list may contain at most 1024 entries. // // Only one of BlockedRegistries or AllowedRegistries may be set. // +optional // +listType=atomic - // +kubebuilder:validation:MaxItems=1024 - // +kubebuilder:validation:items:MinLength=1 - // +kubebuilder:validation:items:MaxLength=256 - // +kubebuilder:validation:items:XValidation:rule="self.matches('^\\\\*(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+$|^((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\\\\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?$')",message="each registry must be a valid hostname[:port][/path] or wildcard *.hostname format without tags or digests" AllowedRegistries []string `json:"allowedRegistries,omitempty"` // containerRuntimeSearchRegistries are registries that will be searched when pulling images that do not have fully qualified // domains in their pull specs. Registries will be searched in the order provided in the list. diff --git a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go index e7680899d4..c579be3a11 100644 --- a/vendor/github.com/openshift/api/config/v1/types_infrastructure.go +++ b/vendor/github.com/openshift/api/config/v1/types_infrastructure.go @@ -295,8 +295,7 @@ type ExternalPlatformSpec struct { // PlatformSpec holds the desired state specific to the underlying infrastructure provider // of the current cluster. Since these are used at spec-level for the underlying cluster, it // is supposed that only one of the spec structs is set. -// +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="!has(oldSelf.vsphere) && has(self.vsphere) ? (has(self.vsphere.vcenters) && size(self.vsphere.vcenters) < 2) : true",message="vcenters can have at most 1 item when configured post-install" -// +openshift:validation:FeatureGateAwareXValidation:featureGate=VSphereMultiVCenterDay2,rule="oldSelf.?vsphere.vcenters.hasValue() ? self.?vsphere.vcenters.hasValue() : true",message="vcenters is required once set and cannot be removed" +// +kubebuilder:validation:XValidation:rule="!has(oldSelf.vsphere) && has(self.vsphere) ? size(self.vsphere.vcenters) < 2 : true",message="vcenters can have at most 1 item when configured post-install" type PlatformSpec struct { // type is the underlying infrastructure provider for the cluster. This // value controls whether infrastructure automation such as service load @@ -1642,24 +1641,21 @@ type VSpherePlatformNodeNetworking struct { // use these fields for configuration. // +kubebuilder:validation:XValidation:rule="!has(oldSelf.apiServerInternalIPs) || has(self.apiServerInternalIPs)",message="apiServerInternalIPs list is required once set" // +kubebuilder:validation:XValidation:rule="!has(oldSelf.ingressIPs) || has(self.ingressIPs)",message="ingressIPs list is required once set" +// +kubebuilder:validation:XValidation:rule="!has(oldSelf.vcenters) && has(self.vcenters) ? size(self.vcenters) < 2 : true",message="vcenters can have at most 1 item when configured post-install" type VSpherePlatformSpec struct { // vcenters holds the connection details for services to communicate with vCenter. - // Up to 3 vCenters are supported. + // Currently, only a single vCenter is supported, but in tech preview 3 vCenters are supported. // Once the cluster has been installed, you are unable to change the current number of defined - // vCenters except when 1.) the cluster has been upgraded from a version of OpenShift - // where the vsphere platform spec was not present or 2.) in TechPreview you are able to add and - // remove vCenters but may not remove all vCenters. You may make modifications to the existing + // vCenters except in the case where the cluster has been upgraded from a version of OpenShift + // where the vsphere platform spec was not present. You may make modifications to the existing // vCenters that are defined in the vcenters list in order to match with any added or modified // failure domains. // --- // + If VCenters is not defined use the existing cloud-config configmap defined // + in openshift-config. - // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MinItems=0 // +kubebuilder:validation:MaxItems=3 - // +openshift:validation:FeatureGateAwareXValidation:featureGate="",rule="size(self) != size(oldSelf) ? size(oldSelf) == 0 && size(self) < 2 : true",message="vcenters cannot be added or removed once set" - // +openshift:validation:FeatureGateAwareXValidation:featureGate=VSphereMultiVCenterDay2,rule="size(self) >= size(oldSelf) ? oldSelf.all(x, self.exists(y, y.server == x.server)) : true",message="Cannot add and remove vCenters at the same time" - // +openshift:validation:FeatureGateAwareXValidation:featureGate=VSphereMultiVCenterDay2,rule="size(self) < size(oldSelf) ? self.all(x, oldSelf.exists(y, y.server == x.server)) : true",message="Cannot add and remove vCenters at the same time" - // +kubebuilder:validation:XValidation:rule="self.all(x, self.exists_one(y, y.server == x.server))",message="vcenters must have unique server values" + // +kubebuilder:validation:XValidation:rule="size(self) != size(oldSelf) ? size(oldSelf) == 0 && size(self) < 2 : true",message="vcenters cannot be added or removed once set" // +listType=atomic // +optional VCenters []VSpherePlatformVCenterSpec `json:"vcenters,omitempty"` diff --git a/vendor/github.com/openshift/api/config/v1/types_kmsencryption.go b/vendor/github.com/openshift/api/config/v1/types_kmsencryption.go index 67e572b546..7ab8f782bb 100644 --- a/vendor/github.com/openshift/api/config/v1/types_kmsencryption.go +++ b/vendor/github.com/openshift/api/config/v1/types_kmsencryption.go @@ -1,10 +1,10 @@ package v1 -// KMSPluginConfig defines the configuration for the KMS instance +// KMSConfig defines the configuration for the KMS instance // that will be used with KMS encryption // +kubebuilder:validation:XValidation:rule="self.type == 'Vault' ? has(self.vault) : !has(self.vault)",message="vault config is required when kms provider type is Vault, and forbidden otherwise" // +union -type KMSPluginConfig struct { +type KMSConfig struct { // type defines the kind of platform for the KMS provider. // Allowed values are Vault. // When set to Vault, the plugin connects to a HashiCorp Vault server for key management. @@ -20,7 +20,7 @@ type KMSPluginConfig struct { // // +unionMember // +optional - Vault VaultKMSPluginConfig `json:"vault,omitempty,omitzero"` + Vault VaultKMSConfig `json:"vault,omitempty,omitzero"` // --- TOMBSTONE --- // aws was a field that allowed configuring AWS KMS. @@ -114,14 +114,16 @@ const ( type VaultAppRoleAuthentication struct { // secret references a secret in the openshift-config namespace containing // the AppRole credentials used to authenticate with Vault. - // The secret must contain two keys: "role-id" for the AppRole Role ID and "secret-id" for the AppRole Secret ID. + // The secret must contain two keys: "roleID" for the AppRole Role ID and "secretID" for the AppRole Secret ID. + // + // The namespace for the secret is openshift-config. // // +required Secret VaultSecretReference `json:"secret,omitzero"` } -// VaultKMSPluginConfig defines the KMS plugin configuration specific to Vault KMS -type VaultKMSPluginConfig struct { +// VaultKMSConfig defines the KMS plugin configuration specific to Vault KMS +type VaultKMSConfig struct { // kmsPluginImage specifies the container image for the HashiCorp Vault KMS plugin. // // The image must be a fully qualified OCI image pull spec with a SHA256 digest. @@ -192,35 +194,33 @@ type VaultKMSPluginConfig struct { Authentication VaultAuthentication `json:"authentication,omitzero"` // transitMount specifies the mount path of the Vault Transit engine. + // The value must be between 1 and 1024 characters when specified. // // When omitted, this means the user has no opinion and the platform is left // to choose a reasonable default. These defaults are subject to change over time. // The current default is "transit". // - // The transit mount must be between 1 and 1024 characters when specified, cannot start or - // end with a forward slash, cannot contain consecutive forward slashes, and must only contain - // RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward - // slashes as path separators. + // The mount path cannot start or end with a forward slash, cannot contain spaces, + // and cannot contain consecutive forward slashes. // // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=1024 // +kubebuilder:validation:XValidation:rule="!self.startsWith('/')",message="transitMount cannot start with a forward slash" // +kubebuilder:validation:XValidation:rule="!self.endsWith('/')",message="transitMount cannot end with a forward slash" + // +kubebuilder:validation:XValidation:rule="!self.contains(' ')",message="transitMount cannot contain spaces" // +kubebuilder:validation:XValidation:rule="!self.contains('//')",message="transitMount cannot contain consecutive forward slashes" - // +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._~/-]+$')",message="transitMount must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes" // +optional TransitMount string `json:"transitMount,omitempty"` // transitKey specifies the name of the encryption key in Vault's Transit engine. // This key is used to encrypt and decrypt data. // - // The transit key must be between 1 and 512 characters, cannot contain forward slashes, - // and must only contain alphanumeric characters, hyphens, periods, and underscores. + // The key name must be between 1 and 512 characters and cannot contain spaces or forward slashes. // // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=512 + // +kubebuilder:validation:XValidation:rule="!self.contains(' ')",message="transitKey cannot contain spaces" // +kubebuilder:validation:XValidation:rule="!self.contains('/')",message="transitKey cannot contain forward slashes" - // +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._-]+$')",message="transitKey must only contain alphanumeric characters, hyphens, periods, and underscores" // +required TransitKey string `json:"transitKey,omitempty"` } diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go index 1cb3cceaef..bca5d18192 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go @@ -42,7 +42,11 @@ func (in *APIServer) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *APIServerEncryption) DeepCopyInto(out *APIServerEncryption) { *out = *in - out.KMS = in.KMS + if in.KMS != nil { + in, out := &in.KMS, &out.KMS + *out = new(KMSConfig) + **out = **in + } return } @@ -144,7 +148,7 @@ func (in *APIServerSpec) DeepCopyInto(out *APIServerSpec) { *out = make([]string, len(*in)) copy(*out, *in) } - out.Encryption = in.Encryption + in.Encryption.DeepCopyInto(&out.Encryption) if in.TLSSecurityProfile != nil { in, out := &in.TLSSecurityProfile, &out.TLSSecurityProfile *out = new(TLSSecurityProfile) @@ -936,6 +940,45 @@ func (in *ClientConnectionOverrides) DeepCopy() *ClientConnectionOverrides { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientCredentialConfig) DeepCopyInto(out *ClientCredentialConfig) { + *out = *in + out.ClientSecret = in.ClientSecret + if in.Scopes != nil { + in, out := &in.Scopes, &out.Scopes + *out = make([]OAuth2Scope, len(*in)) + copy(*out, *in) + } + out.TLS = in.TLS + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientCredentialConfig. +func (in *ClientCredentialConfig) DeepCopy() *ClientCredentialConfig { + if in == nil { + return nil + } + out := new(ClientCredentialConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientSecretSecretReference) DeepCopyInto(out *ClientSecretSecretReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientSecretSecretReference. +func (in *ClientSecretSecretReference) DeepCopy() *ClientSecretSecretReference { + if in == nil { + return nil + } + out := new(ClientSecretSecretReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CloudControllerManagerStatus) DeepCopyInto(out *CloudControllerManagerStatus) { *out = *in @@ -2083,6 +2126,35 @@ func (in *EtcdStorageConfig) DeepCopy() *EtcdStorageConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalClaimsSource) DeepCopyInto(out *ExternalClaimsSource) { + *out = *in + in.Authentication.DeepCopyInto(&out.Authentication) + out.TLS = in.TLS + out.URL = in.URL + if in.Mappings != nil { + in, out := &in.Mappings, &out.Mappings + *out = make([]SourcedClaimMapping, len(*in)) + copy(*out, *in) + } + if in.Predicates != nil { + in, out := &in.Predicates, &out.Predicates + *out = make([]ExternalSourcePredicate, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalClaimsSource. +func (in *ExternalClaimsSource) DeepCopy() *ExternalClaimsSource { + if in == nil { + return nil + } + out := new(ExternalClaimsSource) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExternalIPConfig) DeepCopyInto(out *ExternalIPConfig) { *out = *in @@ -2168,6 +2240,72 @@ func (in *ExternalPlatformStatus) DeepCopy() *ExternalPlatformStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalSourceAuthentication) DeepCopyInto(out *ExternalSourceAuthentication) { + *out = *in + in.ClientCredential.DeepCopyInto(&out.ClientCredential) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSourceAuthentication. +func (in *ExternalSourceAuthentication) DeepCopy() *ExternalSourceAuthentication { + if in == nil { + return nil + } + out := new(ExternalSourceAuthentication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalSourceCertificateAuthorityConfigMapReference) DeepCopyInto(out *ExternalSourceCertificateAuthorityConfigMapReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSourceCertificateAuthorityConfigMapReference. +func (in *ExternalSourceCertificateAuthorityConfigMapReference) DeepCopy() *ExternalSourceCertificateAuthorityConfigMapReference { + if in == nil { + return nil + } + out := new(ExternalSourceCertificateAuthorityConfigMapReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalSourcePredicate) DeepCopyInto(out *ExternalSourcePredicate) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSourcePredicate. +func (in *ExternalSourcePredicate) DeepCopy() *ExternalSourcePredicate { + if in == nil { + return nil + } + out := new(ExternalSourcePredicate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalSourceTLS) DeepCopyInto(out *ExternalSourceTLS) { + *out = *in + out.CertificateAuthority = in.CertificateAuthority + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSourceTLS. +func (in *ExternalSourceTLS) DeepCopy() *ExternalSourceTLS { + if in == nil { + return nil + } + out := new(ExternalSourceTLS) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExtraMapping) DeepCopyInto(out *ExtraMapping) { *out = *in @@ -3811,18 +3949,18 @@ func (in *IntermediateTLSProfile) DeepCopy() *IntermediateTLSProfile { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KMSPluginConfig) DeepCopyInto(out *KMSPluginConfig) { +func (in *KMSConfig) DeepCopyInto(out *KMSConfig) { *out = *in out.Vault = in.Vault return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KMSPluginConfig. -func (in *KMSPluginConfig) DeepCopy() *KMSPluginConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KMSConfig. +func (in *KMSConfig) DeepCopy() *KMSConfig { if in == nil { return nil } - out := new(KMSPluginConfig) + out := new(KMSConfig) in.DeepCopyInto(out) return out } @@ -4824,6 +4962,13 @@ func (in *OIDCProvider) DeepCopyInto(out *OIDCProvider) { *out = make([]TokenUserValidationRule, len(*in)) copy(*out, *in) } + if in.ExternalClaimsSources != nil { + in, out := &in.ExternalClaimsSources, &out.ExternalClaimsSources + *out = make([]ExternalClaimsSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -6164,6 +6309,38 @@ func (in *SignatureStore) DeepCopy() *SignatureStore { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SourceURL) DeepCopyInto(out *SourceURL) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceURL. +func (in *SourceURL) DeepCopy() *SourceURL { + if in == nil { + return nil + } + out := new(SourceURL) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SourcedClaimMapping) DeepCopyInto(out *SourcedClaimMapping) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourcedClaimMapping. +func (in *SourcedClaimMapping) DeepCopy() *SourcedClaimMapping { + if in == nil { + return nil + } + out := new(SourcedClaimMapping) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Storage) DeepCopyInto(out *Storage) { *out = *in @@ -6929,19 +7106,19 @@ func (in *VaultConfigMapReference) DeepCopy() *VaultConfigMapReference { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VaultKMSPluginConfig) DeepCopyInto(out *VaultKMSPluginConfig) { +func (in *VaultKMSConfig) DeepCopyInto(out *VaultKMSConfig) { *out = *in out.TLS = in.TLS out.Authentication = in.Authentication return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultKMSPluginConfig. -func (in *VaultKMSPluginConfig) DeepCopy() *VaultKMSPluginConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultKMSConfig. +func (in *VaultKMSConfig) DeepCopy() *VaultKMSConfig { if in == nil { return nil } - out := new(VaultKMSPluginConfig) + out := new(VaultKMSConfig) in.DeepCopyInto(out) return out } diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml index ff232e723e..9744044bdf 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml @@ -31,6 +31,7 @@ authentications.config.openshift.io: Category: "" FeatureGates: - ExternalOIDC + - ExternalOIDCExternalClaimsSourcing - ExternalOIDCWithUIDAndExtraClaimMappings - ExternalOIDCWithUpstreamParity FilenameOperatorName: config-operator @@ -376,7 +377,6 @@ infrastructures.config.openshift.io: - OnPremDNSRecords - VSphereHostVMGroupZonal - VSphereMultiNetworks - - VSphereMultiVCenterDay2 FilenameOperatorName: config-operator FilenameOperatorOrdering: "01" FilenameRunLevel: "0000_10" diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go index 02900dbab8..d3379f70ea 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go @@ -388,6 +388,28 @@ func (AuthenticationStatus) SwaggerDoc() map[string]string { return map_AuthenticationStatus } +var map_ClientCredentialConfig = map[string]string{ + "": "ClientCredentialConfig configures the client credentials and token endpoint to use to get an access token via the OAuth2 client credentials grant flow.", + "clientID": "clientID is a required client identifier to use during the OAuth2 client credentials flow. clientID must be at least 1 character in length, must not exceed 256 characters in length, and must only contain printable ASCII characters.", + "clientSecret": "clientSecret is a required reference to a Secret in the openshift-config namespace to be used as the client secret during the OAuth2 client credentials flow.\n\nThe key 'client-secret' is used to locate the client secret data in the Secret.", + "tokenEndpoint": "tokenEndpoint is a required URL to query for an access token using the client credential OAuth2 flow. tokenEndpoint must be at least 1 character in length and must not exceed 2048 characters in length. tokenEndpoint must be a valid HTTPS URL. tokenEndpoint must have a host and a path. tokenEndpoint must not contain query parameters, fragments, or user information (e.g., \"user:password@host\").", + "scopes": "scopes is an optional list of OAuth2 scopes to request when obtaining an access token.\n\nIf not specified, the token endpoint's default scopes will be used.\n\nWhen specified, there must be at least 1 entry and must not exceed 16 entries. Each entry must be at least 1 character in length and must not exceed 256 characters in length. Each entry must only contain printable ASCII characters, excluding spaces, double quotes and backslashes. Entries must be unique.", + "tls": "tls is an optional field that allows configuring the TLS settings used to interact with the identity provider as an OAuth2 client.\n\nWhen omitted, system default TLS settings will be used for the OAuth2 client.", +} + +func (ClientCredentialConfig) SwaggerDoc() map[string]string { + return map_ClientCredentialConfig +} + +var map_ClientSecretSecretReference = map[string]string{ + "": "ClientSecretSecretReference is a reference to a Secret in the openshift-config namespace that should be used for configuring the client secret to be used when sourcing claims from external sources with the client credential authentication flow.", + "name": "name is the required name of the Secret that exists in the openshift-config namespace.\n\nIt must be at least 1 character in length, must not exceed 253 characters in length, must start and end with a lowercase alphanumeric character, and must only contain lowercase alphanumeric characters, '-' or '.'.", +} + +func (ClientSecretSecretReference) SwaggerDoc() map[string]string { + return map_ClientSecretSecretReference +} + var map_DeprecatedWebhookTokenAuthenticator = map[string]string{ "": "deprecatedWebhookTokenAuthenticator holds the necessary configuration options for a remote token authenticator. It's the same as WebhookTokenAuthenticator but it's missing the 'required' validation on KubeConfig field.", "kubeConfig": "kubeConfig contains kube config file data which describes how to access the remote webhook service. For further details, see: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication The key \"kubeConfig\" is used to locate the data. If the secret or expected key is not found, the webhook is not honored. If the specified kube config data is not valid, the webhook is not honored. The namespace for this secret is determined by the point of use.", @@ -397,6 +419,56 @@ func (DeprecatedWebhookTokenAuthenticator) SwaggerDoc() map[string]string { return map_DeprecatedWebhookTokenAuthenticator } +var map_ExternalClaimsSource = map[string]string{ + "": "ExternalClaimsSource provides the configuration for a single external claim source.", + "authentication": "authentication is an optional field that configures how the apiserver authenticates with an external claims source. When not specified, anonymous authentication is used.", + "tls": "tls is an optional field that configures the http client TLS settings when fetching external claims from this source.\n\nWhen omitted, system default TLS settings will be used for fetching claims from the external source.", + "url": "url is a required configuration of the URL for which the external claims are located.", + "mappings": "mappings is a required list of the claim and response handling expression pairs that produces the claims from the external source. mappings must have at least 1 entry and must not exceed 16 entries. Entries must have a unique name across all external claim sources.", + "predicates": "predicates is an optional list of constraints in which claims should attempt to be fetched from this external source.\n\nWhen omitted, claims are always attempted to be fetched from this external source.\n\nWhen specified, all predicates must evaluate to 'true' before claims are attempted to be fetched from this external source. predicates must have at least 1 entry and must not exceed 16 entries. Entries must have unique expressions.", +} + +func (ExternalClaimsSource) SwaggerDoc() map[string]string { + return map_ExternalClaimsSource +} + +var map_ExternalSourceAuthentication = map[string]string{ + "": "ExternalSourceAuthentication configures how the apiserver should attempt to authenticate with an external claims source.", + "type": "type is a required field that sets the type of authentication method used by the authenticator when fetching external claims.\n\nAllowed values are 'RequestProvidedToken' and 'ClientCredential'.\n\nWhen set to 'RequestProvidedToken', the authenticator will use the token provided to the kube-apiserver as part of the request to authenticate with the external claims source.\n\nWhen set to 'ClientCredential', the authenticator will use the configured client-id, client-secret, and token endpoint to fetch an access token using the OAuth2 client credentials grant flow. The fetched access token will then be used to authenticate with the external claims source.", + "clientCredential": "clientCredential configures the client credentials and token endpoint to use to get an access token. clientCredential is required when type is 'ClientCredential', and forbidden otherwise.", +} + +func (ExternalSourceAuthentication) SwaggerDoc() map[string]string { + return map_ExternalSourceAuthentication +} + +var map_ExternalSourceCertificateAuthorityConfigMapReference = map[string]string{ + "": "CertificateAuthorityConfigMapReference is a reference to a ConfigMap in the openshift-config namespace that should be used for configuring the certificate authority to be used when sourcing claims from external sources.", + "name": "name is the required name of the ConfigMap that exists in the openshift-config namespace.\n\nIt must be at least 1 character in length, must not exceed 253 characters in length, must start and end with a lowercase alphanumeric character, and must only contain lowercase alphanumeric characters, '-' or '.'.", +} + +func (ExternalSourceCertificateAuthorityConfigMapReference) SwaggerDoc() map[string]string { + return map_ExternalSourceCertificateAuthorityConfigMapReference +} + +var map_ExternalSourcePredicate = map[string]string{ + "": "ExternalSourcePredicate configures a singular condition that must return true before the external source is queried to retrieve external claims.", + "expression": "expression is a required CEL expression that is used to determine whether or not an external source should be used to fetch external claims.\n\nThe expression must return a boolean value, where true means that the source should be consulted and false means that it should not.\n\nClaims from the token used for the request to the kube-apiserver are made available via the `claims` variable.\n\nexpression must be at least 1 character and must not exceed 1024 characters in length.", +} + +func (ExternalSourcePredicate) SwaggerDoc() map[string]string { + return map_ExternalSourcePredicate +} + +var map_ExternalSourceTLS = map[string]string{ + "": "ExternalSourceTLS configures the TLS options that the apiserver uses as a client when making a request to the external claim source.", + "certificateAuthority": "certificateAuthority is a required reference to a ConfigMap in the openshift-config namespace that contains the CA certificate to use to validate TLS connections with the external claims source.", +} + +func (ExternalSourceTLS) SwaggerDoc() map[string]string { + return map_ExternalSourceTLS +} + var map_ExtraMapping = map[string]string{ "": "ExtraMapping allows specifying a key and CEL expression to evaluate the keys' value. It is used to create additional mappings and attributes added to a cluster identity from a provided authentication token.", "key": "key is a required field that specifies the string to use as the extra attribute key.\n\nkey must be a domain-prefix path (e.g 'example.org/foo'). key must not exceed 510 characters in length. key must contain the '/' character, separating the domain and path characters. key must not be empty.\n\nThe domain portion of the key (string of characters prior to the '/') must be a valid RFC1123 subdomain. It must not exceed 253 characters in length. It must start and end with an alphanumeric character. It must only contain lower case alphanumeric characters and '-' or '.'. It must not use the reserved domains, or be subdomains of, \"kubernetes.io\", \"k8s.io\", and \"openshift.io\".\n\nThe path portion of the key (string of characters after the '/') must not be empty and must consist of at least one alphanumeric character, percent-encoded octets, '-', '.', '_', '~', '!', '$', '&', ''', '(', ')', '*', '+', ',', ';', '=', and ':'. It must not exceed 256 characters in length.", @@ -445,12 +517,13 @@ func (OIDCClientStatus) SwaggerDoc() map[string]string { } var map_OIDCProvider = map[string]string{ - "name": "name is a required field that configures the unique human-readable identifier associated with the identity provider. It is used to distinguish between multiple identity providers and has no impact on token validation or authentication mechanics.\n\nname must not be an empty string (\"\").", - "issuer": "issuer is a required field that configures how the platform interacts with the identity provider and how tokens issued from the identity provider are evaluated by the Kubernetes API server.", - "oidcClients": "oidcClients is an optional field that configures how on-cluster, platform clients should request tokens from the identity provider. oidcClients must not exceed 20 entries and entries must have unique namespace/name pairs.", - "claimMappings": "claimMappings is a required field that configures the rules to be used by the Kubernetes API server for translating claims in a JWT token, issued by the identity provider, to a cluster identity.", - "claimValidationRules": "claimValidationRules is an optional field that configures the rules to be used by the Kubernetes API server for validating the claims in a JWT token issued by the identity provider.\n\nValidation rules are joined via an AND operation.", - "userValidationRules": "userValidationRules is an optional field that configures the set of rules used to validate the cluster user identity that was constructed via mapping token claims to user identity attributes. Rules are CEL expressions that must evaluate to 'true' for authentication to succeed. If any rule in the chain of rules evaluates to 'false', authentication will fail. When specified, at least one rule must be specified and no more than 64 rules may be specified.", + "name": "name is a required field that configures the unique human-readable identifier associated with the identity provider. It is used to distinguish between multiple identity providers and has no impact on token validation or authentication mechanics.\n\nname must not be an empty string (\"\").", + "issuer": "issuer is a required field that configures how the platform interacts with the identity provider and how tokens issued from the identity provider are evaluated by the Kubernetes API server.", + "oidcClients": "oidcClients is an optional field that configures how on-cluster, platform clients should request tokens from the identity provider. oidcClients must not exceed 20 entries and entries must have unique namespace/name pairs.", + "claimMappings": "claimMappings is a required field that configures the rules to be used by the Kubernetes API server for translating claims in a JWT token, issued by the identity provider, to a cluster identity.", + "claimValidationRules": "claimValidationRules is an optional field that configures the rules to be used by the Kubernetes API server for validating the claims in a JWT token issued by the identity provider.\n\nValidation rules are joined via an AND operation.", + "userValidationRules": "userValidationRules is an optional field that configures the set of rules used to validate the cluster user identity that was constructed via mapping token claims to user identity attributes. Rules are CEL expressions that must evaluate to 'true' for authentication to succeed. If any rule in the chain of rules evaluates to 'false', authentication will fail. When specified, at least one rule must be specified and no more than 64 rules may be specified.", + "externalClaimsSources": "externalClaimsSources is an optional field that can be used to configure sources, external to the token provided in a request, in which claims should be fetched from and made available to the claim mapping process that is used to build the identity of a token holder.\n\nFor example, fetching additional user metadata from an OIDC provider's UserInfo endpoint.\n\nWhen not specified, only claims present in the token itself will be available in the claim mapping process.\n\nWhen specified, at least one external claim source must be specified and no more than 5 sources may be specified.", } func (OIDCProvider) SwaggerDoc() map[string]string { @@ -466,6 +539,26 @@ func (PrefixedClaimMapping) SwaggerDoc() map[string]string { return map_PrefixedClaimMapping } +var map_SourceURL = map[string]string{ + "": "SourceURL configures the options used to build the URL that is queried for external claims.", + "hostname": "hostname is a required hostname for which the external claims are located.\n\nIt must be a valid DNS subdomain name as per RFC1123.\n\nThis means that it must start and end with a lowercase alphanumeric character, must only consist of lowercase alphanumeric characters, '-', and '.'. hostname must be at least 1 character in length and must not exceed 253 characters in length. hostname may optionally specify a port in the format ':{port}'. If a port is specified it must not exceed 65535.", + "pathExpression": "pathExpression is a required CEL expression that returns a list of string values used to construct the URL path. Claims from the token used for the request to the kube-apiserver are made available via the `claims` variable. expression must be at least 1 character in length and must not exceed 1024 characters in length.\n\nValues in the returned list will be joined with the hostname using a forward slash (`/`) as a separator. Values in the returned list do not need to include the forward slash.", +} + +func (SourceURL) SwaggerDoc() map[string]string { + return map_SourceURL +} + +var map_SourcedClaimMapping = map[string]string{ + "": "SourcedClaimMapping configures the mapping behavior for a single external claim from the response the apiserver received from the external claim source.", + "name": "name is a required name of the claim that will be produced and made available during the claim-to-identity mapping process. name must consist of only lowercase alpha characters and underscores ('_'). name must be at least 1 character and must not exceed 256 characters in length.", + "expression": "expression is a required CEL expression that will produce a value to be assigned to the claim. The full response body from the request to the external claim source is provided via the `response` variable. expression must be at least 1 character and must not exceed 1024 characters in length.", +} + +func (SourcedClaimMapping) SwaggerDoc() map[string]string { + return map_SourcedClaimMapping +} + var map_TokenClaimMapping = map[string]string{ "": "TokenClaimMapping allows specifying a JWT token claim to be used when mapping claims from an authentication token to cluster identities.", "claim": "claim is an optional field for specifying the JWT token claim that is used in the mapping. The value of this claim will be assigned to the field in which this mapping is associated. claim must not exceed 256 characters in length. When set to the empty string `\"\"`, this means that no named claim should be used for the group mapping. claim is required when the ExternalOIDCWithUpstreamParity feature gate is not enabled.", @@ -1165,9 +1258,9 @@ func (RegistryLocation) SwaggerDoc() map[string]string { var map_RegistrySources = map[string]string{ "": "RegistrySources holds cluster-wide information about how to handle the registries config.", - "insecureRegistries": "insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections. Each entry must be a valid registry scope in the format hostname[:port][/path], optionally prefixed with \"*.\" for wildcard subdomains (e.g., \"*.example.com\"). The hostname must consist of valid DNS labels separated by dots, where each label contains only alphanumeric characters and hyphens and does not start or end with a hyphen. Entries must not be empty, must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\"), and must be at most 256 characters in length. The list may contain at most 1024 entries.", - "blockedRegistries": "blockedRegistries cannot be used for image pull and push actions. All other registries are permitted. Each entry must be a valid registry scope in the format hostname[:port][/path], optionally prefixed with \"*.\" for wildcard subdomains (e.g., \"*.example.com\"). The hostname must consist of valid DNS labels separated by dots, where each label contains only alphanumeric characters and hyphens and does not start or end with a hyphen. Entries must not be empty, must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\"), and must be at most 256 characters in length. The list may contain at most 1024 entries.\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", - "allowedRegistries": "allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied. Each entry must be a valid registry scope in the format hostname[:port][/path], optionally prefixed with \"*.\" for wildcard subdomains (e.g., \"*.example.com\"). The hostname must consist of valid DNS labels separated by dots, where each label contains only alphanumeric characters and hyphens and does not start or end with a hyphen. Entries must not be empty, must not include tags (e.g., \":latest\") or digests (e.g., \"@sha256:...\"), and must be at most 256 characters in length. The list may contain at most 1024 entries.\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", + "insecureRegistries": "insecureRegistries are registries which do not have a valid TLS certificates or only support HTTP connections.", + "blockedRegistries": "blockedRegistries cannot be used for image pull and push actions. All other registries are permitted.\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", + "allowedRegistries": "allowedRegistries are the only registries permitted for image pull and push actions. All other registries are denied.\n\nOnly one of BlockedRegistries or AllowedRegistries may be set.", "containerRuntimeSearchRegistries": "containerRuntimeSearchRegistries are registries that will be searched when pulling images that do not have fully qualified domains in their pull specs. Registries will be searched in the order provided in the list. Note: this search list only works with the container runtime, i.e CRI-O. Will NOT work with builds or imagestream imports.", } @@ -2082,7 +2175,7 @@ func (VSpherePlatformNodeNetworkingSpec) SwaggerDoc() map[string]string { var map_VSpherePlatformSpec = map[string]string{ "": "VSpherePlatformSpec holds the desired state of the vSphere infrastructure provider. In the future the cloud provider operator, storage operator and machine operator will use these fields for configuration.", - "vcenters": "vcenters holds the connection details for services to communicate with vCenter. Up to 3 vCenters are supported. Once the cluster has been installed, you are unable to change the current number of defined vCenters except when 1.) the cluster has been upgraded from a version of OpenShift where the vsphere platform spec was not present or 2.) in TechPreview you are able to add and remove vCenters but may not remove all vCenters. You may make modifications to the existing vCenters that are defined in the vcenters list in order to match with any added or modified failure domains.", + "vcenters": "vcenters holds the connection details for services to communicate with vCenter. Currently, only a single vCenter is supported, but in tech preview 3 vCenters are supported. Once the cluster has been installed, you are unable to change the current number of defined vCenters except in the case where the cluster has been upgraded from a version of OpenShift where the vsphere platform spec was not present. You may make modifications to the existing vCenters that are defined in the vcenters list in order to match with any added or modified failure domains.", "failureDomains": "failureDomains contains the definition of region, zone and the vCenter topology. If this is omitted failure domains (regions and zones) will not be used.", "nodeNetworking": "nodeNetworking contains the definition of internal and external network constraints for assigning the node's networking. If this field is omitted, networking defaults to the legacy address selection behavior which is to only support a single address and return the first one found.", "apiServerInternalIPs": "apiServerInternalIPs are the IP addresses to contact the Kubernetes API server that can be used by components inside the cluster, like kubelets using the infrastructure rather than Kubernetes networking. These are the IPs for a self-hosted load balancer in front of the API servers. In dual stack clusters this list contains two IP addresses, one from IPv4 family and one from IPv6. In single stack clusters a single IP address is expected. When omitted, values from the status.apiServerInternalIPs will be used. Once set, the list cannot be completely removed (but its second entry can).", @@ -2329,19 +2422,19 @@ func (Storage) SwaggerDoc() map[string]string { return map_Storage } -var map_KMSPluginConfig = map[string]string{ - "": "KMSPluginConfig defines the configuration for the KMS instance that will be used with KMS encryption", +var map_KMSConfig = map[string]string{ + "": "KMSConfig defines the configuration for the KMS instance that will be used with KMS encryption", "type": "type defines the kind of platform for the KMS provider. Allowed values are Vault. When set to Vault, the plugin connects to a HashiCorp Vault server for key management.", "vault": "vault defines the configuration for the Vault KMS plugin. The plugin connects to a Vault Enterprise server that is managed by the user outside the purview of the control plane. This field must be set when type is Vault, and must be unset otherwise.", } -func (KMSPluginConfig) SwaggerDoc() map[string]string { - return map_KMSPluginConfig +func (KMSConfig) SwaggerDoc() map[string]string { + return map_KMSConfig } var map_VaultAppRoleAuthentication = map[string]string{ "": "VaultAppRoleAuthentication defines the configuration for AppRole authentication with Vault.", - "secret": "secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. The secret must contain two keys: \"role-id\" for the AppRole Role ID and \"secret-id\" for the AppRole Secret ID.", + "secret": "secret references a secret in the openshift-config namespace containing the AppRole credentials used to authenticate with Vault. The secret must contain two keys: \"roleID\" for the AppRole Role ID and \"secretID\" for the AppRole Secret ID.\n\nThe namespace for the secret is openshift-config.", } func (VaultAppRoleAuthentication) SwaggerDoc() map[string]string { @@ -2367,19 +2460,19 @@ func (VaultConfigMapReference) SwaggerDoc() map[string]string { return map_VaultConfigMapReference } -var map_VaultKMSPluginConfig = map[string]string{ - "": "VaultKMSPluginConfig defines the KMS plugin configuration specific to Vault KMS", +var map_VaultKMSConfig = map[string]string{ + "": "VaultKMSConfig defines the KMS plugin configuration specific to Vault KMS", "kmsPluginImage": "kmsPluginImage specifies the container image for the HashiCorp Vault KMS plugin.\n\nThe image must be a fully qualified OCI image pull spec with a SHA256 digest. The format is: host[:port][/namespace]/name@sha256: where the digest must be 64 characters long and consist only of lowercase hexadecimal characters, a-f and 0-9. The total length must be between 75 and 447 characters.\n\nShort names (e.g., \"vault-plugin\" or \"hashicorp/vault-plugin\") are not allowed. The registry hostname must be included and must contain at least one dot. Image tags (e.g., \":latest\", \":v1.0.0\") are not allowed.\n\nConsult the OpenShift documentation for compatible plugin versions with your cluster version, then obtain the image digest for that version from HashiCorp's container registry.\n\nFor disconnected environments, mirror the plugin image to an accessible registry and reference the mirrored location with its digest.", "vaultAddress": "vaultAddress specifies the address of the HashiCorp Vault instance. The value must be a valid HTTPS URL containing only scheme, host, and optional port. Paths, user info, query parameters, and fragments are not allowed.\n\nFormat: https://hostname[:port] Example: https://vault.example.com:8200\n\nThe value must be between 1 and 512 characters.", "vaultNamespace": "vaultNamespace specifies the Vault namespace where the Transit secrets engine is mounted. This is only applicable for Vault Enterprise installations. When this field is not set, no namespace is used.\n\nThe value must be between 1 and 4096 characters. The namespace cannot end with a forward slash, cannot contain spaces, and cannot be one of the reserved strings: root, sys, audit, auth, cubbyhole, or identity.", "tls": "tls contains the TLS configuration for connecting to the Vault server. When this field is not set, system default TLS settings are used.", "authentication": "authentication defines the authentication method used to authenticate with Vault.", - "transitMount": "transitMount specifies the mount path of the Vault Transit engine.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is \"transit\".\n\nThe transit mount must be between 1 and 1024 characters when specified, cannot start or end with a forward slash, cannot contain consecutive forward slashes, and must only contain RFC 3986 unreserved characters (alphanumeric, hyphen, period, underscore, tilde) and forward slashes as path separators.", - "transitKey": "transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data.\n\nThe transit key must be between 1 and 512 characters, cannot contain forward slashes, and must only contain alphanumeric characters, hyphens, periods, and underscores.", + "transitMount": "transitMount specifies the mount path of the Vault Transit engine. The value must be between 1 and 1024 characters when specified.\n\nWhen omitted, this means the user has no opinion and the platform is left to choose a reasonable default. These defaults are subject to change over time. The current default is \"transit\".\n\nThe mount path cannot start or end with a forward slash, cannot contain spaces, and cannot contain consecutive forward slashes.", + "transitKey": "transitKey specifies the name of the encryption key in Vault's Transit engine. This key is used to encrypt and decrypt data.\n\nThe key name must be between 1 and 512 characters and cannot contain spaces or forward slashes.", } -func (VaultKMSPluginConfig) SwaggerDoc() map[string]string { - return map_VaultKMSPluginConfig +func (VaultKMSConfig) SwaggerDoc() map[string]string { + return map_VaultKMSConfig } var map_VaultSecretReference = map[string]string{ diff --git a/vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go b/vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go index 4dbfb12681..083c2d6b55 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go +++ b/vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go @@ -456,14 +456,6 @@ type NodeExporterCollectorConfig struct { // Enable when you need metrics for specific units; scope units carefully. // +optional Systemd NodeExporterCollectorSystemdConfig `json:"systemd,omitempty,omitzero"` - // softirqs configures the softirqs collector, which exposes detailed softirq statistics - // from /proc/softirqs. - // softirqs is optional. - // When omitted, this means no opinion and the platform is left to choose a reasonable default, - // which is subject to change over time. The current default is disabled. - // Enable when you need visibility into kernel softirq processing across CPUs. - // +optional - Softirqs NodeExporterCollectorSoftirqsConfig `json:"softirqs,omitempty,omitzero"` } // NodeExporterCollectorCpufreqConfig provides configuration for the cpufreq collector @@ -673,20 +665,6 @@ type NodeExporterCollectorSystemdCollectConfig struct { // +kubebuilder:validation:MaxLength=1024 type NodeExporterSystemdUnit string -// NodeExporterCollectorSoftirqsConfig provides configuration for the softirqs collector -// of the node-exporter agent. The softirqs collector exposes detailed softirq statistics -// from /proc/softirqs. -// It is disabled by default. -type NodeExporterCollectorSoftirqsConfig struct { - // collectionPolicy declares whether the softirqs collector collects metrics. - // This field is required. - // Valid values are "Collect" and "DoNotCollect". - // When set to "Collect", the softirqs collector is active and softirq statistics are collected. - // When set to "DoNotCollect", the softirqs collector is inactive. - // +required - CollectionPolicy NodeExporterCollectorCollectionPolicy `json:"collectionPolicy,omitempty"` -} - // MonitoringPluginConfig provides configuration options for the monitoring plugin // that runs as a dynamic plugin of the OpenShift web console. // The monitoring plugin provides the monitoring UI in the OpenShift web console diff --git a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go index d690c688b2..f0f0a86de6 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go @@ -950,7 +950,6 @@ func (in *NodeExporterCollectorConfig) DeepCopyInto(out *NodeExporterCollectorCo out.Ksmd = in.Ksmd out.Processes = in.Processes in.Systemd.DeepCopyInto(&out.Systemd) - out.Softirqs = in.Softirqs return } @@ -1093,22 +1092,6 @@ func (in *NodeExporterCollectorProcessesConfig) DeepCopy() *NodeExporterCollecto return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeExporterCollectorSoftirqsConfig) DeepCopyInto(out *NodeExporterCollectorSoftirqsConfig) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeExporterCollectorSoftirqsConfig. -func (in *NodeExporterCollectorSoftirqsConfig) DeepCopy() *NodeExporterCollectorSoftirqsConfig { - if in == nil { - return nil - } - out := new(NodeExporterCollectorSoftirqsConfig) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeExporterCollectorSystemdCollectConfig) DeepCopyInto(out *NodeExporterCollectorSystemdCollectConfig) { *out = *in diff --git a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go index ae91964235..45e803f588 100644 --- a/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go @@ -330,7 +330,6 @@ var map_NodeExporterCollectorConfig = map[string]string{ "ksmd": "ksmd configures the ksmd collector, which collects statistics from the kernel same-page merger daemon. ksmd is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default is disabled. Enable on nodes where KSM is in use and you want visibility into merging activity.", "processes": "processes configures the processes collector, which collects statistics from processes and threads running in the system. processes is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default is disabled. Enable for process/thread-level insight; can be expensive on busy nodes.", "systemd": "systemd configures the systemd collector, which collects statistics on the systemd daemon and its managed services. systemd is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default is disabled. Enabling this collector with a long list of selected units may produce metrics with high cardinality. If you enable this collector, closely monitor the prometheus-k8s deployment for excessive memory usage. Enable when you need metrics for specific units; scope units carefully.", - "softirqs": "softirqs configures the softirqs collector, which exposes detailed softirq statistics from /proc/softirqs. softirqs is optional. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default is disabled. Enable when you need visibility into kernel softirq processing across CPUs.", } func (NodeExporterCollectorConfig) SwaggerDoc() map[string]string { @@ -410,15 +409,6 @@ func (NodeExporterCollectorProcessesConfig) SwaggerDoc() map[string]string { return map_NodeExporterCollectorProcessesConfig } -var map_NodeExporterCollectorSoftirqsConfig = map[string]string{ - "": "NodeExporterCollectorSoftirqsConfig provides configuration for the softirqs collector of the node-exporter agent. The softirqs collector exposes detailed softirq statistics from /proc/softirqs. It is disabled by default.", - "collectionPolicy": "collectionPolicy declares whether the softirqs collector collects metrics. This field is required. Valid values are \"Collect\" and \"DoNotCollect\". When set to \"Collect\", the softirqs collector is active and softirq statistics are collected. When set to \"DoNotCollect\", the softirqs collector is inactive.", -} - -func (NodeExporterCollectorSoftirqsConfig) SwaggerDoc() map[string]string { - return map_NodeExporterCollectorSoftirqsConfig -} - var map_NodeExporterCollectorSystemdCollectConfig = map[string]string{ "": "NodeExporterCollectorSystemdCollectConfig holds configuration options for the systemd collector when it is actively collecting metrics. At least one field must be specified.", "units": "units is a list of regular expression patterns that match systemd units to be included by the systemd collector. units is optional. By default, the list is empty, so the collector exposes no metrics for systemd units. Each entry is a regular expression pattern and must be at least 1 character and at most 1024 characters. Maximum length for this list is 50. Minimum length for this list is 1. Entries in this list must be unique.", diff --git a/vendor/github.com/openshift/api/console/v1/types_console_plugin.go b/vendor/github.com/openshift/api/console/v1/types_console_plugin.go index c63db50d52..0160a4a242 100644 --- a/vendor/github.com/openshift/api/console/v1/types_console_plugin.go +++ b/vendor/github.com/openshift/api/console/v1/types_console_plugin.go @@ -90,6 +90,7 @@ type ConsolePluginSpec struct { // OpenShift web console server CSP response header: // Content-Security-Policy: default-src 'self'; base-uri 'self'; script-src 'self' https://script1.com/ https://script2.com/ https://script3.com/; font-src 'self' https://font1.com/ https://font2.com/; img-src 'self' https://img1.com/; style-src 'self'; frame-src 'none'; object-src 'none' // + // +openshift:enable:FeatureGate=ConsolePluginContentSecurityPolicy // +kubebuilder:validation:MaxItems=5 // +kubebuilder:validation:XValidation:rule="self.map(x, x.values.map(y, y.size()).sum()).sum() < 8192",message="the total combined size of values of all directives must not exceed 8192 (8kb)" // +listType=map diff --git a/vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml b/vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml index 26524d0a17..caa676e691 100644 --- a/vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml @@ -137,7 +137,8 @@ consoleplugins.console.openshift.io: CRDName: consoleplugins.console.openshift.io Capability: Console Category: "" - FeatureGates: [] + FeatureGates: + - ConsolePluginContentSecurityPolicy FilenameOperatorName: "" FilenameOperatorOrdering: "90" FilenameRunLevel: "" diff --git a/vendor/github.com/openshift/api/features.md b/vendor/github.com/openshift/api/features.md index 58a420dfb1..24149f56e9 100644 --- a/vendor/github.com/openshift/api/features.md +++ b/vendor/github.com/openshift/api/features.md @@ -21,7 +21,6 @@ | NewOLMOwnSingleNamespace| | | | Enabled | | | | Enabled | | NewOLMPreflightPermissionChecks| | | | Enabled | | | | Enabled | | NoRegistryClusterInstall| | | | Enabled | | | | Enabled | -| OLMLifecycleAndCompatibility| | | | Enabled | | | | Enabled | | ProvisioningRequestAvailable| | | Enabled | Enabled | | | | | | VSphereMultiVCenterDay2| | | Enabled | Enabled | | | | | | AWSClusterHostedDNS| | | Enabled | Enabled | | | Enabled | Enabled | @@ -53,7 +52,9 @@ | ClusterVersionOperatorConfiguration| | | Enabled | Enabled | | | Enabled | Enabled | | ConfigurablePKI| | | Enabled | Enabled | | | Enabled | Enabled | | DNSNameResolver| | | Enabled | Enabled | | | Enabled | Enabled | +| DRAPartitionableDevices| | | Enabled | Enabled | | | Enabled | Enabled | | DyanmicServiceEndpointIBMCloud| | | Enabled | Enabled | | | Enabled | Enabled | +| EVPN| | | Enabled | Enabled | | | Enabled | Enabled | | EtcdBackendQuota| | | Enabled | Enabled | | | Enabled | Enabled | | Example| | | Enabled | Enabled | | | Enabled | Enabled | | ExternalOIDCWithUpstreamParity| | | Enabled | Enabled | | | Enabled | Enabled | @@ -72,6 +73,7 @@ | MinimumKubeletVersion| | | Enabled | Enabled | | | Enabled | Enabled | | MixedCPUsAllocation| | | Enabled | Enabled | | | Enabled | Enabled | | MultiDiskSetup| | | Enabled | Enabled | | | Enabled | Enabled | +| MutatingAdmissionPolicy| | | Enabled | Enabled | | | Enabled | Enabled | | NewOLM| | Enabled | | Enabled | | Enabled | | Enabled | | NewOLMWebhookProviderOpenshiftServiceCA| | Enabled | | Enabled | | Enabled | | Enabled | | NoOverlayMode| | | Enabled | Enabled | | | Enabled | Enabled | @@ -90,8 +92,8 @@ | AzureWorkloadIdentity| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | BootImageSkewEnforcement| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | BuildCSIVolumes| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | +| ConsolePluginContentSecurityPolicy| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | DualReplica| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | -| EVPN| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | EventTTL| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | ExternalOIDC| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | ExternalOIDCWithUIDAndExtraClaimMappings| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | @@ -103,7 +105,6 @@ | ManagedBootImagesCPMS| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | MetricsCollectionProfiles| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | MutableCSINodeAllocatableCount| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | -| MutatingAdmissionPolicy| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | OpenShiftPodSecurityAdmission| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | RouteExternalCertificate| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | | ServiceAccountTokenNodeBinding| Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | Enabled | diff --git a/vendor/github.com/openshift/api/features/features.go b/vendor/github.com/openshift/api/features/features.go index 035834bf97..6fdc233195 100644 --- a/vendor/github.com/openshift/api/features/features.go +++ b/vendor/github.com/openshift/api/features/features.go @@ -75,6 +75,14 @@ func AllFeatureSets() map[uint64]map[ClusterProfileName]map[configv1.FeatureSet] var ( allFeatureGates = map[configv1.FeatureGateName][]featureGateStatus{} + FeatureGateConsolePluginCSP = newFeatureGate("ConsolePluginContentSecurityPolicy"). + reportProblemsToJiraComponent("Management Console"). + contactPerson("jhadvig"). + productScope(ocpSpecific). + enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). + enhancementPR("https://github.com/openshift/enhancements/pull/1706"). + mustRegister() + FeatureGateServiceAccountTokenNodeBinding = newFeatureGate("ServiceAccountTokenNodeBinding"). reportProblemsToJiraComponent("apiserver-auth"). contactPerson("ibihim"). @@ -88,7 +96,7 @@ var ( contactPerson("benluddy"). productScope(kubernetes). enhancementPR("https://github.com/kubernetes/enhancements/issues/3962"). - enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). + enable(inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() FeatureGateOpenShiftPodSecurityAdmission = newFeatureGate("OpenShiftPodSecurityAdmission"). @@ -207,7 +215,7 @@ var ( contactPerson("jcaamano"). productScope(ocpSpecific). enhancementPR("https://github.com/openshift/enhancements/pull/1862"). - enable(inDefault(), inOKD(), inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). + enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). mustRegister() FeatureGateOVNObservability = newFeatureGate("OVNObservability"). @@ -464,14 +472,6 @@ var ( enable(inClusterProfile(SelfManaged), inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). mustRegister() - FeatureGateOLMLifecycleAndCompatibility = newFeatureGate("OLMLifecycleAndCompatibility"). - reportProblemsToJiraComponent("olm"). - contactPerson("joelanford"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1991"). - enable(inClusterProfile(SelfManaged), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). - mustRegister() - FeatureGateInsightsOnDemandDataGather = newFeatureGate("InsightsOnDemandDataGather"). reportProblemsToJiraComponent("insights"). contactPerson("tremes"). @@ -622,6 +622,7 @@ var ( enable(inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() + FeatureGateVSphereMultiNetworks = newFeatureGate("VSphereMultiNetworks"). reportProblemsToJiraComponent("SPLAT"). contactPerson("rvanderp"). @@ -922,6 +923,14 @@ var ( enable(inClusterProfile(Hypershift), inDefault(), inOKD(), inTechPreviewNoUpgrade(), inDevPreviewNoUpgrade()). mustRegister() + FeatureGateDRAPartitionableDevices = newFeatureGate("DRAPartitionableDevices"). + reportProblemsToJiraComponent("Node"). + contactPerson("harche"). + productScope(kubernetes). + enhancementPR("https://github.com/kubernetes/enhancements/issues/4815"). + enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). + mustRegister() + FeatureGateConfigurablePKI = newFeatureGate("ConfigurablePKI"). reportProblemsToJiraComponent("kube-apiserver"). contactPerson("sanchezl"). @@ -970,11 +979,11 @@ var ( enable(inDevPreviewNoUpgrade(), inTechPreviewNoUpgrade()). mustRegister() - FeatureGateConfidentialCluster = newFeatureGate("ConfidentialCluster"). - reportProblemsToJiraComponent("ConfidentialClusters"). - contactPerson("fjin"). - productScope(ocpSpecific). - enhancementPR("https://github.com/openshift/enhancements/pull/1962"). - enable(inDevPreviewNoUpgrade()). - mustRegister() + FeatureGateConfidentialCluster = newFeatureGate("ConfidentialCluster"). + reportProblemsToJiraComponent("ConfidentialClusters"). + contactPerson("fjin"). + productScope(ocpSpecific). + enhancementPR("https://github.com/openshift/enhancements/pull/1962"). + enable(inDevPreviewNoUpgrade()). + mustRegister() ) diff --git a/vendor/github.com/openshift/api/install.go b/vendor/github.com/openshift/api/install.go index 6efcc1c298..e4574e7c4f 100644 --- a/vendor/github.com/openshift/api/install.go +++ b/vendor/github.com/openshift/api/install.go @@ -14,6 +14,8 @@ import ( kauthorizationv1beta1 "k8s.io/api/authorization/v1beta1" kautoscalingv1 "k8s.io/api/autoscaling/v1" kautoscalingv2 "k8s.io/api/autoscaling/v2" + kautoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1" + kautoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" kbatchv1 "k8s.io/api/batch/v1" kbatchv1beta1 "k8s.io/api/batch/v1beta1" kcertificatesv1 "k8s.io/api/certificates/v1" @@ -38,6 +40,7 @@ import ( krbacv1alpha1 "k8s.io/api/rbac/v1alpha1" krbacv1beta1 "k8s.io/api/rbac/v1beta1" kschedulingv1 "k8s.io/api/scheduling/v1" + kschedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" kschedulingv1beta1 "k8s.io/api/scheduling/v1beta1" kstoragev1 "k8s.io/api/storage/v1" kstoragev1alpha1 "k8s.io/api/storage/v1alpha1" @@ -131,6 +134,8 @@ var ( kauthorizationv1beta1.AddToScheme, kautoscalingv1.AddToScheme, kautoscalingv2.AddToScheme, + kautoscalingv2beta1.AddToScheme, + kautoscalingv2beta2.AddToScheme, kbatchv1.AddToScheme, kbatchv1beta1.AddToScheme, kcertificatesv1.AddToScheme, @@ -155,6 +160,7 @@ var ( krbacv1beta1.AddToScheme, krbacv1alpha1.AddToScheme, kschedulingv1.AddToScheme, + kschedulingv1alpha1.AddToScheme, kschedulingv1beta1.AddToScheme, kstoragev1.AddToScheme, kstoragev1beta1.AddToScheme, diff --git a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/types.go b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/types.go index 34dcc153d7..43ea0cffe3 100644 --- a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/types.go +++ b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/types.go @@ -62,6 +62,15 @@ type JWTAuthenticator struct { // The validation rules are logically ANDed together and must all return true for the validation to pass. // +optional UserValidationRules []UserValidationRule + + // externalClaimSources is an optional field that can be used to configure + // sources, external to the token provided in a request, in which claims + // should be fetched from and made available to the claim mapping process + // that is used to build the identity of a token holder. + // For example, fetching additional user metadata from an OIDC provider's UserInfo endpoint. + // externalClaimSources must not exceed 5 entries. + // +optional + ExternalClaimsSources []ExternalClaimsSource } // Issuer provides the configuration for an external provider's specific settings. @@ -337,3 +346,210 @@ type UserValidationRule struct { // +optional Message string } + +// ExternalClaimsSource provides the configuration for a single external claim source. +type ExternalClaimsSource struct { + // authentication is an optional field that configures how the apiserver authenticates with an external claims source. + // When not specified, anonymous authentication is used. + // +optional + Authentication *Authentication + // tls is an optional field that configures the http client TLS + // settings when fetching external claims from this source. + // At least one subfield must be set when this field is specified. + // +optional + TLS *TLS + // url is a required configuration of the URL + // for which the external claims are located. + // +required + URL *SourceURL + // mappings is a required list of the claim + // and response handling expression pairs + // that produces the claims from the external source. + // mappings must have at least 1 entry and must not exceed 16 entries. + // Entries must have a unique name across all external claim sources. + // + // WARNING: claims sourced using these mappings will override any claims + // that exist within the token during the claim-to-identity mapping + // process. Use caution when sourcing external claims to avoid unintentionally + // overriding token claims. To help guard against this, sourcing + // external claims can have guard conditions defined in the 'conditions' + // field. + // + // +required + Mappings []SourcedClaimMapping + // conditions is an optional list of conditions in + // which claims should attempt to be fetched from this + // external source. + // When omitted or empty, claims are always attempted to be fetched + // from this external source. + // When specified, all conditions must evaluate to 'true' + // before claims are attempted to be fetched from this external source. + // conditions must not exceed 16 entries. + // Entries must have unique expressions. + // +optional + Conditions []ExternalSourceCondition +} + +// TLS configures the TLS options that the apiserver uses as a client +// when making a request to the external claim source. +// At least one field must be set when specified. +type TLS struct { + // certificateAuthority is an optional field that configures the certificate authority + // used to validate TLS connections with the external claims source. + // Must not be empty and must be a valid PEM-encoded certificate. + // +optional + CertificateAuthority *string +} + +func (t *TLS) IsZero() bool { + return t.CertificateAuthority == nil +} + +// Authentication configures how the apiserver should attempt to authenticate +// with an external claims source. +type Authentication struct { + // type is a required field that sets the type of + // authentication method used by the authenticator + // when fetching external claims. + // + // Allowed values are 'RequestProvidedToken' and 'ClientCredential'. + // + // When set to 'RequestProvidedToken', the authenticator will + // use the token provided to the kube-apiserver as part of the + // request to authenticate with the external claims source. + // + // When set to 'ClientCredential', the authenticator will + // use the configured client-id, client-secret, and token endpoint + // to fetch an access token using the OAuth2 client credentials grant + // flow. The fetched access token will then be used to authenticate + // with the external claims source. + // +required + Type *AuthenticationType + + // clientCredential configures the client credentials + // and token endpoint to use to get an access token. + // This field must be set when type is ClientCredential. + // This field must not be set when type is not ClientCredential. + // +optional + ClientCredential *ClientCredentialConfig +} + +// AuthenticationType is the type of authentication that should be used +// when fetching claims from an external source. +type AuthenticationType string + +const ( + // AuthenticationTypeRequestProvidedToken is an AuthenticationType + // that represents that the token being evaluated for authentication + // should be used for authenticating with the external claims source. + // This is useful for scenarios where a token has multiple audiences + // and scopes so that it can be used to access both the cluster and + // the UserInfo endpoint that contains additional information about the + // user not present in the token. + AuthenticationTypeRequestProvidedToken AuthenticationType = "RequestProvidedToken" + + // AuthenticationTypeClientCredential is an AuthenticationType + // that represents that the authenticator should use the OAuth2 + // client credentials grant flow to obtain an access token for + // authenticating with the external claims source. + // This is useful for scenarios such as fetching user information + // from Microsoft's Graph API where a separate client credential + // is needed to access the API. + AuthenticationTypeClientCredential AuthenticationType = "ClientCredential" +) + +// ClientCredentialConfig configures the client credentials and token endpoint +// to use to get an access token via the OAuth2 client credentials grant flow. +type ClientCredentialConfig struct { + // clientID is the client identifier to use during the OAuth2 client credentials flow. + // clientID must not be an empty string (""). + // clientID must only contain printable ASCII characters. + // +required + ClientID string + + // clientSecret is the client secret to use during the OAuth2 client credentials flow. + // clientSecret is the literal string value of the client secret. + // clientSecret must not be an empty string (""). + // clientSecret must only contain printable ASCII characters. + // +required + ClientSecret string + + // tokenEndpoint is a required URL to query for an access token using + // the client credential OAuth2 flow. + // tokenEndpoint must not be an empty string (""). + // tokenEndpoint must be a valid HTTPS URL. + // tokenEndpoint must have a host and a path. + // tokenEndpoint must not contain query parameters, fragments, + // or user information (e.g., "user:password@host"). + // +required + TokenEndpoint string + + // scopes is an optional list of OAuth2 scopes to request when obtaining + // an access token. If not specified, the token endpoint's default scopes + // will be used. Each scope must not be an empty string (""). + // +optional + Scopes []string + + // tls is an optional field that configures the http client TLS + // settings when fetching an access token for this source. + // At least one subfield must be set when this field is specified. + // +optional + TLS *TLS +} + +// SourceURL configures the options used to build the URL that is queried for external claims. +type SourceURL struct { + // hostname is a required hostname for which the external claims are located. + // It must be a valid DNS subdomain name as per RFC1123. + // This means that it must start and end with a lowercase alphanumeric character, + // must only consist of lowercase alphanumeric characters, '-', and '.'. + // hostname must not be an empty string ("") and must not exceed 253 characters in length. + // hostname may optionally specify a port in the format ':{port}'. + // +required + Hostname *string + // pathExpression is a required CEL expression that returns a list + // of string values used to construct the URL path. + // Claims from the token used for the request to the kube-apiserver + // are made available via the `claims` variable. + // expression must not be an empty string (""). + // +required + PathExpression *string +} + +// SourcedClaimMapping configures the mapping behavior for a single external claim +// from the response the apiserver received from the external claim source. +type SourcedClaimMapping struct { + // name is a required name of the claim that + // will be produced and made available during + // the claim-to-identity mapping process. + // name must consist of only lowercase alpha characters and underscores ('_'). + // name must not be an empty string ("") and must not exceed 256 characters in length. + // +required + Name *string + + // expression is a required CEL expression that + // will produce a value to be assigned to the claim. + // The full response body from the request to the + // external claim source is provided via the + // `response` variable. + // expression must not be an empty string (""). + // +required + Expression *string +} + +// ExternalSourceCondition configures a singular condition +// that must return true before the external source is queried +// to retrieve external claims. +type ExternalSourceCondition struct { + // expression is a required CEL expression that + // is used to determine whether or not an external + // source should be used to fetch external claims. + // The expression must return a boolean value, + // where true means that the source should be consulted + // and false means that it should not. + // Claims from the token used for the request to the kube-apiserver + // are made available via the `claims` variable. + // expression must not be an empty string (""). + // +required + Expression *string +} diff --git a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/types.go b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/types.go index 4493db0c19..e354e81ad0 100644 --- a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/types.go +++ b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/types.go @@ -62,6 +62,15 @@ type JWTAuthenticator struct { // The validation rules are logically ANDed together and must all return true for the validation to pass. // +optional UserValidationRules []UserValidationRule `json:"userValidationRules,omitempty"` + + // externalClaimSources is an optional field that can be used to configure + // sources, external to the token provided in a request, in which claims + // should be fetched from and made available to the claim mapping process + // that is used to build the identity of a token holder. + // For example, fetching additional user metadata from an OIDC provider's UserInfo endpoint. + // externalClaimSources must not exceed 5 entries. + // +optional + ExternalClaimsSources []ExternalClaimsSource `json:"externalClaimsSources,omitempty"` } // Issuer provides the configuration for an external provider's specific settings. @@ -337,3 +346,207 @@ type UserValidationRule struct { // +optional Message string `json:"message,omitempty"` } + +// ExternalClaimsSource provides the configuration for a single external claim source. +type ExternalClaimsSource struct { + // authentication is an optional field that configures how the apiserver authenticates with an external claims source. + // When not specified, anonymous authentication is used. + // +optional + Authentication *Authentication `json:"authentication,omitempty"` + // tls is an optional field that configures the http client TLS + // settings when fetching external claims from this source. + // At least one subfield must be set when this field is specified. + // +optional + TLS *TLS `json:"tls,omitempty"` + // url is a required configuration of the URL + // for which the external claims are located. + // +required + URL *SourceURL `json:"url,omitempty"` + // mappings is a required list of the claim + // and response handling expression pairs + // that produces the claims from the external source. + // + // mappings must have at least 1 entry and must not exceed 16 entries. + // Entries must have a unique name across all external claim sources. + // + // WARNING: claims sourced using these mappings will override any claims + // that exist within the token during the claim-to-identity mapping + // process. Use caution when sourcing external claims to avoid unintentionally + // overriding token claims. To help guard against this, sourcing + // external claims can have guard conditions defined in the 'conditions' + // field. + // + // +required + Mappings []SourcedClaimMapping `json:"mappings,omitempty"` + // conditions is an optional list of conditions in + // which claims should attempt to be fetched from this + // external source. + // When omitted or empty, claims are always attempted to be fetched + // from this external source. + // When specified, all conditions must evaluate to 'true' + // before claims are attempted to be fetched from this external source. + // conditions must not exceed 16 entries. + // Entries must have unique expressions. + // +optional + Conditions []ExternalSourceCondition `json:"conditions,omitempty"` +} + +// TLS configures the TLS options that the apiserver uses as a client +// when making a request to the external claim source. +// At least one field must be set when specified. +type TLS struct { + // certificateAuthority is an optional field that configures the certificate authority + // used to validate TLS connections with the external claims source. + // Must not be empty and must be a valid PEM-encoded certificate. + // +optional + CertificateAuthority *string `json:"certificateAuthority,omitempty"` +} + +// Authentication configures how the apiserver should attempt to authenticate +// with an external claims source. +type Authentication struct { + // type is a required field that sets the type of + // authentication method used by the authenticator + // when fetching external claims. + // + // Allowed values are 'RequestProvidedToken' and 'ClientCredential'. + // + // When set to 'RequestProvidedToken', the authenticator will + // use the token provided to the kube-apiserver as part of the + // request to authenticate with the external claims source. + // + // When set to 'ClientCredential', the authenticator will + // use the configured client-id, client-secret, and token endpoint + // to fetch an access token using the OAuth2 client credentials grant + // flow. The fetched access token will then be used to authenticate + // with the external claims source. + // +required + Type *AuthenticationType `json:"type,omitempty"` + + // clientCredential configures the client credentials + // and token endpoint to use to get an access token. + // This field must be set when type is ClientCredential. + // This field must not be set when type is not ClientCredential. + // +optional + ClientCredential *ClientCredentialConfig `json:"clientCredential,omitempty"` +} + +// AuthenticationType is the type of authentication that should be used +// when fetching claims from an external source. +type AuthenticationType string + +const ( + // AuthenticationTypeRequestProvidedToken is an AuthenticationType + // that represents that the token being evaluated for authentication + // should be used for authenticating with the external claims source. + // This is useful for scenarios where a token has multiple audiences + // and scopes so that it can be used to access both the cluster and + // the UserInfo endpoint that contains additional information about the + // user not present in the token. + AuthenticationTypeRequestProvidedToken AuthenticationType = "RequestProvidedToken" + + // AuthenticationTypeClientCredential is an AuthenticationType + // that represents that the authenticator should use the OAuth2 + // client credentials grant flow to obtain an access token for + // authenticating with the external claims source. + // This is useful for scenarios such as fetching user information + // from Microsoft's Graph API where a separate client credential + // is needed to access the API. + AuthenticationTypeClientCredential AuthenticationType = "ClientCredential" +) + +// ClientCredentialConfig configures the client credentials and token endpoint +// to use to get an access token via the OAuth2 client credentials grant flow. +type ClientCredentialConfig struct { + // clientID is the client identifier to use during the OAuth2 client credentials flow. + // clientID must not be an empty string (""). + // clientID must only contain printable ASCII characters. + // +required + ClientID string `json:"clientID,omitempty"` + + // clientSecret is the client secret to use during the OAuth2 client credentials flow. + // clientSecret is the literal string value of the client secret. + // clientSecret must not be an empty string (""). + // clientSecret must only contain printable ASCII characters. + // +required + ClientSecret string `json:"clientSecret,omitempty"` + + // tokenEndpoint is a required URL to query for an access token using + // the client credential OAuth2 flow. + // tokenEndpoint must not be an empty string (""). + // tokenEndpoint must be a valid HTTPS URL. + // tokenEndpoint must have a host and a path. + // tokenEndpoint must not contain query parameters, fragments, + // or user information (e.g., "user:password@host"). + // +required + TokenEndpoint string `json:"tokenEndpoint,omitempty"` + + // scopes is an optional list of OAuth2 scopes to request when obtaining + // an access token. If not specified, the token endpoint's default scopes + // will be used. Each scope must not be an empty string (""). + // +optional + Scopes []string `json:"scopes,omitempty"` + + // tls is an optional field that configures the http client TLS + // settings when fetching an access token for this source. + // At least one subfield must be set when this field is specified. + // +optional + TLS *TLS `json:"tls,omitempty"` +} + +// SourceURL configures the options used to build the URL that is queried for external claims. +type SourceURL struct { + // hostname is a required hostname for which the external claims are located. + // It must be a valid DNS subdomain name as per RFC1123. + // This means that it must start and end with a lowercase alphanumeric character, + // must only consist of lowercase alphanumeric characters, '-', and '.'. + // hostname must not be an empty string ("") and must not exceed 253 characters in length. + // hostname may optionally specify a port in the format ':{port}'. + // +required + Hostname *string `json:"hostname,omitempty"` + // pathExpression is a required CEL expression that returns a list + // of string values used to construct the URL path. + // Claims from the token used for the request to the kube-apiserver + // are made available via the `claims` variable. + // expression must not be an empty string (""). + // +required + PathExpression *string `json:"pathExpression,omitempty"` +} + +// SourcedClaimMapping configures the mapping behavior for a single external claim +// from the response the apiserver received from the external claim source. +type SourcedClaimMapping struct { + // name is a required name of the claim that + // will be produced and made available during + // the claim-to-identity mapping process. + // name must consist of only lowercase alpha characters and underscores ('_'). + // name must not be an empty string ("") and must not exceed 256 characters in length. + // +required + Name *string `json:"name,omitempty"` + + // expression is a required CEL expression that + // will produce a value to be assigned to the claim. + // The full response body from the request to the + // external claim source is provided via the + // `response` variable. + // expression must not be an empty string (""). + // +required + Expression *string `json:"expression,omitempty"` +} + +// ExternalSourceCondition configures a singular condition +// that must return true before the external source is queried +// to retrieve external claims. +type ExternalSourceCondition struct { + // expression is a required CEL expression that + // is used to determine whether or not an external + // source should be used to fetch external claims. + // The expression must return a boolean value, + // where true means that the source should be consulted + // and false means that it should not. + // Claims from the token used for the request to the kube-apiserver + // are made available via the `claims` variable. + // expression must not be an empty string (""). + // +required + Expression *string `json:"expression,omitempty"` +} diff --git a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/zz_generated.conversion.go b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/zz_generated.conversion.go index 8e0c14e7a6..307f5a47d3 100644 --- a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/zz_generated.conversion.go +++ b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/zz_generated.conversion.go @@ -20,6 +20,16 @@ func init() { // RegisterConversions adds conversion functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*Authentication)(nil), (*authentication.Authentication)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Authentication_To_authentication_Authentication(a.(*Authentication), b.(*authentication.Authentication), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*authentication.Authentication)(nil), (*Authentication)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_authentication_Authentication_To_v1alpha1_Authentication(a.(*authentication.Authentication), b.(*Authentication), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*AuthenticationConfiguration)(nil), (*authentication.AuthenticationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha1_AuthenticationConfiguration_To_authentication_AuthenticationConfiguration(a.(*AuthenticationConfiguration), b.(*authentication.AuthenticationConfiguration), scope) }); err != nil { @@ -60,6 +70,36 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*ClientCredentialConfig)(nil), (*authentication.ClientCredentialConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ClientCredentialConfig_To_authentication_ClientCredentialConfig(a.(*ClientCredentialConfig), b.(*authentication.ClientCredentialConfig), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*authentication.ClientCredentialConfig)(nil), (*ClientCredentialConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_authentication_ClientCredentialConfig_To_v1alpha1_ClientCredentialConfig(a.(*authentication.ClientCredentialConfig), b.(*ClientCredentialConfig), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ExternalClaimsSource)(nil), (*authentication.ExternalClaimsSource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ExternalClaimsSource_To_authentication_ExternalClaimsSource(a.(*ExternalClaimsSource), b.(*authentication.ExternalClaimsSource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*authentication.ExternalClaimsSource)(nil), (*ExternalClaimsSource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_authentication_ExternalClaimsSource_To_v1alpha1_ExternalClaimsSource(a.(*authentication.ExternalClaimsSource), b.(*ExternalClaimsSource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ExternalSourceCondition)(nil), (*authentication.ExternalSourceCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ExternalSourceCondition_To_authentication_ExternalSourceCondition(a.(*ExternalSourceCondition), b.(*authentication.ExternalSourceCondition), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*authentication.ExternalSourceCondition)(nil), (*ExternalSourceCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_authentication_ExternalSourceCondition_To_v1alpha1_ExternalSourceCondition(a.(*authentication.ExternalSourceCondition), b.(*ExternalSourceCondition), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*ExtraMapping)(nil), (*authentication.ExtraMapping)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha1_ExtraMapping_To_authentication_ExtraMapping(a.(*ExtraMapping), b.(*authentication.ExtraMapping), scope) }); err != nil { @@ -100,6 +140,36 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*SourceURL)(nil), (*authentication.SourceURL)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_SourceURL_To_authentication_SourceURL(a.(*SourceURL), b.(*authentication.SourceURL), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*authentication.SourceURL)(nil), (*SourceURL)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_authentication_SourceURL_To_v1alpha1_SourceURL(a.(*authentication.SourceURL), b.(*SourceURL), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*SourcedClaimMapping)(nil), (*authentication.SourcedClaimMapping)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_SourcedClaimMapping_To_authentication_SourcedClaimMapping(a.(*SourcedClaimMapping), b.(*authentication.SourcedClaimMapping), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*authentication.SourcedClaimMapping)(nil), (*SourcedClaimMapping)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_authentication_SourcedClaimMapping_To_v1alpha1_SourcedClaimMapping(a.(*authentication.SourcedClaimMapping), b.(*SourcedClaimMapping), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*TLS)(nil), (*authentication.TLS)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_TLS_To_authentication_TLS(a.(*TLS), b.(*authentication.TLS), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*authentication.TLS)(nil), (*TLS)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_authentication_TLS_To_v1alpha1_TLS(a.(*authentication.TLS), b.(*TLS), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*UserValidationRule)(nil), (*authentication.UserValidationRule)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha1_UserValidationRule_To_authentication_UserValidationRule(a.(*UserValidationRule), b.(*authentication.UserValidationRule), scope) }); err != nil { @@ -113,6 +183,28 @@ func RegisterConversions(s *runtime.Scheme) error { return nil } +func autoConvert_v1alpha1_Authentication_To_authentication_Authentication(in *Authentication, out *authentication.Authentication, s conversion.Scope) error { + out.Type = (*authentication.AuthenticationType)(unsafe.Pointer(in.Type)) + out.ClientCredential = (*authentication.ClientCredentialConfig)(unsafe.Pointer(in.ClientCredential)) + return nil +} + +// Convert_v1alpha1_Authentication_To_authentication_Authentication is an autogenerated conversion function. +func Convert_v1alpha1_Authentication_To_authentication_Authentication(in *Authentication, out *authentication.Authentication, s conversion.Scope) error { + return autoConvert_v1alpha1_Authentication_To_authentication_Authentication(in, out, s) +} + +func autoConvert_authentication_Authentication_To_v1alpha1_Authentication(in *authentication.Authentication, out *Authentication, s conversion.Scope) error { + out.Type = (*AuthenticationType)(unsafe.Pointer(in.Type)) + out.ClientCredential = (*ClientCredentialConfig)(unsafe.Pointer(in.ClientCredential)) + return nil +} + +// Convert_authentication_Authentication_To_v1alpha1_Authentication is an autogenerated conversion function. +func Convert_authentication_Authentication_To_v1alpha1_Authentication(in *authentication.Authentication, out *Authentication, s conversion.Scope) error { + return autoConvert_authentication_Authentication_To_v1alpha1_Authentication(in, out, s) +} + func autoConvert_v1alpha1_AuthenticationConfiguration_To_authentication_AuthenticationConfiguration(in *AuthenticationConfiguration, out *authentication.AuthenticationConfiguration, s conversion.Scope) error { out.JWT = *(*[]authentication.JWTAuthenticator)(unsafe.Pointer(&in.JWT)) return nil @@ -219,6 +311,82 @@ func Convert_authentication_ClaimValidationRule_To_v1alpha1_ClaimValidationRule( return autoConvert_authentication_ClaimValidationRule_To_v1alpha1_ClaimValidationRule(in, out, s) } +func autoConvert_v1alpha1_ClientCredentialConfig_To_authentication_ClientCredentialConfig(in *ClientCredentialConfig, out *authentication.ClientCredentialConfig, s conversion.Scope) error { + out.ClientID = in.ClientID + out.ClientSecret = in.ClientSecret + out.TokenEndpoint = in.TokenEndpoint + out.Scopes = *(*[]string)(unsafe.Pointer(&in.Scopes)) + out.TLS = (*authentication.TLS)(unsafe.Pointer(in.TLS)) + return nil +} + +// Convert_v1alpha1_ClientCredentialConfig_To_authentication_ClientCredentialConfig is an autogenerated conversion function. +func Convert_v1alpha1_ClientCredentialConfig_To_authentication_ClientCredentialConfig(in *ClientCredentialConfig, out *authentication.ClientCredentialConfig, s conversion.Scope) error { + return autoConvert_v1alpha1_ClientCredentialConfig_To_authentication_ClientCredentialConfig(in, out, s) +} + +func autoConvert_authentication_ClientCredentialConfig_To_v1alpha1_ClientCredentialConfig(in *authentication.ClientCredentialConfig, out *ClientCredentialConfig, s conversion.Scope) error { + out.ClientID = in.ClientID + out.ClientSecret = in.ClientSecret + out.TokenEndpoint = in.TokenEndpoint + out.Scopes = *(*[]string)(unsafe.Pointer(&in.Scopes)) + out.TLS = (*TLS)(unsafe.Pointer(in.TLS)) + return nil +} + +// Convert_authentication_ClientCredentialConfig_To_v1alpha1_ClientCredentialConfig is an autogenerated conversion function. +func Convert_authentication_ClientCredentialConfig_To_v1alpha1_ClientCredentialConfig(in *authentication.ClientCredentialConfig, out *ClientCredentialConfig, s conversion.Scope) error { + return autoConvert_authentication_ClientCredentialConfig_To_v1alpha1_ClientCredentialConfig(in, out, s) +} + +func autoConvert_v1alpha1_ExternalClaimsSource_To_authentication_ExternalClaimsSource(in *ExternalClaimsSource, out *authentication.ExternalClaimsSource, s conversion.Scope) error { + out.Authentication = (*authentication.Authentication)(unsafe.Pointer(in.Authentication)) + out.TLS = (*authentication.TLS)(unsafe.Pointer(in.TLS)) + out.URL = (*authentication.SourceURL)(unsafe.Pointer(in.URL)) + out.Mappings = *(*[]authentication.SourcedClaimMapping)(unsafe.Pointer(&in.Mappings)) + out.Conditions = *(*[]authentication.ExternalSourceCondition)(unsafe.Pointer(&in.Conditions)) + return nil +} + +// Convert_v1alpha1_ExternalClaimsSource_To_authentication_ExternalClaimsSource is an autogenerated conversion function. +func Convert_v1alpha1_ExternalClaimsSource_To_authentication_ExternalClaimsSource(in *ExternalClaimsSource, out *authentication.ExternalClaimsSource, s conversion.Scope) error { + return autoConvert_v1alpha1_ExternalClaimsSource_To_authentication_ExternalClaimsSource(in, out, s) +} + +func autoConvert_authentication_ExternalClaimsSource_To_v1alpha1_ExternalClaimsSource(in *authentication.ExternalClaimsSource, out *ExternalClaimsSource, s conversion.Scope) error { + out.Authentication = (*Authentication)(unsafe.Pointer(in.Authentication)) + out.TLS = (*TLS)(unsafe.Pointer(in.TLS)) + out.URL = (*SourceURL)(unsafe.Pointer(in.URL)) + out.Mappings = *(*[]SourcedClaimMapping)(unsafe.Pointer(&in.Mappings)) + out.Conditions = *(*[]ExternalSourceCondition)(unsafe.Pointer(&in.Conditions)) + return nil +} + +// Convert_authentication_ExternalClaimsSource_To_v1alpha1_ExternalClaimsSource is an autogenerated conversion function. +func Convert_authentication_ExternalClaimsSource_To_v1alpha1_ExternalClaimsSource(in *authentication.ExternalClaimsSource, out *ExternalClaimsSource, s conversion.Scope) error { + return autoConvert_authentication_ExternalClaimsSource_To_v1alpha1_ExternalClaimsSource(in, out, s) +} + +func autoConvert_v1alpha1_ExternalSourceCondition_To_authentication_ExternalSourceCondition(in *ExternalSourceCondition, out *authentication.ExternalSourceCondition, s conversion.Scope) error { + out.Expression = (*string)(unsafe.Pointer(in.Expression)) + return nil +} + +// Convert_v1alpha1_ExternalSourceCondition_To_authentication_ExternalSourceCondition is an autogenerated conversion function. +func Convert_v1alpha1_ExternalSourceCondition_To_authentication_ExternalSourceCondition(in *ExternalSourceCondition, out *authentication.ExternalSourceCondition, s conversion.Scope) error { + return autoConvert_v1alpha1_ExternalSourceCondition_To_authentication_ExternalSourceCondition(in, out, s) +} + +func autoConvert_authentication_ExternalSourceCondition_To_v1alpha1_ExternalSourceCondition(in *authentication.ExternalSourceCondition, out *ExternalSourceCondition, s conversion.Scope) error { + out.Expression = (*string)(unsafe.Pointer(in.Expression)) + return nil +} + +// Convert_authentication_ExternalSourceCondition_To_v1alpha1_ExternalSourceCondition is an autogenerated conversion function. +func Convert_authentication_ExternalSourceCondition_To_v1alpha1_ExternalSourceCondition(in *authentication.ExternalSourceCondition, out *ExternalSourceCondition, s conversion.Scope) error { + return autoConvert_authentication_ExternalSourceCondition_To_v1alpha1_ExternalSourceCondition(in, out, s) +} + func autoConvert_v1alpha1_ExtraMapping_To_authentication_ExtraMapping(in *ExtraMapping, out *authentication.ExtraMapping, s conversion.Scope) error { out.Key = in.Key out.ValueExpression = in.ValueExpression @@ -274,6 +442,7 @@ func autoConvert_v1alpha1_JWTAuthenticator_To_authentication_JWTAuthenticator(in out.ClaimValidationRules = *(*[]authentication.ClaimValidationRule)(unsafe.Pointer(&in.ClaimValidationRules)) out.ClaimMappings = (*authentication.ClaimMappings)(unsafe.Pointer(in.ClaimMappings)) out.UserValidationRules = *(*[]authentication.UserValidationRule)(unsafe.Pointer(&in.UserValidationRules)) + out.ExternalClaimsSources = *(*[]authentication.ExternalClaimsSource)(unsafe.Pointer(&in.ExternalClaimsSources)) return nil } @@ -287,6 +456,7 @@ func autoConvert_authentication_JWTAuthenticator_To_v1alpha1_JWTAuthenticator(in out.ClaimValidationRules = *(*[]ClaimValidationRule)(unsafe.Pointer(&in.ClaimValidationRules)) out.ClaimMappings = (*ClaimMappings)(unsafe.Pointer(in.ClaimMappings)) out.UserValidationRules = *(*[]UserValidationRule)(unsafe.Pointer(&in.UserValidationRules)) + out.ExternalClaimsSources = *(*[]ExternalClaimsSource)(unsafe.Pointer(&in.ExternalClaimsSources)) return nil } @@ -319,6 +489,70 @@ func Convert_authentication_PrefixedClaimOrExpression_To_v1alpha1_PrefixedClaimO return autoConvert_authentication_PrefixedClaimOrExpression_To_v1alpha1_PrefixedClaimOrExpression(in, out, s) } +func autoConvert_v1alpha1_SourceURL_To_authentication_SourceURL(in *SourceURL, out *authentication.SourceURL, s conversion.Scope) error { + out.Hostname = (*string)(unsafe.Pointer(in.Hostname)) + out.PathExpression = (*string)(unsafe.Pointer(in.PathExpression)) + return nil +} + +// Convert_v1alpha1_SourceURL_To_authentication_SourceURL is an autogenerated conversion function. +func Convert_v1alpha1_SourceURL_To_authentication_SourceURL(in *SourceURL, out *authentication.SourceURL, s conversion.Scope) error { + return autoConvert_v1alpha1_SourceURL_To_authentication_SourceURL(in, out, s) +} + +func autoConvert_authentication_SourceURL_To_v1alpha1_SourceURL(in *authentication.SourceURL, out *SourceURL, s conversion.Scope) error { + out.Hostname = (*string)(unsafe.Pointer(in.Hostname)) + out.PathExpression = (*string)(unsafe.Pointer(in.PathExpression)) + return nil +} + +// Convert_authentication_SourceURL_To_v1alpha1_SourceURL is an autogenerated conversion function. +func Convert_authentication_SourceURL_To_v1alpha1_SourceURL(in *authentication.SourceURL, out *SourceURL, s conversion.Scope) error { + return autoConvert_authentication_SourceURL_To_v1alpha1_SourceURL(in, out, s) +} + +func autoConvert_v1alpha1_SourcedClaimMapping_To_authentication_SourcedClaimMapping(in *SourcedClaimMapping, out *authentication.SourcedClaimMapping, s conversion.Scope) error { + out.Name = (*string)(unsafe.Pointer(in.Name)) + out.Expression = (*string)(unsafe.Pointer(in.Expression)) + return nil +} + +// Convert_v1alpha1_SourcedClaimMapping_To_authentication_SourcedClaimMapping is an autogenerated conversion function. +func Convert_v1alpha1_SourcedClaimMapping_To_authentication_SourcedClaimMapping(in *SourcedClaimMapping, out *authentication.SourcedClaimMapping, s conversion.Scope) error { + return autoConvert_v1alpha1_SourcedClaimMapping_To_authentication_SourcedClaimMapping(in, out, s) +} + +func autoConvert_authentication_SourcedClaimMapping_To_v1alpha1_SourcedClaimMapping(in *authentication.SourcedClaimMapping, out *SourcedClaimMapping, s conversion.Scope) error { + out.Name = (*string)(unsafe.Pointer(in.Name)) + out.Expression = (*string)(unsafe.Pointer(in.Expression)) + return nil +} + +// Convert_authentication_SourcedClaimMapping_To_v1alpha1_SourcedClaimMapping is an autogenerated conversion function. +func Convert_authentication_SourcedClaimMapping_To_v1alpha1_SourcedClaimMapping(in *authentication.SourcedClaimMapping, out *SourcedClaimMapping, s conversion.Scope) error { + return autoConvert_authentication_SourcedClaimMapping_To_v1alpha1_SourcedClaimMapping(in, out, s) +} + +func autoConvert_v1alpha1_TLS_To_authentication_TLS(in *TLS, out *authentication.TLS, s conversion.Scope) error { + out.CertificateAuthority = (*string)(unsafe.Pointer(in.CertificateAuthority)) + return nil +} + +// Convert_v1alpha1_TLS_To_authentication_TLS is an autogenerated conversion function. +func Convert_v1alpha1_TLS_To_authentication_TLS(in *TLS, out *authentication.TLS, s conversion.Scope) error { + return autoConvert_v1alpha1_TLS_To_authentication_TLS(in, out, s) +} + +func autoConvert_authentication_TLS_To_v1alpha1_TLS(in *authentication.TLS, out *TLS, s conversion.Scope) error { + out.CertificateAuthority = (*string)(unsafe.Pointer(in.CertificateAuthority)) + return nil +} + +// Convert_authentication_TLS_To_v1alpha1_TLS is an autogenerated conversion function. +func Convert_authentication_TLS_To_v1alpha1_TLS(in *authentication.TLS, out *TLS, s conversion.Scope) error { + return autoConvert_authentication_TLS_To_v1alpha1_TLS(in, out, s) +} + func autoConvert_v1alpha1_UserValidationRule_To_authentication_UserValidationRule(in *UserValidationRule, out *authentication.UserValidationRule, s conversion.Scope) error { out.Expression = in.Expression out.Message = in.Message diff --git a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/zz_generated.deepcopy.go index 1212676a04..d62e0272ee 100644 --- a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1/zz_generated.deepcopy.go @@ -9,6 +9,32 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Authentication) DeepCopyInto(out *Authentication) { + *out = *in + if in.Type != nil { + in, out := &in.Type, &out.Type + *out = new(AuthenticationType) + **out = **in + } + if in.ClientCredential != nil { + in, out := &in.ClientCredential, &out.ClientCredential + *out = new(ClientCredentialConfig) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Authentication. +func (in *Authentication) DeepCopy() *Authentication { + if in == nil { + return nil + } + out := new(Authentication) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationConfiguration) DeepCopyInto(out *AuthenticationConfiguration) { *out = *in @@ -97,6 +123,98 @@ func (in *ClaimValidationRule) DeepCopy() *ClaimValidationRule { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientCredentialConfig) DeepCopyInto(out *ClientCredentialConfig) { + *out = *in + if in.Scopes != nil { + in, out := &in.Scopes, &out.Scopes + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLS) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientCredentialConfig. +func (in *ClientCredentialConfig) DeepCopy() *ClientCredentialConfig { + if in == nil { + return nil + } + out := new(ClientCredentialConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalClaimsSource) DeepCopyInto(out *ExternalClaimsSource) { + *out = *in + if in.Authentication != nil { + in, out := &in.Authentication, &out.Authentication + *out = new(Authentication) + (*in).DeepCopyInto(*out) + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLS) + (*in).DeepCopyInto(*out) + } + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(SourceURL) + (*in).DeepCopyInto(*out) + } + if in.Mappings != nil { + in, out := &in.Mappings, &out.Mappings + *out = make([]SourcedClaimMapping, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]ExternalSourceCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalClaimsSource. +func (in *ExternalClaimsSource) DeepCopy() *ExternalClaimsSource { + if in == nil { + return nil + } + out := new(ExternalClaimsSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalSourceCondition) DeepCopyInto(out *ExternalSourceCondition) { + *out = *in + if in.Expression != nil { + in, out := &in.Expression, &out.Expression + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSourceCondition. +func (in *ExternalSourceCondition) DeepCopy() *ExternalSourceCondition { + if in == nil { + return nil + } + out := new(ExternalSourceCondition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExtraMapping) DeepCopyInto(out *ExtraMapping) { *out = *in @@ -157,6 +275,13 @@ func (in *JWTAuthenticator) DeepCopyInto(out *JWTAuthenticator) { *out = make([]UserValidationRule, len(*in)) copy(*out, *in) } + if in.ExternalClaimsSources != nil { + in, out := &in.ExternalClaimsSources, &out.ExternalClaimsSources + *out = make([]ExternalClaimsSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -191,6 +316,79 @@ func (in *PrefixedClaimOrExpression) DeepCopy() *PrefixedClaimOrExpression { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SourceURL) DeepCopyInto(out *SourceURL) { + *out = *in + if in.Hostname != nil { + in, out := &in.Hostname, &out.Hostname + *out = new(string) + **out = **in + } + if in.PathExpression != nil { + in, out := &in.PathExpression, &out.PathExpression + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceURL. +func (in *SourceURL) DeepCopy() *SourceURL { + if in == nil { + return nil + } + out := new(SourceURL) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SourcedClaimMapping) DeepCopyInto(out *SourcedClaimMapping) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.Expression != nil { + in, out := &in.Expression, &out.Expression + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourcedClaimMapping. +func (in *SourcedClaimMapping) DeepCopy() *SourcedClaimMapping { + if in == nil { + return nil + } + out := new(SourcedClaimMapping) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLS) DeepCopyInto(out *TLS) { + *out = *in + if in.CertificateAuthority != nil { + in, out := &in.CertificateAuthority, &out.CertificateAuthority + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLS. +func (in *TLS) DeepCopy() *TLS { + if in == nil { + return nil + } + out := new(TLS) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UserValidationRule) DeepCopyInto(out *UserValidationRule) { *out = *in diff --git a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/zz_generated.deepcopy.go b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/zz_generated.deepcopy.go index 51841b827d..1332d28cb1 100644 --- a/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/zz_generated.deepcopy.go @@ -9,6 +9,32 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Authentication) DeepCopyInto(out *Authentication) { + *out = *in + if in.Type != nil { + in, out := &in.Type, &out.Type + *out = new(AuthenticationType) + **out = **in + } + if in.ClientCredential != nil { + in, out := &in.ClientCredential, &out.ClientCredential + *out = new(ClientCredentialConfig) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Authentication. +func (in *Authentication) DeepCopy() *Authentication { + if in == nil { + return nil + } + out := new(Authentication) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationConfiguration) DeepCopyInto(out *AuthenticationConfiguration) { *out = *in @@ -97,6 +123,98 @@ func (in *ClaimValidationRule) DeepCopy() *ClaimValidationRule { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientCredentialConfig) DeepCopyInto(out *ClientCredentialConfig) { + *out = *in + if in.Scopes != nil { + in, out := &in.Scopes, &out.Scopes + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLS) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientCredentialConfig. +func (in *ClientCredentialConfig) DeepCopy() *ClientCredentialConfig { + if in == nil { + return nil + } + out := new(ClientCredentialConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalClaimsSource) DeepCopyInto(out *ExternalClaimsSource) { + *out = *in + if in.Authentication != nil { + in, out := &in.Authentication, &out.Authentication + *out = new(Authentication) + (*in).DeepCopyInto(*out) + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLS) + (*in).DeepCopyInto(*out) + } + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(SourceURL) + (*in).DeepCopyInto(*out) + } + if in.Mappings != nil { + in, out := &in.Mappings, &out.Mappings + *out = make([]SourcedClaimMapping, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]ExternalSourceCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalClaimsSource. +func (in *ExternalClaimsSource) DeepCopy() *ExternalClaimsSource { + if in == nil { + return nil + } + out := new(ExternalClaimsSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalSourceCondition) DeepCopyInto(out *ExternalSourceCondition) { + *out = *in + if in.Expression != nil { + in, out := &in.Expression, &out.Expression + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSourceCondition. +func (in *ExternalSourceCondition) DeepCopy() *ExternalSourceCondition { + if in == nil { + return nil + } + out := new(ExternalSourceCondition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExtraMapping) DeepCopyInto(out *ExtraMapping) { *out = *in @@ -157,6 +275,13 @@ func (in *JWTAuthenticator) DeepCopyInto(out *JWTAuthenticator) { *out = make([]UserValidationRule, len(*in)) copy(*out, *in) } + if in.ExternalClaimsSources != nil { + in, out := &in.ExternalClaimsSources, &out.ExternalClaimsSources + *out = make([]ExternalClaimsSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -191,6 +316,79 @@ func (in *PrefixedClaimOrExpression) DeepCopy() *PrefixedClaimOrExpression { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SourceURL) DeepCopyInto(out *SourceURL) { + *out = *in + if in.Hostname != nil { + in, out := &in.Hostname, &out.Hostname + *out = new(string) + **out = **in + } + if in.PathExpression != nil { + in, out := &in.PathExpression, &out.PathExpression + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceURL. +func (in *SourceURL) DeepCopy() *SourceURL { + if in == nil { + return nil + } + out := new(SourceURL) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SourcedClaimMapping) DeepCopyInto(out *SourcedClaimMapping) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.Expression != nil { + in, out := &in.Expression, &out.Expression + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourcedClaimMapping. +func (in *SourcedClaimMapping) DeepCopy() *SourcedClaimMapping { + if in == nil { + return nil + } + out := new(SourcedClaimMapping) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLS) DeepCopyInto(out *TLS) { + *out = *in + if in.CertificateAuthority != nil { + in, out := &in.CertificateAuthority, &out.CertificateAuthority + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLS. +func (in *TLS) DeepCopy() *TLS { + if in == nil { + return nil + } + out := new(TLS) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UserValidationRule) DeepCopyInto(out *UserValidationRule) { *out = *in diff --git a/vendor/modules.txt b/vendor/modules.txt index c1581431fc..d553933c55 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -227,7 +227,7 @@ github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo github.com/openshift-eng/openshift-tests-extension/pkg/junit github.com/openshift-eng/openshift-tests-extension/pkg/util/sets github.com/openshift-eng/openshift-tests-extension/pkg/version -# github.com/openshift/api v0.0.0-20260511191110-9b69e5fa27e9 +# github.com/openshift/api v0.0.0-20260511191110-9b69e5fa27e9 => github.com/everettraven/openshift-api v0.0.0-20260507192020-4affa2ac4dea ## explicit; go 1.25.0 github.com/openshift/api github.com/openshift/api/annotations @@ -466,7 +466,7 @@ github.com/openshift/multi-operator-manager/pkg/flagtypes github.com/openshift/multi-operator-manager/pkg/library/libraryapplyconfiguration github.com/openshift/multi-operator-manager/pkg/library/libraryinputresources github.com/openshift/multi-operator-manager/pkg/library/libraryoutputresources -# github.com/openshift/oauth-apiserver v0.0.0-20260430140618-160ac7fb4ea6 +# github.com/openshift/oauth-apiserver v0.0.0-20260520145010-97a820bd5412 ## explicit; go 1.24.0 github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication github.com/openshift/oauth-apiserver/pkg/externaloidc/apis/authentication/v1alpha1 @@ -1651,3 +1651,4 @@ sigs.k8s.io/structured-merge-diff/v6/value ## explicit; go 1.22 sigs.k8s.io/yaml # github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 +# github.com/openshift/api => github.com/everettraven/openshift-api v0.0.0-20260507192020-4affa2ac4dea