Merge pull request #2025 from flant/kubernetes-apiextensions-version

feat: create CRDs as apiextensions.k8s.io/v1
This commit is contained in:
Maksim Nabokikh 2021-07-08 10:52:55 +04:00 committed by GitHub
commit 033a8d89f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 387 additions and 171 deletions

1
go.mod
View file

@ -5,6 +5,7 @@ go 1.16
require ( require (
entgo.io/ent v0.8.0 entgo.io/ent v0.8.0
github.com/AppsFlyer/go-sundheit v0.4.0 github.com/AppsFlyer/go-sundheit v0.4.0
github.com/Masterminds/semver v1.5.0
github.com/Masterminds/sprig/v3 v3.2.2 github.com/Masterminds/sprig/v3 v3.2.2
github.com/beevik/etree v1.1.0 github.com/beevik/etree v1.1.0
github.com/coreos/go-oidc/v3 v3.0.0 github.com/coreos/go-oidc/v3 v3.0.0

2
go.sum
View file

@ -52,6 +52,8 @@ github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20O
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: authcodes.dex.coreos.com name: authcodes.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: AuthCodeList listKind: AuthCodeList
plural: authcodes plural: authcodes
singular: authcode singular: authcode
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: authrequests.dex.coreos.com name: authrequests.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: AuthRequestList listKind: AuthRequestList
plural: authrequests plural: authrequests
singular: authrequest singular: authrequest
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: connectors.dex.coreos.com name: connectors.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: ConnectorList listKind: ConnectorList
plural: connectors plural: connectors
singular: connector singular: connector
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: devicerequests.dex.coreos.com name: devicerequests.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: DeviceRequestList listKind: DeviceRequestList
plural: devicerequests plural: devicerequests
singular: devicerequest singular: devicerequest
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: devicetokens.dex.coreos.com name: devicetokens.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: DeviceTokenList listKind: DeviceTokenList
plural: devicetokens plural: devicetokens
singular: devicetoken singular: devicetoken
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: oauth2clients.dex.coreos.com name: oauth2clients.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: OAuth2ClientList listKind: OAuth2ClientList
plural: oauth2clients plural: oauth2clients
singular: oauth2client singular: oauth2client
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: offlinesessionses.dex.coreos.com name: offlinesessionses.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: OfflineSessionsList listKind: OfflineSessionsList
plural: offlinesessionses plural: offlinesessionses
singular: offlinesessions singular: offlinesessions
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: passwords.dex.coreos.com name: passwords.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: PasswordList listKind: PasswordList
plural: passwords plural: passwords
singular: password singular: password
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: refreshtokens.dex.coreos.com name: refreshtokens.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: RefreshTokenList listKind: RefreshTokenList
plural: refreshtokens plural: refreshtokens
singular: refreshtoken singular: refreshtoken
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1 apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
name: signingkeies.dex.coreos.com name: signingkeies.dex.coreos.com
@ -9,4 +9,12 @@ spec:
listKind: SigningKeyList listKind: SigningKeyList
plural: signingkeies plural: signingkeies
singular: signingkey singular: signingkey
version: v1 scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -22,6 +22,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/Masterminds/semver"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"golang.org/x/net/http2" "golang.org/x/net/http2"
@ -47,6 +48,10 @@ type client struct {
// API version of the oidc resources. For example "oidc.coreos.com". This is // API version of the oidc resources. For example "oidc.coreos.com". This is
// currently not configurable, but could be in the future. // currently not configurable, but could be in the future.
apiVersion string apiVersion string
// API version of the custom resource definitions.
// Different Kubernetes version requires to create CRD in certain API. It will be discovered automatically on
// storage opening.
crdAPIVersion string
// This is called once the client's Close method is called to signal goroutines, // This is called once the client's Close method is called to signal goroutines,
// such as the one creating third party resources, to stop. // such as the one creating third party resources, to stop.
@ -195,6 +200,37 @@ func (cli *client) postResource(apiVersion, namespace, resource string, v interf
return checkHTTPErr(resp, http.StatusCreated) return checkHTTPErr(resp, http.StatusCreated)
} }
func (cli *client) detectKubernetesVersion() error {
var version struct{ GitVersion string }
url := cli.baseURL + "/version"
resp, err := cli.client.Get(url)
if err != nil {
return err
}
defer closeResp(resp)
if err := checkHTTPErr(resp, http.StatusOK); err != nil {
return err
}
if err := json.NewDecoder(resp.Body).Decode(&version); err != nil {
return err
}
clusterVersion, err := semver.NewVersion(version.GitVersion)
if err != nil {
cli.logger.Warnf("cannot detect Kubernetes version (%s): %v", clusterVersion, err)
return nil
}
if clusterVersion.LessThan(semver.MustParse("v1.16.0")) {
cli.crdAPIVersion = legacyCRDAPIVersion
}
return nil
}
func (cli *client) delete(resource, name string) error { func (cli *client) delete(resource, name string) error {
url := cli.urlFor(cli.apiVersion, cli.namespace, resource, name) url := cli.urlFor(cli.apiVersion, cli.namespace, resource, name)
req, err := http.NewRequest("DELETE", url, nil) req, err := http.NewRequest("DELETE", url, nil)
@ -351,11 +387,12 @@ func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string, l
Transport: t, Transport: t,
Timeout: 15 * time.Second, Timeout: 15 * time.Second,
}, },
baseURL: cluster.Server, baseURL: cluster.Server,
hash: func() hash.Hash { return fnv.New64() }, hash: func() hash.Hash { return fnv.New64() },
namespace: namespace, namespace: namespace,
apiVersion: apiVersion, apiVersion: apiVersion,
logger: logger, crdAPIVersion: crdAPIVersion,
logger: logger,
}, nil }, nil
} }

