Update the schema of CredentialIssuerConfig

- Move the current info from spec to status
- Add schema for new stuff that we will use in a future commit to status
- Regenerate the generated code
This commit is contained in:
Ryan Richard 2020-08-21 17:00:42 -07:00
parent ace01c86de
commit 6d43d7ba19
11 changed files with 333 additions and 124 deletions

View File

@ -7,7 +7,14 @@
#! metadata:
#! name: credential-issuer-config
#! namespace: integration
#! spec:
#! status:
#! strategies:
#! - type: KubeClusterSigningCertificate
#! lastUpdateTime: 2020-08-21T20:08:18Z
#! status: Error
#! reason: CouldNotFetchKey
#! message: "There was an error getting the signing cert"
#! kubeConfigInfo:
#! server: https://foo
#! certificateAuthorityData: bar
@ -20,18 +27,44 @@ spec:
group: crd.pinniped.dev
versions:
#! Any changes to these schemas should also be reflected in the types.go file(s)
#! in https://github.com/suzerain-io/pinniped-api/tree/main/pkg/apis/pinniped
- name: v1alpha1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
required: [spec]
properties:
spec:
status:
type: object
required: [server, certificateAuthorityData]
properties:
strategies:
type: array
items:
type: object
required: [ type, status,reason, message, lastUpdateTime ]
properties:
type: #! this property is called "type"
type: string
minLength: 1
pattern: '^KubeClusterSigningCertificate$'
status:
type: string
minLength: 1
pattern: '^Success$|^Error$'
reason:
type: string
minLength: 1
pattern: '^CouldNotFetchKey$|^FetchedKey$'
message:
type: string
minLength: 1
lastUpdateTime:
type: string
format: date-time
minLength: 1
kubeConfigInfo:
type: object
required: [ server, certificateAuthorityData ]
properties:
server:
type: string

View File

