1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 16:06:56 +00:00
kyverno/pkg/openapi/crdSync.go

112 lines
2.5 KiB
Go
Raw Normal View History

2020-03-04 18:56:59 +05:30
package openapi
import (
2020-03-05 22:50:32 +05:30
"encoding/json"
2020-03-04 18:56:59 +05:30
"time"
2020-03-06 01:09:38 +05:30
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2020-03-05 22:50:32 +05:30
"gopkg.in/yaml.v2"
"github.com/googleapis/gnostic/compiler"
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
2020-03-20 11:43:21 -07:00
log "sigs.k8s.io/controller-runtime/pkg/log"
2020-03-05 22:50:32 +05:30
2020-03-04 18:56:59 +05:30
client "github.com/nirmata/kyverno/pkg/dclient"
"k8s.io/apimachinery/pkg/util/wait"
)
2020-03-05 22:50:32 +05:30
type crdDefinition struct {
Spec struct {
Names struct {
Kind string `json:"kind"`
} `json:"names"`
Versions []struct {
Schema struct {
OpenAPIV3Schema interface{} `json:"openAPIV3Schema"`
} `json:"schema"`
} `json:"versions"`
} `json:"spec"`
}
2020-03-04 18:56:59 +05:30
type crdSync struct {
client *client.Client
}
func NewCRDSync(client *client.Client) *crdSync {
return &crdSync{
client: client,
}
}
func (c *crdSync) Run(workers int, stopCh <-chan struct{}) {
2020-03-05 22:50:32 +05:30
newDoc, err := c.client.DiscoveryClient.OpenAPISchema()
if err != nil {
2020-03-20 11:43:21 -07:00
log.Log.Error(err, "cannot get openapi schema")
2020-03-05 22:50:32 +05:30
}
err = useOpenApiDocument(newDoc)
if err != nil {
2020-03-20 11:43:21 -07:00
log.Log.Error(err, "Could not set custom OpenApi document")
2020-03-05 22:50:32 +05:30
}
2020-03-04 18:56:59 +05:30
for i := 0; i < workers; i++ {
2020-03-05 22:50:32 +05:30
go wait.Until(c.sync, time.Second*10, stopCh)
2020-03-04 18:56:59 +05:30
}
2020-03-04 19:16:26 +05:30
<-stopCh
2020-03-04 18:56:59 +05:30
}
2020-03-05 22:50:32 +05:30
func (c *crdSync) sync() {
openApiGlobalState.mutex.Lock()
defer openApiGlobalState.mutex.Unlock()
crds, err := c.client.ListResource("CustomResourceDefinition", "", nil)
2020-03-04 18:56:59 +05:30
if err != nil {
2020-03-20 11:43:21 -07:00
log.Log.Error(err, "could not fetch crd's from server")
2020-03-05 22:50:32 +05:30
return
2020-03-04 18:56:59 +05:30
}
2020-03-06 01:09:38 +05:30
deleteCRDFromPreviousSync()
2020-03-05 22:50:32 +05:30
for _, crd := range crds.Items {
2020-03-06 01:09:38 +05:30
parseCRD(crd)
}
}
func deleteCRDFromPreviousSync() {
for _, crd := range openApiGlobalState.crdList {
delete(openApiGlobalState.kindToDefinitionName, crd)
delete(openApiGlobalState.definitions, crd)
}
openApiGlobalState.crdList = []string{}
}
func parseCRD(crd unstructured.Unstructured) {
var crdDefinition crdDefinition
crdRaw, _ := json.Marshal(crd.Object)
_ = json.Unmarshal(crdRaw, &crdDefinition)
crdName := crdDefinition.Spec.Names.Kind
if len(crdDefinition.Spec.Versions) < 1 {
2020-03-20 11:43:21 -07:00
log.Log.V(4).Info("could not parse crd schema, no versions present")
2020-03-06 01:09:38 +05:30
return
2020-03-04 18:56:59 +05:30
}
2020-03-06 01:09:38 +05:30
var schema yaml.MapSlice
schemaRaw, _ := json.Marshal(crdDefinition.Spec.Versions[0].Schema.OpenAPIV3Schema)
_ = yaml.Unmarshal(schemaRaw, &schema)
parsedSchema, err := openapi_v2.NewSchema(schema, compiler.NewContext("schema", nil))
if err != nil {
2020-03-20 11:43:21 -07:00
log.Log.Error(err, "could not parse crd schema:")
2020-03-06 01:09:38 +05:30
return
}
openApiGlobalState.crdList = append(openApiGlobalState.crdList, crdName)
openApiGlobalState.kindToDefinitionName[crdName] = crdName
openApiGlobalState.definitions[crdName] = parsedSchema
2020-03-04 18:56:59 +05:30
}