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

Factorize the NewCustomCRD function

This commit is contained in:
Antoine Legrand 2018-01-30 14:51:34 +01:00
parent dbf258e773
commit 9d7d753a55
9 changed files with 3638 additions and 164 deletions
cmd/po-crdgen
example/prometheus-operator-crd
pkg
alertmanager
client/monitoring/v1
k8sutil
prometheus

View file

@ -1,67 +0,0 @@
// 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 (
"encoding/json"
"fmt"
monitoringv1 "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1"
k8sutil "github.com/coreos/prometheus-operator/pkg/k8sutil"
prometheus "github.com/coreos/prometheus-operator/pkg/prometheus"
"github.com/ghodss/yaml"
extensionsobj "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"os"
)
// 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, outputFormat string) {
jsonBytes, err := json.MarshalIndent(crd, "", " ")
if err != nil {
fmt.Println("error:", err)
}
if outputFormat == "json" {
os.Stdout.Write(jsonBytes)
} else {
yamlBytes, err := yaml.JSONToYAML(jsonBytes)
if err != nil {
fmt.Println("error:", err)
}
os.Stdout.Write([]byte("---\n"))
os.Stdout.Write(yamlBytes)
}
}
// 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, 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, conf.OutputFormat)
marshallCrd(serviceMonitorCrd, conf.OutputFormat)
marshallCrd(alertManagerCrd, conf.OutputFormat)
}

View file