@ -115,10 +115,13 @@ func (c *publisherController) Sync(ctx controller.Context) error {
Name: configName,
Namespace: c.namespace,
},
Spec: crdpinnipedv1alpha1.CredentialIssuerConfigSpec{
Status: crdpinnipedv1alpha1.CredentialIssuerConfigStatus{
Strategies: []crdpinnipedv1alpha1.CredentialIssuerConfigStrategy{},
KubeConfigInfo: &crdpinnipedv1alpha1.CredentialIssuerConfigKubeConfigInfo{
Server: server,
CertificateAuthorityData: certificateAuthorityData,
},
},
}
if err := c.createOrUpdateCredentialIssuerConfig(ctx.Context, &credentialIssuerConfig); err != nil {
return err
@ -129,34 +132,34 @@ func (c *publisherController) Sync(ctx controller.Context) error {
func (c *publisherController) createOrUpdateCredentialIssuerConfig(
ctx context.Context,
credentialIssuerConfig *crdpinnipedv1alpha1.CredentialIssuerConfig,
newCredentialIssuerConfig *crdpinnipedv1alpha1.CredentialIssuerConfig,
) error {
existingCredentialIssuerConfig, err := c.credentialIssuerConfigInformer.
Lister().
CredentialIssuerConfigs(c.namespace).
Get(credentialIssuerConfig.Name)
Get(newCredentialIssuerConfig.Name)
notFound := k8serrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("could not get credentialissuerconfig: %w", err)
}
credentialIssuerConfigs := c.pinnipedClient.
CrdV1alpha1().
CredentialIssuerConfigs(c.namespace)
credentialIssuerConfigsClient := c.pinnipedClient.CrdV1alpha1().CredentialIssuerConfigs(c.namespace)
if notFound {
if _, err := credentialIssuerConfigs.Create(
if _, err := credentialIssuerConfigsClient.Create(
ctx,
credentialIssuerConfig,
newCredentialIssuerConfig,
metav1.CreateOptions{},
); err != nil {
return fmt.Errorf("could not create credentialissuerconfig: %w", err)
}
} else if !equal(existingCredentialIssuerConfig, credentialIssuerConfig) {
} else if !equal(existingCredentialIssuerConfig, newCredentialIssuerConfig) {
// Update just the fields we care about.
existingCredentialIssuerConfig.Spec.Server = credentialIssuerConfig.Spec.Server
existingCredentialIssuerConfig.Spec.CertificateAuthorityData = credentialIssuerConfig.Spec.CertificateAuthorityData
newServer := newCredentialIssuerConfig.Status.KubeConfigInfo.Server
newCA := newCredentialIssuerConfig.Status.KubeConfigInfo.CertificateAuthorityData
existingCredentialIssuerConfig.Status.KubeConfigInfo.Server = newServer
existingCredentialIssuerConfig.Status.KubeConfigInfo.CertificateAuthorityData = newCA
if _, err := credentialIssuerConfigs.Update(
if _, err := credentialIssuerConfigsClient.Update(
ctx,
existingCredentialIssuerConfig,
metav1.UpdateOptions{},
@ -169,6 +172,6 @@ func (c *publisherController) createOrUpdateCredentialIssuerConfig(
}
func equal(a, b *crdpinnipedv1alpha1.CredentialIssuerConfig) bool {
return a.Spec.Server == b.Spec.Server &&
a.Spec.CertificateAuthorityData == b.Spec.CertificateAuthorityData
return a.Status.KubeConfigInfo.Server == b.Status.KubeConfigInfo.Server &&
a.Status.KubeConfigInfo.CertificateAuthorityData == b.Status.KubeConfigInfo.CertificateAuthorityData
}

View File

@ -190,10 +190,13 @@ func TestSync(t *testing.T) {
Name: "pinniped-config",
Namespace: expectedNamespace,
},
Spec: crdpinnipedv1alpha1.CredentialIssuerConfigSpec{
Status: crdpinnipedv1alpha1.CredentialIssuerConfigStatus{
Strategies: []crdpinnipedv1alpha1.CredentialIssuerConfigStrategy{},
KubeConfigInfo: &crdpinnipedv1alpha1.CredentialIssuerConfigKubeConfigInfo{
Server: expectedServerURL,
CertificateAuthorityData: expectedCAData,
},
},
}
return expectedCredentialIssuerConfigGVR, expectedCredentialIssuerConfig
}
@ -324,7 +327,7 @@ func TestSync(t *testing.T) {
kubeServerURL,
caData,
)
expectedCredentialIssuerConfig.Spec.Server = "https://some-server-override"
expectedCredentialIssuerConfig.Status.KubeConfigInfo.Server = "https://some-server-override"
r.Equal(
[]coretesting.Action{
@ -368,7 +371,7 @@ func TestSync(t *testing.T) {
kubeServerURL,
caData,
)
expectedCredentialIssuerConfig.Spec.Server = "https://some-other-server"
expectedCredentialIssuerConfig.Status.KubeConfigInfo.Server = "https://some-other-server"
r.NoError(pinnipedInformerClient.Tracker().Add(expectedCredentialIssuerConfig))
r.NoError(pinnipedAPIClient.Tracker().Add(expectedCredentialIssuerConfig))
})

View File

@ -7,7 +7,14 @@ package v1alpha1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
type CredentialIssuerConfigSpec struct {
type CredentialIssuerConfigStatus struct {
Strategies []CredentialIssuerConfigStrategy `json:"strategies"`
// +optional
KubeConfigInfo *CredentialIssuerConfigKubeConfigInfo `json:"kubeConfigInfo,omitempty"`
}
type CredentialIssuerConfigKubeConfigInfo struct {
// The K8s API server URL. Required.
Server string `json:"server,omitempty"`
@ -15,6 +22,14 @@ type CredentialIssuerConfigSpec struct {
CertificateAuthorityData string `json:"certificateAuthorityData,omitempty"`
}
type CredentialIssuerConfigStrategy struct {
Type string `json:"type,omitempty"`
Status string `json:"status,omitempty"`
Reason string `json:"reason,omitempty"`
Message string `json:"message,omitempty"`
LastUpdateTime metav1.Time `json:"lastUpdateTime"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@ -22,7 +37,7 @@ type CredentialIssuerConfig struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec CredentialIssuerConfigSpec `json:"spec"`
Status CredentialIssuerConfigStatus `json:"status"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View File

@ -18,7 +18,7 @@ func (in *CredentialIssuerConfig) DeepCopyInto(out *CredentialIssuerConfig) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
in.Status.DeepCopyInto(&out.Status)
return
}
@ -40,6 +40,22 @@ func (in *CredentialIssuerConfig) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerConfigKubeConfigInfo) DeepCopyInto(out *CredentialIssuerConfigKubeConfigInfo) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerConfigKubeConfigInfo.
func (in *CredentialIssuerConfigKubeConfigInfo) DeepCopy() *CredentialIssuerConfigKubeConfigInfo {
if in == nil {
return nil
}
out := new(CredentialIssuerConfigKubeConfigInfo)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerConfigList) DeepCopyInto(out *CredentialIssuerConfigList) {
*out = *in
@ -74,17 +90,46 @@ func (in *CredentialIssuerConfigList) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerConfigSpec) DeepCopyInto(out *CredentialIssuerConfigSpec) {
func (in *CredentialIssuerConfigStatus) DeepCopyInto(out *CredentialIssuerConfigStatus) {
*out = *in
if in.Strategies != nil {
in, out := &in.Strategies, &out.Strategies
*out = make([]CredentialIssuerConfigStrategy, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.KubeConfigInfo != nil {
in, out := &in.KubeConfigInfo, &out.KubeConfigInfo
*out = new(CredentialIssuerConfigKubeConfigInfo)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerConfigSpec.
func (in *CredentialIssuerConfigSpec) DeepCopy() *CredentialIssuerConfigSpec {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerConfigStatus.
func (in *CredentialIssuerConfigStatus) DeepCopy() *CredentialIssuerConfigStatus {
if in == nil {
return nil
}
out := new(CredentialIssuerConfigSpec)
out := new(CredentialIssuerConfigStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialIssuerConfigStrategy) DeepCopyInto(out *CredentialIssuerConfigStrategy) {
*out = *in
in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialIssuerConfigStrategy.
func (in *CredentialIssuerConfigStrategy) DeepCopy() *CredentialIssuerConfigStrategy {
if in == nil {
return nil
}
out := new(CredentialIssuerConfigStrategy)
in.DeepCopyInto(out)
return out
}

View File

@ -20,8 +20,10 @@ import (
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfig": schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfig(ref),
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigKubeConfigInfo": schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigKubeConfigInfo(ref),
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigList": schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigList(ref),
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigSpec": schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigSpec(ref),
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigStatus": schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigStatus(ref),
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigStrategy": schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigStrategy(ref),
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/pinniped/v1alpha1.CredentialRequest": schema_api_apis_pinniped_v1alpha1_CredentialRequest(ref),
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/pinniped/v1alpha1.CredentialRequestCredential": schema_api_apis_pinniped_v1alpha1_CredentialRequestCredential(ref),
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/pinniped/v1alpha1.CredentialRequestList": schema_api_apis_pinniped_v1alpha1_CredentialRequestList(ref),
@ -108,17 +110,43 @@ func schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfig(ref common.Refe
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
},
},
"spec": {
"status": {
SchemaProps: spec.SchemaProps{
Ref: ref("github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigSpec"),
Ref: ref("github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigStatus"),
},
},
},
Required: []string{"spec"},
Required: []string{"status"},
},
},
Dependencies: []string{
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
}
}
func schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigKubeConfigInfo(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"server": {
SchemaProps: spec.SchemaProps{
Description: "The K8s API server URL. Required.",
Type: []string{"string"},
Format: "",
},
},
"certificateAuthorityData": {
SchemaProps: spec.SchemaProps{
Description: "The K8s API server CA bundle. Required.",
Type: []string{"string"},
Format: "",
},
},
},
},
},
}
}
@ -168,29 +196,79 @@ func schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigList(ref common.
}
}
func schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
func schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"server": {
"strategies": {
SchemaProps: spec.SchemaProps{
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: ref("github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigStrategy"),
},
},
},
},
},
"kubeConfigInfo": {
SchemaProps: spec.SchemaProps{
Ref: ref("github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigKubeConfigInfo"),
},
},
},
Required: []string{"strategies"},
},
},
Dependencies: []string{
"github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigKubeConfigInfo", "github.com/suzerain-io/pinniped/kubernetes/1.19/api/apis/crdpinniped/v1alpha1.CredentialIssuerConfigStrategy"},
}
}
func schema_api_apis_crdpinniped_v1alpha1_CredentialIssuerConfigStrategy(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"type": {
SchemaProps: spec.SchemaProps{
Description: "The K8s API server URL. Required.",
Type: []string{"string"},
Format: "",
},
},
"certificateAuthorityData": {
"status": {
SchemaProps: spec.SchemaProps{
Description: "The K8s API server CA bundle. Required.",
Type: []string{"string"},
Format: "",
},
},
"reason": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
"message": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
"lastUpdateTime": {
SchemaProps: spec.SchemaProps{
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"),
},
},
},
Required: []string{"lastUpdateTime"},
},
},
Dependencies: []string{
"k8s.io/apimachinery/pkg/apis/meta/v1.Time"},
}
}

