Merge pull request #2167 from vmware-tanzu/jtc/federation-domain-issuer-must-be-https-url
Some checks failed
CodeQL / Analyze (go) (push) Failing after 56s
CodeQL / Analyze (javascript) (push) Failing after 45s

Federation domain issuer must be https url
This commit is contained in:
Ryan Richard
2025-01-28 10:56:35 -08:00
committed by GitHub
59 changed files with 295 additions and 958 deletions

View File

@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
type CredentialIssuerStatus struct {
// List of integration strategies that were attempted by Pinniped.
Strategies []CredentialIssuerStrategy `json:"strategies"`
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This field is deprecated and will be removed in a future version.
// +optional
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This type is deprecated and will be removed in a future version.
type CredentialIssuerKubeConfigInfo struct {
// The K8s API server URL.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^https://|^http://`
Server string `json:"server"`
// The K8s API server CA bundle.
// +kubebuilder:validation:MinLength=1
CertificateAuthorityData string `json:"certificateAuthorityData"`
}
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.

View File

@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
// See
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
Issuer string `json:"issuer"`
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.

View File

@@ -540,26 +540,15 @@ func getConciergeFrontend(credentialIssuer *conciergeconfigv1alpha1.CredentialIs
continue
}
// Backfill the .status.strategies[].frontend field from .status.kubeConfigInfo for backwards compatibility.
if strategy.Type == conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType && strategy.Frontend == nil && credentialIssuer.Status.KubeConfigInfo != nil {
strategy = *strategy.DeepCopy()
strategy.Frontend = &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: credentialIssuer.Status.KubeConfigInfo.Server,
CertificateAuthorityData: credentialIssuer.Status.KubeConfigInfo.CertificateAuthorityData,
},
}
}
// If the strategy frontend is still nil, skip.
// If the strategy frontend is nil, skip.
if strategy.Frontend == nil {
continue
}
// Skip any unknown frontend types.
switch strategy.Frontend.Type {
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType, conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
case conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
conciergeconfigv1alpha1.ImpersonationProxyFrontendType:
default:
continue
}

View File