@ -16,27 +16,59 @@ package main
import (
"flag"
"fmt"
crdutils "github.com/ant31/crd-validation/pkg"
monitoringv1 "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1"
k8sutil "github.com/coreos/prometheus-operator/pkg/k8sutil"
extensionsobj "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"os"
)
var (
cfg Config
cfg crdutils.Config
)
func init() {
cfg.CrdKinds = monitoringv1.DefaultCrdKinds
flagset := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
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")
func initFlags(crdkind monitoringv1.CrdKind, flagset *flag.FlagSet) *flag.FlagSet {
flagset.Var(&cfg.Labels, "labels", "Labels")
flagset.Var(&cfg.Annotations, "annotations", "Annotations")
flagset.BoolVar(&cfg.EnableValidation, "with-validation", true, "Add CRD validation field, default: true")
flagset.StringVar(&cfg.Group, "apigroup", monitoringv1.Group, "CRD api group")
flagset.StringVar(&cfg.SpecDefinitionName, "spec-name", crdkind.SpecName, "CRD spec definition name")
flagset.StringVar(&cfg.OutputFormat, "output", "yaml", "output format: json|yaml")
flagset.Var(&cfg.CrdKinds, "crd-kinds", "customize CRD kind names")
flagset.Parse(os.Args[1:])
flagset.StringVar(&cfg.Kind, "kind", crdkind.Kind, "CRD Kind")
flagset.StringVar(&cfg.ResourceScope, "scope", string(extensionsobj.NamespaceScoped), "CRD scope: 'Namespaced' | 'Cluster'. Default: Namespaced")
flagset.StringVar(&cfg.Version, "version", monitoringv1.Version, "CRD version, default: 'v1'")
flagset.StringVar(&cfg.Plural, "plural", crdkind.Plural, "CRD plural name")
return flagset
}
func init() {
var command *flag.FlagSet
if len(os.Args) == 1 {
fmt.Println("usage: po-crdgen [prometheus | alertmanager | servicemonitor] [<options>]")
os.Exit(1)
}
switch os.Args[1] {
case "prometheus":
command = initFlags(monitoringv1.DefaultCrdKinds.Prometheus, flag.NewFlagSet("prometheus", flag.ExitOnError))
case "servicemonitor":
command = initFlags(monitoringv1.DefaultCrdKinds.ServiceMonitor, flag.NewFlagSet("servicemonitor", flag.ExitOnError))
case "alertmanager":
command = initFlags(monitoringv1.DefaultCrdKinds.Alertmanager, flag.NewFlagSet("alertmanager", flag.ExitOnError))
default:
fmt.Printf("%q is not valid command.\n choices: [prometheus, alertmanager, servicemonitor]", os.Args[1])
os.Exit(2)
}
command.Parse(os.Args[2:])
}
func main() {
PrintCrd(cfg)
crd := k8sutil.NewCustomResourceDefinition(
monitoringv1.CrdKind{Plural: cfg.Plural,
Kind: cfg.Kind,
SpecName: cfg.SpecDefinitionName},
cfg.Group, cfg.Labels.LabelsMap, cfg.EnableValidation)
crdutils.MarshallCrd(crd, cfg.OutputFormat)
os.Exit(0)
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,232 @@
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
name: servicemonitors.monitoring.coreos.com
spec:
group: monitoring.coreos.com
names:
kind: ServiceMonitor
plural: servicemonitors
scope: Namespaced
validation:
openAPIV3Schema:
description: ServiceMonitor defines monitoring for a set of services.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
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
spec:
description: ServiceMonitorSpec contains specification parameters for a
ServiceMonitor.
properties:
endpoints:
description: A list of endpoints allowed as part of this ServiceMonitor.
items:
description: Endpoint defines a scrapeable endpoint serving Prometheus
metrics.
properties:
basicAuth:
description: 'BasicAuth allow an endpoint to authenticate over
basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints'
properties:
password:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
optional:
description: Specify whether the Secret or it's key must
be defined
type: boolean
required:
- key
username:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
optional:
description: Specify whether the Secret or it's key must
be defined
type: boolean
required:
- key
bearerTokenFile:
description: File to read bearer token for scraping targets.
type: string
honorLabels:
description: HonorLabels chooses the metric's labels on collisions
with target labels.
type: boolean
interval:
description: Interval at which metrics should be scraped
type: string
metricRelabelings:
description: MetricRelabelConfigs to apply to samples before ingestion.
items:
description: RelabelConfig allows dynamic rewriting of the label
set.
properties:
action:
description: Action to perform based on regex matching.
Default is 'replace'
type: string
modulus:
description: Modulus to take of the hash of the source label
values.
format: int64
type: integer
regex:
description: Regular expression against which the extracted
value is matched. defailt is '(.*)'
type: string
replacement:
description: Replacement value against which a regex replace
is performed if the regular expression matches. Regex
capture groups are available. Default is '$1'
type: string
separator:
description: Separator placed between concatenated source
label values. default is ';'.
type: string
sourceLabels:
description: The source labels select values from existing
labels. Their content is concatenated using the configured
separator and matched against the configured regular expression
for the replace, keep, and drop actions.
items:
type: string
type: array
targetLabel:
description: Label to which the resulting value is written
in a replace action. It is mandatory for replace actions.
Regex capture groups are available.
type: string
required:
- sourceLabels
- replacement
type: array
params:
description: Optional HTTP URL parameters
type: object
path:
description: HTTP path to scrape for metrics.
type: string
port:
description: Name of the service port this endpoint refers to.
Mutually exclusive with targetPort.
type: string
scheme:
description: HTTP scheme to use for scraping.
type: string
scrapeTimeout:
description: Timeout after which the scrape is ended
type: string
targetPort: {}
tlsConfig:
description: TLSConfig specifies TLS configuration parameters.
properties:
caFile:
description: The CA cert to use for the targets.
type: string
certFile:
description: The client cert file for the targets.
type: string
insecureSkipVerify:
description: Disable target certificate validation.
type: boolean
keyFile:
description: The client key file for the targets.
type: string
serverName:
description: Used to verify the hostname for the targets.
type: string
type: array
jobLabel:
description: The label to use to retrieve the job name from.
type: string
namespaceSelector:
description: A selector for selecting namespaces either selecting all
namespaces or a list of namespaces.
properties:
any:
description: Boolean describing whether all namespaces are selected
in contrast to a list restricting them.
type: boolean
matchNames:
description: List of namespace names.
items:
type: string
type: array
selector:
description: A label selector is a label query over a set of resources.
The result of matchLabels and matchExpressions are ANDed. An empty
label selector matches all objects. A null label selector matches
no objects.
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: A label selector requirement is a selector that contains
values, a key, and an operator that relates the key and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: operator represents a key's relationship to a
set of values. Valid operators are In, NotIn, Exists and
DoesNotExist.
type: string
values:
description: values is an array of string values. If the operator
is In or NotIn, the values array must be non-empty. If the
operator is Exists or DoesNotExist, the values array must
be empty. This array is replaced during a strategic merge
patch.
items:
type: string
type: array
required:
- key
- operator
type: array
matchLabels:
description: matchLabels is a map of {key,value} pairs. A single
{key,value} in the matchLabels map is equivalent to an element
of matchExpressions, whose key field is "key", the operator is
"In", and the values array contains only "value". The requirements
are ANDed.
type: object
required:
- endpoints
- selector
required:
- spec
version: v1
status:
acceptedNames:
kind: ""
plural: ""
conditions: null

View file

@ -528,7 +528,7 @@ func (c *Operator) createCRDs() error {
}
crds := []*extensionsobj.CustomResourceDefinition{
k8sutil.NewAlertmanagerCustomResourceDefinition(c.config.CrdKinds.Alertmanager, c.config.CrdGroup, c.config.Labels.LabelsMap, c.config.EnableValidation),
k8sutil.NewCustomResourceDefinition(c.config.CrdKinds.Alertmanager, c.config.CrdGroup, c.config.Labels.LabelsMap, c.config.EnableValidation),
}
crdClient := c.crdclient.ApiextensionsV1beta1().CustomResourceDefinitions()

View file

@ -32,8 +32,9 @@ const (
)
type CrdKind struct {
Kind string
Plural string
Kind string
Plural string
SpecName string
}
type CrdKinds struct {
@ -45,9 +46,9 @@ type CrdKinds struct {
var DefaultCrdKinds CrdKinds = CrdKinds{
KindsString: "",
Prometheus: CrdKind{Plural: PrometheusName, Kind: PrometheusesKind},
ServiceMonitor: CrdKind{Plural: ServiceMonitorName, Kind: ServiceMonitorsKind},
Alertmanager: CrdKind{Plural: AlertmanagerName, Kind: AlertmanagersKind},
Prometheus: CrdKind{Plural: PrometheusName, Kind: PrometheusesKind, SpecName: "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.Prometheus"},
ServiceMonitor: CrdKind{Plural: ServiceMonitorName, Kind: ServiceMonitorsKind, SpecName: "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.ServiceMonitor"},
Alertmanager: CrdKind{Plural: AlertmanagerName, Kind: AlertmanagersKind, SpecName: "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.Alertmanager"},
}
// Implement the flag.Value interface

View file

@ -212,82 +212,16 @@ func NewAlertmanagerTPRDefinition() *extensionsobjold.ThirdPartyResource {
}
}
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,
},
TypeMeta: CustomResourceDefinitionTypeMeta,
Spec: extensionsobj.CustomResourceDefinitionSpec{
Group: group,
Version: monitoringv1.Version,
Scope: extensionsobj.NamespaceScoped,
Names: extensionsobj.CustomResourceDefinitionNames{
Plural: crdkind.Plural,
Kind: crdkind.Kind,
},
},
}
if validation {
addValidationSpec(crd, "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.Prometheus")
}
return crd
}
func addValidationSpec(crd *extensionsobj.CustomResourceDefinition, specDefinitionName string) {
crd.Spec.Validation = crdutils.GetCustomResourceValidation(specDefinitionName, monitoringv1.GetOpenAPIDefinitions)
}
// NewServiceMonitorCustomResourceDefinition creates the ServiceMonitor CRD API resource
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,
},
TypeMeta: CustomResourceDefinitionTypeMeta,
Spec: extensionsobj.CustomResourceDefinitionSpec{
Group: group,
Version: monitoringv1.Version,
Scope: extensionsobj.NamespaceScoped,
Names: extensionsobj.CustomResourceDefinitionNames{
Plural: crdkind.Plural,
Kind: crdkind.Kind,
},
},
}
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, validation bool) *extensionsobj.CustomResourceDefinition {
crd := &extensionsobj.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: crdkind.Plural + "." + group,
Labels: labels,
},
TypeMeta: CustomResourceDefinitionTypeMeta,
Spec: extensionsobj.CustomResourceDefinitionSpec{
Group: group,
Version: monitoringv1.Version,
Scope: extensionsobj.NamespaceScoped,
Names: extensionsobj.CustomResourceDefinitionNames{
Plural: crdkind.Plural,
Kind: crdkind.Kind,
},
},
}
if validation {
addValidationSpec(crd, "github.com/coreos/prometheus-operator/pkg/client/monitoring/v1.AlertmanagerSpec")
}
return crd
func NewCustomResourceDefinition(crdKind monitoringv1.CrdKind, group string, labels map[string]string, validation bool) *extensionsobj.CustomResourceDefinition {
return crdutils.NewCustomResourceDefinition(crdutils.Config{
SpecDefinitionName: crdKind.SpecName,
EnableValidation: validation,
Labels: crdutils.Labels{LabelsMap: labels},
ResourceScope: string(extensionsobj.NamespaceScoped),
Group: group,
Kind: crdKind.Kind,
Version: monitoringv1.Version,
Plural: crdKind.Plural,
GetOpenAPIDefinitions: monitoringv1.GetOpenAPIDefinitions,
})
}

View file

@ -1023,8 +1023,8 @@ func (c *Operator) createCRDs() error {
}
crds := []*extensionsobj.CustomResourceDefinition{
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),
k8sutil.NewCustomResourceDefinition(c.config.CrdKinds.Prometheus, c.config.CrdGroup, c.config.Labels.LabelsMap, c.config.EnableValidation),
k8sutil.NewCustomResourceDefinition(c.config.CrdKinds.ServiceMonitor, c.config.CrdGroup, c.config.Labels.LabelsMap, c.config.EnableValidation),
}
crdClient := c.crdclient.ApiextensionsV1beta1().CustomResourceDefinitions()