diff --git a/Makefile b/Makefile index 4732c8998..b7d419c6a 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ check-jq: jq --version > /dev/null .PHONY: docs -docs: $(CRDOC) +docs: $(CRDOC) generate-crds mkdir -p docs $(CRDOC) --resources deploy/crds/common --output docs/api.md diff --git a/bundle/manifests/observability-operator.clusterserviceversion.yaml b/bundle/manifests/observability-operator.clusterserviceversion.yaml index 1a4a4ae16..f721444dc 100644 --- a/bundle/manifests/observability-operator.clusterserviceversion.yaml +++ b/bundle/manifests/observability-operator.clusterserviceversion.yaml @@ -41,8 +41,8 @@ metadata: capabilities: Basic Install categories: Monitoring certified: "false" - containerImage: observability-operator:1.0.0 - createdAt: "2025-03-03T08:38:22Z" + containerImage: grover.home:5000/alanconway/observability-operator:3.3.3 + createdAt: "2025-04-10T17:19:16Z" description: A Go based Kubernetes operator to setup and manage highly available Monitoring Stack using Prometheus, Alertmanager and Thanos Querier. operatorframework.io/cluster-monitoring: "true" @@ -58,7 +58,7 @@ metadata: ] operators.operatorframework.io/project_layout: unknown repository: https://github.com/rhobs/observability-operator - name: observability-operator.v1.0.0 + name: observability-operator.v3.3.3 namespace: placeholder spec: apiservicedefinitions: {} @@ -511,23 +511,33 @@ spec: - apiGroups: - observability.openshift.io resources: - - uiplugins + - signalmanagers verbs: - - create - - delete - get - list - - patch - - update - watch - apiGroups: - observability.openshift.io resources: + - signalmanagers/finalizers + - signalmanagers/status - uiplugins/finalizers - uiplugins/status verbs: - get - update + - apiGroups: + - observability.openshift.io + resources: + - uiplugins + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - operator.openshift.io resources: @@ -917,7 +927,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: observability-operator:1.0.0 + image: grover.home:5000/alanconway/observability-operator:3.3.3 imagePullPolicy: Always livenessProbe: httpGet: @@ -1045,7 +1055,7 @@ spec: maturity: alpha provider: name: Red Hat - version: 1.0.0 + version: 3.3.3 webhookdefinitions: - admissionReviewVersions: - v1 diff --git a/cmd/operator/main.go b/cmd/operator/main.go index d61d8d0b3..aa4884a0f 100644 --- a/cmd/operator/main.go +++ b/cmd/operator/main.go @@ -40,13 +40,13 @@ var defaultImages = map[string]string{ "alertmanager": "", "thanos": obopo.DefaultThanosImage, "ui-dashboards": "quay.io/openshift-observability-ui/console-dashboards-plugin:v0.4.0", - "ui-troubleshooting-panel": "quay.io/openshift-observability-ui/troubleshooting-panel-console-plugin:v0.4.0", + "ui-troubleshooting-panel": "grover.home:5000/alanconway/troubleshooting-panel-console-plugin:latest", "ui-distributed-tracing-pf4": "quay.io/openshift-observability-ui/distributed-tracing-console-plugin:v0.3.0", "ui-distributed-tracing": "quay.io/openshift-observability-ui/distributed-tracing-console-plugin:v0.4.0", "ui-logging-pf4": "quay.io/openshift-observability-ui/logging-view-plugin:v6.0.0", "ui-logging": "quay.io/openshift-observability-ui/logging-view-plugin:v6.1.0", "ui-monitoring": "quay.io/openshift-observability-ui/monitoring-console-plugin:release-coo-1.1", - "korrel8r": "quay.io/korrel8r/korrel8r:0.7.4", + "korrel8r": "grover.home:5000/alanconway/korrel8r:latest", "health-analyzer": "quay.io/openshiftanalytics/cluster-health-analyzer:v0.4.0", "perses": "quay.io/persesdev/perses:v0.50.1", } @@ -95,7 +95,7 @@ func main() { flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&healthProbeAddr, "health-probe-bind-address", ":8081", "The address the health probe endpoint binds to.") flag.Var(images, "images", fmt.Sprintf("Full images refs to use for containers managed by the operator. E.g thanos=quay.io/thanos/thanos:v0.33.0. Images used are %v", imagesUsed())) - flag.BoolVar(&openShiftEnabled, "openshift.enabled", false, "Enable OpenShift specific features such as Console Plugins.") + flag.BoolVar(&openShiftEnabled, "openshift.enabled", true, "Enable OpenShift specific features such as Console Plugins.") opts := zap.Options{ Development: true, diff --git a/deploy/crds/common/observability.openshift.io_configs.yaml b/deploy/crds/common/observability.openshift.io_configs.yaml new file mode 100644 index 000000000..64c5e62d0 --- /dev/null +++ b/deploy/crds/common/observability.openshift.io_configs.yaml @@ -0,0 +1,94 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.2 + name: configs.observability.openshift.io +spec: + group: observability.openshift.io + names: + kind: Config + listKind: ConfigList + plural: configs + singular: config + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + Config defines an observability configuration that can deploy operators and resources for + observability signal collectors and stores. + 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/sig-architecture/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/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ConfigSpec specifies what to install. + properties: + defaultInstall: + description: |- + DefaultInstall is the default install type for signals that are not listed or + are listed without an `install` field. + For example, `{ defaultinstall: Default }` with no `signals` field installs all signal + types with default settings. + type: string + installDefinitions: + items: + description: InstallDefinitionSpec defines a new installation type. + properties: + configMap: + description: |- + ConfigMap contains deployment bundles for the install type, with key=signal type. + FIXME: which way around? install < signal or signal < install + type: string + install: + description: Name of the installation type. + type: string + type: object + type: array + signals: + description: Signals specifies what to install for each signal type. + items: + properties: + installType: + description: Install type for this signal. Optional, if absent + use ..defaultInstall + type: string + namespace: + description: |- + Namespace to install to. Optional, each signal type has a default namespace. + A signal can be listed multiple times with different `namespace` values, + to install in multiple namespaces. + type: string + signal: + description: Name of this signal type. + type: string + required: + - signal + type: object + type: array + type: object + status: + description: FIXME Status + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy/crds/common/observability.openshift.io_signalmanagers.yaml b/deploy/crds/common/observability.openshift.io_signalmanagers.yaml new file mode 100644 index 000000000..b3b05e023 --- /dev/null +++ b/deploy/crds/common/observability.openshift.io_signalmanagers.yaml @@ -0,0 +1,135 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.2 + name: signalmanagers.observability.openshift.io +spec: + group: observability.openshift.io + names: + kind: SignalManager + listKind: SignalManagerList + plural: signalmanagers + singular: signalmanager + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: "SignalManager is a custom resource to enable observability in + the cluster.\n\nEach type of observability signal (logs, metrics, network + events, ...) requires operators to be\ninstalled and resources created to + configure collection, processing, and storage of signal data.\n\nThe SignalManager + automatically installs the operators, custom resource definitions, and\nresources + to enable all the desired observability signals in a cluster with default\nconfigurations.\n\nThis + means you can get observability up and running quickly and easily,\nbut + still customize the details if and when you need to.\n\n## Pattern\n\nA + \"Pattern\" is a named set of configurations for each of the observability + signals.\nChoosing a pattern automatically installs required operators (if + needed) _and_ creates\nworking resources so you have complete, working, + observability stacks.\n\nThe following patterns are always available, others + may be made available.\n\n - Default:\n Installs operators and resources + suitable for the most common use cases.\n The operator owns and manages + the resources, and keeps them in the default state.\n - Custom:\n Installs + operators, but does not create any live resources.\n The user can create + customized resources, they will not be modified by this operator.\n - Disabled: + Do not install any operators, resource definitions, or resources.\n\nCustom + patterns can be defined in `spec.patterns`.\n\n## Examples\n\nEnable all + observability components with default settings.\n\n\tkind: SignalManager\n\tspec:\n\t + \ pattern: Default\n\nDisable all observability components except for logging.\n\n\tkind: + SignalManager\n\tspec:\n\t pattern: Disabled\n\t signals:\n\t name: + Log\n\t pattern: Default\n\nEnable most components with defaults, install + the logging operators,\nbut use custom logging resources (created separately)\n\n\tkind: + SignalManager\n\tspec:\n\t pattern: Default\n\t signals:\n\t name: + log\n\t pattern: Custom\n\n## Lifecycle and ownership\n\nOwnership of + resources depends on the pattern:\n\n - None: No operators installed, no + resources created or reconciled.\n - Custom: Operators installed but no + resources created. User is free to create resources\n they are not owned + or reconciled by this operator.\n - Default, or any other defined configuration:\n + \ This operator creates, owns, and reconciles resources to keep them consistent + with the chosen\n pattern.\n\nFIXME: Operator may reconcile only part + of the resource and allow user to tweak other parts.\nNeeds consideration. + COO already uses server-side-apply to do this in some cases.\n\nFIXME: Patterns + may need to be \"parameterized\" e.g. with sizing data.\nHow to include + such parameters without duplicating existing CRs?\n\nFIXME: Define behavior + on spec changes: deleting, re-creating, updating resources.\nChange to Custom + should leave resources in place so user can eddit.\nWhat to do on change + _from_ Custom?" + 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/sig-architecture/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/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Lists signals and the pattern to deploy them. + properties: + pattern: + description: The default pattern for signals that are not listed or + have no `pattern` field. + type: string + patterns: + description: Patterns is a list of custom pattern definitions. + items: + description: |- + PatternSpec defines a custom pattern. + + on the cluster. Simplest format is a flat YAML file, but we may need more structure + to store kustomize scripts, multi-stage deployments, health checks, metadata etc.... + Possible storage formats: ConfigMap, PersistentVolume, container image... + + Patterns should also be usable directly, without depending on this API. + Preferably using only kubectl and kustomize. + properties: + pattern: + description: Name of the pattern. + type: string + required: + - pattern + type: object + type: array + signals: + description: Signals is a list of signal types with the desired pattern. + items: + properties: + name: + description: Signal name + type: string + namespace: + description: |- + Namespace to install to. + + Optional, each signal type has a default namespace. + type: string + pattern: + description: Pattern for this signal. Optional, if absent use + the 'Default' pattern. + type: string + required: + - name + type: object + type: array + required: + - pattern + type: object + status: + description: Status of the signal manager. + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy/olm/kustomization.yaml b/deploy/olm/kustomization.yaml index ba0c104fb..994541ea6 100644 --- a/deploy/olm/kustomization.yaml +++ b/deploy/olm/kustomization.yaml @@ -12,8 +12,8 @@ resources: images: - name: observability-operator - newName: observability-operator - newTag: 1.0.0 + newName: grover.home:5000/alanconway/observability-operator + newTag: 3.3.3 patches: - patch: |- diff --git a/deploy/operator/observability-operator-cluster-role.yaml b/deploy/operator/observability-operator-cluster-role.yaml index 6b0b82ca1..ef9d305d4 100644 --- a/deploy/operator/observability-operator-cluster-role.yaml +++ b/deploy/operator/observability-operator-cluster-role.yaml @@ -226,23 +226,33 @@ rules: - apiGroups: - observability.openshift.io resources: - - uiplugins + - signalmanagers verbs: - - create - - delete - get - list - - patch - - update - watch - apiGroups: - observability.openshift.io resources: + - signalmanagers/finalizers + - signalmanagers/status - uiplugins/finalizers - uiplugins/status verbs: - get - update +- apiGroups: + - observability.openshift.io + resources: + - uiplugins + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - operator.openshift.io resources: diff --git a/deploy/package-operator/operator/kustomization.yaml b/deploy/package-operator/operator/kustomization.yaml index cebb4fc32..68c43937e 100644 --- a/deploy/package-operator/operator/kustomization.yaml +++ b/deploy/package-operator/operator/kustomization.yaml @@ -3,8 +3,8 @@ kind: Kustomization namespace: observability-operator images: - name: observability-operator - newName: observability-operator - newTag: 1.0.0 + newName: grover.home:5000/alanconway/observability-operator + newTag: 3.3.3 commonAnnotations: package-operator.run/phase: operator resources: diff --git a/docs/api.md b/docs/api.md index 37e47a052..35836e01c 100644 --- a/docs/api.md +++ b/docs/api.md @@ -3984,11 +3984,438 @@ Reference to the TLS private key for the web server. Resource Types: +- [Config](#config) + +- [SignalManager](#signalmanager) + - [UIPlugin](#uiplugin) +## Config +[↩ Parent](#observabilityopenshiftiov1alpha1 ) + + + + + + +Config defines an observability configuration that can deploy operators and resources for +observability signal collectors and stores. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
apiVersionstringobservability.openshift.io/v1alpha1true
kindstringConfigtrue
metadataobjectRefer to the Kubernetes API documentation for the fields of the `metadata` field.true
specobject + ConfigSpec specifies what to install.
+
false
statusobject + FIXME Status
+
false
+ + +### Config.spec +[↩ Parent](#config) + + + +ConfigSpec specifies what to install. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
defaultInstallstring + DefaultInstall is the default install type for signals that are not listed or +are listed without an `install` field. +For example, `{ defaultinstall: Default }` with no `signals` field installs all signal +types with default settings.
+
false
installDefinitions[]object +
+
false
signals[]object + Signals specifies what to install for each signal type.
+
false
+ + +### Config.spec.installDefinitions[index] +[↩ Parent](#configspec) + + + +InstallDefinitionSpec defines a new installation type. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
configMapstring + ConfigMap contains deployment bundles for the install type, with key=signal type. +FIXME: which way around? install < signal or signal < install
+
false
installstring + Name of the installation type.
+
false
+ + +### Config.spec.signals[index] +[↩ Parent](#configspec) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
signalstring + Name of this signal type.
+
true
installTypestring + Install type for this signal. Optional, if absent use ..defaultInstall
+
false
namespacestring + Namespace to install to. Optional, each signal type has a default namespace. +A signal can be listed multiple times with different `namespace` values, +to install in multiple namespaces.
+
false
+ +## SignalManager +[↩ Parent](#observabilityopenshiftiov1alpha1 ) + + + + + + +SignalManager is a custom resource to enable observability in the cluster. + +Each type of observability signal (logs, metrics, network events, ...) requires operators to be +installed and resources created to configure collection, processing, and storage of signal data. + +The SignalManager automatically installs the operators, custom resource definitions, and +resources to enable all the desired observability signals in a cluster with default +configurations. + +This means you can get observability up and running quickly and easily, +but still customize the details if and when you need to. + +## Pattern + +A "Pattern" is a named set of configurations for each of the observability signals. +Choosing a pattern automatically installs required operators (if needed) _and_ creates +working resources so you have complete, working, observability stacks. + +The following patterns are always available, others may be made available. + + - Default: + Installs operators and resources suitable for the most common use cases. + The operator owns and manages the resources, and keeps them in the default state. + - Custom: + Installs operators, but does not create any live resources. + The user can create customized resources, they will not be modified by this operator. + - Disabled: Do not install any operators, resource definitions, or resources. + +Custom patterns can be defined in `spec.patterns`. + +## Examples + +Enable all observability components with default settings. + + kind: SignalManager + spec: + pattern: Default + +Disable all observability components except for logging. + + kind: SignalManager + spec: + pattern: Disabled + signals: + name: Log + pattern: Default + +Enable most components with defaults, install the logging operators, +but use custom logging resources (created separately) + + kind: SignalManager + spec: + pattern: Default + signals: + name: log + pattern: Custom + +## Lifecycle and ownership + +Ownership of resources depends on the pattern: + + - None: No operators installed, no resources created or reconciled. + - Custom: Operators installed but no resources created. User is free to create resources + they are not owned or reconciled by this operator. + - Default, or any other defined configuration: + This operator creates, owns, and reconciles resources to keep them consistent with the chosen + pattern. + +FIXME: Operator may reconcile only part of the resource and allow user to tweak other parts. +Needs consideration. COO already uses server-side-apply to do this in some cases. + +FIXME: Patterns may need to be "parameterized" e.g. with sizing data. +How to include such parameters without duplicating existing CRs? + +FIXME: Define behavior on spec changes: deleting, re-creating, updating resources. +Change to Custom should leave resources in place so user can eddit. +What to do on change _from_ Custom? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
apiVersionstringobservability.openshift.io/v1alpha1true
kindstringSignalManagertrue
metadataobjectRefer to the Kubernetes API documentation for the fields of the `metadata` field.true
specobject + Lists signals and the pattern to deploy them.
+
false
statusobject + Status of the signal manager.
+
false
+ + +### SignalManager.spec +[↩ Parent](#signalmanager) + + + +Lists signals and the pattern to deploy them. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
patternstring + The default pattern for signals that are not listed or have no `pattern` field.
+
true
patterns[]object + Patterns is a list of custom pattern definitions.
+
false
signals[]object + Signals is a list of signal types with the desired pattern.
+
false
+ + +### SignalManager.spec.patterns[index] +[↩ Parent](#signalmanagerspec) + + + +PatternSpec defines a custom pattern. + +on the cluster. Simplest format is a flat YAML file, but we may need more structure +to store kustomize scripts, multi-stage deployments, health checks, metadata etc.... +Possible storage formats: ConfigMap, PersistentVolume, container image... + +Patterns should also be usable directly, without depending on this API. +Preferably using only kubectl and kustomize. + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
patternstring + Name of the pattern.
+
true
+ + +### SignalManager.spec.signals[index] +[↩ Parent](#signalmanagerspec) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
namestring + Signal name
+
true
namespacestring + Namespace to install to. + +Optional, each signal type has a default namespace.
+
false
patternstring + Pattern for this signal. Optional, if absent use the 'Default' pattern.
+
false
+ ## UIPlugin [↩ Parent](#observabilityopenshiftiov1alpha1 ) diff --git a/pkg/apis/signal_manager/v1alpha1/#zz_generated.deepcopy.go# b/pkg/apis/signal_manager/v1alpha1/#zz_generated.deepcopy.go# new file mode 100644 index 000000000..7ea43fb61 --- /dev/null +++ b/pkg/apis/signal_manager/v1alpha1/#zz_generated.deepcopy.go# @@ -0,0 +1,146 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2021. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StrategySpec) DeepCopyInto(out *StrategySpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstallDefinitionSpec. +func (in *StrategySpec) DeepCopy() *StrategySpec { + if in == nil { + return nil + } + out := new(StrategySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalManager) DeepCopyInto(out *SignalManager) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalManager. +func (in *SignalManager) DeepCopy() *SignalManager { + if in == nil { + return nil + } + out := new(SignalManager) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalManagerList) DeepCopyInto(out *SignalManagerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SignalManager, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalManagerList. +func (in *SignalManagerList) DeepCopy() *SignalManagerList { + if in == nil { + return nil + } + out := new(SignalManagerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SignalManagerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalManagerSpec) DeepCopyInto(out *SignalManagerSpec) { + *out = *in + if in.Signals != nil { + in, out := &in.Signals, &out.Signals + *out = make([]SignalSpec, len(*in)) + copy(*out, *in) + } + if in.InstallDefinitions != nil { + in, out := &in.InstallDefinitions, &out.InstallDefinitions + *out = make([]StrategySpec, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalManagerSpec. +func (in *SignalManagerSpec) DeepCopy() *SignalManagerSpec { + if in == nil { + return nil + } + out := new(SignalManagerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalManagerStatus) DeepCopyInto(out *SignalManagerStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalManagerStatus. +func (in *SignalManagerStatus) DeepCopy() *SignalManagerStatus { + if in == nil { + return nil + } + out := new(SignalManagerStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalSpec) DeepCopyInto(out *SignalSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalSpec. +func (in *SignalSpec) DeepCopy() *SignalSpec { + if in == nil { + return nil + } + out := new(SignalSpec) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/signal_manager/v1alpha1/register.go b/pkg/apis/signal_manager/v1alpha1/register.go new file mode 100644 index 000000000..116f9d39c --- /dev/null +++ b/pkg/apis/signal_manager/v1alpha1/register.go @@ -0,0 +1,40 @@ +/* +Copyright 2021. + +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 v1alpha1 contains API Schema definitions for the config APIs. +// +kubebuilder:object:generate=true +// +groupName=observability.openshift.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "observability.openshift.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) + +func init() { + SchemeBuilder.Register(&SignalManager{}, &SignalManagerList{}) +} diff --git a/pkg/apis/signal_manager/v1alpha1/types.go b/pkg/apis/signal_manager/v1alpha1/types.go new file mode 100644 index 000000000..f58347e09 --- /dev/null +++ b/pkg/apis/signal_manager/v1alpha1/types.go @@ -0,0 +1,185 @@ +// +groupName=observability.openshift.io +// +kubebuilder:rbac:groups=observability.openshift.io,resources=signalmanagers,verbs=list;get;watch +// +kubebuilder:rbac:groups=observability.openshift.io,resources=signalmanagers/status;signalmanagers/finalizers,verbs=get;update +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// FIXME review naming: SignalManager, Pattern +// FIXME: review cluster scope, validation + +// SignalManager is a custom resource to enable observability in the cluster. +// +// Each type of observability signal (logs, metrics, network events, ...) requires operators to be +// installed and resources created to configure collection, processing, and storage of signal data. +// +// The SignalManager automatically installs the operators, custom resource definitions, and +// resources to enable all the desired observability signals in a cluster with default +// configurations. +// +// This means you can get observability up and running quickly and easily, +// but still customize the details if and when you need to. +// +// ## Pattern +// +// A "Pattern" is a named set of configurations for each of the observability signals. +// Choosing a pattern automatically installs required operators (if needed) _and_ creates +// working resources so you have complete, working, observability stacks. +// +// The following patterns are always available, others may be made available. +// +// - Default: +// Installs operators and resources suitable for the most common use cases. +// The operator owns and manages the resources, and keeps them in the default state. +// - Custom: +// Installs operators, but does not create any live resources. +// The user can create customized resources, they will not be modified by this operator. +// - Disabled: Do not install any operators, resource definitions, or resources. +// +// Custom patterns can be defined in `spec.patterns`. +// +// ## Examples +// +// Enable all observability components with default settings. +// +// kind: SignalManager +// spec: +// pattern: Default +// +// Disable all observability components except for logging. +// +// kind: SignalManager +// spec: +// pattern: Disabled +// signals: +// name: Log +// pattern: Default +// +// Enable most components with defaults, install the logging operators, +// but use custom logging resources (created separately) +// +// kind: SignalManager +// spec: +// pattern: Default +// signals: +// name: log +// pattern: Custom +// +// ## Lifecycle and ownership +// +// Ownership of resources depends on the pattern: +// +// - None: No operators installed, no resources created or reconciled. +// - Custom: Operators installed but no resources created. User is free to create resources +// they are not owned or reconciled by this operator. +// - Default, or any other defined configuration: +// This operator creates, owns, and reconciles resources to keep them consistent with the chosen +// pattern. +// +// FIXME: Operator may reconcile only part of the resource and allow user to tweak other parts. +// Needs consideration. COO already uses server-side-apply to do this in some cases. +// +// FIXME: Patterns may need to be "parameterized" e.g. with sizing data. +// How to include such parameters without duplicating existing CRs? +// +// FIXME: Define behavior on spec changes: deleting, re-creating, updating resources. +// Change to Custom should leave resources in place so user can eddit. +// What to do on change _from_ Custom? +// +// +k8s:openapi-gen=true +// +kubebuilder:resource:scope=Cluster +// +kubebuilder:subresource:status +type SignalManager struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Lists signals and the pattern to deploy them. + Spec SignalManagerSpec `json:"spec,omitempty"` + + // Status of the signal manager. + Status SignalManagerStatus `json:"status,omitempty"` +} + +// +kubebuilder:resource +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type SignalManagerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []SignalManager `json:"items"` +} + +type SignalManagerSpec struct { + + // The default pattern for signals that are not listed or have no `pattern` field. + Pattern Pattern `json:"pattern"` + + // Signals is a list of signal types with the desired pattern. + Signals []SignalSpec `json:"signals,omitempty"` + + // Patterns is a list of custom pattern definitions. + Patterns []PatternSpec `json:"patterns,omitempty"` +} + +type SignalSpec struct { + // Signal name + Name Signal `json:"name"` + + // Pattern for this signal. Optional, if absent use the 'Default' pattern. + Pattern Pattern `json:"pattern,omitempty"` + + // Namespace to install to. + // + // Optional, each signal type has a default namespace. + Namespace string `json:"namespace,omitempty"` +} + +// Signal is the name of a signal type. +// TODO complete the list +type Signal string + +const ( + SignalLog Signal = "Log" + SignalTrace = "Trace" + SignalMetric = "Metric" + SignalNetflow = "Netflow" +) + +// Pattern is the name of a deployment pattern. The following patterns are always available: +// - Default: Install operators and custom resources to enable the signal with a default configuration +// intended to be suitable for most single-cluster use cases. +// The operator owns and manages the resources, and keeps them in the default state. +// - Custom: Install operators and custom resource definitions, but do not create any resources. +// The user can create customized resources, they will not be managed or modified by this operator. +// - Disabled: Do not install operators, resource definitions, or resources. +// +// Custom patterns can also be defined in spec.patterns. +// The operator owns and manages the resources, and keeps them in the state specified by the pattern. +type Pattern string + +const ( + PatternDefault = "Default" + PatternCustom = "Custom" + PatternDisabled Pattern = "Disabled" +) + +// PatternSpec defines a custom pattern. +// +// TODO a pattern is a bundle of YAML resources. Need to define how they are stored +// on the cluster. Simplest format is a flat YAML file, but we may need more structure +// to store kustomize scripts, multi-stage deployments, health checks, metadata etc.... +// Possible storage formats: ConfigMap, PersistentVolume, container image... +// +// Patterns should also be usable directly, without depending on this API. +// Preferably using only kubectl and kustomize. +type PatternSpec struct { + // Name of the pattern. + Name Pattern `json:"pattern"` +} + +// SignalManagerStatus TODO +// - Conditions to track status of each pattern - pull condition info from signal operators? +type SignalManagerStatus struct{} diff --git a/pkg/apis/signal_manager/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/signal_manager/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..193467846 --- /dev/null +++ b/pkg/apis/signal_manager/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,146 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2021. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalManager) DeepCopyInto(out *SignalManager) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalManager. +func (in *SignalManager) DeepCopy() *SignalManager { + if in == nil { + return nil + } + out := new(SignalManager) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalManagerList) DeepCopyInto(out *SignalManagerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SignalManager, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalManagerList. +func (in *SignalManagerList) DeepCopy() *SignalManagerList { + if in == nil { + return nil + } + out := new(SignalManagerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SignalManagerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalManagerSpec) DeepCopyInto(out *SignalManagerSpec) { + *out = *in + if in.Signals != nil { + in, out := &in.Signals, &out.Signals + *out = make([]SignalSpec, len(*in)) + copy(*out, *in) + } + if in.Strategies != nil { + in, out := &in.Strategies, &out.Strategies + *out = make([]StrategySpec, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalManagerSpec. +func (in *SignalManagerSpec) DeepCopy() *SignalManagerSpec { + if in == nil { + return nil + } + out := new(SignalManagerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalManagerStatus) DeepCopyInto(out *SignalManagerStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalManagerStatus. +func (in *SignalManagerStatus) DeepCopy() *SignalManagerStatus { + if in == nil { + return nil + } + out := new(SignalManagerStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SignalSpec) DeepCopyInto(out *SignalSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignalSpec. +func (in *SignalSpec) DeepCopy() *SignalSpec { + if in == nil { + return nil + } + out := new(SignalSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StrategySpec) DeepCopyInto(out *StrategySpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StrategySpec. +func (in *StrategySpec) DeepCopy() *StrategySpec { + if in == nil { + return nil + } + out := new(StrategySpec) + in.DeepCopyInto(out) + return out +}