1
0
Fork 0
mirror of https://github.com/prometheus-operator/prometheus-operator.git synced 2025-04-21 11:48:53 +00:00

Add option to include Validation Spec to CRDs

This commit is contained in:
Antoine Legrand 2018-01-25 13:21:22 +01:00
parent 1c6922ba8a
commit 982f24c22e
12 changed files with 11233 additions and 24 deletions

View file

@ -16,7 +16,7 @@ build: promu
short-build:
go install github.com/coreos/prometheus-operator/cmd/operator
crdgen:
po-crdgen:
go install github.com/coreos/prometheus-operator/cmd/po-crdgen
crossbuild: promu
@ -77,6 +77,14 @@ generate-deepcopy: deepcopy-gen
deepcopy-gen -i github.com/coreos/prometheus-operator/pkg/client/monitoring/v1 --go-header-file="$(GOPATH)/src/github.com/coreos/prometheus-operator/.header" -v=4 --logtostderr --bounding-dirs "github.com/coreos/prometheus-operator/pkg/client" --output-file-base zz_generated.deepcopy
deepcopy-gen -i github.com/coreos/prometheus-operator/pkg/client/monitoring/v1alpha1 --go-header-file="$(GOPATH)/src/github.com/coreos/prometheus-operator/.header" -v=4 --logtostderr --bounding-dirs "github.com/coreos/prometheus-operator/pkg/client" --output-file-base zz_generated.deepcopy
openapi-gen:
go get -u -v -d k8s.io/code-generator/cmd/openapi-gen
cd $(GOPATH)/src/k8s.io/code-generator; git checkout release-1.8
go install k8s.io/code-generator/cmd/openapi-gen
generate-openapi: openapi-gen
openapi-gen -i github.com/coreos/prometheus-operator/pkg/client/monitoring/v1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/api/core/v1 -p github.com/coreos/prometheus-operator/pkg/client/monitoring/v1
generate-bundle:
hack/generate-bundle.sh

View file

@ -58,6 +58,7 @@ func init() {
flagset.Var(&cfg.Labels, "labels", "Labels to be add to all resources created by the operator")
flagset.StringVar(&cfg.CrdGroup, "crd-apigroup", monitoringv1.Group, "prometheus CRD API group name")
flagset.Var(&cfg.CrdKinds, "crd-kinds", " - EXPERIMENTAL (could be removed in future releases) - customize CRD kind names")
flagset.BoolVar(&cfg.EnableValidation, "with-validation", false, "Include the validation spec")
flagset.Parse(os.Args[1:])
}

View file

