supervisor-oidc: checkpoint: add status to provider CRD

Signed-off-by: Ryan Richard <richardry@vmware.com>
This commit is contained in:
Andrew Keesler 2020-10-08 13:27:45 -04:00 committed by Ryan Richard
parent 6b653fc663
commit da00fc708f
No known key found for this signature in database
GPG Key ID: 27CE0444346F9413
27 changed files with 669 additions and 53 deletions

View File

@ -5,6 +5,15 @@ package v1alpha1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +kubebuilder:validation:Enum=Success;Duplicate;Invalid
type OIDCProviderStatus string
const (
SuccessOIDCProviderStatus = OIDCProviderStatus("Success")
DuplicateOIDCProviderStatus = OIDCProviderStatus("Duplicate")
InvalidOIDCProviderStatus = OIDCProviderStatus("Invalid")
)
// OIDCProviderConfigSpec is a struct that describes an OIDC Provider.
type OIDCProviderConfigSpec struct {
// Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the
@ -19,6 +28,18 @@ type OIDCProviderConfigSpec struct {
Issuer string `json:"issuer"`
}
// OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.
type OIDCProviderConfigStatus struct {
// Status holds an enum that describes the state of this OIDC Provider. Note that this Status can
// represent success or failure.
// +optional
Status OIDCProviderStatus `json:"status,omitempty"`
// Message provides human-readable details about the Status.
// +optional
Message string `json:"message,omitempty"`
}
// OIDCProviderConfig describes the configuration of an OIDC provider.
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@ -28,7 +49,10 @@ type OIDCProviderConfig struct {
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec of the OIDC provider.
Spec OIDCProviderConfigSpec `json:"status"`
Spec OIDCProviderConfigSpec `json:"spec"`
// Status of the OIDC provider.
Status OIDCProviderConfigStatus `json:"status,omitempty"`
}
// List of OIDCProviderConfig objects.

View File

@ -12,6 +12,7 @@ import (
"os/signal"
"time"
"k8s.io/apimachinery/pkg/util/clock"
"k8s.io/client-go/pkg/version"
"k8s.io/client-go/rest"
restclient "k8s.io/client-go/rest"
@ -61,6 +62,7 @@ func waitForSignal() os.Signal {
func startControllers(
ctx context.Context,
issuerProvider *provider.Manager,
pinnipedClient pinnipedclientset.Interface,
pinnipedInformers pinnipedinformers.SharedInformerFactory,
) {
// Create controller manager.
@ -69,6 +71,8 @@ func startControllers(
WithController(
supervisorconfig.NewOIDCProviderConfigWatcherController(
issuerProvider,
clock.RealClock{},
pinnipedClient,
pinnipedInformers.Config().V1alpha1().OIDCProviderConfigs(),
controllerlib.WithInformer,
),
@ -111,7 +115,7 @@ func run(serverInstallationNamespace string) error {
)
oidProvidersManager := provider.NewManager(http.NotFoundHandler())
startControllers(ctx, oidProvidersManager, pinnipedInformers)
startControllers(ctx, oidProvidersManager, pinnipedClient, pinnipedInformers)
//nolint: gosec // Intentionally binding to all network interfaces.
l, err := net.Listen("tcp", ":80")

View File

@ -15,7 +15,7 @@ metadata:
rules:
- apiGroups: [config.pinniped.dev]
resources: [oidcproviderconfigs]
verbs: [get, list, watch]
verbs: [update, get, list, watch]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1

View File

@ -35,7 +35,7 @@ spec:
type: string
metadata:
type: object
status:
spec:
description: Spec of the OIDC provider.
properties:
issuer:
@ -52,8 +52,23 @@ spec:
required:
- issuer
type: object
status:
description: Status of the OIDC provider.
properties:
message:
description: Message provides human-readable details about the Status.
type: string
status:
description: Status holds an enum that describes the state of this
OIDCProvider. Note that this Status can represent success or failure.
enum:
- Success
- Duplicate
- Invalid
type: string
type: object
required:
- status
- spec
type: object
served: true
storage: true

View File

@ -110,7 +110,8 @@ OIDCProviderConfig describes the configuration of an OIDC provider.
| Field | Description
| *`metadata`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#objectmeta-v1-meta[$$ObjectMeta$$]__ | Refer to Kubernetes API documentation for fields of `metadata`.
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-config-v1alpha1-oidcproviderconfigspec[$$OIDCProviderConfigSpec$$]__ | Spec of the OIDC provider.
| *`spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-config-v1alpha1-oidcproviderconfigspec[$$OIDCProviderConfigSpec$$]__ | Spec of the OIDC provider.
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-config-v1alpha1-oidcproviderconfigstatus[$$OIDCProviderConfigStatus$$]__ | Status of the OIDC provider.
|===
@ -134,6 +135,24 @@ OIDCProviderConfigSpec is a struct that describes an OIDC Provider.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-config-v1alpha1-oidcproviderconfigstatus"]
==== OIDCProviderConfigStatus
OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-config-v1alpha1-oidcproviderconfig[$$OIDCProviderConfig$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`status`* __OIDCProviderStatus__ | Status holds an enum that describes the state of this OIDCProvider. Note that this Status can represent success or failure.
| *`message`* __string__ | Message provides human-readable details about the Status.
|===
[id="{anchor_prefix}-idp-pinniped-dev-v1alpha1"]
=== idp.pinniped.dev/v1alpha1

View File

@ -5,6 +5,15 @@ package v1alpha1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +kubebuilder:validation:Enum=Success;Duplicate;Invalid
type OIDCProviderStatus string
const (
SuccessOIDCProviderStatus = OIDCProviderStatus("Success")
DuplicateOIDCProviderStatus = OIDCProviderStatus("Duplicate")
InvalidOIDCProviderStatus = OIDCProviderStatus("Invalid")
)
// OIDCProviderConfigSpec is a struct that describes an OIDC Provider.
type OIDCProviderConfigSpec struct {
// Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the
@ -19,6 +28,18 @@ type OIDCProviderConfigSpec struct {
Issuer string `json:"issuer"`
}
// OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.
type OIDCProviderConfigStatus struct {
// Status holds an enum that describes the state of this OIDCProvider. Note that this Status can
// represent success or failure.
// +optional
Status OIDCProviderStatus `json:"status,omitempty"`
// Message provides human-readable details about the Status.
// +optional
Message string `json:"message,omitempty"`
}
// OIDCProviderConfig describes the configuration of an OIDC provider.
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@ -28,7 +49,10 @@ type OIDCProviderConfig struct {
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec of the OIDC provider.
Spec OIDCProviderConfigSpec `json:"status"`
Spec OIDCProviderConfigSpec `json:"spec"`
// Status of the OIDC provider.
Status OIDCProviderConfigStatus `json:"status,omitempty"`
}
// List of OIDCProviderConfig objects.

View File

@ -138,6 +138,7 @@ func (in *OIDCProviderConfig) DeepCopyInto(out *OIDCProviderConfig) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
return
}
@ -207,3 +208,19 @@ func (in *OIDCProviderConfigSpec) DeepCopy() *OIDCProviderConfigSpec {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OIDCProviderConfigStatus) DeepCopyInto(out *OIDCProviderConfigStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCProviderConfigStatus.
func (in *OIDCProviderConfigStatus) DeepCopy() *OIDCProviderConfigStatus {
if in == nil {
return nil
}
out := new(OIDCProviderConfigStatus)
in.DeepCopyInto(out)
return out
}

View File

@ -87,6 +87,18 @@ func (c *FakeOIDCProviderConfigs) Update(oIDCProviderConfig *v1alpha1.OIDCProvid
return obj.(*v1alpha1.OIDCProviderConfig), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeOIDCProviderConfigs) UpdateStatus(oIDCProviderConfig *v1alpha1.OIDCProviderConfig) (*v1alpha1.OIDCProviderConfig, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(oidcproviderconfigsResource, "status", c.ns, oIDCProviderConfig), &v1alpha1.OIDCProviderConfig{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.OIDCProviderConfig), err
}
// Delete takes name of the oIDCProviderConfig and deletes it. Returns an error if one occurs.
func (c *FakeOIDCProviderConfigs) Delete(name string, options *v1.DeleteOptions) error {
_, err := c.Fake.

View File

@ -26,6 +26,7 @@ type OIDCProviderConfigsGetter interface {
type OIDCProviderConfigInterface interface {
Create(*v1alpha1.OIDCProviderConfig) (*v1alpha1.OIDCProviderConfig, error)
Update(*v1alpha1.OIDCProviderConfig) (*v1alpha1.OIDCProviderConfig, error)
UpdateStatus(*v1alpha1.OIDCProviderConfig) (*v1alpha1.OIDCProviderConfig, error)
Delete(name string, options *v1.DeleteOptions) error
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
Get(name string, options v1.GetOptions) (*v1alpha1.OIDCProviderConfig, error)
@ -119,6 +120,22 @@ func (c *oIDCProviderConfigs) Update(oIDCProviderConfig *v1alpha1.OIDCProviderCo
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *oIDCProviderConfigs) UpdateStatus(oIDCProviderConfig *v1alpha1.OIDCProviderConfig) (result *v1alpha1.OIDCProviderConfig, err error) {
result = &v1alpha1.OIDCProviderConfig{}
err = c.client.Put().
Namespace(c.ns).
Resource("oidcproviderconfigs").
Name(oIDCProviderConfig.Name).
SubResource("status").
Body(oIDCProviderConfig).
Do().
Into(result)
return
}
// Delete takes name of the oIDCProviderConfig and deletes it. Returns an error if one occurs.
func (c *oIDCProviderConfigs) Delete(name string, options *v1.DeleteOptions) error {
return c.client.Delete().

View File

@ -25,6 +25,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"go.pinniped.dev/generated/1.17/apis/config/v1alpha1.OIDCProviderConfig": schema_117_apis_config_v1alpha1_OIDCProviderConfig(ref),
"go.pinniped.dev/generated/1.17/apis/config/v1alpha1.OIDCProviderConfigList": schema_117_apis_config_v1alpha1_OIDCProviderConfigList(ref),
"go.pinniped.dev/generated/1.17/apis/config/v1alpha1.OIDCProviderConfigSpec": schema_117_apis_config_v1alpha1_OIDCProviderConfigSpec(ref),
"go.pinniped.dev/generated/1.17/apis/config/v1alpha1.OIDCProviderConfigStatus": schema_117_apis_config_v1alpha1_OIDCProviderConfigStatus(ref),
"go.pinniped.dev/generated/1.17/apis/idp/v1alpha1.Condition": schema_117_apis_idp_v1alpha1_Condition(ref),
"go.pinniped.dev/generated/1.17/apis/idp/v1alpha1.TLSSpec": schema_117_apis_idp_v1alpha1_TLSSpec(ref),
"go.pinniped.dev/generated/1.17/apis/idp/v1alpha1.WebhookIdentityProvider": schema_117_apis_idp_v1alpha1_WebhookIdentityProvider(ref),
@ -315,18 +316,24 @@ func schema_117_apis_config_v1alpha1_OIDCProviderConfig(ref common.ReferenceCall
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
},
},
"status": {
"spec": {
SchemaProps: spec.SchemaProps{
Description: "Spec of the OIDC provider.",
Ref: ref("go.pinniped.dev/generated/1.17/apis/config/v1alpha1.OIDCProviderConfigSpec"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Status of the OIDC provider.",
Ref: ref("go.pinniped.dev/generated/1.17/apis/config/v1alpha1.OIDCProviderConfigStatus"),
},
},
},
Required: []string{"status"},
Required: []string{"spec"},
},
},
Dependencies: []string{
"go.pinniped.dev/generated/1.17/apis/config/v1alpha1.OIDCProviderConfigSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
"go.pinniped.dev/generated/1.17/apis/config/v1alpha1.OIDCProviderConfigSpec", "go.pinniped.dev/generated/1.17/apis/config/v1alpha1.OIDCProviderConfigStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}
@ -397,6 +404,33 @@ func schema_117_apis_config_v1alpha1_OIDCProviderConfigSpec(ref common.Reference
}
}
func schema_117_apis_config_v1alpha1_OIDCProviderConfigStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"status": {
SchemaProps: spec.SchemaProps{
Description: "Status holds an enum that describes the state of this OIDCProvider. Note that this Status can represent success or failure.",
Type: []string{"string"},
Format: "",
},
},
"message": {
SchemaProps: spec.SchemaProps{
Description: "Message provides human-readable details about the Status.",
Type: []string{"string"},
Format: "",
},
},
},
},
},
}
}
func schema_117_apis_idp_v1alpha1_Condition(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{

View File

@ -35,7 +35,7 @@ spec:
type: string
metadata:
type: object
status:
spec:
description: Spec of the OIDC provider.
properties:
issuer:
@ -52,8 +52,23 @@ spec:
required:
- issuer
type: object
status:
description: Status of the OIDC provider.
properties:
message:
description: Message provides human-readable details about the Status.
type: string
status:
description: Status holds an enum that describes the state of this
OIDCProvider. Note that this Status can represent success or failure.
enum:
- Success
- Duplicate
- Invalid
type: string
type: object
required:
- status
- spec
type: object
served: true
storage: true

View File

@ -110,7 +110,8 @@ OIDCProviderConfig describes the configuration of an OIDC provider.
| Field | Description
| *`metadata`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta[$$ObjectMeta$$]__ | Refer to Kubernetes API documentation for fields of `metadata`.
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-config-v1alpha1-oidcproviderconfigspec[$$OIDCProviderConfigSpec$$]__ | Spec of the OIDC provider.
| *`spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-config-v1alpha1-oidcproviderconfigspec[$$OIDCProviderConfigSpec$$]__ | Spec of the OIDC provider.
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-config-v1alpha1-oidcproviderconfigstatus[$$OIDCProviderConfigStatus$$]__ | Status of the OIDC provider.
|===
@ -134,6 +135,24 @@ OIDCProviderConfigSpec is a struct that describes an OIDC Provider.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-config-v1alpha1-oidcproviderconfigstatus"]
==== OIDCProviderConfigStatus
OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-config-v1alpha1-oidcproviderconfig[$$OIDCProviderConfig$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`status`* __OIDCProviderStatus__ | Status holds an enum that describes the state of this OIDCProvider. Note that this Status can represent success or failure.
| *`message`* __string__ | Message provides human-readable details about the Status.
|===
[id="{anchor_prefix}-idp-pinniped-dev-v1alpha1"]
=== idp.pinniped.dev/v1alpha1

View File

@ -5,6 +5,15 @@ package v1alpha1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +kubebuilder:validation:Enum=Success;Duplicate;Invalid
type OIDCProviderStatus string
const (
SuccessOIDCProviderStatus = OIDCProviderStatus("Success")
DuplicateOIDCProviderStatus = OIDCProviderStatus("Duplicate")
InvalidOIDCProviderStatus = OIDCProviderStatus("Invalid")
)
// OIDCProviderConfigSpec is a struct that describes an OIDC Provider.
type OIDCProviderConfigSpec struct {
// Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the
@ -19,6 +28,18 @@ type OIDCProviderConfigSpec struct {
Issuer string `json:"issuer"`
}
// OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.
type OIDCProviderConfigStatus struct {
// Status holds an enum that describes the state of this OIDCProvider. Note that this Status can
// represent success or failure.
// +optional
Status OIDCProviderStatus `json:"status,omitempty"`
// Message provides human-readable details about the Status.
// +optional
Message string `json:"message,omitempty"`
}
// OIDCProviderConfig describes the configuration of an OIDC provider.
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@ -28,7 +49,10 @@ type OIDCProviderConfig struct {
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec of the OIDC provider.
Spec OIDCProviderConfigSpec `json:"status"`
Spec OIDCProviderConfigSpec `json:"spec"`
// Status of the OIDC provider.
Status OIDCProviderConfigStatus `json:"status,omitempty"`
}
// List of OIDCProviderConfig objects.

View File

@ -138,6 +138,7 @@ func (in *OIDCProviderConfig) DeepCopyInto(out *OIDCProviderConfig) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
return
}
@ -207,3 +208,19 @@ func (in *OIDCProviderConfigSpec) DeepCopy() *OIDCProviderConfigSpec {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OIDCProviderConfigStatus) DeepCopyInto(out *OIDCProviderConfigStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCProviderConfigStatus.
func (in *OIDCProviderConfigStatus) DeepCopy() *OIDCProviderConfigStatus {
if in == nil {
return nil
}
out := new(OIDCProviderConfigStatus)
in.DeepCopyInto(out)
return out
}

View File

@ -89,6 +89,18 @@ func (c *FakeOIDCProviderConfigs) Update(ctx context.Context, oIDCProviderConfig
return obj.(*v1alpha1.OIDCProviderConfig), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeOIDCProviderConfigs) UpdateStatus(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.UpdateOptions) (*v1alpha1.OIDCProviderConfig, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(oidcproviderconfigsResource, "status", c.ns, oIDCProviderConfig), &v1alpha1.OIDCProviderConfig{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.OIDCProviderConfig), err
}
// Delete takes name of the oIDCProviderConfig and deletes it. Returns an error if one occurs.
func (c *FakeOIDCProviderConfigs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.

View File

@ -27,6 +27,7 @@ type OIDCProviderConfigsGetter interface {
type OIDCProviderConfigInterface interface {
Create(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.CreateOptions) (*v1alpha1.OIDCProviderConfig, error)
Update(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.UpdateOptions) (*v1alpha1.OIDCProviderConfig, error)
UpdateStatus(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.UpdateOptions) (*v1alpha1.OIDCProviderConfig, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.OIDCProviderConfig, error)
@ -122,6 +123,22 @@ func (c *oIDCProviderConfigs) Update(ctx context.Context, oIDCProviderConfig *v1
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *oIDCProviderConfigs) UpdateStatus(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.UpdateOptions) (result *v1alpha1.OIDCProviderConfig, err error) {
result = &v1alpha1.OIDCProviderConfig{}
err = c.client.Put().
Namespace(c.ns).
Resource("oidcproviderconfigs").
Name(oIDCProviderConfig.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(oIDCProviderConfig).
Do(ctx).
Into(result)
return
}
// Delete takes name of the oIDCProviderConfig and deletes it. Returns an error if one occurs.
func (c *oIDCProviderConfigs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().

View File

@ -25,6 +25,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"go.pinniped.dev/generated/1.18/apis/config/v1alpha1.OIDCProviderConfig": schema_118_apis_config_v1alpha1_OIDCProviderConfig(ref),
"go.pinniped.dev/generated/1.18/apis/config/v1alpha1.OIDCProviderConfigList": schema_118_apis_config_v1alpha1_OIDCProviderConfigList(ref),
"go.pinniped.dev/generated/1.18/apis/config/v1alpha1.OIDCProviderConfigSpec": schema_118_apis_config_v1alpha1_OIDCProviderConfigSpec(ref),
"go.pinniped.dev/generated/1.18/apis/config/v1alpha1.OIDCProviderConfigStatus": schema_118_apis_config_v1alpha1_OIDCProviderConfigStatus(ref),
"go.pinniped.dev/generated/1.18/apis/idp/v1alpha1.Condition": schema_118_apis_idp_v1alpha1_Condition(ref),
"go.pinniped.dev/generated/1.18/apis/idp/v1alpha1.TLSSpec": schema_118_apis_idp_v1alpha1_TLSSpec(ref),
"go.pinniped.dev/generated/1.18/apis/idp/v1alpha1.WebhookIdentityProvider": schema_118_apis_idp_v1alpha1_WebhookIdentityProvider(ref),
@ -315,18 +316,24 @@ func schema_118_apis_config_v1alpha1_OIDCProviderConfig(ref common.ReferenceCall
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
},
},
"status": {
"spec": {
SchemaProps: spec.SchemaProps{
Description: "Spec of the OIDC provider.",
Ref: ref("go.pinniped.dev/generated/1.18/apis/config/v1alpha1.OIDCProviderConfigSpec"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Status of the OIDC provider.",
Ref: ref("go.pinniped.dev/generated/1.18/apis/config/v1alpha1.OIDCProviderConfigStatus"),
},
},
},
Required: []string{"status"},
Required: []string{"spec"},
},
},
Dependencies: []string{
"go.pinniped.dev/generated/1.18/apis/config/v1alpha1.OIDCProviderConfigSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
"go.pinniped.dev/generated/1.18/apis/config/v1alpha1.OIDCProviderConfigSpec", "go.pinniped.dev/generated/1.18/apis/config/v1alpha1.OIDCProviderConfigStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}
@ -397,6 +404,33 @@ func schema_118_apis_config_v1alpha1_OIDCProviderConfigSpec(ref common.Reference
}
}
func schema_118_apis_config_v1alpha1_OIDCProviderConfigStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"status": {
SchemaProps: spec.SchemaProps{
Description: "Status holds an enum that describes the state of this OIDCProvider. Note that this Status can represent success or failure.",
Type: []string{"string"},
Format: "",
},
},
"message": {
SchemaProps: spec.SchemaProps{
Description: "Message provides human-readable details about the Status.",
Type: []string{"string"},
Format: "",
},
},
},
},
},
}
}
func schema_118_apis_idp_v1alpha1_Condition(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{

View File

@ -35,7 +35,7 @@ spec:
type: string
metadata:
type: object
status:
spec:
description: Spec of the OIDC provider.
properties:
issuer:
@ -52,8 +52,23 @@ spec:
required:
- issuer
type: object
status:
description: Status of the OIDC provider.
properties:
message:
description: Message provides human-readable details about the Status.
type: string
status:
description: Status holds an enum that describes the state of this
OIDCProvider. Note that this Status can represent success or failure.
enum:
- Success
- Duplicate
- Invalid
type: string
type: object
required:
- status
- spec
type: object
served: true
storage: true

View File

@ -110,7 +110,8 @@ OIDCProviderConfig describes the configuration of an OIDC provider.
| Field | Description
| *`metadata`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#objectmeta-v1-meta[$$ObjectMeta$$]__ | Refer to Kubernetes API documentation for fields of `metadata`.
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-config-v1alpha1-oidcproviderconfigspec[$$OIDCProviderConfigSpec$$]__ | Spec of the OIDC provider.
| *`spec`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-config-v1alpha1-oidcproviderconfigspec[$$OIDCProviderConfigSpec$$]__ | Spec of the OIDC provider.
| *`status`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-config-v1alpha1-oidcproviderconfigstatus[$$OIDCProviderConfigStatus$$]__ | Status of the OIDC provider.
|===
@ -134,6 +135,24 @@ OIDCProviderConfigSpec is a struct that describes an OIDC Provider.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-config-v1alpha1-oidcproviderconfigstatus"]
==== OIDCProviderConfigStatus
OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-config-v1alpha1-oidcproviderconfig[$$OIDCProviderConfig$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`status`* __OIDCProviderStatus__ | Status holds an enum that describes the state of this OIDCProvider. Note that this Status can represent success or failure.
| *`message`* __string__ | Message provides human-readable details about the Status.
|===
[id="{anchor_prefix}-idp-pinniped-dev-v1alpha1"]
=== idp.pinniped.dev/v1alpha1

View File

@ -5,6 +5,15 @@ package v1alpha1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +kubebuilder:validation:Enum=Success;Duplicate;Invalid
type OIDCProviderStatus string
const (
SuccessOIDCProviderStatus = OIDCProviderStatus("Success")
DuplicateOIDCProviderStatus = OIDCProviderStatus("Duplicate")
InvalidOIDCProviderStatus = OIDCProviderStatus("Invalid")
)
// OIDCProviderConfigSpec is a struct that describes an OIDC Provider.
type OIDCProviderConfigSpec struct {
// Issuer is the OIDC Provider's issuer, per the OIDC Discovery Metadata document, as well as the
@ -19,6 +28,18 @@ type OIDCProviderConfigSpec struct {
Issuer string `json:"issuer"`
}
// OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.
type OIDCProviderConfigStatus struct {
// Status holds an enum that describes the state of this OIDCProvider. Note that this Status can
// represent success or failure.
// +optional
Status OIDCProviderStatus `json:"status,omitempty"`
// Message provides human-readable details about the Status.
// +optional
Message string `json:"message,omitempty"`
}
// OIDCProviderConfig describes the configuration of an OIDC provider.
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@ -28,7 +49,10 @@ type OIDCProviderConfig struct {
metav1.ObjectMeta `json:"metadata,omitempty"`
// Spec of the OIDC provider.
Spec OIDCProviderConfigSpec `json:"status"`
Spec OIDCProviderConfigSpec `json:"spec"`
// Status of the OIDC provider.
Status OIDCProviderConfigStatus `json:"status,omitempty"`
}
// List of OIDCProviderConfig objects.

View File

@ -138,6 +138,7 @@ func (in *OIDCProviderConfig) DeepCopyInto(out *OIDCProviderConfig) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
return
}
@ -207,3 +208,19 @@ func (in *OIDCProviderConfigSpec) DeepCopy() *OIDCProviderConfigSpec {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OIDCProviderConfigStatus) DeepCopyInto(out *OIDCProviderConfigStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCProviderConfigStatus.
func (in *OIDCProviderConfigStatus) DeepCopy() *OIDCProviderConfigStatus {
if in == nil {
return nil
}
out := new(OIDCProviderConfigStatus)
in.DeepCopyInto(out)
return out
}

View File

@ -89,6 +89,18 @@ func (c *FakeOIDCProviderConfigs) Update(ctx context.Context, oIDCProviderConfig
return obj.(*v1alpha1.OIDCProviderConfig), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeOIDCProviderConfigs) UpdateStatus(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.UpdateOptions) (*v1alpha1.OIDCProviderConfig, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(oidcproviderconfigsResource, "status", c.ns, oIDCProviderConfig), &v1alpha1.OIDCProviderConfig{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.OIDCProviderConfig), err
}
// Delete takes name of the oIDCProviderConfig and deletes it. Returns an error if one occurs.
func (c *FakeOIDCProviderConfigs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.

View File

@ -27,6 +27,7 @@ type OIDCProviderConfigsGetter interface {
type OIDCProviderConfigInterface interface {
Create(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.CreateOptions) (*v1alpha1.OIDCProviderConfig, error)
Update(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.UpdateOptions) (*v1alpha1.OIDCProviderConfig, error)
UpdateStatus(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.UpdateOptions) (*v1alpha1.OIDCProviderConfig, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.OIDCProviderConfig, error)
@ -122,6 +123,22 @@ func (c *oIDCProviderConfigs) Update(ctx context.Context, oIDCProviderConfig *v1
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *oIDCProviderConfigs) UpdateStatus(ctx context.Context, oIDCProviderConfig *v1alpha1.OIDCProviderConfig, opts v1.UpdateOptions) (result *v1alpha1.OIDCProviderConfig, err error) {
result = &v1alpha1.OIDCProviderConfig{}
err = c.client.Put().
Namespace(c.ns).
Resource("oidcproviderconfigs").
Name(oIDCProviderConfig.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(oIDCProviderConfig).
Do(ctx).
Into(result)
return
}
// Delete takes name of the oIDCProviderConfig and deletes it. Returns an error if one occurs.
func (c *oIDCProviderConfigs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().

View File

@ -25,6 +25,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"go.pinniped.dev/generated/1.19/apis/config/v1alpha1.OIDCProviderConfig": schema_119_apis_config_v1alpha1_OIDCProviderConfig(ref),
"go.pinniped.dev/generated/1.19/apis/config/v1alpha1.OIDCProviderConfigList": schema_119_apis_config_v1alpha1_OIDCProviderConfigList(ref),
"go.pinniped.dev/generated/1.19/apis/config/v1alpha1.OIDCProviderConfigSpec": schema_119_apis_config_v1alpha1_OIDCProviderConfigSpec(ref),
"go.pinniped.dev/generated/1.19/apis/config/v1alpha1.OIDCProviderConfigStatus": schema_119_apis_config_v1alpha1_OIDCProviderConfigStatus(ref),
"go.pinniped.dev/generated/1.19/apis/idp/v1alpha1.Condition": schema_119_apis_idp_v1alpha1_Condition(ref),
"go.pinniped.dev/generated/1.19/apis/idp/v1alpha1.TLSSpec": schema_119_apis_idp_v1alpha1_TLSSpec(ref),
"go.pinniped.dev/generated/1.19/apis/idp/v1alpha1.WebhookIdentityProvider": schema_119_apis_idp_v1alpha1_WebhookIdentityProvider(ref),
@ -316,18 +317,24 @@ func schema_119_apis_config_v1alpha1_OIDCProviderConfig(ref common.ReferenceCall
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
},
},
"status": {
"spec": {
SchemaProps: spec.SchemaProps{
Description: "Spec of the OIDC provider.",
Ref: ref("go.pinniped.dev/generated/1.19/apis/config/v1alpha1.OIDCProviderConfigSpec"),
},
},
"status": {
SchemaProps: spec.SchemaProps{
Description: "Status of the OIDC provider.",
Ref: ref("go.pinniped.dev/generated/1.19/apis/config/v1alpha1.OIDCProviderConfigStatus"),
},
},
},
Required: []string{"status"},
Required: []string{"spec"},
},
},
Dependencies: []string{
"go.pinniped.dev/generated/1.19/apis/config/v1alpha1.OIDCProviderConfigSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
"go.pinniped.dev/generated/1.19/apis/config/v1alpha1.OIDCProviderConfigSpec", "go.pinniped.dev/generated/1.19/apis/config/v1alpha1.OIDCProviderConfigStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}
@ -398,6 +405,33 @@ func schema_119_apis_config_v1alpha1_OIDCProviderConfigSpec(ref common.Reference
}
}
func schema_119_apis_config_v1alpha1_OIDCProviderConfigStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "OIDCProviderConfigStatus is a struct that describes the actual state of an OIDC Provider.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"status": {
SchemaProps: spec.SchemaProps{
Description: "Status holds an enum that describes the state of this OIDCProvider. Note that this Status can represent success or failure.",
Type: []string{"string"},
Format: "",
},
},
"message": {
SchemaProps: spec.SchemaProps{
Description: "Message provides human-readable details about the Status.",
Type: []string{"string"},
Format: "",
},
},
},
},
},
}
}
func schema_119_apis_idp_v1alpha1_Condition(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{

View File

@ -35,7 +35,7 @@ spec:
type: string
metadata:
type: object
status:
spec:
description: Spec of the OIDC provider.
properties:
issuer:
@ -52,8 +52,23 @@ spec:
required:
- issuer
type: object
status:
description: Status of the OIDC provider.
properties:
message:
description: Message provides human-readable details about the Status.
type: string
status:
description: Status holds an enum that describes the state of this
OIDCProvider. Note that this Status can represent success or failure.
enum:
- Success
- Duplicate
- Invalid
type: string
type: object
required:
- status
- spec
type: object
served: true
storage: true

View File

@ -4,11 +4,19 @@
package supervisorconfig
import (
"context"
"fmt"
"net/url"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/clock"
"k8s.io/client-go/util/retry"
"k8s.io/klog/v2"
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/config/v1alpha1"
pinnipedclientset "go.pinniped.dev/generated/1.19/client/clientset/versioned"
configinformers "go.pinniped.dev/generated/1.19/client/informers/externalversions/config/v1alpha1"
pinnipedcontroller "go.pinniped.dev/internal/controller"
"go.pinniped.dev/internal/controllerlib"
@ -24,13 +32,17 @@ type ProvidersSetter interface {
type oidcProviderConfigWatcherController struct {
providerSetter ProvidersSetter
clock clock.Clock
client pinnipedclientset.Interface
opcInformer configinformers.OIDCProviderConfigInformer
}
// NewOIDCProviderConfigWatcherController creates a controllerlib.Controller that watches
// OIDCProviderConfig objects and notifies a callback object of the collection of provider configs.
func NewOIDCProviderConfigWatcherController(
issuerObserver ProvidersSetter,
providerSetter ProvidersSetter,
clock clock.Clock,
client pinnipedclientset.Interface,
opcInformer configinformers.OIDCProviderConfigInformer,
withInformer pinnipedcontroller.WithInformerOptionFunc,
) controllerlib.Controller {
@ -38,7 +50,9 @@ func NewOIDCProviderConfigWatcherController(
controllerlib.Config{
Name: "OIDCProviderConfigWatcherController",
Syncer: &oidcProviderConfigWatcherController{
providerSetter: issuerObserver,
providerSetter: providerSetter,
clock: clock,
client: client,
opcInformer: opcInformer,
},
},
@ -57,35 +71,133 @@ func (c *oidcProviderConfigWatcherController) Sync(ctx controllerlib.Context) er
return err
}
issuerCounts := make(map[string]int)
for _, opc := range all {
issuerCounts[opc.Spec.Issuer] = issuerCounts[opc.Spec.Issuer] + 1
}
errs := newMultiError()
oidcProviders := make([]*provider.OIDCProvider, 0)
for _, opc := range all {
issuerURL, err := url.Parse(opc.Spec.Issuer)
if err != nil {
klog.InfoS(
"OIDCProviderConfigWatcherController Sync failed to parse issuer",
"err",
err,
)
if issuerCount := issuerCounts[opc.Spec.Issuer]; issuerCount > 1 {
if err := c.updateStatus(
ctx.Context,
opc.Namespace,
opc.Name,
configv1alpha1.DuplicateOIDCProviderStatus,
"Duplicate issuer",
); err != nil {
errs.add(fmt.Errorf("could not update status: %w", err))
}
continue
}
issuerURL, err := url.Parse(opc.Spec.Issuer)
if err != nil {
if err := c.updateStatus(
ctx.Context,
opc.Namespace,
opc.Name,
configv1alpha1.InvalidOIDCProviderStatus,
"Invalid issuer URL: "+err.Error(),
); err != nil {
errs.add(fmt.Errorf("could not update status: %w", err))
}
continue
}
oidcProvider := &provider.OIDCProvider{Issuer: issuerURL}
err = oidcProvider.Validate()
if err != nil {
klog.InfoS(
"OIDCProviderConfigWatcherController Sync could failed to validate OIDCProviderConfig",
"err",
err,
)
if err := c.updateStatus(
ctx.Context,
opc.Namespace,
opc.Name,
configv1alpha1.InvalidOIDCProviderStatus,
"Invalid issuer: "+err.Error(),
); err != nil {
errs.add(fmt.Errorf("could not update status: %w", err))
}
continue
}
oidcProviders = append(oidcProviders, oidcProvider)
klog.InfoS(
"OIDCProviderConfigWatcherController Sync accepted OIDCProviderConfig",
"issuer",
issuerURL,
)
if err := c.updateStatus(
ctx.Context,
opc.Namespace,
opc.Name,
configv1alpha1.SuccessOIDCProviderStatus,
"Provider successfully created",
); err != nil {
// errs.add(fmt.Errorf("could not update status: %w", err))
return fmt.Errorf("could not update status: %w", err)
}
}
c.providerSetter.SetProviders(oidcProviders...)
return errs.errOrNil()
}
func (c *oidcProviderConfigWatcherController) updateStatus(
ctx context.Context,
namespace, name string,
status configv1alpha1.OIDCProviderStatus,
message string,
) error {
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
opc, err := c.client.ConfigV1alpha1().OIDCProviderConfigs(namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("get failed: %w", err)
}
if opc.Status.Status == status && opc.Status.Message == message {
return nil
}
klog.InfoS(
"attempting status update",
"openidproviderconfig",
klog.KRef(namespace, name),
"status",
status,
"message",
message,
)
opc.Status.Status = status
opc.Status.Message = message
_, err = c.client.ConfigV1alpha1().OIDCProviderConfigs(namespace).Update(ctx, opc, metav1.UpdateOptions{})
return err
})
}
type multiError []error
func newMultiError() multiError {
return make([]error, 0)
}
func (m *multiError) add(err error) {
*m = append(*m, err)
}
func (m multiError) len() int {
return len(m)
}
func (m multiError) Error() string {
sb := strings.Builder{}
fmt.Fprintf(&sb, "%d errors:", m.len())
for _, err := range m {
fmt.Fprintf(&sb, "\n- %s", err.Error())
}
return sb.String()
}
func (m multiError) errOrNil() error {
if m.len() > 0 {
return m
}
return nil
}

View File

@ -59,21 +59,43 @@ func TestSupervisorOIDCDiscovery(t *testing.T) {
issuer2 := fmt.Sprintf("http://%s/nested/issuer2", env.SupervisorAddress)
issuer3 := fmt.Sprintf("http://%s/issuer3", env.SupervisorAddress)
issuer4 := fmt.Sprintf("http://%s/issuer4", env.SupervisorAddress)
issuer5 := fmt.Sprintf("http://%s/issuer5", env.SupervisorAddress)
badIssuer := fmt.Sprintf("http://%s/badIssuer?cannot-use=queries", env.SupervisorAddress)
// When OIDCProviderConfig are created in sequence they each cause a discovery endpoint to appear only for as long as the OIDCProviderConfig exists.
createdOIDCProviderConfig1 := requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t, client, ns, issuer1, "from-integration-test1")
requireDeletingOIDCProviderConfigCausesWellKnownEndpointToDisappear(t, createdOIDCProviderConfig1, client, ns, issuer1)
createdOIDCProviderConfig2 := requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t, client, ns, issuer2, "from-integration-test2")
requireDeletingOIDCProviderConfigCausesWellKnownEndpointToDisappear(t, createdOIDCProviderConfig2, client, ns, issuer2)
config1 := requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t, client, ns, issuer1, "from-integration-test1")
requireDeletingOIDCProviderConfigCausesWellKnownEndpointToDisappear(t, config1, client, ns, issuer1)
config2 := requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t, client, ns, issuer2, "from-integration-test2")
requireDeletingOIDCProviderConfigCausesWellKnownEndpointToDisappear(t, config2, client, ns, issuer2)
// When multiple OIDCProviderConfigs exist at the same time they each serve a unique discovery endpoint.
createdOIDCProviderConfig3 := requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t, client, ns, issuer3, "from-integration-test3")
createdOIDCProviderConfig4 := requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t, client, ns, issuer4, "from-integration-test4")
config3 := requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t, client, ns, issuer3, "from-integration-test3")
config4 := requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t, client, ns, issuer4, "from-integration-test4")
requireWellKnownEndpointIsWorking(t, issuer3) // discovery for issuer3 is still working after issuer4 started working
// When they are deleted they stop serving discovery endpoints.
requireDeletingOIDCProviderConfigCausesWellKnownEndpointToDisappear(t, createdOIDCProviderConfig3, client, ns, issuer2)
requireDeletingOIDCProviderConfigCausesWellKnownEndpointToDisappear(t, createdOIDCProviderConfig4, client, ns, issuer2)
requireDeletingOIDCProviderConfigCausesWellKnownEndpointToDisappear(t, config3, client, ns, issuer3)
requireDeletingOIDCProviderConfigCausesWellKnownEndpointToDisappear(t, config4, client, ns, issuer4)
// When the same issuer is added twice, both issuers are marked as duplicates, and neither provider is serving.
config5Duplicate1 := requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t, client, ns, issuer5, "from-integration-test5")
config5Duplicate2 := createOIDCProviderConfig(t, "from-integration-test5-duplicate", client, ns, issuer5)
requireStatus(t, client, ns, config5Duplicate1.Name, v1alpha1.DuplicateOIDCProviderStatus)
requireStatus(t, client, ns, config5Duplicate2.Name, v1alpha1.DuplicateOIDCProviderStatus)
requireDiscoveryEndpointIsNotFound(t, issuer5)
// If we delete the first duplicate issuer, the second duplicate issuer starts serving.
requireDelete(t, client, ns, config5Duplicate1.Name)
requireWellKnownEndpointIsWorking(t, issuer5)
requireStatus(t, client, ns, config5Duplicate2.Name, v1alpha1.SuccessOIDCProviderStatus)
// When we finally delete all issuers, the endpoint should be down.
requireDeletingOIDCProviderConfigCausesWellKnownEndpointToDisappear(t, config5Duplicate2, client, ns, issuer5)
// When we create a provider with an invalid issuer, the status is set to invalid.
badConfig := createOIDCProviderConfig(t, "from-integration-test6", client, ns, badIssuer)
requireStatus(t, client, ns, badConfig.Name, v1alpha1.InvalidOIDCProviderStatus)
requireDiscoveryEndpointIsNotFound(t, badIssuer)
}
func requireDiscoveryEndpointIsNotFound(t *testing.T, issuerName string) {
@ -104,6 +126,7 @@ func requireCreatingOIDCProviderConfigCausesWellKnownEndpointToAppear(t *testing
t.Helper()
newOIDCProviderConfig := createOIDCProviderConfig(t, oidcProviderConfigName, client, ns, issuerName)
requireWellKnownEndpointIsWorking(t, issuerName)
requireStatus(t, client, ns, oidcProviderConfigName, v1alpha1.SuccessOIDCProviderStatus)
return newOIDCProviderConfig
}
@ -205,3 +228,27 @@ func createOIDCProviderConfig(t *testing.T, oidcProviderConfigName string, clien
return createdOIDCProviderConfig
}
func requireDelete(t *testing.T, client pinnipedclientset.Interface, ns, name string) {
t.Helper()
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
err := client.ConfigV1alpha1().OIDCProviderConfigs(ns).Delete(ctx, name, metav1.DeleteOptions{})
require.NoError(t, err)
}
func requireStatus(t *testing.T, client pinnipedclientset.Interface, ns, name string, status v1alpha1.OIDCProviderStatus) {
t.Helper()
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var opc *v1alpha1.OIDCProviderConfig
var err error
assert.Eventually(t, func() bool {
opc, err = client.ConfigV1alpha1().OIDCProviderConfigs(ns).Get(ctx, name, metav1.GetOptions{})
return err == nil && opc.Status.Status == status
}, 10*time.Second, 200*time.Millisecond)
require.NoError(t, err)
require.Equalf(t, status, opc.Status.Status, "unexpected status (message = '%s')", opc.Status.Message)
}