Skip to content

Commit

Permalink
Merge pull request #1442 from cyberark/crd-schema
Browse files Browse the repository at this point in the history
Add schema for CRD
  • Loading branch information
szh authored Dec 23, 2021
2 parents 8b93cfb + b2211be commit a5591d8
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 57 deletions.
141 changes: 119 additions & 22 deletions internal/configurationmanagers/kubernetes/crd/crd_injector.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,140 @@ import (
"log"
"strings"

apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apierrors "k8s.io/apimachinery/pkg/api/errors"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func createCRD(apiExtClient *apiextensionsclientset.Clientset) error {
secretlessCRD := &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: meta_v1.ObjectMeta{
Name: CRDFQDNName,
// This schema should be kept up-to-date to match secretless-resource-definition.yaml
// and the Config struct in pkg/secretless/config/v1/config.go
var secretlessCRD = &apiextensionsv1.CustomResourceDefinition{
ObjectMeta: meta_v1.ObjectMeta{
Name: CRDFQDNName,
},
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
Group: CRDGroupName,
Names: apiextensionsv1.CustomResourceDefinitionNames{
Kind: strings.Title(CRDLongName),
Plural: CRDName,
ShortNames: CRDShortNames,
},
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
Group: CRDGroupName,
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Kind: strings.Title(CRDLongName),
Plural: CRDName,
ShortNames: CRDShortNames,
},
Version: "v1",
Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{
apiextensionsv1beta1.CustomResourceDefinitionVersion{
Name: "v1",
Served: true,
Storage: true,
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
{
Name: "v1",
Served: true,
Storage: true,
Schema: &apiextensionsv1.CustomResourceValidation{
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
Type: "object",
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"spec": {
Type: "object",
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"listeners": {
Type: "array",
Items: &apiextensionsv1.JSONSchemaPropsOrArray{
Schema: &apiextensionsv1.JSONSchemaProps{
Type: "object",
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"name": {
Type: "string",
},
"protocol": {
Type: "string",
},
"socket": {
Type: "string",
},
"address": {
Type: "string",
},
"debug": {
Type: "boolean",
},
"caCertFiles": {
Type: "array",
Items: &apiextensionsv1.JSONSchemaPropsOrArray{
Schema: &apiextensionsv1.JSONSchemaProps{
Type: "string",
},
},
},
},
},
},
},
"handlers": {
Type: "array",
Items: &apiextensionsv1.JSONSchemaPropsOrArray{
Schema: &apiextensionsv1.JSONSchemaProps{
Type: "object",
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"name": {
Type: "string",
},
"type": {
Type: "string",
},
"listener": {
Type: "string",
},
"debug": {
Type: "boolean",
},
"match": {
Type: "array",
Items: &apiextensionsv1.JSONSchemaPropsOrArray{
Schema: &apiextensionsv1.JSONSchemaProps{
Type: "string",
},
},
},
"credentials": {
Type: "array",
Items: &apiextensionsv1.JSONSchemaPropsOrArray{
Schema: &apiextensionsv1.JSONSchemaProps{
Type: "object",
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"name": {
Type: "string",
},
"provider": {
Type: "string",
},
"id": {
Type: "string",
},
},
},
},
},
},
},
},
},
},
},
},
},
},
},
Scope: apiextensionsv1beta1.NamespaceScoped,
},
}
Scope: apiextensionsv1.NamespaceScoped,
},
}