@@ -613,18 +613,18 @@ func TestGetKubeconfig(t *testing.T) {
&conciergeconfigv1alpha1.CredentialIssuer{
ObjectMeta: metav1.ObjectMeta{Name: "test-credential-issuer"},
Status: conciergeconfigv1alpha1.CredentialIssuerStatus{
KubeConfigInfo: &conciergeconfigv1alpha1.CredentialIssuerKubeConfigInfo{
Server: "https://concierge-endpoint",
CertificateAuthorityData: "ZmFrZS1jZXJ0aWZpY2F0ZS1hdXRob3JpdHktZGF0YS12YWx1ZQ==",
},
Strategies: []conciergeconfigv1alpha1.CredentialIssuerStrategy{{
Type: conciergeconfigv1alpha1.KubeClusterSigningCertificateStrategyType,
Status: conciergeconfigv1alpha1.SuccessStrategyStatus,
Reason: conciergeconfigv1alpha1.FetchedKeyStrategyReason,
Message: "Successfully fetched key",
LastUpdateTime: metav1.Now(),
// Simulate a previous version of CredentialIssuer that's missing this Frontend field.
Frontend: nil,
Frontend: &conciergeconfigv1alpha1.CredentialIssuerFrontend{
Type: conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType,
TokenCredentialRequestAPIInfo: &conciergeconfigv1alpha1.TokenCredentialRequestAPIInfo{
Server: "https://concierge-endpoint.example.com",
},
},
}},
},
},

View File

@@ -134,24 +134,6 @@ spec:
status:
description: CredentialIssuerStatus describes the status of the Concierge.
properties:
kubeConfigInfo:
description: |-
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This field is deprecated and will be removed in a future version.
properties:
certificateAuthorityData:
description: The K8s API server CA bundle.
minLength: 1
type: string
server:
description: The K8s API server URL.
minLength: 1
pattern: ^https://|^http://
type: string
required:
- certificateAuthorityData
- server
type: object
strategies:
description: List of integration strategies that were attempted by
Pinniped.

View File

@@ -289,6 +289,9 @@ spec:
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
minLength: 1
type: string
x-kubernetes-validations:
- message: issuer must be an HTTPS URL
rule: isURL(self) && url(self).getScheme() == 'https'
tls:
description: TLS specifies a secret which will contain Transport Layer
Security (TLS) configuration for the FederationDomain.

View File

@@ -428,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo"]
==== CredentialIssuerKubeConfigInfo
CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This type is deprecated and will be removed in a future version.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`server`* __string__ | The K8s API server URL. +
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerspec"]
@@ -480,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|===
| Field | Description
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-25-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
This field is deprecated and will be removed in a future version. +
|===

View File

@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
type CredentialIssuerStatus struct {
// List of integration strategies that were attempted by Pinniped.
Strategies []CredentialIssuerStrategy `json:"strategies"`
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This field is deprecated and will be removed in a future version.
// +optional
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This type is deprecated and will be removed in a future version.
type CredentialIssuerKubeConfigInfo struct {
// The K8s API server URL.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^https://|^http://`
Server string `json:"server"`
// The K8s API server CA bundle.
// +kubebuilder:validation:MinLength=1
CertificateAuthorityData string `json:"certificateAuthorityData"`
}
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.

View File

@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
if in == nil {
return nil
}
out := new(CredentialIssuerKubeConfigInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
*out = *in
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.KubeConfigInfo != nil {
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
*out = new(CredentialIssuerKubeConfigInfo)
**out = **in
}
return
}

View File

@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
// See
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
Issuer string `json:"issuer"`
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.

View File

@@ -134,24 +134,6 @@ spec:
status:
description: CredentialIssuerStatus describes the status of the Concierge.
properties:
kubeConfigInfo:
description: |-
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This field is deprecated and will be removed in a future version.
properties:
certificateAuthorityData:
description: The K8s API server CA bundle.
minLength: 1
type: string
server:
description: The K8s API server URL.
minLength: 1
pattern: ^https://|^http://
type: string
required:
- certificateAuthorityData
- server
type: object
strategies:
description: List of integration strategies that were attempted by
Pinniped.

View File

@@ -289,6 +289,9 @@ spec:
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
minLength: 1
type: string
x-kubernetes-validations:
- message: issuer must be an HTTPS URL
rule: isURL(self) && url(self).getScheme() == 'https'
tls:
description: TLS specifies a secret which will contain Transport Layer
Security (TLS) configuration for the FederationDomain.

View File

@@ -428,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo"]
==== CredentialIssuerKubeConfigInfo
CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This type is deprecated and will be removed in a future version.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`server`* __string__ | The K8s API server URL. +
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerspec"]
@@ -480,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|===
| Field | Description
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-26-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
This field is deprecated and will be removed in a future version. +
|===

View File

@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
type CredentialIssuerStatus struct {
// List of integration strategies that were attempted by Pinniped.
Strategies []CredentialIssuerStrategy `json:"strategies"`
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This field is deprecated and will be removed in a future version.
// +optional
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This type is deprecated and will be removed in a future version.
type CredentialIssuerKubeConfigInfo struct {
// The K8s API server URL.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^https://|^http://`
Server string `json:"server"`
// The K8s API server CA bundle.
// +kubebuilder:validation:MinLength=1
CertificateAuthorityData string `json:"certificateAuthorityData"`
}
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.

View File

@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
if in == nil {
return nil
}
out := new(CredentialIssuerKubeConfigInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
*out = *in
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.KubeConfigInfo != nil {
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
*out = new(CredentialIssuerKubeConfigInfo)
**out = **in
}
return
}

View File

@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
// See
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
Issuer string `json:"issuer"`
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.

View File

@@ -134,24 +134,6 @@ spec:
status:
description: CredentialIssuerStatus describes the status of the Concierge.
properties:
kubeConfigInfo:
description: |-
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This field is deprecated and will be removed in a future version.
properties:
certificateAuthorityData:
description: The K8s API server CA bundle.
minLength: 1
type: string
server:
description: The K8s API server URL.
minLength: 1
pattern: ^https://|^http://
type: string
required:
- certificateAuthorityData
- server
type: object
strategies:
description: List of integration strategies that were attempted by
Pinniped.

View File

@@ -289,6 +289,9 @@ spec:
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
minLength: 1
type: string
x-kubernetes-validations:
- message: issuer must be an HTTPS URL
rule: isURL(self) && url(self).getScheme() == 'https'
tls:
description: TLS specifies a secret which will contain Transport Layer
Security (TLS) configuration for the FederationDomain.

View File

@@ -428,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo"]
==== CredentialIssuerKubeConfigInfo
CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This type is deprecated and will be removed in a future version.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`server`* __string__ | The K8s API server URL. +
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerspec"]
@@ -480,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|===
| Field | Description
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-27-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
This field is deprecated and will be removed in a future version. +
|===

View File

@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
type CredentialIssuerStatus struct {
// List of integration strategies that were attempted by Pinniped.
Strategies []CredentialIssuerStrategy `json:"strategies"`
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This field is deprecated and will be removed in a future version.
// +optional
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This type is deprecated and will be removed in a future version.
type CredentialIssuerKubeConfigInfo struct {
// The K8s API server URL.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^https://|^http://`
Server string `json:"server"`
// The K8s API server CA bundle.
// +kubebuilder:validation:MinLength=1
CertificateAuthorityData string `json:"certificateAuthorityData"`
}
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.

View File

@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
if in == nil {
return nil
}
out := new(CredentialIssuerKubeConfigInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
*out = *in
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.KubeConfigInfo != nil {
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
*out = new(CredentialIssuerKubeConfigInfo)
**out = **in
}
return
}

View File

@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
// See
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
Issuer string `json:"issuer"`
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.

View File

@@ -134,24 +134,6 @@ spec:
status:
description: CredentialIssuerStatus describes the status of the Concierge.
properties:
kubeConfigInfo:
description: |-
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This field is deprecated and will be removed in a future version.
properties:
certificateAuthorityData:
description: The K8s API server CA bundle.
minLength: 1
type: string
server:
description: The K8s API server URL.
minLength: 1
pattern: ^https://|^http://
type: string
required:
- certificateAuthorityData
- server
type: object
strategies:
description: List of integration strategies that were attempted by
Pinniped.

View File

@@ -289,6 +289,9 @@ spec:
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
minLength: 1
type: string
x-kubernetes-validations:
- message: issuer must be an HTTPS URL
rule: isURL(self) && url(self).getScheme() == 'https'
tls:
description: TLS specifies a secret which will contain Transport Layer
Security (TLS) configuration for the FederationDomain.

View File

@@ -428,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo"]
==== CredentialIssuerKubeConfigInfo
CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This type is deprecated and will be removed in a future version.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`server`* __string__ | The K8s API server URL. +
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerspec"]
@@ -480,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|===
| Field | Description
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-28-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
This field is deprecated and will be removed in a future version. +
|===

View File

@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
type CredentialIssuerStatus struct {
// List of integration strategies that were attempted by Pinniped.
Strategies []CredentialIssuerStrategy `json:"strategies"`
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This field is deprecated and will be removed in a future version.
// +optional
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This type is deprecated and will be removed in a future version.
type CredentialIssuerKubeConfigInfo struct {
// The K8s API server URL.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^https://|^http://`
Server string `json:"server"`
// The K8s API server CA bundle.
// +kubebuilder:validation:MinLength=1
CertificateAuthorityData string `json:"certificateAuthorityData"`
}
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.

View File

@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
if in == nil {
return nil
}
out := new(CredentialIssuerKubeConfigInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
*out = *in
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.KubeConfigInfo != nil {
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
*out = new(CredentialIssuerKubeConfigInfo)
**out = **in
}
return
}

View File

@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
// See
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
Issuer string `json:"issuer"`
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.

View File

@@ -134,24 +134,6 @@ spec:
status:
description: CredentialIssuerStatus describes the status of the Concierge.
properties:
kubeConfigInfo:
description: |-
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This field is deprecated and will be removed in a future version.
properties:
certificateAuthorityData:
description: The K8s API server CA bundle.
minLength: 1
type: string
server:
description: The K8s API server URL.
minLength: 1
pattern: ^https://|^http://
type: string
required:
- certificateAuthorityData
- server
type: object
strategies:
description: List of integration strategies that were attempted by
Pinniped.

View File

@@ -289,6 +289,9 @@ spec:
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
minLength: 1
type: string
x-kubernetes-validations:
- message: issuer must be an HTTPS URL
rule: isURL(self) && url(self).getScheme() == 'https'
tls:
description: TLS specifies a secret which will contain Transport Layer
Security (TLS) configuration for the FederationDomain.

View File

@@ -428,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo"]
==== CredentialIssuerKubeConfigInfo
CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This type is deprecated and will be removed in a future version.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`server`* __string__ | The K8s API server URL. +
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-credentialissuerspec"]
@@ -480,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|===
| Field | Description
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-29-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
This field is deprecated and will be removed in a future version. +
|===

View File

@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
type CredentialIssuerStatus struct {
// List of integration strategies that were attempted by Pinniped.
Strategies []CredentialIssuerStrategy `json:"strategies"`
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This field is deprecated and will be removed in a future version.
// +optional
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This type is deprecated and will be removed in a future version.
type CredentialIssuerKubeConfigInfo struct {
// The K8s API server URL.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^https://|^http://`
Server string `json:"server"`
// The K8s API server CA bundle.
// +kubebuilder:validation:MinLength=1
CertificateAuthorityData string `json:"certificateAuthorityData"`
}
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.

View File

@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
if in == nil {
return nil
}
out := new(CredentialIssuerKubeConfigInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
*out = *in
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.KubeConfigInfo != nil {
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
*out = new(CredentialIssuerKubeConfigInfo)
**out = **in
}
return
}

View File

@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
// See
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
Issuer string `json:"issuer"`
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.

View File

@@ -134,24 +134,6 @@ spec:
status:
description: CredentialIssuerStatus describes the status of the Concierge.
properties:
kubeConfigInfo:
description: |-
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This field is deprecated and will be removed in a future version.
properties:
certificateAuthorityData:
description: The K8s API server CA bundle.
minLength: 1
type: string
server:
description: The K8s API server URL.
minLength: 1
pattern: ^https://|^http://
type: string
required:
- certificateAuthorityData
- server
type: object
strategies:
description: List of integration strategies that were attempted by
Pinniped.

View File

@@ -289,6 +289,9 @@ spec:
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
minLength: 1
type: string
x-kubernetes-validations:
- message: issuer must be an HTTPS URL
rule: isURL(self) && url(self).getScheme() == 'https'
tls:
description: TLS specifies a secret which will contain Transport Layer
Security (TLS) configuration for the FederationDomain.

View File

@@ -428,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo"]
==== CredentialIssuerKubeConfigInfo
CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This type is deprecated and will be removed in a future version.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`server`* __string__ | The K8s API server URL. +
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-credentialissuerspec"]
@@ -480,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|===
| Field | Description
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-30-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
This field is deprecated and will be removed in a future version. +
|===

View File

@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
type CredentialIssuerStatus struct {
// List of integration strategies that were attempted by Pinniped.
Strategies []CredentialIssuerStrategy `json:"strategies"`
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This field is deprecated and will be removed in a future version.
// +optional
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This type is deprecated and will be removed in a future version.
type CredentialIssuerKubeConfigInfo struct {
// The K8s API server URL.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^https://|^http://`
Server string `json:"server"`
// The K8s API server CA bundle.
// +kubebuilder:validation:MinLength=1
CertificateAuthorityData string `json:"certificateAuthorityData"`
}
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.

View File

@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
if in == nil {
return nil
}
out := new(CredentialIssuerKubeConfigInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
*out = *in
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.KubeConfigInfo != nil {
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
*out = new(CredentialIssuerKubeConfigInfo)
**out = **in
}
return
}

View File

@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
// See
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
Issuer string `json:"issuer"`
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.

View File

@@ -134,24 +134,6 @@ spec:
status:
description: CredentialIssuerStatus describes the status of the Concierge.
properties:
kubeConfigInfo:
description: |-
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This field is deprecated and will be removed in a future version.
properties:
certificateAuthorityData:
description: The K8s API server CA bundle.
minLength: 1
type: string
server:
description: The K8s API server URL.
minLength: 1
pattern: ^https://|^http://
type: string
required:
- certificateAuthorityData
- server
type: object
strategies:
description: List of integration strategies that were attempted by
Pinniped.

View File

@@ -289,6 +289,9 @@ spec:
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
minLength: 1
type: string
x-kubernetes-validations:
- message: issuer must be an HTTPS URL
rule: isURL(self) && url(self).getScheme() == 'https'
tls:
description: TLS specifies a secret which will contain Transport Layer
Security (TLS) configuration for the FederationDomain.

View File

@@ -428,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo"]
==== CredentialIssuerKubeConfigInfo
CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This type is deprecated and will be removed in a future version.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`server`* __string__ | The K8s API server URL. +
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerspec"]
@@ -480,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|===
| Field | Description
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
This field is deprecated and will be removed in a future version. +
|===

View File

@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
type CredentialIssuerStatus struct {
// List of integration strategies that were attempted by Pinniped.
Strategies []CredentialIssuerStrategy `json:"strategies"`
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This field is deprecated and will be removed in a future version.
// +optional
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This type is deprecated and will be removed in a future version.
type CredentialIssuerKubeConfigInfo struct {
// The K8s API server URL.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^https://|^http://`
Server string `json:"server"`
// The K8s API server CA bundle.
// +kubebuilder:validation:MinLength=1
CertificateAuthorityData string `json:"certificateAuthorityData"`
}
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.

View File

@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
if in == nil {
return nil
}
out := new(CredentialIssuerKubeConfigInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
*out = *in
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.KubeConfigInfo != nil {
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
*out = new(CredentialIssuerKubeConfigInfo)
**out = **in
}
return
}

View File

@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
// See
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
Issuer string `json:"issuer"`
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.

View File

@@ -134,24 +134,6 @@ spec:
status:
description: CredentialIssuerStatus describes the status of the Concierge.
properties:
kubeConfigInfo:
description: |-
Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This field is deprecated and will be removed in a future version.
properties:
certificateAuthorityData:
description: The K8s API server CA bundle.
minLength: 1
type: string
server:
description: The K8s API server URL.
minLength: 1
pattern: ^https://|^http://
type: string
required:
- certificateAuthorityData
- server
type: object
strategies:
description: List of integration strategies that were attempted by
Pinniped.

View File

@@ -289,6 +289,9 @@ spec:
https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
minLength: 1
type: string
x-kubernetes-validations:
- message: issuer must be an HTTPS URL
rule: isURL(self) && url(self).getScheme() == 'https'
tls:
description: TLS specifies a secret which will contain Transport Layer
Security (TLS) configuration for the FederationDomain.

View File

@@ -428,25 +428,6 @@ This field is only set when Type is "ImpersonationProxy". +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo"]
==== CredentialIssuerKubeConfigInfo
CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
This type is deprecated and will be removed in a future version.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerstatus[$$CredentialIssuerStatus$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`server`* __string__ | The K8s API server URL. +
| *`certificateAuthorityData`* __string__ | The K8s API server CA bundle. +
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerspec"]
@@ -480,8 +461,6 @@ CredentialIssuerStatus describes the status of the Concierge.
|===
| Field | Description
| *`strategies`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerstrategy[$$CredentialIssuerStrategy$$] array__ | List of integration strategies that were attempted by Pinniped. +
| *`kubeConfigInfo`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-31-apis-concierge-config-v1alpha1-credentialissuerkubeconfiginfo[$$CredentialIssuerKubeConfigInfo$$]__ | Information needed to form a valid Pinniped-based kubeconfig using this credential issuer. +
This field is deprecated and will be removed in a future version. +
|===

View File

@@ -161,24 +161,6 @@ type ImpersonationProxyServiceSpec struct {
type CredentialIssuerStatus struct {
// List of integration strategies that were attempted by Pinniped.
Strategies []CredentialIssuerStrategy `json:"strategies"`
// Information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This field is deprecated and will be removed in a future version.
// +optional
KubeConfigInfo *CredentialIssuerKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
// CredentialIssuerKubeConfigInfo provides the information needed to form a valid Pinniped-based kubeconfig using this credential issuer.
// This type is deprecated and will be removed in a future version.
type CredentialIssuerKubeConfigInfo struct {
// The K8s API server URL.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:Pattern=`^https://|^http://`
Server string `json:"server"`
// The K8s API server CA bundle.
// +kubebuilder:validation:MinLength=1
CertificateAuthorityData string `json:"certificateAuthorityData"`
}
// CredentialIssuerStrategy describes the status of an integration strategy that was attempted by Pinniped.

View File

@@ -66,22 +66,6 @@ func (in *CredentialIssuerFrontend) DeepCopy() *CredentialIssuerFrontend {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerKubeConfigInfo) DeepCopyInto(out *CredentialIssuerKubeConfigInfo) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerKubeConfigInfo.
func (in *CredentialIssuerKubeConfigInfo) DeepCopy() *CredentialIssuerKubeConfigInfo {
if in == nil {
return nil
}
out := new(CredentialIssuerKubeConfigInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerList) DeepCopyInto(out *CredentialIssuerList) {
*out = *in
@@ -146,11 +130,6 @@ func (in *CredentialIssuerStatus) DeepCopyInto(out *CredentialIssuerStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.KubeConfigInfo != nil {
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
*out = new(CredentialIssuerKubeConfigInfo)
**out = **in
}
return
}

View File

@@ -209,6 +209,7 @@ type FederationDomainSpec struct {
// See
// https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 for more information.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:message="issuer must be an HTTPS URL",rule="isURL(self) && url(self).getScheme() == 'https'"
Issuer string `json:"issuer"`
// TLS specifies a secret which will contain Transport Layer Security (TLS) configuration for the FederationDomain.

View File

@@ -49,14 +49,6 @@ func mergeStrategy(configToUpdate *conciergeconfigv1alpha1.CredentialIssuerStatu
configToUpdate.Strategies = append(configToUpdate.Strategies, strategy)
}
sort.Stable(sortableStrategies(configToUpdate.Strategies))
// Special case: the "TokenCredentialRequestAPI" data is mirrored into the deprecated status.kubeConfigInfo field.
if strategy.Frontend != nil && strategy.Frontend.Type == conciergeconfigv1alpha1.TokenCredentialRequestAPIFrontendType {
configToUpdate.KubeConfigInfo = &conciergeconfigv1alpha1.CredentialIssuerKubeConfigInfo{
Server: strategy.Frontend.TokenCredentialRequestAPIInfo.Server,
CertificateAuthorityData: strategy.Frontend.TokenCredentialRequestAPIInfo.CertificateAuthorityData,
}
}
}
// weights are a set of priorities for each strategy type.

View File

@@ -87,10 +87,6 @@ func TestMergeStrategy(t *testing.T) {
},
},
},
KubeConfigInfo: &conciergeconfigv1alpha1.CredentialIssuerKubeConfigInfo{
Server: "https://test-server",
CertificateAuthorityData: "test-ca-bundle",
},
},
},
{

View File

@@ -1,4 +1,4 @@
// Copyright 2021-2024 the Pinniped contributors. All Rights Reserved.
// Copyright 2021-2025 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package testutil
@@ -45,7 +45,7 @@ func KubeServerMinorVersionAtLeastInclusive(t *testing.T, discoveryClient discov
return !KubeServerMinorVersionInBetweenInclusive(t, discoveryClient, 0, min-1)
}
func KubeServerMinorVersionInBetweenInclusive(t *testing.T, discoveryClient discovery.DiscoveryInterface, min, max int) bool {
func KubeServerMinorVersion(t *testing.T, discoveryClient discovery.DiscoveryInterface) int {
t.Helper()
version, err := discoveryClient.ServerVersion()
@@ -56,6 +56,12 @@ func KubeServerMinorVersionInBetweenInclusive(t *testing.T, discoveryClient disc
minor, err := strconv.Atoi(strings.TrimSuffix(version.Minor, "+"))
require.NoError(t, err)
return minor
}
func KubeServerMinorVersionInBetweenInclusive(t *testing.T, discoveryClient discovery.DiscoveryInterface, min, max int) bool {
minor := KubeServerMinorVersion(t, discoveryClient)
return minor >= min && minor <= max
}

View File

@@ -36,7 +36,6 @@ func TestCredentialIssuer(t *testing.T) {
require.Len(t, actualConfigList.Items, 1)
actualConfig := actualConfigList.Items[0]
actualStatusKubeConfigInfo := actualConfigList.Items[0].Status.KubeConfigInfo
for k, v := range env.ConciergeCustomLabels {
require.Equalf(t, v, actualConfig.Labels[k], "expected ci to have label `%s: %s`", k, v)
@@ -77,22 +76,11 @@ func TestCredentialIssuer(t *testing.T) {
CertificateAuthorityData: base64.StdEncoding.EncodeToString(config.TLSClientConfig.CAData),
}
require.Equal(t, &expectedTokenRequestAPIInfo, actualStatusStrategy.Frontend.TokenCredentialRequestAPIInfo)
// Verify the published kube config info.
require.Equal(
t,
&conciergeconfigv1alpha1.CredentialIssuerKubeConfigInfo{
Server: expectedTokenRequestAPIInfo.Server,
CertificateAuthorityData: expectedTokenRequestAPIInfo.CertificateAuthorityData,
},
actualStatusKubeConfigInfo,
)
} else {
require.Equal(t, conciergeconfigv1alpha1.ErrorStrategyStatus, actualStatusStrategy.Status)
require.Equal(t, conciergeconfigv1alpha1.CouldNotFetchKeyStrategyReason, actualStatusStrategy.Reason)
require.Contains(t, actualStatusStrategy.Message, "could not find a healthy kube-controller-manager pod (0 candidates): "+
"note that this error is the expected behavior for some cluster types, including most cloud provider clusters (e.g. GKE, AKS, EKS)")
require.Nil(t, actualStatusKubeConfigInfo)
}
})
}

View File

@@ -452,7 +452,7 @@ func TestGetAPIResourceList(t *testing.T) { //nolint:gocyclo // each t.Run is pr
}
// manually update this value whenever you add additional fields to an API resource and then run the generator
totalExpectedAPIFields := 313
totalExpectedAPIFields := 310
// Because we are parsing text from `kubectl explain` and because the format of that text can change
// over time, make a rudimentary assertion that this test exercised the whole tree of all fields of all

View File

@@ -1,4 +1,4 @@
// Copyright 2023-2024 the Pinniped contributors. All Rights Reserved.
// Copyright 2023-2025 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package integration
@@ -563,311 +563,263 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
t.Cleanup(cancel)
adminClient := testlib.NewKubernetesClientset(t)
usingKubeVersionInCluster23OrOlder := testutil.KubeServerMinorVersionInBetweenInclusive(t, adminClient.Discovery(), 0, 23)
usingKubeVersionInCluster24Through31Inclusive := testutil.KubeServerMinorVersionInBetweenInclusive(t, adminClient.Discovery(), 24, 31)
usingKubeVersionInCluster32OrNewer := !usingKubeVersionInCluster23OrOlder && !usingKubeVersionInCluster24Through31Inclusive
objectMeta := testlib.ObjectMetaWithRandomName(t, "federation-domain")
// Certain non-CEL validation failures will prevent CEL validations from running,
// and the Kubernetes API server will return this error message for those cases.
const couldNotRunCELValidationsErrMessage = `<nil>: Invalid value: "null": some validation rules were not checked because the object was invalid; correct the existing errors to complete validation`
tests := []struct {
name string
fd *supervisorconfigv1alpha1.FederationDomain
wantErr string
name string
spec *supervisorconfigv1alpha1.FederationDomainSpec
wantErrs []string
// optionally override wantErr for one or more specific versions of Kube, due to changing validation error text
wantKube23OrOlderErr string
wantKube24Through31InclusiveErr string
wantKube32OrNewerErr string
wantKube23OrOlderErrs []string
wantKube24Through31InclusiveErrs []string
wantKube32OrNewerErrs []string
// These errors are appended to any other wanted errors when k8sAPIServerSupportsCEL is true
wantCELErrorsForKube25Through28Inclusive []string
wantCELErrorsForKube29OrNewer []string
}{
{
name: "issuer cannot be empty",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "",
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "",
},
wantErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.issuer: Invalid value: "": spec.issuer in body should be at least 1 chars long`,
env.APIGroupSuffix, objectMeta.Name),
wantErrs: []string{`spec.issuer: Invalid value: "": spec.issuer in body should be at least 1 chars long`},
wantCELErrorsForKube25Through28Inclusive: []string{`spec.issuer: Invalid value: "string": issuer must be an HTTPS URL`},
wantCELErrorsForKube29OrNewer: []string{`spec.issuer: Invalid value: "string": issuer must be an HTTPS URL`},
},
{
name: "issuer must be a URL",
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "foo",
},
wantCELErrorsForKube25Through28Inclusive: []string{`spec.issuer: Invalid value: "string": issuer must be an HTTPS URL`},
wantCELErrorsForKube29OrNewer: []string{`spec.issuer: Invalid value: "string": issuer must be an HTTPS URL`},
},
{
name: "issuer URL scheme must be 'https'",
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "http://example.com",
},
wantCELErrorsForKube25Through28Inclusive: []string{`spec.issuer: Invalid value: "string": issuer must be an HTTPS URL`},
wantCELErrorsForKube29OrNewer: []string{`spec.issuer: Invalid value: "string": issuer must be an HTTPS URL`},
},
{
name: "IDP display names cannot be empty",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
},
},
},
wantErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].displayName: Invalid value: "": `+
"spec.identityProviders[0].displayName in body should be at least 1 chars long",
env.APIGroupSuffix, objectMeta.Name),
wantErrs: []string{`spec.identityProviders[0].displayName: Invalid value: "": spec.identityProviders[0].displayName in body should be at least 1 chars long`},
},
{
name: "IDP transform constants must have unique names",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "notUnique", Type: "string", StringValue: "foo"},
{Name: "notUnique", Type: "string", StringValue: "bar"},
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "notUnique", Type: "string", StringValue: "foo"},
{Name: "notUnique", Type: "string", StringValue: "bar"},
},
},
},
},
},
wantKube23OrOlderErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].transforms.constants[1]: Duplicate value: map[string]interface {}{"name":"notUnique"}`,
env.APIGroupSuffix, objectMeta.Name),
wantErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].transforms.constants[1]: Duplicate value: map[string]interface {}{"name":"notUnique"}`,
env.APIGroupSuffix, objectMeta.Name),
// For some unknown reason, Kubernetes versions 1.23 and older return errors *with indices* for this test case only.
wantKube23OrOlderErrs: []string{`spec.identityProviders[0].transforms.constants[1]: Duplicate value: map[string]interface {}{"name":"notUnique"}`},
wantErrs: []string{`spec.identityProviders[0].transforms.constants[1]: Duplicate value: map[string]interface {}{"name":"notUnique"}`},
},
{
name: "IDP transform constant names cannot be empty",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "", Type: "string"},
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "", Type: "string"},
},
},
},
},
},
wantErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].transforms.constants[0].name: Invalid value: "": `+
`spec.identityProviders[0].transforms.constants[0].name in body should be at least 1 chars long`,
env.APIGroupSuffix, objectMeta.Name),
wantErrs: []string{`spec.identityProviders[0].transforms.constants[0].name: Invalid value: "": spec.identityProviders[0].transforms.constants[0].name in body should be at least 1 chars long`},
},
{
name: "IDP transform constant names cannot be more than 64 characters",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "12345678901234567890123456789012345678901234567890123456789012345", Type: "string"},
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "12345678901234567890123456789012345678901234567890123456789012345", Type: "string"},
},
},
},
},
},
wantKube23OrOlderErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders.transforms.constants.name: Invalid value: "12345678901234567890123456789012345678901234567890123456789012345": `+
`spec.identityProviders.transforms.constants.name in body should be at most 64 chars long`,
env.APIGroupSuffix, objectMeta.Name),
wantKube24Through31InclusiveErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].transforms.constants[0].name: Too long: may not be longer than 64`,
env.APIGroupSuffix, objectMeta.Name),
wantKube32OrNewerErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].transforms.constants[0].name: Too long: may not be more than 64 bytes`,
env.APIGroupSuffix, objectMeta.Name),
wantKube23OrOlderErrs: []string{`spec.identityProviders.transforms.constants.name: Invalid value: "12345678901234567890123456789012345678901234567890123456789012345": spec.identityProviders.transforms.constants.name in body should be at most 64 chars long`},
wantKube24Through31InclusiveErrs: []string{`spec.identityProviders[0].transforms.constants[0].name: Too long: may not be longer than 64`},
wantKube32OrNewerErrs: []string{`spec.identityProviders[0].transforms.constants[0].name: Too long: may not be more than 64 bytes`},
wantCELErrorsForKube25Through28Inclusive: []string{couldNotRunCELValidationsErrMessage},
wantCELErrorsForKube29OrNewer: []string{couldNotRunCELValidationsErrMessage},
},
{
name: "IDP transform constant names must be a legal CEL variable name",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "cannot have spaces", Type: "string"},
{Name: "1mustStartWithLetter", Type: "string"},
{Name: "_mustStartWithLetter", Type: "string"},
{Name: "canOnlyIncludeLettersAndNumbersAnd_", Type: "string"},
{Name: "CanStart1_withUpperCase", Type: "string"},
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "cannot have spaces", Type: "string"},
{Name: "1mustStartWithLetter", Type: "string"},
{Name: "_mustStartWithLetter", Type: "string"},
{Name: "canOnlyIncludeLettersAndNumbersAnd_", Type: "string"},
{Name: "CanStart1_withUpperCase", Type: "string"},
},
},
},
},
},
wantKube23OrOlderErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders.transforms.constants.name: Invalid value: "cannot have spaces": `+
`spec.identityProviders.transforms.constants.name in body should match '^[a-zA-Z][_a-zA-Z0-9]*$'`,
env.APIGroupSuffix, objectMeta.Name),
wantErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`[spec.identityProviders[0].transforms.constants[0].name: Invalid value: "cannot have spaces": `+
`spec.identityProviders[0].transforms.constants[0].name in body should match '^[a-zA-Z][_a-zA-Z0-9]*$', `+
`spec.identityProviders[0].transforms.constants[1].name: Invalid value: "1mustStartWithLetter": `+
`spec.identityProviders[0].transforms.constants[1].name in body should match '^[a-zA-Z][_a-zA-Z0-9]*$', `+
`spec.identityProviders[0].transforms.constants[2].name: Invalid value: "_mustStartWithLetter": `+
`spec.identityProviders[0].transforms.constants[2].name in body should match '^[a-zA-Z][_a-zA-Z0-9]*$']`,
env.APIGroupSuffix, objectMeta.Name),
wantKube23OrOlderErrs: []string{`spec.identityProviders.transforms.constants.name: Invalid value: "cannot have spaces": spec.identityProviders.transforms.constants.name in body should match '^[a-zA-Z][_a-zA-Z0-9]*$'`},
wantErrs: []string{
`spec.identityProviders[0].transforms.constants[0].name: Invalid value: "cannot have spaces": spec.identityProviders[0].transforms.constants[0].name in body should match '^[a-zA-Z][_a-zA-Z0-9]*$'`,
`spec.identityProviders[0].transforms.constants[1].name: Invalid value: "1mustStartWithLetter": spec.identityProviders[0].transforms.constants[1].name in body should match '^[a-zA-Z][_a-zA-Z0-9]*$'`,
`spec.identityProviders[0].transforms.constants[2].name: Invalid value: "_mustStartWithLetter": spec.identityProviders[0].transforms.constants[2].name in body should match '^[a-zA-Z][_a-zA-Z0-9]*$'`},
},
{
name: "IDP transform constant types must be one of the allowed enum strings",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "a", Type: "this is invalid"},
{Name: "b", Type: "string"},
{Name: "c", Type: "stringList"},
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "a", Type: "this is invalid"},
{Name: "b", Type: "string"},
{Name: "c", Type: "stringList"},
},
},
},
},
},
wantErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].transforms.constants[0].type: Unsupported value: "this is invalid": `+
`supported values: "string", "stringList"`,
env.APIGroupSuffix, objectMeta.Name),
wantErrs: []string{`spec.identityProviders[0].transforms.constants[0].type: Unsupported value: "this is invalid": supported values: "string", "stringList"`},
wantCELErrorsForKube29OrNewer: []string{couldNotRunCELValidationsErrMessage}, // this should not be checked on kind 1.25, 1.26, 1.27, 1.28
},
{
name: "IDP transform expression types must be one of the allowed enum strings",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "this is invalid", Expression: "foo"},
{Type: "policy/v1", Expression: "foo"},
{Type: "username/v1", Expression: "foo"},
{Type: "groups/v1", Expression: "foo"},
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "this is invalid", Expression: "foo"},
{Type: "policy/v1", Expression: "foo"},
{Type: "username/v1", Expression: "foo"},
{Type: "groups/v1", Expression: "foo"},
},
},
},
},
},
wantErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].transforms.expressions[0].type: Unsupported value: "this is invalid": `+
`supported values: "policy/v1", "username/v1", "groups/v1"`,
env.APIGroupSuffix, objectMeta.Name),
wantErrs: []string{`spec.identityProviders[0].transforms.expressions[0].type: Unsupported value: "this is invalid": supported values: "policy/v1", "username/v1", "groups/v1"`},
wantCELErrorsForKube29OrNewer: []string{couldNotRunCELValidationsErrMessage}, // this should not be checked on kind 1.25, 1.26, 1.27, 1.28
},
{
name: "IDP transform expressions cannot be empty",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "username/v1", Expression: ""},
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "username/v1", Expression: ""},
},
},
},
},
},
wantErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].transforms.expressions[0].expression: Invalid value: "": `+
`spec.identityProviders[0].transforms.expressions[0].expression in body should be at least 1 chars long`,
env.APIGroupSuffix, objectMeta.Name),
wantErrs: []string{`spec.identityProviders[0].transforms.expressions[0].expression: Invalid value: "": spec.identityProviders[0].transforms.expressions[0].expression in body should be at least 1 chars long`},
},
{
name: "IDP transform example usernames cannot be empty",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: objectMeta,
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{Username: ""},
{Username: "non-empty"},
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{Username: ""},
{Username: "non-empty"},
},
},
},
},
},
wantErr: fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: "+
`spec.identityProviders[0].transforms.examples[0].username: Invalid value: "": `+
`spec.identityProviders[0].transforms.examples[0].username in body should be at least 1 chars long`,
env.APIGroupSuffix, objectMeta.Name),
wantErrs: []string{`spec.identityProviders[0].transforms.examples[0].username: Invalid value: "": spec.identityProviders[0].transforms.examples[0].username in body should be at least 1 chars long`},
},
{
name: "minimum valid",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: testlib.ObjectMetaWithRandomName(t, "fd"),
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
},
},
{
name: "minimum valid when IDPs are included",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: testlib.ObjectMetaWithRandomName(t, "fd"),
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
},
},
@@ -875,26 +827,23 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
},
{
name: "minimum valid when IDP has transform constants, expressions, and examples",
fd: &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: testlib.ObjectMetaWithRandomName(t, "fd"),
Spec: supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
spec: &supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: "https://example.com",
IdentityProviders: []supervisorconfigv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "foo",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: ptr.To("required in older versions of Kubernetes for each item in the identityProviders slice"),
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "foo", Type: "string"},
},
Transforms: supervisorconfigv1alpha1.FederationDomainTransforms{
Constants: []supervisorconfigv1alpha1.FederationDomainTransformsConstant{
{Name: "foo", Type: "string"},
},
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "username/v1", Expression: "foo"},
},
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{Username: "foo"},
},
Expressions: []supervisorconfigv1alpha1.FederationDomainTransformsExpression{
{Type: "username/v1", Expression: "foo"},
},
Examples: []supervisorconfigv1alpha1.FederationDomainTransformsExample{
{Username: "foo"},
},
},
},
@@ -908,50 +857,76 @@ func TestSupervisorFederationDomainCRDValidations_Parallel(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
_, createErr := fdClient.Create(ctx, tt.fd, metav1.CreateOptions{})
fd := &supervisorconfigv1alpha1.FederationDomain{
ObjectMeta: testlib.ObjectMetaWithRandomName(t, "federation-domain"),
Spec: *tt.spec,
}
_, actualCreateErr := fdClient.Create(ctx, fd, metav1.CreateOptions{})
t.Cleanup(func() {
// Delete it if it exists.
delErr := fdClient.Delete(ctx, tt.fd.Name, metav1.DeleteOptions{})
delErr := fdClient.Delete(ctx, fd.Name, metav1.DeleteOptions{})
if !apierrors.IsNotFound(delErr) {
require.NoError(t, delErr)
}
})
if tt.wantErr != "" && tt.wantKube23OrOlderErr != "" && tt.wantKube24Through31InclusiveErr != "" && tt.wantKube32OrNewerErr != "" {
if len(tt.wantErrs) > 0 && len(tt.wantKube23OrOlderErrs) > 0 && len(tt.wantKube24Through31InclusiveErrs) > 0 && len(tt.wantKube32OrNewerErrs) > 0 {
require.Fail(t, "test setup problem: wanted every possible kind of error, which would cause tt.wantErr to be unused")
}
if tt.wantErr == "" && tt.wantKube23OrOlderErr == "" && tt.wantKube24Through31InclusiveErr == "" && tt.wantKube32OrNewerErr == "" { //nolint:nestif
// Did not want any error.
require.NoError(t, createErr)
} else {
wantErr := tt.wantErr
if usingKubeVersionInCluster23OrOlder {
// Old versions of Kubernetes did not show the index where the error occurred in some of the messages,
// so remove the indices from the expected messages when running against an old version of Kube.
// For the above tests, it should be enough to assume that there will only be indices up to 10.
// This is useful when the only difference in the message between old and new is the missing indices.
// Otherwise, use wantKube23OrOlderErr to say what the expected message should be for old versions.
for i := range 10 {
wantErr = strings.ReplaceAll(wantErr, fmt.Sprintf("[%d]", i), "")
minor := testutil.KubeServerMinorVersion(t, adminClient.Discovery())
wantErr := tt.wantErrs
if minor <= 23 {
// Old versions of Kubernetes did not show the index where the error occurred in some of the messages,
// so remove the indices from the expected messages when running against an old version of Kube.
// For the above tests, it should be enough to assume that there will only be indices up to 10.
// This is useful when the only difference in the message between old and new is the missing indices.
// Otherwise, use wantKube23OrOlderErr to say what the expected message should be for old versions.
for i := range wantErr {
for j := range 10 {
wantErr[i] = strings.ReplaceAll(wantErr[i], fmt.Sprintf("[%d]", j), "")
}
}
if usingKubeVersionInCluster23OrOlder && tt.wantKube23OrOlderErr != "" {
// Sometimes there are other difference in older Kubernetes messages, so also allow exact
// expectation strings for those cases in wantKube23OrOlderErr. When provided, use it on these Kube clusters.
wantErr = tt.wantKube23OrOlderErr
}
if usingKubeVersionInCluster24Through31Inclusive && tt.wantKube24Through31InclusiveErr != "" {
// Also allow overriding with an exact expected error for these Kube versions.
wantErr = tt.wantKube24Through31InclusiveErr
}
if usingKubeVersionInCluster32OrNewer && tt.wantKube32OrNewerErr != "" {
// Also allow overriding with an exact expected error for these Kube versions.
wantErr = tt.wantKube32OrNewerErr
}
require.EqualError(t, createErr, wantErr)
}
if minor <= 23 && len(tt.wantKube23OrOlderErrs) > 0 {
// Sometimes there are other difference in older Kubernetes messages, so also allow exact
// expectation strings for those cases in wantKube23OrOlderErr. When provided, use it on these Kube clusters.
wantErr = tt.wantKube23OrOlderErrs
}
if minor >= 24 && minor <= 31 && len(tt.wantKube24Through31InclusiveErrs) > 0 {
// Also allow overriding with an exact expected error for these Kube versions.
wantErr = tt.wantKube24Through31InclusiveErrs
}
if minor >= 32 && len(tt.wantKube32OrNewerErrs) > 0 {
// Also allow overriding with an exact expected error for these Kube versions.
wantErr = tt.wantKube32OrNewerErrs
}
if minor >= 25 && minor <= 28 && len(tt.wantCELErrorsForKube25Through28Inclusive) > 0 {
wantErr = append(wantErr, tt.wantCELErrorsForKube25Through28Inclusive...)
} else if minor >= 29 && len(tt.wantCELErrorsForKube29OrNewer) > 0 {
wantErr = append(wantErr, tt.wantCELErrorsForKube29OrNewer...)
}
// Did not want any error.
if len(wantErr) == 0 {
require.NoError(t, actualCreateErr)
return
}
wantErrStr := fmt.Sprintf("FederationDomain.config.supervisor.%s %q is invalid: ",
env.APIGroupSuffix, fd.Name)
if len(wantErr) == 1 {
wantErrStr += wantErr[0]
} else {
wantErrStr += "[" + strings.Join(wantErr, ", ") + "]"
}
require.EqualError(t, actualCreateErr, wantErrStr)
})
}
}

View File

@@ -31,7 +31,7 @@ func TestSupervisorSecrets_Parallel(t *testing.T) {
// Create our FederationDomain under test.
federationDomain := testlib.CreateTestFederationDomain(ctx, t,
supervisorconfigv1alpha1.FederationDomainSpec{
Issuer: fmt.Sprintf("http://test-issuer-%s.pinniped.dev", testlib.RandHex(t, 8)),
Issuer: fmt.Sprintf("https://test-issuer-%s.pinniped.dev", testlib.RandHex(t, 8)),
},
supervisorconfigv1alpha1.FederationDomainPhaseError, // in phase error until there is an IDP created, but this test does not care
)