@ -1,3 +1,17 @@
// Copyright 2018 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
@ -15,22 +29,22 @@ import (
// Config stores the user configuration input
type Config struct {
EnableValidation bool
OutputFormat string
Namespace string
Labels prometheus.Labels
CrdGroup string
CrdKinds monitoringv1.CrdKinds
}
func marshallCrd(crd *extensionsobj.CustomResourceDefinition, encode string) {
func marshallCrd(crd *extensionsobj.CustomResourceDefinition, outputFormat string) {
jsonBytes, err := json.MarshalIndent(crd, "", " ")
if err != nil {
fmt.Println("error:", err)
}
if encode == "json" {
if outputFormat == "json" {
os.Stdout.Write(jsonBytes)
} else {
yamlBytes, err := yaml.JSONToYAML(jsonBytes)
if err != nil {
fmt.Println("error:", err)
@ -42,12 +56,12 @@ func marshallCrd(crd *extensionsobj.CustomResourceDefinition, encode string) {
// PrintCrd write on stdout the Prometheus CRD files as json or yaml
func PrintCrd(conf Config) {
promCrd := k8sutil.NewPrometheusCustomResourceDefinition(conf.CrdKinds.Prometheus, conf.CrdGroup, conf.Labels.LabelsMap)
serviceMonitorCrd := k8sutil.NewServiceMonitorCustomResourceDefinition(conf.CrdKinds.ServiceMonitor, conf.CrdGroup, conf.Labels.LabelsMap)
alertManagerCrd := k8sutil.NewAlertmanagerCustomResourceDefinition(conf.CrdKinds.Alertmanager, conf.CrdGroup, conf.Labels.LabelsMap)
promCrd := k8sutil.NewPrometheusCustomResourceDefinition(conf.CrdKinds.Prometheus, conf.CrdGroup, conf.Labels.LabelsMap, conf.EnableValidation)
serviceMonitorCrd := k8sutil.NewServiceMonitorCustomResourceDefinition(conf.CrdKinds.ServiceMonitor, conf.CrdGroup, conf.Labels.LabelsMap, conf.EnableValidation)
alertManagerCrd := k8sutil.NewAlertmanagerCustomResourceDefinition(conf.CrdKinds.Alertmanager, conf.CrdGroup, conf.Labels.LabelsMap, conf.EnableValidation)
marshallCrd(promCrd, "yaml")
marshallCrd(serviceMonitorCrd, "yaml")
marshallCrd(alertManagerCrd, "yaml")
marshallCrd(promCrd, conf.OutputFormat)
marshallCrd(serviceMonitorCrd, conf.OutputFormat)
marshallCrd(alertManagerCrd, conf.OutputFormat)
}

View file

@ -1,4 +1,4 @@
// Copyright 2016 The prometheus-operator Authors
// Copyright 2018 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -17,7 +17,6 @@ package main
import (
"flag"
monitoringv1 "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1"
"k8s.io/api/core/v1"
"os"
)
@ -32,8 +31,8 @@ func init() {
flagset.Var(&cfg.Labels, "labels", "Labels to be add to all resources created by the operator")
flagset.BoolVar(&cfg.EnableValidation, "with-validation", false, "Include the validation spec")
flagset.StringVar(&cfg.CrdGroup, "crd-apigroup", monitoringv1.Group, "prometheus CRD API group name")
flagset.StringVar(&cfg.OutputFormat, "output", "yaml", "output format: json|yaml")
flagset.Var(&cfg.CrdKinds, "crd-kinds", "customize CRD kind names")
flagset.StringVar(&cfg.Namespace, "namespace", v1.NamespaceAll, "Namespace to scope the interaction of the Prometheus Operator and the apiserver.")
flagset.Parse(os.Args[1:])
}

View file

@ -71,6 +71,7 @@ type Config struct {
Labels prometheusoperator.Labels
CrdKinds monitoringv1.CrdKinds
CrdGroup string
EnableValidation bool
}
// New creates a new controller.
@ -109,6 +110,7 @@ func New(c prometheusoperator.Config, logger log.Logger) (*Operator, error) {
CrdGroup: c.CrdGroup,
CrdKinds: c.CrdKinds,
Labels: c.Labels,
EnableValidation: c.EnableValidation,
},
}
@ -526,7 +528,7 @@ func (c *Operator) createCRDs() error {
}
crds := []*extensionsobj.CustomResourceDefinition{
k8sutil.NewAlertmanagerCustomResourceDefinition(c.config.CrdKinds.Alertmanager, c.config.CrdGroup, c.config.Labels.LabelsMap),
k8sutil.NewAlertmanagerCustomResourceDefinition(c.config.CrdKinds.Alertmanager, c.config.CrdGroup, c.config.Labels.LabelsMap, c.config.EnableValidation),
}
crdClient := c.crdclient.ApiextensionsV1beta1().CustomResourceDefinitions()

View file

@ -16,13 +16,12 @@ package v1
import (
"fmt"
"strings"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"strings"
)
const (

File diff suppressed because it is too large Load diff

View file

@ -15,13 +15,21 @@
package v1
import (
spec "github.com/go-openapi/spec"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
)
// CustomResourceValidation is a list of validation methods for CustomResources.
type CustomResourceValidation struct {
// OpenAPIV3Schema is the OpenAPI v3 schema to be validated against.
OpenAPIV3Schema *spec.Schema `json:"openAPIV3Schema,omitempty" protobuf:"bytes,1,opt,name=openAPIV3Schema"`
}
// Prometheus defines a Prometheus deployment.
// +k8s:openapi-gen=true
type Prometheus struct {
metav1.TypeMeta `json:",inline"`
// Standard objects metadata. More info:
@ -38,6 +46,7 @@ type Prometheus struct {
}
// PrometheusList is a list of Prometheuses.
// +k8s:openapi-gen=true
type PrometheusList struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata
@ -49,6 +58,7 @@ type PrometheusList struct {
// Specification of the desired behavior of the Prometheus cluster. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
// +k8s:openapi-gen=true
type PrometheusSpec struct {
// Standard objects metadata. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata
@ -128,6 +138,7 @@ type PrometheusSpec struct {
// included when requesting from the apiserver, only from the Prometheus
// Operator API itself. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
// +k8s:openapi-gen=true
type PrometheusStatus struct {
// Represents whether any actions on the underlaying managed objects are
// being performed. Only delete actions will be performed.
@ -146,12 +157,14 @@ type PrometheusStatus struct {
}
// AlertingSpec defines parameters for alerting configuration of Prometheus servers.
// +k8s:openapi-gen=true
type AlertingSpec struct {
// AlertmanagerEndpoints Prometheus should fire alerts against.
Alertmanagers []AlertmanagerEndpoints `json:"alertmanagers"`
}
// StorageSpec defines the configured storage for a group Prometheus servers.
// +k8s:openapi-gen=true
type StorageSpec struct {
// Name of the StorageClass to use when requesting storage provisioning. More
// info: https://kubernetes.io/docs/user-guide/persistent-volumes/#storageclasses
@ -172,6 +185,7 @@ type StorageSpec struct {
}
// RemoteWriteSpec defines the remote_write configuration for prometheus.
// +k8s:openapi-gen=true
type RemoteWriteSpec struct {
//The URL of the endpoint to send samples to.
URL string `json:"url"`
@ -192,6 +206,7 @@ type RemoteWriteSpec struct {
}
// RemoteReadSpec defines the remote_read configuration for prometheus.
// +k8s:openapi-gen=true
type RemoteReadSpec struct {
//The URL of the endpoint to send samples to.
URL string `json:"url"`
@ -210,6 +225,7 @@ type RemoteReadSpec struct {
}
// RelabelConfig allows dynamic rewriting of the label set.
// +k8s:openapi-gen=true
type RelabelConfig struct {
//The source labels select values from existing labels. Their content is concatenated
//using the configured separator and matched against the configured regular expression
@ -233,6 +249,7 @@ type RelabelConfig struct {
// AlertmanagerEndpoints defines a selection of a single Endpoints object
// containing alertmanager IPs to fire alerts against.
// +k8s:openapi-gen=true
type AlertmanagerEndpoints struct {
// Namespace of Endpoints object.
Namespace string `json:"namespace"`
@ -247,6 +264,7 @@ type AlertmanagerEndpoints struct {
}
// ServiceMonitor defines monitoring for a set of services.
// +k8s:openapi-gen=true
type ServiceMonitor struct {
metav1.TypeMeta `json:",inline"`
// Standard objects metadata. More info:
@ -258,6 +276,7 @@ type ServiceMonitor struct {
}
// ServiceMonitorSpec contains specification parameters for a ServiceMonitor.
// +k8s:openapi-gen=true
type ServiceMonitorSpec struct {
// The label to use to retrieve the job name from.
JobLabel string `json:"jobLabel,omitempty"`
@ -270,6 +289,7 @@ type ServiceMonitorSpec struct {
}
// Endpoint defines a scrapeable endpoint serving Prometheus metrics.
// +k8s:openapi-gen=true
type Endpoint struct {
// Name of the service port this endpoint refers to. Mutually exclusive with targetPort.
Port string `json:"port,omitempty"`
@ -300,6 +320,7 @@ type Endpoint struct {
// BasicAuth allow an endpoint to authenticate over basic authentication
// More info: https://prometheus.io/docs/operating/configuration/#endpoints
// +k8s:openapi-gen=true
type BasicAuth struct {
// The secret that contains the username for authenticate
Username v1.SecretKeySelector `json:"username,omitempty"`
@ -308,6 +329,7 @@ type BasicAuth struct {
}
// TLSConfig specifies TLS configuration parameters.
// +k8s:openapi-gen=true
type TLSConfig struct {
// The CA cert to use for the targets.
CAFile string `json:"caFile,omitempty"`
@ -322,6 +344,7 @@ type TLSConfig struct {
}
// A list of ServiceMonitors.
// +k8s:openapi-gen=true
type ServiceMonitorList struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata
@ -332,6 +355,7 @@ type ServiceMonitorList struct {
}
// Describes an Alertmanager cluster.
// +k8s:openapi-gen=true
type Alertmanager struct {
metav1.TypeMeta `json:",inline"`
// Standard objects metadata. More info:
@ -349,6 +373,7 @@ type Alertmanager struct {
// Specification of the desired behavior of the Alertmanager cluster. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
// +k8s:openapi-gen=true
type AlertmanagerSpec struct {
// Standard objects metadata. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata
@ -398,6 +423,7 @@ type AlertmanagerSpec struct {
}
// A list of Alertmanagers.
// +k8s:openapi-gen=true
type AlertmanagerList struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata
@ -411,6 +437,7 @@ type AlertmanagerList struct {
// included when requesting from the apiserver, only from the Prometheus
// Operator API itself. More info:
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
// +k8s:openapi-gen=true
type AlertmanagerStatus struct {
// Represents whether any actions on the underlaying managed objects are
// being performed. Only delete actions will be performed.
@ -430,6 +457,7 @@ type AlertmanagerStatus struct {
// A selector for selecting namespaces either selecting all namespaces or a
// list of namespaces.
// +k8s:openapi-gen=true
type NamespaceSelector struct {
// Boolean describing whether all namespaces are selected in contrast to a
// list restricting them.

View file

@ -0,0 +1,243 @@
// Copyright 2018 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package k8sutil
import (
"fmt"
spec "github.com/go-openapi/spec"
extensionsobj "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
common "k8s.io/kube-openapi/pkg/common"
"strings"
)
func OpenAPIRefCallBack(name string) spec.Ref {
defName := name[strings.LastIndex(name, "/")+1:]
return spec.MustCreateRef("#/definitions/" + common.EscapeJsonPointer(defName))
}
// SchemaPropsToJsonProps converts an array of Schema to an Array of JsonProps
func SchemaPropsToJsonPropsArray(schemas []spec.Schema) []extensionsobj.JSONSchemaProps {
var s []extensionsobj.JSONSchemaProps
for _, schema := range schemas {
s = append(s, *SchemaPropsToJsonProps(&schema))
}
return s
}
func StringOrArrayToString(strOrArray spec.StringOrArray) string {
if len(strOrArray) > 0 {
return strOrArray[0]
}
return ""
}
func EnumJSON(enum []interface{}) []extensionsobj.JSON {
var s []extensionsobj.JSON
for _, elt := range enum {
s = append(s, extensionsobj.JSON{
Raw: []byte(fmt.Sprintf("%v", elt)),
})
}
return s
}
func SchemaOrArrayToJsonItems(schemaOrArray *spec.SchemaOrArray) *extensionsobj.JSONSchemaPropsOrArray {
var array *extensionsobj.JSONSchemaPropsOrArray
if schemaOrArray == nil {
return array
}
return &extensionsobj.JSONSchemaPropsOrArray{
Schema: SchemaPropsToJsonProps(schemaOrArray.Schema),
JSONSchemas: SchemaPropsToJsonPropsArray(schemaOrArray.Schemas),
}
}
func SchemaOrBoolToJsonProps(schemaOrBool *spec.SchemaOrBool) *extensionsobj.JSONSchemaPropsOrBool {
var s *extensionsobj.JSONSchemaPropsOrBool
if schemaOrBool == nil {
return s
}
return &extensionsobj.JSONSchemaPropsOrBool{
Schema: SchemaPropsToJsonProps(schemaOrBool.Schema),
Allows: schemaOrBool.Allows,
}
}
func SchemPropsMapToJsonMap(schemaMap map[string]spec.Schema) map[string]extensionsobj.JSONSchemaProps {
var m map[string]extensionsobj.JSONSchemaProps
m = make(map[string]extensionsobj.JSONSchemaProps)
for key, schema := range schemaMap {
m[key] = *SchemaPropsToJsonProps(&schema)
}
return m
}
// SchemaPropsToJsonProps converts a SchemaProps to a JsonProps
func SchemaPropsToJsonProps(schema *spec.Schema) *extensionsobj.JSONSchemaProps {
var props *extensionsobj.JSONSchemaProps
if schema == nil {
return props
}
schemaProps := &schema.SchemaProps
var ref *string
if schemaProps.Ref.String() != "" {
ref = new(string)
*ref = schemaProps.Ref.String()
}
props = &extensionsobj.JSONSchemaProps{
ID: schema.ID,
Ref: ref,
Schema: extensionsobj.JSONSchemaURL(string(schema.Schema)),
Description: schemaProps.Description,
Type: StringOrArrayToString(schemaProps.Type),
Format: schemaProps.Format,
Title: schemaProps.Title,
Maximum: schemaProps.Maximum,
ExclusiveMaximum: schemaProps.ExclusiveMaximum,
Minimum: schemaProps.Minimum,
ExclusiveMinimum: schemaProps.ExclusiveMinimum,
MaxLength: schemaProps.MaxLength,
MinLength: schemaProps.MinLength,
Pattern: schemaProps.Pattern,
MaxItems: schemaProps.MaxItems,
MinItems: schemaProps.MinItems,
UniqueItems: schemaProps.UniqueItems,
MultipleOf: schemaProps.MultipleOf,
Enum: EnumJSON(schemaProps.Enum),
MaxProperties: schemaProps.MaxProperties,
MinProperties: schemaProps.MinProperties,
Required: schemaProps.Required,
Items: SchemaOrArrayToJsonItems(schemaProps.Items),
AllOf: SchemaPropsToJsonPropsArray(schemaProps.AllOf),
OneOf: SchemaPropsToJsonPropsArray(schemaProps.OneOf),
AnyOf: SchemaPropsToJsonPropsArray(schemaProps.AnyOf),
Not: SchemaPropsToJsonProps(schemaProps.Not),
Properties: SchemPropsMapToJsonMap(schemaProps.Properties),
AdditionalProperties: SchemaOrBoolToJsonProps(schemaProps.AdditionalProperties),
PatternProperties: SchemPropsMapToJsonMap(schemaProps.PatternProperties),
AdditionalItems: SchemaOrBoolToJsonProps(schemaProps.AdditionalItems),
}
return props
}
// Type: ,
// Format:
// Title
// Default
// Maximum
// ExclusiveMaximum
// Minimum
// ExclusiveMinimum
// MaxLength
// MinLength
// Pattern
// MaxItems
// MinItems
// UniqueItems
// MultipleOf
// Enum
// MaxProperties
// MinProperties
// Required
// Items
// AllOf
// OneOf
// AnyOf
// Not
// Properties
// AdditionalProperties
// PatternProperties
// Dependencies
// AdditionalItems
// Definitions
// ExternalDocs
// Example
// }
// return &props
// type JSONSchemaProps struct {
// ID string `json:"id,omitempty" protobuf:"bytes,1,opt,name=id"`
// Schema JSONSchemaURL `json:"$schema,omitempty" protobuf:"bytes,2,opt,name=schema"`
// Ref *string `json:"$ref,omitempty" protobuf:"bytes,3,opt,name=ref"`
// Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"`
// Type string `json:"type,omitempty" protobuf:"bytes,5,opt,name=type"`
// Format string `json:"format,omitempty" protobuf:"bytes,6,opt,name=format"`
// Title string `json:"title,omitempty" protobuf:"bytes,7,opt,name=title"`
// Default *JSON `json:"default,omitempty" protobuf:"bytes,8,opt,name=default"`
// Maximum *float64 `json:"maximum,omitempty" protobuf:"bytes,9,opt,name=maximum"`
// ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty" protobuf:"bytes,10,opt,name=exclusiveMaximum"`
// Minimum *float64 `json:"minimum,omitempty" protobuf:"bytes,11,opt,name=minimum"`
// ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty" protobuf:"bytes,12,opt,name=exclusiveMinimum"`
// MaxLength *int64 `json:"maxLength,omitempty" protobuf:"bytes,13,opt,name=maxLength"`
// MinLength *int64 `json:"minLength,omitempty" protobuf:"bytes,14,opt,name=minLength"`
// Pattern string `json:"pattern,omitempty" protobuf:"bytes,15,opt,name=pattern"`
// MaxItems *int64 `json:"maxItems,omitempty" protobuf:"bytes,16,opt,name=maxItems"`
// MinItems *int64 `json:"minItems,omitempty" protobuf:"bytes,17,opt,name=minItems"`
// UniqueItems bool `json:"uniqueItems,omitempty" protobuf:"bytes,18,opt,name=uniqueItems"`
// MultipleOf *float64 `json:"multipleOf,omitempty" protobuf:"bytes,19,opt,name=multipleOf"`
// Enum []JSON `json:"enum,omitempty" protobuf:"bytes,20,rep,name=enum"`
// MaxProperties *int64 `json:"maxProperties,omitempty" protobuf:"bytes,21,opt,name=maxProperties"`
// MinProperties *int64 `json:"minProperties,omitempty" protobuf:"bytes,22,opt,name=minProperties"`
// Required []string `json:"required,omitempty" protobuf:"bytes,23,rep,name=required"`
// Items *JSONSchemaPropsOrArray `json:"items,omitempty" protobuf:"bytes,24,opt,name=items"`
// AllOf []JSONSchemaProps `json:"allOf,omitempty" protobuf:"bytes,25,rep,name=allOf"`
// OneOf []JSONSchemaProps `json:"oneOf,omitempty" protobuf:"bytes,26,rep,name=oneOf"`
// AnyOf []JSONSchemaProps `json:"anyOf,omitempty" protobuf:"bytes,27,rep,name=anyOf"`
// Not *JSONSchemaProps `json:"not,omitempty" protobuf:"bytes,28,opt,name=not"`
// Properties map[string]JSONSchemaProps `json:"properties,omitempty" protobuf:"bytes,29,rep,name=properties"`
// AdditionalProperties *JSONSchemaPropsOrBool `json:"additionalProperties,omitempty" protobuf:"bytes,30,opt,name=additionalProperties"`
// PatternProperties map[string]JSONSchemaProps `json:"patternProperties,omitempty" protobuf:"bytes,31,rep,name=patternProperties"`
// Dependencies JSONSchemaDependencies `json:"dependencies,omitempty" protobuf:"bytes,32,opt,name=dependencies"`
// AdditionalItems *JSONSchemaPropsOrBool `json:"additionalItems,omitempty" protobuf:"bytes,33,opt,name=additionalItems"`
// Definitions JSONSchemaDefinitions `json:"definitions,omitempty" protobuf:"bytes,34,opt,name=definitions"`
// ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty" protobuf:"bytes,35,opt,name=externalDocs"`
// Example *JSON `json:"example,omitempty" protobuf:"bytes,36,opt,name=example"`
// }
// type SchemaProps struct {
// ID string `json:"id,omitempty"`
// Ref Ref `json:"-"`
// Schema SchemaURL `json:"-"`
// Description string `json:"description,omitempty"`
// Type StringOrArray `json:"type,omitempty"`
// Format string `json:"format,omitempty"`
// Title string `json:"title,omitempty"`
// Default interface{} `json:"default,omitempty"`
// Maximum *float64 `json:"maximum,omitempty"`
// ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
// Minimum *float64 `json:"minimum,omitempty"`
// ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
// MaxLength *int64 `json:"maxLength,omitempty"`
// MinLength *int64 `json:"minLength,omitempty"`
// Pattern string `json:"pattern,omitempty"`
// MaxItems *int64 `json:"maxItems,omitempty"`
// MinItems *int64 `json:"minItems,omitempty"`
// UniqueItems bool `json:"uniqueItems,omitempty"`
// MultipleOf *float64 `json:"multipleOf,omitempty"`
// Enum []interface{} `json:"enum,omitempty"`
// MaxProperties *int64 `json:"maxProperties,omitempty"`
// MinProperties *int64 `json:"minProperties,omitempty"`
// Required []string `json:"required,omitempty"`
// Items *SchemaOrArray `json:"items,omitempty"`
// AllOf []Schema `json:"allOf,omitempty"`
// OneOf []Schema `json:"oneOf,omitempty"`
// AnyOf []Schema `json:"anyOf,omitempty"`
// Not *Schema `json:"not,omitempty"`
// Properties map[string]Schema `json:"properties,omitempty"`
// AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitempty"`
// PatternProperties map[string]Schema `json:"patternProperties,omitempty"`
// Dependencies Dependencies `json:"dependencies,omitempty"`
// AdditionalItems *SchemaOrBool `json:"additionalItems,omitempty"`
// Definitions Definitions `json:"definitions,omitempty"`
// }

View file

@ -0,0 +1,95 @@
// Copyright 2018 The prometheus-operator Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package k8sutil
import (
"encoding/json"
"fmt"
"os"
spec "github.com/go-openapi/spec"
extensionsobj "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
// common "k8s.io/kube-openapi/pkg/common"
//"strings"
"testing"
)
func TestConvertSchematoJsonProp(t *testing.T) {
ref := new(string)
*ref = "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"
schema := spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "Standard objects metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata",
Ref: OpenAPIRefCallBack(*ref),
},
}
expected := extensionsobj.JSONSchemaProps{
Description: "Standard objects metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata",
Ref: ref,
}
props := SchemaPropsToJsonProps(&schema)
if props.Description != expected.Description {
t.Errorf("Description: expected %s, got %s", schema.Description, expected.Description)
}
if *props.Ref != schema.Ref.String() {
t.Errorf("Ref: expected '%s', got '%s'", schema.Ref.String(), *props.Ref)
}
}
func TestConvertFullSchematoJsonProp(t *testing.T) {
schema := spec.Schema{SchemaProps: spec.SchemaProps{
Description: "Describes an Alertmanager cluster.",
Properties: map[string]spec.Schema{
"kind": {
SchemaProps: spec.SchemaProps{
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
Type: []string{"string"},
Format: "",
},
},
"items": {
SchemaProps: spec.SchemaProps{
Description: "List of Alertmanagers",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: OpenAPIRefCallBack("github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.Alertmanager"),
},
},
},
},
},
"metadata": {
SchemaProps: spec.SchemaProps{
Description: "Standard objects metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata",
Ref: OpenAPIRefCallBack("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
},
},
},
},
}
props := SchemaPropsToJsonProps(&schema)
jsonBytes, err := json.MarshalIndent(props, "", " ")
if err != nil {
fmt.Println("error:", err)
}
os.Stdout.Write(jsonBytes)
}

View file

@ -211,8 +211,8 @@ func NewAlertmanagerTPRDefinition() *extensionsobjold.ThirdPartyResource {
}
}
func NewPrometheusCustomResourceDefinition(crdkind monitoringv1.CrdKind, group string, labels map[string]string) *extensionsobj.CustomResourceDefinition {
return &extensionsobj.CustomResourceDefinition{
func NewPrometheusCustomResourceDefinition(crdkind monitoringv1.CrdKind, group string, labels map[string]string, validation bool) *extensionsobj.CustomResourceDefinition {
crd := &extensionsobj.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: crdkind.Plural + "." + group,
Labels: labels,
@ -228,10 +228,22 @@ func NewPrometheusCustomResourceDefinition(crdkind monitoringv1.CrdKind, group s
},
},
}
if validation {
addValidationSpec(crd, "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.Prometheus")
}
return crd
}
func addValidationSpec(crd *extensionsobj.CustomResourceDefinition, specDefinitionName string) {
schema := monitoringv1.GetOpenAPIDefinitions(OpenAPIRefCallBack)[specDefinitionName].Schema
crd.Spec.Validation = &extensionsobj.CustomResourceValidation{
OpenAPIV3Schema: SchemaPropsToJsonProps(&schema),
}
}
func NewServiceMonitorCustomResourceDefinition(crdkind monitoringv1.CrdKind, group string, labels map[string]string) *extensionsobj.CustomResourceDefinition {
return &extensionsobj.CustomResourceDefinition{
func NewServiceMonitorCustomResourceDefinition(crdkind monitoringv1.CrdKind, group string, labels map[string]string, validation bool) *extensionsobj.CustomResourceDefinition {
crd := &extensionsobj.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: crdkind.Plural + "." + group,
Labels: labels,
@ -247,10 +259,16 @@ func NewServiceMonitorCustomResourceDefinition(crdkind monitoringv1.CrdKind, gro
},
},
}
if validation {
addValidationSpec(crd, "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ServiceMonitor")
}
return crd
}
func NewAlertmanagerCustomResourceDefinition(crdkind monitoringv1.CrdKind, group string, labels map[string]string) *extensionsobj.CustomResourceDefinition {
return &extensionsobj.CustomResourceDefinition{
func NewAlertmanagerCustomResourceDefinition(crdkind monitoringv1.CrdKind, group string, labels map[string]string, validation bool) *extensionsobj.CustomResourceDefinition {
crd := &extensionsobj.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: crdkind.Plural + "." + group,
Labels: labels,
@ -266,4 +284,10 @@ func NewAlertmanagerCustomResourceDefinition(crdkind monitoringv1.CrdKind, group
},
},
}
if validation {
addValidationSpec(crd, "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.AlertmanagerSpec")
}
return crd
}

View file

@ -126,6 +126,7 @@ type Config struct {
Labels Labels
CrdGroup string
CrdKinds monitoringv1.CrdKinds
EnableValidation bool
}
type BasicAuthCredentials struct {
@ -1022,8 +1023,8 @@ func (c *Operator) createCRDs() error {
}
crds := []*extensionsobj.CustomResourceDefinition{
k8sutil.NewPrometheusCustomResourceDefinition(c.config.CrdKinds.Prometheus, c.config.CrdGroup, c.config.Labels.LabelsMap),
k8sutil.NewServiceMonitorCustomResourceDefinition(c.config.CrdKinds.ServiceMonitor, c.config.CrdGroup, c.config.Labels.LabelsMap),
k8sutil.NewPrometheusCustomResourceDefinition(c.config.CrdKinds.Prometheus, c.config.CrdGroup, c.config.Labels.LabelsMap, c.config.EnableValidation),
k8sutil.NewServiceMonitorCustomResourceDefinition(c.config.CrdKinds.ServiceMonitor, c.config.CrdGroup, c.config.Labels.LabelsMap, c.config.EnableValidation),
}
crdClient := c.crdclient.ApiextensionsV1beta1().CustomResourceDefinitions()