func createCRD(apiExtClient *apiextensionsclientset.Clientset) error {
res, err := apiExtClient.ApiextensionsV1().CustomResourceDefinitions().Create(
context.TODO(), secretlessCRD, meta_v1.CreateOptions{})

res, err := apiExtClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(context.TODO(), secretlessCRD, meta_v1.CreateOptions{})
if err != nil && !apierrors.IsAlreadyExists(err) {
return fmt.Errorf("%s: ERROR: Could not create Secretless CRD: %v - %v", PluginName,
err, res)
}

if apierrors.IsAlreadyExists(err) == false {
if !apierrors.IsAlreadyExists(err) {
log.Printf("%s: CRD was uccessfully added!", PluginName)
}

Expand Down
1 change: 1 addition & 0 deletions k8s-ci/k8s_crds/deployment.yaml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,5 @@ spec:
imagePullPolicy: Always
ports:
- containerPort: 8080
EOL
10 changes: 9 additions & 1 deletion resource-definitions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ configurations.secretless.io 1m
$ kubectl get crd -o yaml
apiVersion: v1
items:
- apiVersion: apiextensions.k8s.io/v1beta1
- apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
Expand Down Expand Up @@ -146,6 +146,14 @@ customresourcedefinition.apiextensions.k8s.io "configurations.secretless.io" del
This method is a bit more complicated, especially if it's run in-cluster due to needing to
have service account privileges but with that prerequisite, you can then use the `crd_injector.go`:

Open the `crd_injector.go` file in an editor and add the CRD schema:

```go
var crdSchema = &apiextensionsv1.JSONSchemaProps{
// NOTE: Take the CRD schema from the internal/configurationmanagers/kubernetes/crd/crd_injector.go
}
```

```
$ kubectl get crd
No resources found.
Expand Down
66 changes: 38 additions & 28 deletions resource-definitions/crd_injector.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package main

import (
"context"
"flag"
"log"
"os"
"path/filepath"
"time"

apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apierrors "k8s.io/apimachinery/pkg/api/errors"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -21,41 +22,50 @@ var (
CRDName = "configurations." + GroupName
)

func getHomeDir() string {
if home := os.Getenv("HOME"); home != "" {
return home
}
return os.Getenv("USERPROFILE")
var crdSchema = &apiextensionsv1.JSONSchemaProps{
// NOTE: Take the CRD schema from the internal/configurationmanagers/kubernetes/crd/crd_injector.go
}

func createCRD(apiExtClient *apiextensionsclientset.Clientset) {
secretlessCRD := &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: meta_v1.ObjectMeta{
Name: CRDName,
},
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
Group: GroupName,
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Kind: "Configuration",
Plural: "configurations",
ShortNames: []string{
"sbconfig",
},
// This schema should be kept up-to-date to match secretless-resource-definition.yaml
// and the Config struct in pkg/secretless/config/v1/config.go
var secretlessCRD = &apiextensionsv1.CustomResourceDefinition{
ObjectMeta: meta_v1.ObjectMeta{
Name: CRDName,
},
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
Group: GroupName,
Names: apiextensionsv1.CustomResourceDefinitionNames{
Kind: "Configuration",
Plural: "configurations",
ShortNames: []string{
"sbconfig",
},
Version: "v1",
Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{
apiextensionsv1beta1.CustomResourceDefinitionVersion{
Name: "v1",
Served: true,
Storage: true,
},
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
apiextensionsv1.CustomResourceDefinitionVersion{
Name: "v1",
Served: true,
Storage: true,
Schema: &apiextensionsv1.CustomResourceValidation{
OpenAPIV3Schema: crdSchema,
},
},
Scope: apiextensionsv1beta1.NamespaceScoped,
},
Scope: apiextensionsv1.NamespaceScoped,
},
}

func getHomeDir() string {
if home := os.Getenv("HOME"); home != "" {
return home
}
return os.Getenv("USERPROFILE")
}

func createCRD(apiExtClient *apiextensionsclientset.Clientset) {
log.Println("Creating CRD...")
res, err := apiExtClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(secretlessCRD)
res, err := apiExtClient.ApiextensionsV1().CustomResourceDefinitions().Create(
context.Background(), secretlessCRD, meta_v1.CreateOptions{})

if err != nil && !apierrors.IsAlreadyExists(err) {
log.Fatalf("ERROR: Could not create Secretless CRD: %v - %v", err, res)
Expand All @@ -71,7 +81,7 @@ func createCRD(apiExtClient *apiextensionsclientset.Clientset) {
// TODO: Use this to wait for the resources to be available
func waitForCRDAvailability(client *rest.RESTClient) error {
checkCRDAvailableFunc := func() (bool, error) {
_, err := client.Get().Resource(CRDName).DoRaw()
_, err := client.Get().Resource(CRDName).DoRaw(context.Background())
if err == nil {
return true, nil
}
Expand Down
7 changes: 4 additions & 3 deletions resource-definitions/crd_watcher.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"context"
"flag"
"log"
"os"
Expand Down Expand Up @@ -66,7 +67,7 @@ func main() {
}

// List the available configurations
list, err := clientset.SecretlessV1().Configurations("default").List(meta_v1.ListOptions{})
list, err := clientset.SecretlessV1().Configurations("default").List(context.Background(), meta_v1.ListOptions{})
log.Printf("Available configs: %v", len(list.Items))
for _, config := range list.Items {
yamlContent, err := yaml.Marshal(&config)
Expand All @@ -79,10 +80,10 @@ func main() {

watchList := &cache.ListWatch{
ListFunc: func(listOpts meta_v1.ListOptions) (result runtime.Object, err error) {
return clientset.SecretlessV1().Configurations(meta_v1.NamespaceAll).List(listOpts)
return clientset.SecretlessV1().Configurations(meta_v1.NamespaceAll).List(context.Background(), listOpts)
},
WatchFunc: func(listOpts meta_v1.ListOptions) (watch.Interface, error) {
return clientset.SecretlessV1().Configurations(meta_v1.NamespaceAll).Watch(listOpts)
return clientset.SecretlessV1().Configurations(meta_v1.NamespaceAll).Watch(context.Background(), listOpts)
},
}

Expand Down
59 changes: 56 additions & 3 deletions resource-definitions/secretless-resource-definition.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: apiextensions.k8s.io/v1beta1
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: configurations.secretless.io
Expand All @@ -9,10 +9,63 @@ spec:
plural: configurations
singular: configuration
shortNames:
- sbconfig
- sbconfig
scope: Namespaced
version: v1
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
listeners:
type: array
items:
type: object
properties:
name:
type: string
protocol:
type: string
socket:
type: string
address:
type: string
debug:
type: boolean
caCertFiles:
type: array
items:
type: string
handlers:
type: array
items:
type: object
properties:
name:
type: string
type:
type: string
listener:
type: string
debug:
type: boolean
match:
type: array
items:
type: string
credentials:
type: array
items:
type: object
properties:
name:
type: string
provider:
type: string
id:
type: string

0 comments on commit a5591d8

Please sign in to comment.