View File

@ -29,6 +29,7 @@ type CredentialIssuerConfigsGetter interface {
type CredentialIssuerConfigInterface interface {
Create(ctx context.Context, credentialIssuerConfig *v1alpha1.CredentialIssuerConfig, opts v1.CreateOptions) (*v1alpha1.CredentialIssuerConfig, error)
Update(ctx context.Context, credentialIssuerConfig *v1alpha1.CredentialIssuerConfig, opts v1.UpdateOptions) (*v1alpha1.CredentialIssuerConfig, error)
UpdateStatus(ctx context.Context, credentialIssuerConfig *v1alpha1.CredentialIssuerConfig, opts v1.UpdateOptions) (*v1alpha1.CredentialIssuerConfig, 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.CredentialIssuerConfig, error)
@ -124,6 +125,22 @@ func (c *credentialIssuerConfigs) Update(ctx context.Context, credentialIssuerCo
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 *credentialIssuerConfigs) UpdateStatus(ctx context.Context, credentialIssuerConfig *v1alpha1.CredentialIssuerConfig, opts v1.UpdateOptions) (result *v1alpha1.CredentialIssuerConfig, err error) {
result = &v1alpha1.CredentialIssuerConfig{}
err = c.client.Put().
Namespace(c.ns).
Resource("credentialissuerconfigs").
Name(credentialIssuerConfig.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(credentialIssuerConfig).
Do(ctx).
Into(result)
return
}
// Delete takes name of the credentialIssuerConfig and deletes it. Returns an error if one occurs.
func (c *credentialIssuerConfigs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().

View File

@ -91,6 +91,18 @@ func (c *FakeCredentialIssuerConfigs) Update(ctx context.Context, credentialIssu
return obj.(*v1alpha1.CredentialIssuerConfig), 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 *FakeCredentialIssuerConfigs) UpdateStatus(ctx context.Context, credentialIssuerConfig *v1alpha1.CredentialIssuerConfig, opts v1.UpdateOptions) (*v1alpha1.CredentialIssuerConfig, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(credentialissuerconfigsResource, "status", c.ns, credentialIssuerConfig), &v1alpha1.CredentialIssuerConfig{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.CredentialIssuerConfig), err
}
// Delete takes name of the credentialIssuerConfig and deletes it. Returns an error if one occurs.
func (c *FakeCredentialIssuerConfigs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.

View File

@ -29,14 +29,14 @@ func TestSuccessfulCredentialIssuerConfig(t *testing.T) {
defer cancel()
config := library.NewClientConfig(t)
expectedLDCSpec := expectedLDCSpec(config)
expectedLDCStatus := expectedLDCStatus(config)
configList, err := client.
CrdV1alpha1().
CredentialIssuerConfigs(namespaceName).
List(ctx, metav1.ListOptions{})
require.NoError(t, err)
require.Len(t, configList.Items, 1)
require.Equal(t, expectedLDCSpec, &configList.Items[0].Spec)
require.Equal(t, expectedLDCStatus, &configList.Items[0].Status)
}
func TestReconcilingCredentialIssuerConfig(t *testing.T) {
@ -55,7 +55,7 @@ func TestReconcilingCredentialIssuerConfig(t *testing.T) {
require.NoError(t, err)
config := library.NewClientConfig(t)
expectedLDCSpec := expectedLDCSpec(config)
expectedLDCStatus := expectedLDCStatus(config)
var actualLDC *crdpinnipedv1alpha1.CredentialIssuerConfig
for i := 0; i < 10; i++ {
@ -69,12 +69,15 @@ func TestReconcilingCredentialIssuerConfig(t *testing.T) {
time.Sleep(time.Millisecond * 750)
}
require.NoError(t, err)
require.Equal(t, expectedLDCSpec, &actualLDC.Spec)
require.Equal(t, expectedLDCStatus, &actualLDC.Status)
}
func expectedLDCSpec(config *rest.Config) *crdpinnipedv1alpha1.CredentialIssuerConfigSpec {
return &crdpinnipedv1alpha1.CredentialIssuerConfigSpec{
func expectedLDCStatus(config *rest.Config) *crdpinnipedv1alpha1.CredentialIssuerConfigStatus {
return &crdpinnipedv1alpha1.CredentialIssuerConfigStatus{
Strategies: []crdpinnipedv1alpha1.CredentialIssuerConfigStrategy{},
KubeConfigInfo: &crdpinnipedv1alpha1.CredentialIssuerConfigKubeConfigInfo{
Server: config.Host,
CertificateAuthorityData: base64.StdEncoding.EncodeToString(config.TLSClientConfig.CAData),
},
}
}