View file

@ -26,6 +26,15 @@ type CustomResourceDefinitionSpec struct {
// Scope indicates whether this resource is cluster or namespace scoped. Default is namespaced // Scope indicates whether this resource is cluster or namespace scoped. Default is namespaced
Scope ResourceScope `json:"scope" protobuf:"bytes,4,opt,name=scope,casttype=ResourceScope"` Scope ResourceScope `json:"scope" protobuf:"bytes,4,opt,name=scope,casttype=ResourceScope"`
// versions is the list of all API versions of the defined custom resource.
// Version names are used to compute the order in which served versions are listed in API discovery.
// If the version string is "kube-like", it will sort above non "kube-like" version strings, which are ordered
// lexicographically. "Kube-like" versions start with a "v", then are followed by a number (the major version),
// then optionally the string "alpha" or "beta" and another number (the minor version). These are sorted first
// by GA > beta > alpha (where GA is a version with no suffix such as beta or alpha), and then by comparing
// major version, then minor version. An example sorted list of versions:
// v10, v2, v1, v11beta2, v10beta3, v3beta1, v12alpha1, v11alpha2, foo1, foo10.
Versions []CustomResourceDefinitionVersion `json:"versions" protobuf:"bytes,7,rep,name=versions"`
} }
// CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition // CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition
@ -139,3 +148,29 @@ type CustomResourceDefinitionList struct {
// Items individual CustomResourceDefinitions // Items individual CustomResourceDefinitions
Items []CustomResourceDefinition `json:"items" protobuf:"bytes,2,rep,name=items"` Items []CustomResourceDefinition `json:"items" protobuf:"bytes,2,rep,name=items"`
} }
type CustomResourceDefinitionVersion struct {
// name is the version name, e.g. “v1”, “v2beta1”, etc.
// The custom resources are served under this version at `/apis/<group>/<version>/...` if `served` is true.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// served is a flag enabling/disabling this version from being served via REST APIs
Served bool `json:"served" protobuf:"varint,2,opt,name=served"`
// storage indicates this version should be used when persisting custom resources to storage.
// There must be exactly one version with storage=true.
Storage bool `json:"storage" protobuf:"varint,3,opt,name=storage"`
// schema describes the schema used for validation, pruning, and defaulting of this version of the custom resource.
// +optional
Schema *CustomResourceValidation `json:"schema,omitempty" protobuf:"bytes,4,opt,name=schema"`
}
// CustomResourceValidation is a list of validation methods for CustomResources.
type CustomResourceValidation struct {
// OpenAPIV3Schema is the OpenAPI v3 schema to be validated against.
OpenAPIV3Schema *JSONSchemaProps `json:"openAPIV3Schema,omitempty" protobuf:"bytes,1,opt,name=openAPIV3Schema"`
}
// JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).
type JSONSchemaProps struct {
Type string `json:"type,omitempty" protobuf:"bytes,5,opt,name=type"`
XPreserveUnknownFields *bool `json:"x-kubernetes-preserve-unknown-fields,omitempty" protobuf:"bytes,38,opt,name=xKubernetesPreserveUnknownFields"`
}

View file

@ -88,6 +88,10 @@ func (c *Config) open(logger log.Logger, waitForResources bool) (*client, error)
return nil, fmt.Errorf("create client: %v", err) return nil, fmt.Errorf("create client: %v", err)
} }
if err = cli.detectKubernetesVersion(); err != nil {
return nil, fmt.Errorf("cannot get kubernetes version: %v", err)
}
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
logger.Info("creating custom Kubernetes resources") logger.Info("creating custom Kubernetes resources")
@ -100,7 +104,6 @@ func (c *Config) open(logger log.Logger, waitForResources bool) (*client, error)
// Try to synchronously create the custom resources once. This doesn't mean // Try to synchronously create the custom resources once. This doesn't mean
// they'll immediately be available, but ensures that the client will actually try // they'll immediately be available, but ensures that the client will actually try
// once. // once.
logger.Errorf("failed creating custom resources: %v", err)
go func() { go func() {
for { for {
if cli.registerCustomResources() { if cli.registerCustomResources() {
@ -136,21 +139,25 @@ func (c *Config) open(logger log.Logger, waitForResources bool) (*client, error)
// Creating a custom resource does not mean that they'll be immediately available. // Creating a custom resource does not mean that they'll be immediately available.
func (cli *client) registerCustomResources() (ok bool) { func (cli *client) registerCustomResources() (ok bool) {
ok = true ok = true
length := len(customResourceDefinitions)
definitions := customResourceDefinitions(cli.crdAPIVersion)
length := len(definitions)
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
var err error var err error
var resourceName string var resourceName string
r := customResourceDefinitions[i] r := definitions[i]
var i interface{} var i interface{}
cli.logger.Infof("checking if custom resource %s has been created already...", r.ObjectMeta.Name) cli.logger.Infof("checking if custom resource %s has already been created...", r.ObjectMeta.Name)
if err := cli.list(r.Spec.Names.Plural, &i); err == nil { if err := cli.list(r.Spec.Names.Plural, &i); err == nil {
cli.logger.Infof("The custom resource %s already available, skipping create", r.ObjectMeta.Name) cli.logger.Infof("The custom resource %s already available, skipping create", r.ObjectMeta.Name)
continue continue
} else { } else {
cli.logger.Infof("failed to list custom resource %s, attempting to create: %v", r.ObjectMeta.Name, err) cli.logger.Infof("failed to list custom resource %s, attempting to create: %v", r.ObjectMeta.Name, err)
} }
err = cli.postResource("apiextensions.k8s.io/v1beta1", "", "customresourcedefinitions", r)
err = cli.postResource(cli.crdAPIVersion, "", "customresourcedefinitions", r)
resourceName = r.ObjectMeta.Name resourceName = r.ObjectMeta.Name
if err != nil { if err != nil {
@ -177,7 +184,7 @@ func (cli *client) waitForCRDs(ctx context.Context) error {
ctx, cancel := context.WithTimeout(ctx, time.Second*30) ctx, cancel := context.WithTimeout(ctx, time.Second*30)
defer cancel() defer cancel()
for _, crd := range customResourceDefinitions { for _, crd := range customResourceDefinitions(cli.crdAPIVersion) {
for { for {
err := cli.isCRDReady(crd.Name) err := cli.isCRDReady(crd.Name)
if err == nil { if err == nil {
@ -199,7 +206,7 @@ func (cli *client) waitForCRDs(ctx context.Context) error {
// isCRDReady determines if a CRD is ready by inspecting its conditions. // isCRDReady determines if a CRD is ready by inspecting its conditions.
func (cli *client) isCRDReady(name string) error { func (cli *client) isCRDReady(name string) error {
var r k8sapi.CustomResourceDefinition var r k8sapi.CustomResourceDefinition
err := cli.getResource("apiextensions.k8s.io/v1beta1", "", "customresourcedefinitions", name, &r) err := cli.getResource(cli.crdAPIVersion, "", "customresourcedefinitions", name, &r)
if err != nil { if err != nil {
return fmt.Errorf("get crd %s: %v", name, err) return fmt.Errorf("get crd %s: %v", name, err)
} }

View file

@ -10,169 +10,223 @@ import (
"github.com/dexidp/dex/storage/kubernetes/k8sapi" "github.com/dexidp/dex/storage/kubernetes/k8sapi"
) )
var crdMeta = k8sapi.TypeMeta{ const (
APIVersion: "apiextensions.k8s.io/v1beta1", apiGroup = "dex.coreos.com"
Kind: "CustomResourceDefinition",
}
const apiGroup = "dex.coreos.com" legacyCRDAPIVersion = "apiextensions.k8s.io/v1beta1"
crdAPIVersion = "apiextensions.k8s.io/v1"
)
// The set of custom resource definitions required by the storage. These are managed by // The set of custom resource definitions required by the storage. These are managed by
// the storage so it can migrate itself by creating new resources. // the storage so it can migrate itself by creating new resources.
var customResourceDefinitions = []k8sapi.CustomResourceDefinition{ func customResourceDefinitions(apiVersion string) []k8sapi.CustomResourceDefinition {
{ crdMeta := k8sapi.TypeMeta{
ObjectMeta: k8sapi.ObjectMeta{ APIVersion: apiVersion,
Name: "authcodes.dex.coreos.com", Kind: "CustomResourceDefinition",
}, }
TypeMeta: crdMeta,
Spec: k8sapi.CustomResourceDefinitionSpec{ var version string
Group: apiGroup, var scope k8sapi.ResourceScope
Version: "v1", var versions []k8sapi.CustomResourceDefinitionVersion
Names: k8sapi.CustomResourceDefinitionNames{
Plural: "authcodes", switch apiVersion {
Singular: "authcode", case crdAPIVersion:
Kind: "AuthCode", preserveUnknownFields := true
versions = []k8sapi.CustomResourceDefinitionVersion{
{
Name: "v1",
Served: true,
Storage: true,
Schema: &k8sapi.CustomResourceValidation{
OpenAPIV3Schema: &k8sapi.JSONSchemaProps{
Type: "object",
XPreserveUnknownFields: &preserveUnknownFields,
},
},
},
}
scope = k8sapi.NamespaceScoped
case legacyCRDAPIVersion:
version = "v1"
default:
panic("unknown apiVersion " + apiVersion)
}
return []k8sapi.CustomResourceDefinition{
{
ObjectMeta: k8sapi.ObjectMeta{
Name: "authcodes.dex.coreos.com",
},
TypeMeta: crdMeta,
Spec: k8sapi.CustomResourceDefinitionSpec{
Group: apiGroup,
Version: version,
Versions: versions,
Scope: scope,
Names: k8sapi.CustomResourceDefinitionNames{
Plural: "authcodes",
Singular: "authcode",
Kind: "AuthCode",
},
}, },
}, },
}, {
{ ObjectMeta: k8sapi.ObjectMeta{
ObjectMeta: k8sapi.ObjectMeta{ Name: "authrequests.dex.coreos.com",
Name: "authrequests.dex.coreos.com", },
}, TypeMeta: crdMeta,
TypeMeta: crdMeta, Spec: k8sapi.CustomResourceDefinitionSpec{
Spec: k8sapi.CustomResourceDefinitionSpec{ Group: apiGroup,
Group: apiGroup, Version: version,
Version: "v1", Versions: versions,
Names: k8sapi.CustomResourceDefinitionNames{ Scope: scope,
Plural: "authrequests", Names: k8sapi.CustomResourceDefinitionNames{
Singular: "authrequest", Plural: "authrequests",
Kind: "AuthRequest", Singular: "authrequest",
Kind: "AuthRequest",
},
}, },
}, },
}, {
{ ObjectMeta: k8sapi.ObjectMeta{
ObjectMeta: k8sapi.ObjectMeta{ Name: "oauth2clients.dex.coreos.com",
Name: "oauth2clients.dex.coreos.com", },
}, TypeMeta: crdMeta,
TypeMeta: crdMeta, Spec: k8sapi.CustomResourceDefinitionSpec{
Spec: k8sapi.CustomResourceDefinitionSpec{ Group: apiGroup,
Group: apiGroup, Version: version,
Version: "v1", Versions: versions,
Names: k8sapi.CustomResourceDefinitionNames{ Scope: scope,
Plural: "oauth2clients", Names: k8sapi.CustomResourceDefinitionNames{
Singular: "oauth2client", Plural: "oauth2clients",
Kind: "OAuth2Client", Singular: "oauth2client",
Kind: "OAuth2Client",
},
}, },
}, },
}, {
{ ObjectMeta: k8sapi.ObjectMeta{
ObjectMeta: k8sapi.ObjectMeta{ Name: "signingkeies.dex.coreos.com",
Name: "signingkeies.dex.coreos.com", },
}, TypeMeta: crdMeta,
TypeMeta: crdMeta, Spec: k8sapi.CustomResourceDefinitionSpec{
Spec: k8sapi.CustomResourceDefinitionSpec{ Group: apiGroup,
Group: apiGroup, Version: version,
Version: "v1", Versions: versions,
Names: k8sapi.CustomResourceDefinitionNames{ Scope: scope,
// `signingkeies` is an artifact from the old TPR pluralization. Names: k8sapi.CustomResourceDefinitionNames{
// Users don't directly interact with this value, hence leaving it // `signingkeies` is an artifact from the old TPR pluralization.
// as is. // Users don't directly interact with this value, hence leaving it
Plural: "signingkeies", // as is.
Singular: "signingkey", Plural: "signingkeies",
Kind: "SigningKey", Singular: "signingkey",
Kind: "SigningKey",
},
}, },
}, },
}, {
{ ObjectMeta: k8sapi.ObjectMeta{
ObjectMeta: k8sapi.ObjectMeta{ Name: "refreshtokens.dex.coreos.com",
Name: "refreshtokens.dex.coreos.com", },
}, TypeMeta: crdMeta,
TypeMeta: crdMeta, Spec: k8sapi.CustomResourceDefinitionSpec{
Spec: k8sapi.CustomResourceDefinitionSpec{ Group: apiGroup,
Group: apiGroup, Version: version,
Version: "v1", Versions: versions,
Names: k8sapi.CustomResourceDefinitionNames{ Scope: scope,
Plural: "refreshtokens", Names: k8sapi.CustomResourceDefinitionNames{
Singular: "refreshtoken", Plural: "refreshtokens",
Kind: "RefreshToken", Singular: "refreshtoken",
Kind: "RefreshToken",
},
}, },
}, },
}, {
{ ObjectMeta: k8sapi.ObjectMeta{
ObjectMeta: k8sapi.ObjectMeta{ Name: "passwords.dex.coreos.com",
Name: "passwords.dex.coreos.com", },
}, TypeMeta: crdMeta,
TypeMeta: crdMeta, Spec: k8sapi.CustomResourceDefinitionSpec{
Spec: k8sapi.CustomResourceDefinitionSpec{ Group: apiGroup,
Group: apiGroup, Version: version,
Version: "v1", Versions: versions,
Names: k8sapi.CustomResourceDefinitionNames{ Scope: scope,
Plural: "passwords", Names: k8sapi.CustomResourceDefinitionNames{
Singular: "password", Plural: "passwords",
Kind: "Password", Singular: "password",
Kind: "Password",
},
}, },
}, },
}, {
{ ObjectMeta: k8sapi.ObjectMeta{
ObjectMeta: k8sapi.ObjectMeta{ Name: "offlinesessionses.dex.coreos.com",
Name: "offlinesessionses.dex.coreos.com", },
}, TypeMeta: crdMeta,
TypeMeta: crdMeta, Spec: k8sapi.CustomResourceDefinitionSpec{
Spec: k8sapi.CustomResourceDefinitionSpec{ Group: apiGroup,
Group: apiGroup, Version: version,
Version: "v1", Versions: versions,
Names: k8sapi.CustomResourceDefinitionNames{ Scope: scope,
Plural: "offlinesessionses", Names: k8sapi.CustomResourceDefinitionNames{
Singular: "offlinesessions", Plural: "offlinesessionses",
Kind: "OfflineSessions", Singular: "offlinesessions",
Kind: "OfflineSessions",
},
}, },
}, },
}, {
{ ObjectMeta: k8sapi.ObjectMeta{
ObjectMeta: k8sapi.ObjectMeta{ Name: "connectors.dex.coreos.com",
Name: "connectors.dex.coreos.com", },
}, TypeMeta: crdMeta,
TypeMeta: crdMeta, Spec: k8sapi.CustomResourceDefinitionSpec{
Spec: k8sapi.CustomResourceDefinitionSpec{ Group: apiGroup,
Group: apiGroup, Version: version,
Version: "v1", Versions: versions,
Names: k8sapi.CustomResourceDefinitionNames{ Scope: scope,
Plural: "connectors", Names: k8sapi.CustomResourceDefinitionNames{
Singular: "connector", Plural: "connectors",
Kind: "Connector", Singular: "connector",
Kind: "Connector",
},
}, },
}, },
}, {
{ ObjectMeta: k8sapi.ObjectMeta{
ObjectMeta: k8sapi.ObjectMeta{ Name: "devicerequests.dex.coreos.com",
Name: "devicerequests.dex.coreos.com", },
}, TypeMeta: crdMeta,
TypeMeta: crdMeta, Spec: k8sapi.CustomResourceDefinitionSpec{
Spec: k8sapi.CustomResourceDefinitionSpec{ Group: apiGroup,
Group: apiGroup, Version: version,
Version: "v1", Versions: versions,
Names: k8sapi.CustomResourceDefinitionNames{ Scope: scope,
Plural: "devicerequests", Names: k8sapi.CustomResourceDefinitionNames{
Singular: "devicerequest", Plural: "devicerequests",
Kind: "DeviceRequest", Singular: "devicerequest",
Kind: "DeviceRequest",
},
}, },
}, },
}, {
{ ObjectMeta: k8sapi.ObjectMeta{
ObjectMeta: k8sapi.ObjectMeta{ Name: "devicetokens.dex.coreos.com",
Name: "devicetokens.dex.coreos.com", },
}, TypeMeta: crdMeta,
TypeMeta: crdMeta, Spec: k8sapi.CustomResourceDefinitionSpec{
Spec: k8sapi.CustomResourceDefinitionSpec{ Group: apiGroup,
Group: apiGroup, Version: version,
Version: "v1", Versions: versions,
Names: k8sapi.CustomResourceDefinitionNames{ Scope: scope,
Plural: "devicetokens", Names: k8sapi.CustomResourceDefinitionNames{
Singular: "devicetoken", Plural: "devicetokens",
Kind: "DeviceToken", Singular: "devicetoken",
Kind: "DeviceToken",
},
}, },
}, },
}, }
} }
// There will only ever be a single keys resource. Maintain this by setting a // There will only ever be a single keys resource. Maintain this by setting a