From fc3b82569a63ff59af9037fedb7ba3b7b04587bb Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 10 Oct 2022 14:12:34 +0300
Subject: [PATCH 001/316] added vector agregator statefuulset
---
api/v1alpha1/vector_types.go | 13 +-
.../observability.kaasops.io_vectors.yaml | 12 ++
.../observability_v1alpha1_vector.yaml | 9 +-
.../observability_v1alpha1_vector_agent.yaml | 8 --
controllers/utils.go | 29 ++++
controllers/vector_agent_controller.go | 4 +-
controllers/vector_agent_daemonset.go | 4 +-
controllers/vector_agent_secret.go | 19 +--
controllers/vector_aggregator_controller.go | 131 ++++++++++++++++++
controllers/vector_aggregator_rbac.go | 17 +++
controllers/vector_aggregator_secret.go | 40 ++++++
controllers/vector_aggregator_service.go | 28 ++++
controllers/vector_aggregator_statefulset.go | 119 ++++++++++++++++
controllers/vector_controller.go | 4 +
go.mod | 1 -
go.sum | 1 -
16 files changed, 407 insertions(+), 32 deletions(-)
delete mode 100644 config/samples/observability_v1alpha1_vector_agent.yaml
create mode 100644 controllers/vector_aggregator_controller.go
create mode 100644 controllers/vector_aggregator_rbac.go
create mode 100644 controllers/vector_aggregator_secret.go
create mode 100644 controllers/vector_aggregator_service.go
create mode 100644 controllers/vector_aggregator_statefulset.go
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index 650065dc..e232e7a3 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -29,6 +29,8 @@ type VectorSpec struct {
DisableAggregation bool `json:"disableAggregation,omitempty"`
// Vector Agent
Agent *VectorAgent `json:"agent,omitempty"`
+ // Vector Aggregator
+ Aggregator *VectorAggregator `json:"aggregator,omitempty"`
}
// VectorStatus defines the observed state of Vector
@@ -39,7 +41,16 @@ type VectorStatus struct {
// VectorAgent is the Schema for the Vector Agent
type VectorAgent struct {
- Service bool `json:"service,omitempty"`
+ // +kubebuilder:default:="timberio/vector:0.24.0-distroless-libc"
+ Image string `json:"image,omitempty"`
+ Service bool `json:"service,omitempty"`
+}
+
+// VectorAggregator is the Schema for the Vector Aggregator
+type VectorAggregator struct {
+ // +kubebuilder:default:="timberio/vector:0.24.0-distroless-libc"
+ Image string `json:"image,omitempty"`
+ Replicas int `json:"replicas,omitempty"`
}
//+kubebuilder:object:root=true
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index bfff347a..d2caad74 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -38,9 +38,21 @@ spec:
agent:
description: Vector Agent
properties:
+ image:
+ default: timberio/vector:0.24.0-distroless-libc
+ type: string
service:
type: boolean
type: object
+ aggregator:
+ description: Vector Aggregator
+ properties:
+ image:
+ default: timberio/vector:0.24.0-distroless-libc
+ type: string
+ replicas:
+ type: integer
+ type: object
disableAggregation:
description: DisableAggregation
type: boolean
diff --git a/config/samples/observability_v1alpha1_vector.yaml b/config/samples/observability_v1alpha1_vector.yaml
index 6016ca4c..6aef4c96 100644
--- a/config/samples/observability_v1alpha1_vector.yaml
+++ b/config/samples/observability_v1alpha1_vector.yaml
@@ -2,5 +2,12 @@ apiVersion: observability.kaasops.io/v1alpha1
kind: Vector
metadata:
name: vector-sample
+ namespace: vector
spec:
- # TODO(user): Add fields here
+ disableAggregation: true
+ agent:
+ service: true
+ image: "timberio/vector:0.24.0-distroless-libc"
+ aggregator:
+ image: "timberio/vector:0.24.0-distroless-libc"
+ replicas: 1
diff --git a/config/samples/observability_v1alpha1_vector_agent.yaml b/config/samples/observability_v1alpha1_vector_agent.yaml
deleted file mode 100644
index 2fe16a23..00000000
--- a/config/samples/observability_v1alpha1_vector_agent.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-apiVersion: observability.kaasops.io/v1alpha1
-kind: Vector
-metadata:
- name: vector-sample
-spec:
- disableAggregation: true
- agent:
- service: true
diff --git a/controllers/utils.go b/controllers/utils.go
index aa63261c..3e611d94 100644
--- a/controllers/utils.go
+++ b/controllers/utils.go
@@ -25,6 +25,10 @@ func (r *VectorReconciler) CreateOrUpdateDaemonSet(daemonSet *appsv1.DaemonSet)
return r.reconcileDaemonSet(daemonSet)
}
+func (r *VectorReconciler) CreateOrUpdateStatefulSet(statefulSet *appsv1.StatefulSet) (*reconcile.Result, error) {
+ return r.reconcileStatefulSet(statefulSet)
+}
+
func (r *VectorReconciler) CreateOrUpdateServiceAccount(secret *corev1.ServiceAccount) (*reconcile.Result, error) {
return r.reconcileServiceAccount(secret)
}
@@ -112,6 +116,31 @@ func (r *VectorReconciler) reconcileDaemonSet(obj runtime.Object) (*reconcile.Re
return nil, nil
}
+func (r *VectorReconciler) reconcileStatefulSet(obj runtime.Object) (*reconcile.Result, error) {
+
+ existing := &appsv1.StatefulSet{}
+ desired := obj.(*appsv1.StatefulSet)
+
+ err := r.Create(context.TODO(), desired)
+ if err != nil && errors.IsAlreadyExists(err) {
+ err := r.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ if err != nil {
+ return nil, err
+ }
+ if !equality.Semantic.DeepEqual(existing, desired) {
+ existing.Spec = desired.Spec
+ existing.Labels = desired.Labels
+ err := r.Update(context.TODO(), existing)
+ return nil, err
+ }
+ }
+ if err != nil && !errors.IsAlreadyExists(err) {
+ return nil, err
+ }
+
+ return nil, nil
+}
+
func (r *VectorReconciler) reconcileServiceAccount(obj runtime.Object) (*reconcile.Result, error) {
existing := &corev1.ServiceAccount{}
diff --git a/controllers/vector_agent_controller.go b/controllers/vector_agent_controller.go
index e03f3674..396f707d 100644
--- a/controllers/vector_agent_controller.go
+++ b/controllers/vector_agent_controller.go
@@ -17,7 +17,7 @@ func (r *VectorReconciler) ensureVectorAgent(vectorCR *vectorv1alpha1.Vector) (d
log.Info("start Reconcile Vector Agent")
- if done, result, err = r.ensureVectorRBAC(vectorCR); done {
+ if done, result, err = r.ensureVectorAgentRBAC(vectorCR); done {
return
}
@@ -38,7 +38,7 @@ func (r *VectorReconciler) ensureVectorAgent(vectorCR *vectorv1alpha1.Vector) (d
return
}
-func (r *VectorReconciler) ensureVectorRBAC(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
+func (r *VectorReconciler) ensureVectorAgentRBAC(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
ctx := context.Background()
log := log.FromContext(ctx).WithValues("vector-agent-rbac", vectorCR.Name)
diff --git a/controllers/vector_agent_daemonset.go b/controllers/vector_agent_daemonset.go
index 82b021af..9a83ec75 100644
--- a/controllers/vector_agent_daemonset.go
+++ b/controllers/vector_agent_daemonset.go
@@ -8,8 +8,6 @@ import (
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
)
-var vectorImage = "timberio/vector:0.24.0-distroless-libc"
-
func (r *VectorReconciler) createVectorAgentDaemonSet(v *vectorv1alpha1.Vector) *appsv1.DaemonSet {
labels := labelsForVectorAgent(v.Name)
@@ -26,7 +24,7 @@ func (r *VectorReconciler) createVectorAgentDaemonSet(v *vectorv1alpha1.Vector)
Containers: []corev1.Container{
{
Name: getNameVectorAgent(v),
- Image: vectorImage,
+ Image: v.Spec.Agent.Image,
Args: []string{"--config-dir", "/etc/vector/"},
Env: generateVectorAgentEnvs(v),
Ports: []corev1.ContainerPort{
diff --git a/controllers/vector_agent_secret.go b/controllers/vector_agent_secret.go
index 4d398083..f4657efb 100644
--- a/controllers/vector_agent_secret.go
+++ b/controllers/vector_agent_secret.go
@@ -15,27 +15,16 @@ api:
sources:
kubernetes_logs:
type: kubernetes_logs
- host_metrics:
- filesystem:
- devices:
- excludes: [binfmt_misc]
- filesystems:
- excludes: [binfmt_misc]
- mountPoints:
- excludes: ["*/proc/sys/fs/binfmt_misc"]
- type: host_metrics
- internal_metrics:
- type: internal_metrics
sinks:
- prom_exporter:
- type: prometheus_exporter
- inputs: [host_metrics, internal_metrics]
- address: 0.0.0.0:9090
stdout:
type: console
inputs: [kubernetes_logs]
encoding:
codec: json
+ vector:
+ type: vector
+ inputs: [kubernetes_logs]
+ address: vector-sample-aggregator:6000
`
func (r *VectorReconciler) createVectorAgentSecret(v *vectorv1alpha1.Vector) *corev1.Secret {
diff --git a/controllers/vector_aggregator_controller.go b/controllers/vector_aggregator_controller.go
new file mode 100644
index 00000000..8c3ba51a
--- /dev/null
+++ b/controllers/vector_aggregator_controller.go
@@ -0,0 +1,131 @@
+package controllers
+
+import (
+ "context"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/label"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+)
+
+func (r *VectorReconciler) ensureVectorAggregator(vectorCR *vectorv1alpha1.Vector) (done bool, result ctrl.Result, err error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-aggregator", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Aggregator")
+
+ if done, result, err = r.ensureVectorRBAC(vectorCR); done {
+ return
+ }
+
+ if done, result, err = r.ensureVectorAggregatorService(vectorCR); done {
+ return
+ }
+
+ if done, result, err = r.ensureVectorAggregatorSecret(vectorCR); done {
+ return
+ }
+
+ if done, result, err = r.ensureVectorAggregatorStatefulSet(vectorCR); done {
+ return
+ }
+
+ return
+}
+
+func (r *VectorReconciler) ensureVectorRBAC(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-aggregator-rbac", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Aggregator RBAC")
+
+ if done, _, err := r.ensureVectorAggregatorServiceAccount(vectorCR); done {
+ return ReconcileResult(err)
+ }
+
+ return ReconcileResult(nil)
+}
+
+func (r *VectorReconciler) ensureVectorAggregatorServiceAccount(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
+ vectorAggregatorServiceAccount := r.createVectorAggregatorServiceAccount(vectorCR)
+
+ if err := controllerutil.SetControllerReference(vectorCR, vectorAggregatorServiceAccount, r.Scheme); err != nil {
+ return ReconcileResult(err)
+ }
+ _, err := r.CreateOrUpdateServiceAccount(vectorAggregatorServiceAccount)
+
+ return ReconcileResult(err)
+}
+
+func (r *VectorReconciler) ensureVectorAggregatorService(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-aggregator-service", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Aggregator Service")
+
+ vectorAggregatorService := r.createVectorAggregatorService(vectorCR)
+
+ if err := controllerutil.SetControllerReference(vectorCR, vectorAggregatorService, r.Scheme); err != nil {
+ return ReconcileResult(err)
+ }
+ _, err := r.CreateOrUpdateService(vectorAggregatorService)
+
+ return ReconcileResult(err)
+}
+
+func (r *VectorReconciler) ensureVectorAggregatorSecret(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-aggregator-secret", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Aggregator Secret")
+
+ vectorAggregatorSecret := r.createVectorAggregatorSecret(vectorCR)
+
+ if err := controllerutil.SetControllerReference(vectorCR, vectorAggregatorSecret, r.Scheme); err != nil {
+ return ReconcileResult(err)
+ }
+ _, err := r.CreateOrUpdateSecret(vectorAggregatorSecret)
+
+ return ReconcileResult(err)
+}
+
+func (r *VectorReconciler) ensureVectorAggregatorStatefulSet(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-aggregator-statefulset", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Aggregator StatefulSet")
+
+ vectorAggregatorStatefulSet := r.createVectorAggregatorStatefulSet(vectorCR)
+
+ if err := controllerutil.SetControllerReference(vectorCR, vectorAggregatorStatefulSet, r.Scheme); err != nil {
+ return ReconcileResult(err)
+ }
+ _, err := r.CreateOrUpdateStatefulSet(vectorAggregatorStatefulSet)
+
+ return ReconcileResult(err)
+}
+
+func labelsForVectorAggregator(name string) map[string]string {
+ return map[string]string{
+ label.ManagedByLabelKey: "vector-operator",
+ label.NameLabelKey: "vector",
+ label.ComponentLabelKey: "Aggregator",
+ label.InstanceLabelKey: name,
+ }
+}
+
+func objectMetaVectorAggregator(v *vectorv1alpha1.Vector, labels map[string]string) metav1.ObjectMeta {
+ return metav1.ObjectMeta{
+ Name: v.Name + "-aggregator",
+ Namespace: v.Namespace,
+ Labels: labels,
+ }
+}
+
+func getNameVectorAggregator(v *vectorv1alpha1.Vector) string {
+ name := v.Name + "-aggregator"
+ return name
+}
diff --git a/controllers/vector_aggregator_rbac.go b/controllers/vector_aggregator_rbac.go
new file mode 100644
index 00000000..67511128
--- /dev/null
+++ b/controllers/vector_aggregator_rbac.go
@@ -0,0 +1,17 @@
+package controllers
+
+import (
+ corev1 "k8s.io/api/core/v1"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+)
+
+func (r *VectorReconciler) createVectorAggregatorServiceAccount(v *vectorv1alpha1.Vector) *corev1.ServiceAccount {
+ labels := labelsForVectorAggregator(v.Name)
+
+ serviceAccount := &corev1.ServiceAccount{
+ ObjectMeta: objectMetaVectorAggregator(v, labels),
+ }
+
+ return serviceAccount
+}
diff --git a/controllers/vector_aggregator_secret.go b/controllers/vector_aggregator_secret.go
new file mode 100644
index 00000000..60bef159
--- /dev/null
+++ b/controllers/vector_aggregator_secret.go
@@ -0,0 +1,40 @@
+package controllers
+
+import (
+ corev1 "k8s.io/api/core/v1"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+)
+
+var vectorAggregatorConfig = `
+data_dir: /vector-data-dir
+api:
+ enabled: true
+ address: 127.0.0.1:8686
+ playground: false
+sources:
+ vector:
+ address: 0.0.0.0:6000
+ type: vector
+ version: "2"
+sinks:
+ stdout:
+ type: console
+ inputs: [vector]
+ encoding:
+ codec: json
+`
+
+func (r *VectorReconciler) createVectorAggregatorSecret(v *vectorv1alpha1.Vector) *corev1.Secret {
+ labels := labelsForVectorAggregator(v.Name)
+
+ config := map[string][]byte{
+ "aggregator.yaml": []byte(vectorAggregatorConfig),
+ }
+
+ secret := &corev1.Secret{
+ ObjectMeta: objectMetaVectorAggregator(v, labels),
+ Data: config,
+ }
+ return secret
+}
diff --git a/controllers/vector_aggregator_service.go b/controllers/vector_aggregator_service.go
new file mode 100644
index 00000000..2e500c12
--- /dev/null
+++ b/controllers/vector_aggregator_service.go
@@ -0,0 +1,28 @@
+package controllers
+
+import (
+ corev1 "k8s.io/api/core/v1"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "k8s.io/apimachinery/pkg/util/intstr"
+)
+
+func (r *VectorReconciler) createVectorAggregatorService(v *vectorv1alpha1.Vector) *corev1.Service {
+ labels := labelsForVectorAggregator(v.Name)
+
+ service := &corev1.Service{
+ ObjectMeta: objectMetaVectorAggregator(v, labels),
+ Spec: corev1.ServiceSpec{
+ Ports: []corev1.ServicePort{
+ {
+ Name: "vector",
+ Protocol: corev1.Protocol("TCP"),
+ Port: 6000,
+ TargetPort: intstr.FromInt(6000),
+ },
+ },
+ Selector: labels,
+ },
+ }
+ return service
+}
diff --git a/controllers/vector_aggregator_statefulset.go b/controllers/vector_aggregator_statefulset.go
new file mode 100644
index 00000000..ce6427fd
--- /dev/null
+++ b/controllers/vector_aggregator_statefulset.go
@@ -0,0 +1,119 @@
+package controllers
+
+import (
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func (r *VectorReconciler) createVectorAggregatorStatefulSet(v *vectorv1alpha1.Vector) *appsv1.StatefulSet {
+ labels := labelsForVectorAggregator(v.Name)
+ replicas := int32(v.Spec.Aggregator.Replicas)
+ statefulset := &appsv1.StatefulSet{
+ ObjectMeta: objectMetaVectorAggregator(v, labels),
+ Spec: appsv1.StatefulSetSpec{
+ Selector: &metav1.LabelSelector{MatchLabels: labels},
+ Replicas: &replicas,
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: objectMetaVectorAggregator(v, labels),
+ Spec: corev1.PodSpec{
+ ServiceAccountName: getNameVectorAggregator(v),
+ Volumes: generateVectorAggregatorVolume(v),
+ SecurityContext: &corev1.PodSecurityContext{},
+ Containers: []corev1.Container{
+ {
+ Name: getNameVectorAggregator(v),
+ Image: v.Spec.Aggregator.Image,
+ Args: []string{"--config-dir", "/etc/vector/"},
+ Env: generateVectorAggregatorEnvs(v),
+ Ports: []corev1.ContainerPort{
+ {
+ Name: "vector",
+ ContainerPort: 6000,
+ Protocol: "TCP",
+ },
+ },
+ VolumeMounts: generateVectorAggregatorVolumeMounts(v),
+ SecurityContext: &corev1.SecurityContext{},
+ },
+ },
+ },
+ },
+ },
+ }
+
+ return statefulset
+}
+
+func generateVectorAggregatorVolume(v *vectorv1alpha1.Vector) []corev1.Volume {
+ volume := []corev1.Volume{
+ {
+ Name: "config",
+ VolumeSource: corev1.VolumeSource{
+ Secret: &corev1.SecretVolumeSource{
+ SecretName: getNameVectorAggregator(v),
+ },
+ },
+ },
+ {
+ Name: "data",
+ VolumeSource: corev1.VolumeSource{
+ HostPath: &corev1.HostPathVolumeSource{
+ Path: "/var/lib/vector",
+ },
+ },
+ },
+ }
+
+ return volume
+}
+
+func generateVectorAggregatorVolumeMounts(spec *vectorv1alpha1.Vector) []corev1.VolumeMount {
+ volumeMount := []corev1.VolumeMount{
+ {
+ Name: "config",
+ MountPath: "/etc/vector/",
+ },
+ {
+ Name: "data",
+ MountPath: "/vector-data-dir",
+ },
+ }
+
+ return volumeMount
+}
+
+func generateVectorAggregatorEnvs(spec *vectorv1alpha1.Vector) []corev1.EnvVar {
+ envs := []corev1.EnvVar{
+ {
+ Name: "VECTOR_SELF_NODE_NAME",
+ ValueFrom: &corev1.EnvVarSource{
+ FieldRef: &corev1.ObjectFieldSelector{
+ APIVersion: "v1",
+ FieldPath: "spec.nodeName",
+ },
+ },
+ },
+ {
+ Name: "VECTOR_SELF_POD_NAME",
+ ValueFrom: &corev1.EnvVarSource{
+ FieldRef: &corev1.ObjectFieldSelector{
+ APIVersion: "v1",
+ FieldPath: "metadata.name",
+ },
+ },
+ },
+ {
+ Name: "VECTOR_SELF_POD_NAMESPACE",
+ ValueFrom: &corev1.EnvVarSource{
+ FieldRef: &corev1.ObjectFieldSelector{
+ APIVersion: "v1",
+ FieldPath: "metadata.namespace",
+ },
+ },
+ },
+ }
+
+ return envs
+}
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 74598596..18ea580b 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -64,6 +64,10 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return result, err
}
+ if done, result, err = r.ensureVectorAggregator(vectorCR); done {
+ return result, err
+ }
+
return ctrl.Result{RequeueAfter: 5 * time.Second}, nil
}
diff --git a/go.mod b/go.mod
index c4556705..d981895a 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,6 @@ go 1.18
require (
github.com/go-logr/logr v1.2.0
- github.com/google/martian v2.1.0+incompatible
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.18.1
k8s.io/api v0.24.2
diff --git a/go.sum b/go.sum
index e31d1d61..c27022bf 100644
--- a/go.sum
+++ b/go.sum
@@ -235,7 +235,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
From be16e06c48942e5e50955b7abac23421a24777f4 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 10 Oct 2022 16:09:00 +0300
Subject: [PATCH 002/316] exclude vector logs
---
controllers/label/label.go | 3 +-
controllers/vector_agent_controller.go | 9 +++--
controllers/vector_aggregator_controller.go | 9 +++--
controllers/vector_aggregator_statefulset.go | 39 +-------------------
4 files changed, 13 insertions(+), 47 deletions(-)
diff --git a/controllers/label/label.go b/controllers/label/label.go
index 13048fe7..3d21f139 100644
--- a/controllers/label/label.go
+++ b/controllers/label/label.go
@@ -14,7 +14,8 @@ const (
// It's set by helm when installing a release
InstanceLabelKey string = "app.kubernetes.io/instance"
// VersionLabelKey is Kubernetes recommended label key, it represents the version of the app
- VersionLabelKey string = "app.kubernetes.io/version"
+ VersionLabelKey string = "app.kubernetes.io/version"
+ VectorExcludeLabel string = "vector.dev/exclude"
// PodName is to select pod by name
// https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-selector
diff --git a/controllers/vector_agent_controller.go b/controllers/vector_agent_controller.go
index 396f707d..8f3dae1c 100644
--- a/controllers/vector_agent_controller.go
+++ b/controllers/vector_agent_controller.go
@@ -140,10 +140,11 @@ func (r *VectorReconciler) ensureVectorAgentDaemonSet(vectorCR *vectorv1alpha1.V
func labelsForVectorAgent(name string) map[string]string {
return map[string]string{
- label.ManagedByLabelKey: "vector-operator",
- label.NameLabelKey: "vector",
- label.ComponentLabelKey: "Agent",
- label.InstanceLabelKey: name,
+ label.ManagedByLabelKey: "vector-operator",
+ label.NameLabelKey: "vector",
+ label.ComponentLabelKey: "Agent",
+ label.InstanceLabelKey: name,
+ label.VectorExcludeLabel: "true",
}
}
diff --git a/controllers/vector_aggregator_controller.go b/controllers/vector_aggregator_controller.go
index 8c3ba51a..ed5e2597 100644
--- a/controllers/vector_aggregator_controller.go
+++ b/controllers/vector_aggregator_controller.go
@@ -110,10 +110,11 @@ func (r *VectorReconciler) ensureVectorAggregatorStatefulSet(vectorCR *vectorv1a
func labelsForVectorAggregator(name string) map[string]string {
return map[string]string{
- label.ManagedByLabelKey: "vector-operator",
- label.NameLabelKey: "vector",
- label.ComponentLabelKey: "Aggregator",
- label.InstanceLabelKey: name,
+ label.ManagedByLabelKey: "vector-operator",
+ label.NameLabelKey: "vector",
+ label.ComponentLabelKey: "Aggregator",
+ label.InstanceLabelKey: name,
+ label.VectorExcludeLabel: "true",
}
}
diff --git a/controllers/vector_aggregator_statefulset.go b/controllers/vector_aggregator_statefulset.go
index ce6427fd..232b7e92 100644
--- a/controllers/vector_aggregator_statefulset.go
+++ b/controllers/vector_aggregator_statefulset.go
@@ -26,7 +26,6 @@ func (r *VectorReconciler) createVectorAggregatorStatefulSet(v *vectorv1alpha1.V
Name: getNameVectorAggregator(v),
Image: v.Spec.Aggregator.Image,
Args: []string{"--config-dir", "/etc/vector/"},
- Env: generateVectorAggregatorEnvs(v),
Ports: []corev1.ContainerPort{
{
Name: "vector",
@@ -59,9 +58,7 @@ func generateVectorAggregatorVolume(v *vectorv1alpha1.Vector) []corev1.Volume {
{
Name: "data",
VolumeSource: corev1.VolumeSource{
- HostPath: &corev1.HostPathVolumeSource{
- Path: "/var/lib/vector",
- },
+ EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
}
@@ -83,37 +80,3 @@ func generateVectorAggregatorVolumeMounts(spec *vectorv1alpha1.Vector) []corev1.
return volumeMount
}
-
-func generateVectorAggregatorEnvs(spec *vectorv1alpha1.Vector) []corev1.EnvVar {
- envs := []corev1.EnvVar{
- {
- Name: "VECTOR_SELF_NODE_NAME",
- ValueFrom: &corev1.EnvVarSource{
- FieldRef: &corev1.ObjectFieldSelector{
- APIVersion: "v1",
- FieldPath: "spec.nodeName",
- },
- },
- },
- {
- Name: "VECTOR_SELF_POD_NAME",
- ValueFrom: &corev1.EnvVarSource{
- FieldRef: &corev1.ObjectFieldSelector{
- APIVersion: "v1",
- FieldPath: "metadata.name",
- },
- },
- },
- {
- Name: "VECTOR_SELF_POD_NAMESPACE",
- ValueFrom: &corev1.EnvVarSource{
- FieldRef: &corev1.ObjectFieldSelector{
- APIVersion: "v1",
- FieldPath: "metadata.namespace",
- },
- },
- },
- }
-
- return envs
-}
From 80cc58c5eeb6c23cf43fdcac605360d990bd6432 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Thu, 13 Oct 2022 11:53:21 +0300
Subject: [PATCH 003/316] aggregator defatult false
---
api/v1alpha1/vector_types.go | 1 +
config/crd/bases/observability.kaasops.io_vectors.yaml | 2 ++
controllers/vector_controller.go | 6 ++++--
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index e232e7a3..3b031373 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -48,6 +48,7 @@ type VectorAgent struct {
// VectorAggregator is the Schema for the Vector Aggregator
type VectorAggregator struct {
+ Enable bool `json:"enable,omitempty"`
// +kubebuilder:default:="timberio/vector:0.24.0-distroless-libc"
Image string `json:"image,omitempty"`
Replicas int `json:"replicas,omitempty"`
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index d2caad74..330a3227 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -47,6 +47,8 @@ spec:
aggregator:
description: Vector Aggregator
properties:
+ enable:
+ type: boolean
image:
default: timberio/vector:0.24.0-distroless-libc
type: string
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 18ea580b..29a40413 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -64,8 +64,10 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return result, err
}
- if done, result, err = r.ensureVectorAggregator(vectorCR); done {
- return result, err
+ if vectorCR.Spec.Aggregator.Enable {
+ if done, result, err = r.ensureVectorAggregator(vectorCR); done {
+ return result, err
+ }
}
return ctrl.Result{RequeueAfter: 5 * time.Second}, nil
From 509d0896abea97db94df47d67e349be02534282e Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Thu, 13 Oct 2022 11:59:24 +0300
Subject: [PATCH 004/316] init VectorPipeline api
---
PROJECT | 9 ++
api/v1alpha1/vectorpipeline_types.go | 64 ++++++++++
api/v1alpha1/zz_generated.deepcopy.go | 109 ++++++++++++++++++
config/crd/kustomization.yaml | 3 +
.../cainjection_in_vectorpipelines.yaml | 7 ++
.../patches/webhook_in_vectorpipelines.yaml | 16 +++
config/rbac/vectorpipeline_editor_role.yaml | 24 ++++
config/rbac/vectorpipeline_viewer_role.yaml | 20 ++++
config/samples/kustomization.yaml | 1 +
...observability_v1alpha1_vectorpipeline.yaml | 6 +
controllers/vectorpipeline_controller.go | 62 ++++++++++
main.go | 7 ++
12 files changed, 328 insertions(+)
create mode 100644 api/v1alpha1/vectorpipeline_types.go
create mode 100644 config/crd/patches/cainjection_in_vectorpipelines.yaml
create mode 100644 config/crd/patches/webhook_in_vectorpipelines.yaml
create mode 100644 config/rbac/vectorpipeline_editor_role.yaml
create mode 100644 config/rbac/vectorpipeline_viewer_role.yaml
create mode 100644 config/samples/observability_v1alpha1_vectorpipeline.yaml
create mode 100644 controllers/vectorpipeline_controller.go
diff --git a/PROJECT b/PROJECT
index 4794c3a9..05c036cc 100644
--- a/PROJECT
+++ b/PROJECT
@@ -16,4 +16,13 @@ resources:
kind: Vector
path: github.com/kaasops/vector-operator/api/v1alpha1
version: v1alpha1
+- api:
+ crdVersion: v1
+ namespaced: true
+ controller: true
+ domain: kaasops.io
+ group: observability
+ kind: VectorPipeline
+ path: github.com/kaasops/vector-operator/api/v1alpha1
+ version: v1alpha1
version: "3"
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
new file mode 100644
index 00000000..6a1c831e
--- /dev/null
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -0,0 +1,64 @@
+/*
+Copyright 2022.
+
+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
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
+// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
+
+// VectorPipelineSpec defines the desired state of VectorPipeline
+type VectorPipelineSpec struct {
+ // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+
+ // Foo is an example field of VectorPipeline. Edit vectorpipeline_types.go to remove/update
+ Foo string `json:"foo,omitempty"`
+}
+
+// VectorPipelineStatus defines the observed state of VectorPipeline
+type VectorPipelineStatus struct {
+ // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+}
+
+//+kubebuilder:object:root=true
+//+kubebuilder:subresource:status
+
+// VectorPipeline is the Schema for the vectorpipelines API
+type VectorPipeline struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec VectorPipelineSpec `json:"spec,omitempty"`
+ Status VectorPipelineStatus `json:"status,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// VectorPipelineList contains a list of VectorPipeline
+type VectorPipelineList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []VectorPipeline `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&VectorPipeline{}, &VectorPipelineList{})
+}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index c0f11c0e..d395d47b 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -67,6 +67,21 @@ func (in *VectorAgent) DeepCopy() *VectorAgent {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VectorAggregator) DeepCopyInto(out *VectorAggregator) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorAggregator.
+func (in *VectorAggregator) DeepCopy() *VectorAggregator {
+ if in == nil {
+ return nil
+ }
+ out := new(VectorAggregator)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VectorList) DeepCopyInto(out *VectorList) {
*out = *in
@@ -99,6 +114,95 @@ func (in *VectorList) DeepCopyObject() runtime.Object {
return nil
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VectorPipeline) DeepCopyInto(out *VectorPipeline) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ out.Spec = in.Spec
+ out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorPipeline.
+func (in *VectorPipeline) DeepCopy() *VectorPipeline {
+ if in == nil {
+ return nil
+ }
+ out := new(VectorPipeline)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *VectorPipeline) 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 *VectorPipelineList) DeepCopyInto(out *VectorPipelineList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]VectorPipeline, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorPipelineList.
+func (in *VectorPipelineList) DeepCopy() *VectorPipelineList {
+ if in == nil {
+ return nil
+ }
+ out := new(VectorPipelineList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *VectorPipelineList) 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 *VectorPipelineSpec) DeepCopyInto(out *VectorPipelineSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorPipelineSpec.
+func (in *VectorPipelineSpec) DeepCopy() *VectorPipelineSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(VectorPipelineSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VectorPipelineStatus) DeepCopyInto(out *VectorPipelineStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorPipelineStatus.
+func (in *VectorPipelineStatus) DeepCopy() *VectorPipelineStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(VectorPipelineStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VectorSpec) DeepCopyInto(out *VectorSpec) {
*out = *in
@@ -107,6 +211,11 @@ func (in *VectorSpec) DeepCopyInto(out *VectorSpec) {
*out = new(VectorAgent)
**out = **in
}
+ if in.Aggregator != nil {
+ in, out := &in.Aggregator, &out.Aggregator
+ *out = new(VectorAggregator)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorSpec.
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index a236a16d..0121c8b1 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -3,17 +3,20 @@
# It should be run by config/default
resources:
- bases/observability.kaasops.io_vectors.yaml
+- bases/observability.kaasops.io_vectorpipelines.yaml
#+kubebuilder:scaffold:crdkustomizeresource
patchesStrategicMerge:
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
# patches here are for enabling the conversion webhook for each CRD
#- patches/webhook_in_vectors.yaml
+#- patches/webhook_in_vectorpipelines.yaml
#+kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
#- patches/cainjection_in_vectors.yaml
+#- patches/cainjection_in_vectorpipelines.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
# the following config is for teaching kustomize how to do kustomization for CRDs.
diff --git a/config/crd/patches/cainjection_in_vectorpipelines.yaml b/config/crd/patches/cainjection_in_vectorpipelines.yaml
new file mode 100644
index 00000000..a6890ec8
--- /dev/null
+++ b/config/crd/patches/cainjection_in_vectorpipelines.yaml
@@ -0,0 +1,7 @@
+# The following patch adds a directive for certmanager to inject CA into the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+ name: vectorpipelines.observability.kaasops.io
diff --git a/config/crd/patches/webhook_in_vectorpipelines.yaml b/config/crd/patches/webhook_in_vectorpipelines.yaml
new file mode 100644
index 00000000..b34cf2f8
--- /dev/null
+++ b/config/crd/patches/webhook_in_vectorpipelines.yaml
@@ -0,0 +1,16 @@
+# The following patch enables a conversion webhook for the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ name: vectorpipelines.observability.kaasops.io
+spec:
+ conversion:
+ strategy: Webhook
+ webhook:
+ clientConfig:
+ service:
+ namespace: system
+ name: webhook-service
+ path: /convert
+ conversionReviewVersions:
+ - v1
diff --git a/config/rbac/vectorpipeline_editor_role.yaml b/config/rbac/vectorpipeline_editor_role.yaml
new file mode 100644
index 00000000..cdf5850a
--- /dev/null
+++ b/config/rbac/vectorpipeline_editor_role.yaml
@@ -0,0 +1,24 @@
+# permissions for end users to edit vectorpipelines.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: vectorpipeline-editor-role
+rules:
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - vectorpipelines
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - vectorpipelines/status
+ verbs:
+ - get
diff --git a/config/rbac/vectorpipeline_viewer_role.yaml b/config/rbac/vectorpipeline_viewer_role.yaml
new file mode 100644
index 00000000..485298ca
--- /dev/null
+++ b/config/rbac/vectorpipeline_viewer_role.yaml
@@ -0,0 +1,20 @@
+# permissions for end users to view vectorpipelines.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: vectorpipeline-viewer-role
+rules:
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - vectorpipelines
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - vectorpipelines/status
+ verbs:
+ - get
diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml
index 1de27a2e..ab24709f 100644
--- a/config/samples/kustomization.yaml
+++ b/config/samples/kustomization.yaml
@@ -1,4 +1,5 @@
## Append samples you want in your CSV to this file as resources ##
resources:
- observability_v1alpha1_vector.yaml
+- observability_v1alpha1_vectorpipeline.yaml
#+kubebuilder:scaffold:manifestskustomizesamples
diff --git a/config/samples/observability_v1alpha1_vectorpipeline.yaml b/config/samples/observability_v1alpha1_vectorpipeline.yaml
new file mode 100644
index 00000000..312d3aa7
--- /dev/null
+++ b/config/samples/observability_v1alpha1_vectorpipeline.yaml
@@ -0,0 +1,6 @@
+apiVersion: observability.kaasops.io/v1alpha1
+kind: VectorPipeline
+metadata:
+ name: vectorpipeline-sample
+spec:
+ # TODO(user): Add fields here
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
new file mode 100644
index 00000000..13f4b773
--- /dev/null
+++ b/controllers/vectorpipeline_controller.go
@@ -0,0 +1,62 @@
+/*
+Copyright 2022.
+
+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 controllers
+
+import (
+ "context"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+
+ observabilityv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+)
+
+// VectorPipelineReconciler reconciles a VectorPipeline object
+type VectorPipelineReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+}
+
+//+kubebuilder:rbac:groups=observability.kaasops.io,resources=vectorpipelines,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=observability.kaasops.io,resources=vectorpipelines/status,verbs=get;update;patch
+//+kubebuilder:rbac:groups=observability.kaasops.io,resources=vectorpipelines/finalizers,verbs=update
+
+// Reconcile is part of the main kubernetes reconciliation loop which aims to
+// move the current state of the cluster closer to the desired state.
+// TODO(user): Modify the Reconcile function to compare the state specified by
+// the VectorPipeline object against the actual cluster state, and then
+// perform operations to make the cluster state reflect the state specified by
+// the user.
+//
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.2/pkg/reconcile
+func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+ _ = log.FromContext(ctx)
+
+ // TODO(user): your logic here
+
+ return ctrl.Result{}, nil
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (r *VectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&observabilityv1alpha1.VectorPipeline{}).
+ Complete(r)
+}
diff --git a/main.go b/main.go
index 2fecdfc8..5bed1890 100644
--- a/main.go
+++ b/main.go
@@ -96,6 +96,13 @@ func main() {
setupLog.Error(err, "unable to create controller", "controller", "Vector")
os.Exit(1)
}
+ if err = (&controllers.VectorPipelineReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "VectorPipeline")
+ os.Exit(1)
+ }
//+kubebuilder:scaffold:builder
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
From 1bebed2fb3fb62a6ad9ad766f219e7d580cce15a Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 17 Oct 2022 11:15:32 +0300
Subject: [PATCH 005/316] Vector pipeline api reconcile
Vector pipeline api reconcile
---
.vscode/launch.json | 15 ++
api/v1alpha1/vector_types.go | 10 +-
api/v1alpha1/vectorpipeline_types.go | 36 +++-
api/v1alpha1/zz_generated.deepcopy.go | 128 +++++++++++++-
...ervability.kaasops.io_vectorpipelines.yaml | 99 +++++++++++
.../observability.kaasops.io_vectors.yaml | 21 +--
config/rbac/role.yaml | 26 +++
.../observability_v1alpha1_vector.yaml | 7 +-
...observability_v1alpha1_vectorpipeline.yaml | 62 ++++++-
controllers/{ => factory/helper}/helper.go | 2 +-
controllers/{ => factory/k8sutils}/utils.go | 84 ++++-----
controllers/{ => factory}/label/label.go | 0
controllers/factory/vector/config_build.go | 112 ++++++++++++
controllers/factory/vector/types.go | 17 ++
.../vectoragent/vector_agent_config.go | 44 +++++
.../vectoragent/vector_agent_controller.go | 164 ++++++++++++++++++
.../vectoragent}/vector_agent_daemonset.go | 6 +-
.../vectoragent}/vector_agent_rbac.go | 8 +-
.../vectoragent}/vector_agent_service.go | 4 +-
.../factory/vectorpipeline/vectorpipeline.go | 38 ++++
controllers/vector_agent_controller.go | 162 -----------------
controllers/vector_agent_secret.go | 42 -----
controllers/vector_aggregator_controller.go | 132 --------------
controllers/vector_aggregator_rbac.go | 17 --
controllers/vector_aggregator_secret.go | 40 -----
controllers/vector_aggregator_service.go | 28 ---
controllers/vector_aggregator_statefulset.go | 82 ---------
controllers/vector_controller.go | 23 ++-
controllers/vectorpipeline_controller.go | 27 ++-
go.mod | 2 +-
30 files changed, 835 insertions(+), 603 deletions(-)
create mode 100644 .vscode/launch.json
create mode 100644 config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
rename controllers/{ => factory/helper}/helper.go (90%)
rename controllers/{ => factory/k8sutils}/utils.go (53%)
rename controllers/{ => factory}/label/label.go (100%)
create mode 100644 controllers/factory/vector/config_build.go
create mode 100644 controllers/factory/vector/types.go
create mode 100644 controllers/factory/vectoragent/vector_agent_config.go
create mode 100644 controllers/factory/vectoragent/vector_agent_controller.go
rename controllers/{ => factory/vectoragent}/vector_agent_daemonset.go (95%)
rename controllers/{ => factory/vectoragent}/vector_agent_rbac.go (75%)
rename controllers/{ => factory/vectoragent}/vector_agent_service.go (82%)
create mode 100644 controllers/factory/vectorpipeline/vectorpipeline.go
delete mode 100644 controllers/vector_agent_controller.go
delete mode 100644 controllers/vector_agent_secret.go
delete mode 100644 controllers/vector_aggregator_controller.go
delete mode 100644 controllers/vector_aggregator_rbac.go
delete mode 100644 controllers/vector_aggregator_secret.go
delete mode 100644 controllers/vector_aggregator_service.go
delete mode 100644 controllers/vector_aggregator_statefulset.go
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000..6deb9a6b
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,15 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Launch Package",
+ "type": "go",
+ "request": "launch",
+ "mode": "auto",
+ "program": "main.go"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index 3b031373..d9704da7 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -26,11 +26,11 @@ import (
// VectorSpec defines the desired state of Vector
type VectorSpec struct {
// DisableAggregation
- DisableAggregation bool `json:"disableAggregation,omitempty"`
+ // DisableAggregation bool `json:"disableAggregation,omitempty"`
// Vector Agent
Agent *VectorAgent `json:"agent,omitempty"`
// Vector Aggregator
- Aggregator *VectorAggregator `json:"aggregator,omitempty"`
+ // Aggregator *VectorAggregator `json:"aggregator,omitempty"`
}
// VectorStatus defines the observed state of Vector
@@ -42,8 +42,10 @@ type VectorStatus struct {
// VectorAgent is the Schema for the Vector Agent
type VectorAgent struct {
// +kubebuilder:default:="timberio/vector:0.24.0-distroless-libc"
- Image string `json:"image,omitempty"`
- Service bool `json:"service,omitempty"`
+ Image string `json:"image,omitempty"`
+ DataDir string `json:"dataDir,omitempty"`
+ ApiEnabled bool `json:"ApiEnabled,omitempty"`
+ Service bool `json:"service,omitempty"`
}
// VectorAggregator is the Schema for the Vector Aggregator
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index 6a1c831e..f7216988 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -25,11 +25,39 @@ import (
// VectorPipelineSpec defines the desired state of VectorPipeline
type VectorPipelineSpec struct {
- // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
- // Important: Run "make" to regenerate code after modifying this file
+ Source map[string]SourceSpec `json:"source,omitempty"`
+ Transforms map[string]TransformSpec `json:"transforms,omitempty"`
+ Sink map[string]SinkSpec `json:"sinks,omitempty"`
+}
+
+type TransformSpec struct {
+ Type string `json:"type,omitempty"`
+ Inputs []string `json:"inputs,omitempty"`
+ Condition *Condition `json:"condition,omitempty"`
+}
+
+type Condition struct {
+ Type string `json:"type,omitempty"`
+ Source string `json:"source,omitempty"`
+}
+
+type SourceSpec struct {
+ Type string `json:"type,omitempty"`
+ ExtraLabelSelector string `json:"extra_label_selector,omitempty"`
+ ExtraFieldSelector string `json:"extra_field_selector,omitempty"`
+}
+
+type SinkSpec struct {
+ Type string `json:"type,omitempty"`
+ Address string `json:"address,omitempty"`
+ Inputs []string `json:"inputs,omitempty"`
+ Encoding *Encoding `json:"encoding,omitempty"`
+ Rate *int32 `json:"rate,omitempty"`
+ PrintIntervalSecs int32 `json:"print_interval_secs,omitempty"`
+}
- // Foo is an example field of VectorPipeline. Edit vectorpipeline_types.go to remove/update
- Foo string `json:"foo,omitempty"`
+type Encoding struct {
+ Codec string `json:"codec,omitempty"`
}
// VectorPipelineStatus defines the observed state of VectorPipeline
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index d395d47b..c51b2b8a 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -25,6 +25,106 @@ 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 *Condition) DeepCopyInto(out *Condition) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
+func (in *Condition) DeepCopy() *Condition {
+ if in == nil {
+ return nil
+ }
+ out := new(Condition)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Encoding) DeepCopyInto(out *Encoding) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Encoding.
+func (in *Encoding) DeepCopy() *Encoding {
+ if in == nil {
+ return nil
+ }
+ out := new(Encoding)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SinkSpec) DeepCopyInto(out *SinkSpec) {
+ *out = *in
+ if in.Inputs != nil {
+ in, out := &in.Inputs, &out.Inputs
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ if in.Encoding != nil {
+ in, out := &in.Encoding, &out.Encoding
+ *out = new(Encoding)
+ **out = **in
+ }
+ if in.Rate != nil {
+ in, out := &in.Rate, &out.Rate
+ *out = new(int32)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SinkSpec.
+func (in *SinkSpec) DeepCopy() *SinkSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(SinkSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SourceSpec) DeepCopyInto(out *SourceSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceSpec.
+func (in *SourceSpec) DeepCopy() *SourceSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(SourceSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *TransformSpec) DeepCopyInto(out *TransformSpec) {
+ *out = *in
+ if in.Inputs != nil {
+ in, out := &in.Inputs, &out.Inputs
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ if in.Condition != nil {
+ in, out := &in.Condition, &out.Condition
+ *out = new(Condition)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TransformSpec.
+func (in *TransformSpec) DeepCopy() *TransformSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(TransformSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Vector) DeepCopyInto(out *Vector) {
*out = *in
@@ -119,7 +219,7 @@ func (in *VectorPipeline) DeepCopyInto(out *VectorPipeline) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
+ in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
@@ -176,6 +276,27 @@ func (in *VectorPipelineList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VectorPipelineSpec) DeepCopyInto(out *VectorPipelineSpec) {
*out = *in
+ if in.Source != nil {
+ in, out := &in.Source, &out.Source
+ *out = make(map[string]SourceSpec, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ if in.Transforms != nil {
+ in, out := &in.Transforms, &out.Transforms
+ *out = make(map[string]TransformSpec, len(*in))
+ for key, val := range *in {
+ (*out)[key] = *val.DeepCopy()
+ }
+ }
+ if in.Sink != nil {
+ in, out := &in.Sink, &out.Sink
+ *out = make(map[string]SinkSpec, len(*in))
+ for key, val := range *in {
+ (*out)[key] = *val.DeepCopy()
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorPipelineSpec.
@@ -211,11 +332,6 @@ func (in *VectorSpec) DeepCopyInto(out *VectorSpec) {
*out = new(VectorAgent)
**out = **in
}
- if in.Aggregator != nil {
- in, out := &in.Aggregator, &out.Aggregator
- *out = new(VectorAggregator)
- **out = **in
- }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorSpec.
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
new file mode 100644
index 00000000..c6c317f1
--- /dev/null
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -0,0 +1,99 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.9.2
+ creationTimestamp: null
+ name: vectorpipelines.observability.kaasops.io
+spec:
+ group: observability.kaasops.io
+ names:
+ kind: VectorPipeline
+ listKind: VectorPipelineList
+ plural: vectorpipelines
+ singular: vectorpipeline
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: VectorPipeline is the Schema for the vectorpipelines API
+ 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: VectorPipelineSpec defines the desired state of VectorPipeline
+ properties:
+ sinks:
+ additionalProperties:
+ properties:
+ address:
+ type: string
+ encoding:
+ properties:
+ codec:
+ type: string
+ type: object
+ inputs:
+ items:
+ type: string
+ type: array
+ print_interval_secs:
+ format: int32
+ type: integer
+ rate:
+ format: int32
+ type: integer
+ type:
+ type: string
+ type: object
+ type: object
+ source:
+ additionalProperties:
+ properties:
+ extra_field_selector:
+ type: string
+ extra_label_selector:
+ type: string
+ type:
+ type: string
+ type: object
+ type: object
+ transforms:
+ additionalProperties:
+ properties:
+ condition:
+ properties:
+ source:
+ type: string
+ type:
+ type: string
+ type: object
+ inputs:
+ items:
+ type: string
+ type: array
+ type:
+ type: string
+ type: object
+ type: object
+ type: object
+ status:
+ description: VectorPipelineStatus defines the observed state of VectorPipeline
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index 330a3227..f24190e7 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -36,28 +36,19 @@ spec:
description: VectorSpec defines the desired state of Vector
properties:
agent:
- description: Vector Agent
+ description: DisableAggregation DisableAggregation bool `json:"disableAggregation,omitempty"`
+ Vector Agent
properties:
+ ApiEnabled:
+ type: boolean
+ dataDir:
+ type: string
image:
default: timberio/vector:0.24.0-distroless-libc
type: string
service:
type: boolean
type: object
- aggregator:
- description: Vector Aggregator
- properties:
- enable:
- type: boolean
- image:
- default: timberio/vector:0.24.0-distroless-libc
- type: string
- replicas:
- type: integer
- type: object
- disableAggregation:
- description: DisableAggregation
- type: boolean
type: object
status:
description: VectorStatus defines the observed state of Vector
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index 187fbbb9..9b633876 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -5,6 +5,32 @@ metadata:
creationTimestamp: null
name: manager-role
rules:
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - vectorpipelines
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - vectorpipelines/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - vectorpipelines/status
+ verbs:
+ - get
+ - patch
+ - update
- apiGroups:
- observability.kaasops.io
resources:
diff --git a/config/samples/observability_v1alpha1_vector.yaml b/config/samples/observability_v1alpha1_vector.yaml
index 6aef4c96..b667b124 100644
--- a/config/samples/observability_v1alpha1_vector.yaml
+++ b/config/samples/observability_v1alpha1_vector.yaml
@@ -2,12 +2,9 @@ apiVersion: observability.kaasops.io/v1alpha1
kind: Vector
metadata:
name: vector-sample
- namespace: vector
+ namespace: vector-operator-system
spec:
- disableAggregation: true
agent:
service: true
image: "timberio/vector:0.24.0-distroless-libc"
- aggregator:
- image: "timberio/vector:0.24.0-distroless-libc"
- replicas: 1
+
diff --git a/config/samples/observability_v1alpha1_vectorpipeline.yaml b/config/samples/observability_v1alpha1_vectorpipeline.yaml
index 312d3aa7..d56874f5 100644
--- a/config/samples/observability_v1alpha1_vectorpipeline.yaml
+++ b/config/samples/observability_v1alpha1_vectorpipeline.yaml
@@ -3,4 +3,64 @@ kind: VectorPipeline
metadata:
name: vectorpipeline-sample
spec:
- # TODO(user): Add fields here
+ source:
+ test1:
+ type: "kubernetes_logs"
+ extra_label_selector: "app!=testdeployment"
+ transforms:
+ test:
+ type: "filter"
+ inputs:
+ - test1
+ condition:
+ type: "vrl"
+ source: ".status != 200"
+ sinks:
+ test2:
+ type: "console"
+ encoding:
+ codec: "json"
+ inputs:
+ - test1
+---
+apiVersion: observability.kaasops.io/v1alpha1
+kind: VectorPipeline
+metadata:
+ name: vectorpipeline-sample1
+ namespace: kube-system
+spec:
+ source:
+ test1:
+ type: "kubernetes_logs"
+ extra_label_selector: "app!=testdeployment2"
+ sinks:
+ test2:
+ type: "console"
+ encoding:
+ codec: "json"
+ inputs:
+ - test1
+# ---
+# apiVersion: observability.kaasops.io/v1alpha1
+# kind: VectorPipeline
+# metadata:
+# name: vectorpipeline-sample2
+# namespace: default
+# spec:
+# source:
+# labelSelector:
+# app: "testdeployment2"
+# sinks:
+# type: "console"
+# ---
+# apiVersion: observability.kaasops.io/v1alpha1
+# kind: VectorPipeline
+# metadata:
+# name: vectorpipeline-sample3
+# namespace: default
+# spec:
+# source:
+# labelSelector:
+# app: "testdeployment2"
+# sinks:
+# type: "console"
\ No newline at end of file
diff --git a/controllers/helper.go b/controllers/factory/helper/helper.go
similarity index 90%
rename from controllers/helper.go
rename to controllers/factory/helper/helper.go
index d57c68fb..5247a1ef 100644
--- a/controllers/helper.go
+++ b/controllers/factory/helper/helper.go
@@ -1,4 +1,4 @@
-package controllers
+package helper
import ctrl "sigs.k8s.io/controller-runtime"
diff --git a/controllers/utils.go b/controllers/factory/k8sutils/utils.go
similarity index 53%
rename from controllers/utils.go
rename to controllers/factory/k8sutils/utils.go
index 3e611d94..d34c444e 100644
--- a/controllers/utils.go
+++ b/controllers/factory/k8sutils/utils.go
@@ -1,4 +1,4 @@
-package controllers
+package k8sutils
import (
"context"
@@ -13,49 +13,49 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
-func (r *VectorReconciler) CreateOrUpdateService(svc *corev1.Service) (*reconcile.Result, error) {
- return r.reconcileService(svc)
+func CreateOrUpdateService(svc *corev1.Service, c client.Client) (*reconcile.Result, error) {
+ return reconcileService(svc, c)
}
-func (r *VectorReconciler) CreateOrUpdateSecret(secret *corev1.Secret) (*reconcile.Result, error) {
- return r.reconcileSecret(secret)
+func CreateOrUpdateSecret(secret *corev1.Secret, c client.Client) (*reconcile.Result, error) {
+ return reconcileSecret(secret, c)
}
-func (r *VectorReconciler) CreateOrUpdateDaemonSet(daemonSet *appsv1.DaemonSet) (*reconcile.Result, error) {
- return r.reconcileDaemonSet(daemonSet)
+func CreateOrUpdateDaemonSet(daemonSet *appsv1.DaemonSet, c client.Client) (*reconcile.Result, error) {
+ return reconcileDaemonSet(daemonSet, c)
}
-func (r *VectorReconciler) CreateOrUpdateStatefulSet(statefulSet *appsv1.StatefulSet) (*reconcile.Result, error) {
- return r.reconcileStatefulSet(statefulSet)
+func CreateOrUpdateStatefulSet(statefulSet *appsv1.StatefulSet, c client.Client) (*reconcile.Result, error) {
+ return reconcileStatefulSet(statefulSet, c)
}
-func (r *VectorReconciler) CreateOrUpdateServiceAccount(secret *corev1.ServiceAccount) (*reconcile.Result, error) {
- return r.reconcileServiceAccount(secret)
+func CreateOrUpdateServiceAccount(secret *corev1.ServiceAccount, c client.Client) (*reconcile.Result, error) {
+ return reconcileServiceAccount(secret, c)
}
-func (r *VectorReconciler) CreateOrUpdateClusterRole(secret *rbacv1.ClusterRole) (*reconcile.Result, error) {
- return r.reconcileClusterRole(secret)
+func CreateOrUpdateClusterRole(secret *rbacv1.ClusterRole, c client.Client) (*reconcile.Result, error) {
+ return reconcileClusterRole(secret, c)
}
-func (r *VectorReconciler) CreateOrUpdateClusterRoleBinding(secret *rbacv1.ClusterRoleBinding) (*reconcile.Result, error) {
- return r.reconcileClusterRoleBinding(secret)
+func CreateOrUpdateClusterRoleBinding(secret *rbacv1.ClusterRoleBinding, c client.Client) (*reconcile.Result, error) {
+ return reconcileClusterRoleBinding(secret, c)
}
-func (r *VectorReconciler) reconcileService(obj runtime.Object) (*reconcile.Result, error) {
+func reconcileService(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
existing := &corev1.Service{}
desired := obj.(*corev1.Service)
- err := r.Create(context.TODO(), desired)
+ err := c.Create(context.TODO(), desired)
if err != nil && errors.IsAlreadyExists(err) {
- err := r.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return nil, err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Spec = desired.Spec
existing.Labels = desired.Labels
- err := r.Update(context.TODO(), existing)
+ err := c.Update(context.TODO(), existing)
return nil, err
}
}
@@ -66,21 +66,21 @@ func (r *VectorReconciler) reconcileService(obj runtime.Object) (*reconcile.Resu
return nil, nil
}
-func (r *VectorReconciler) reconcileSecret(obj runtime.Object) (*reconcile.Result, error) {
+func reconcileSecret(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
existing := &corev1.Secret{}
desired := obj.(*corev1.Secret)
- err := r.Create(context.TODO(), desired)
+ err := c.Create(context.TODO(), desired)
if err != nil && errors.IsAlreadyExists(err) {
- err := r.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return nil, err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Data = desired.Data
existing.Labels = desired.Labels
- err := r.Update(context.TODO(), existing)
+ err := c.Update(context.TODO(), existing)
return nil, err
}
}
@@ -91,21 +91,21 @@ func (r *VectorReconciler) reconcileSecret(obj runtime.Object) (*reconcile.Resul
return nil, nil
}
-func (r *VectorReconciler) reconcileDaemonSet(obj runtime.Object) (*reconcile.Result, error) {
+func reconcileDaemonSet(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
existing := &appsv1.DaemonSet{}
desired := obj.(*appsv1.DaemonSet)
- err := r.Create(context.TODO(), desired)
+ err := c.Create(context.TODO(), desired)
if err != nil && errors.IsAlreadyExists(err) {
- err := r.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return nil, err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Spec = desired.Spec
existing.Labels = desired.Labels
- err := r.Update(context.TODO(), existing)
+ err := c.Update(context.TODO(), existing)
return nil, err
}
}
@@ -116,21 +116,21 @@ func (r *VectorReconciler) reconcileDaemonSet(obj runtime.Object) (*reconcile.Re
return nil, nil
}
-func (r *VectorReconciler) reconcileStatefulSet(obj runtime.Object) (*reconcile.Result, error) {
+func reconcileStatefulSet(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
existing := &appsv1.StatefulSet{}
desired := obj.(*appsv1.StatefulSet)
- err := r.Create(context.TODO(), desired)
+ err := c.Create(context.TODO(), desired)
if err != nil && errors.IsAlreadyExists(err) {
- err := r.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return nil, err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Spec = desired.Spec
existing.Labels = desired.Labels
- err := r.Update(context.TODO(), existing)
+ err := c.Update(context.TODO(), existing)
return nil, err
}
}
@@ -141,14 +141,14 @@ func (r *VectorReconciler) reconcileStatefulSet(obj runtime.Object) (*reconcile.
return nil, nil
}
-func (r *VectorReconciler) reconcileServiceAccount(obj runtime.Object) (*reconcile.Result, error) {
+func reconcileServiceAccount(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
existing := &corev1.ServiceAccount{}
desired := obj.(*corev1.ServiceAccount)
- err := r.Create(context.TODO(), desired)
+ err := c.Create(context.TODO(), desired)
if err != nil && errors.IsAlreadyExists(err) {
- err := r.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return nil, err
}
@@ -160,20 +160,20 @@ func (r *VectorReconciler) reconcileServiceAccount(obj runtime.Object) (*reconci
return nil, nil
}
-func (r *VectorReconciler) reconcileClusterRole(obj runtime.Object) (*reconcile.Result, error) {
+func reconcileClusterRole(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
existing := &rbacv1.ClusterRole{}
desired := obj.(*rbacv1.ClusterRole)
- err := r.Create(context.TODO(), desired)
+ err := c.Create(context.TODO(), desired)
if err != nil && errors.IsAlreadyExists(err) {
- err := r.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return nil, err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Rules = desired.Rules
- err := r.Update(context.TODO(), existing)
+ err := c.Update(context.TODO(), existing)
return nil, err
}
}
@@ -184,21 +184,21 @@ func (r *VectorReconciler) reconcileClusterRole(obj runtime.Object) (*reconcile.
return nil, nil
}
-func (r *VectorReconciler) reconcileClusterRoleBinding(obj runtime.Object) (*reconcile.Result, error) {
+func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
existing := &rbacv1.ClusterRoleBinding{}
desired := obj.(*rbacv1.ClusterRoleBinding)
- err := r.Create(context.TODO(), desired)
+ err := c.Create(context.TODO(), desired)
if err != nil && errors.IsAlreadyExists(err) {
- err := r.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return nil, err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.RoleRef = desired.RoleRef
existing.Subjects = desired.Subjects
- err := r.Update(context.TODO(), existing)
+ err := c.Update(context.TODO(), existing)
return nil, err
}
}
diff --git a/controllers/label/label.go b/controllers/factory/label/label.go
similarity index 100%
rename from controllers/label/label.go
rename to controllers/factory/label/label.go
diff --git a/controllers/factory/vector/config_build.go b/controllers/factory/vector/config_build.go
new file mode 100644
index 00000000..f2064bb6
--- /dev/null
+++ b/controllers/factory/vector/config_build.go
@@ -0,0 +1,112 @@
+package vector
+
+import (
+ "encoding/json"
+
+ "github.com/kaasops/vector-operator/api/v1alpha1"
+)
+
+var (
+ sourceDefault = v1alpha1.SourceSpec{
+ Type: "kubernetes_logs",
+ }
+
+ rate int32 = 100
+ sinkDefault = v1alpha1.SinkSpec{
+ Type: "blackhole",
+ Inputs: []string{"defaultSource"},
+ Rate: &rate,
+ PrintIntervalSecs: 60,
+ }
+)
+
+func GenerateConfig(
+ cr *v1alpha1.Vector,
+ vp map[string]*v1alpha1.VectorPipeline,
+) ([]byte, error) {
+ cfg := NewVectorConfig(cr.Spec.Agent.DataDir, cr.Spec.Agent.ApiEnabled)
+ sources, transforms, sinks := getComponents(vp)
+ if len(sources) == 0 {
+ sources = map[string]*v1alpha1.SourceSpec{
+ "defaultSource": &sourceDefault,
+ }
+ }
+ if len(sinks) == 0 {
+ sinks = map[string]*v1alpha1.SinkSpec{
+ "defaultSink": &sinkDefault,
+ }
+ }
+
+ cfg.Sinks = sinks
+ cfg.Sources = sources
+ cfg.Transforms = transforms
+
+ return vectorConfigToJson(cfg)
+}
+
+func NewVectorConfig(dataDir string, apiEnabled bool) *VectorConfig {
+ sources := make(map[string]*v1alpha1.SourceSpec)
+ sinks := make(map[string]*v1alpha1.SinkSpec)
+
+ return &VectorConfig{
+ DataDir: dataDir,
+ Api: &ApiSpec{
+ Enabled: &apiEnabled,
+ },
+ Sources: sources,
+ Sinks: sinks,
+ }
+}
+
+func getComponents(vps map[string]*v1alpha1.VectorPipeline) (map[string]*v1alpha1.SourceSpec, map[string]*v1alpha1.TransformSpec, map[string]*v1alpha1.SinkSpec) {
+ sources := make(map[string]*v1alpha1.SourceSpec)
+ transforms := make(map[string]*v1alpha1.TransformSpec)
+ sinks := make(map[string]*v1alpha1.SinkSpec)
+
+ for name, vp := range vps {
+ for sourceName, source := range vp.Spec.Source {
+ sources[name+"-"+sourceName+"-source"] = &source
+ }
+
+ for sinkName, sink := range vp.Spec.Sink {
+ inputs := make([]string, 0)
+ for _, i := range sink.Inputs {
+ newInput := name + "-" + i + "-source"
+ inputs = append(inputs, newInput)
+ }
+
+ sink.Inputs = inputs
+ sinks[name+"-"+sinkName+"-source"] = &sink
+ }
+
+ for transformName, transform := range vp.Spec.Transforms {
+ inputs := make([]string, 0)
+ for _, i := range transform.Inputs {
+ newInput := name + "-" + i + "-source"
+ inputs = append(inputs, newInput)
+ }
+
+ transform.Inputs = inputs
+ transforms[name+"-"+transformName+"-transform"] = &transform
+
+ }
+ }
+ return sources, transforms, sinks
+}
+
+// func createKeyValuePairs(m map[string]string) string {
+// b := new(bytes.Buffer)
+// for key, value := range m {
+// fmt.Fprintf(b, "%s=\"%s\",", key, value)
+// }
+// return b.String()
+// }
+
+func vectorConfigToJson(conf *VectorConfig) ([]byte, error) {
+ data, err := json.Marshal(conf)
+ if err != nil {
+ return nil, err
+ }
+
+ return data, nil
+}
diff --git a/controllers/factory/vector/types.go b/controllers/factory/vector/types.go
new file mode 100644
index 00000000..6440c56f
--- /dev/null
+++ b/controllers/factory/vector/types.go
@@ -0,0 +1,17 @@
+package vector
+
+import "github.com/kaasops/vector-operator/api/v1alpha1"
+
+type VectorConfig struct {
+ DataDir string `json:"data_dir,omitempty"`
+ Api *ApiSpec `json:"api,omitempty"`
+ Sources map[string]*v1alpha1.SourceSpec `json:"sources,omitempty"`
+ Transforms map[string]*v1alpha1.TransformSpec `json:"transforms,omitempty"`
+ Sinks map[string]*v1alpha1.SinkSpec `json:"sinks,omitempty"`
+}
+
+type ApiSpec struct {
+ Enabled *bool `json:"enabled,omitempty"`
+ Address *string `json:"address,omitempty"`
+ Playground *bool `json:"playground,omitempty"`
+}
diff --git a/controllers/factory/vectoragent/vector_agent_config.go b/controllers/factory/vectoragent/vector_agent_config.go
new file mode 100644
index 00000000..6e2868a4
--- /dev/null
+++ b/controllers/factory/vectoragent/vector_agent_config.go
@@ -0,0 +1,44 @@
+package vectoragent
+
+import (
+ "context"
+
+ corev1 "k8s.io/api/core/v1"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/vector"
+ "github.com/kaasops/vector-operator/controllers/factory/vectorpipeline"
+)
+
+func createVectorAgentConfig(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) (*corev1.Secret, error) {
+ cfg, err := getConfig(ctx, v, c)
+ if err != nil {
+ return nil, err
+ }
+
+ labels := labelsForVectorAgent(v.Name)
+ config := map[string][]byte{
+ "agent.json": cfg,
+ }
+
+ secret := &corev1.Secret{
+ ObjectMeta: objectMetaVectorAgent(v, labels),
+ Data: config,
+ }
+
+ return secret, nil
+}
+
+func getConfig(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) ([]byte, error) {
+ vps, err := vectorpipeline.Select(ctx, c)
+ if err != nil {
+ return nil, err
+ }
+ cfg, err := vector.GenerateConfig(v, vps)
+ if err != nil {
+ return nil, err
+ }
+
+ return cfg, nil
+}
diff --git a/controllers/factory/vectoragent/vector_agent_controller.go b/controllers/factory/vectoragent/vector_agent_controller.go
new file mode 100644
index 00000000..68c1578d
--- /dev/null
+++ b/controllers/factory/vectoragent/vector_agent_controller.go
@@ -0,0 +1,164 @@
+package vectoragent
+
+import (
+ "context"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/helper"
+ "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
+ "github.com/kaasops/vector-operator/controllers/factory/label"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/utils/pointer"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+)
+
+func EnsureVectorAgent(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (done bool, result ctrl.Result, err error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-agent", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Agent")
+
+ if done, result, err = ensureVectorAgentRBAC(vectorCR, rclient); done {
+ return
+ }
+
+ if vectorCR.Spec.Agent.Service {
+ if done, result, err = ensureVectorAgentService(vectorCR, rclient); done {
+ return
+ }
+ }
+
+ if done, result, err = ensureVectorAgentConfig(vectorCR, rclient); done {
+ return
+ }
+
+ if done, result, err = ensureVectorAgentDaemonSet(vectorCR, rclient); done {
+ return
+ }
+
+ return
+}
+
+func ensureVectorAgentRBAC(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-agent-rbac", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Agent RBAC")
+
+ if done, _, err := ensureVectorAgentServiceAccount(vectorCR, rclient); done {
+ return helper.ReconcileResult(err)
+ }
+ if done, _, err := ensureVectorAgentClusterRole(vectorCR, rclient); done {
+ return helper.ReconcileResult(err)
+ }
+ if done, _, err := ensureVectorAgentClusterRoleBinding(vectorCR, rclient); done {
+ return helper.ReconcileResult(err)
+ }
+
+ return helper.ReconcileResult(nil)
+}
+
+func ensureVectorAgentServiceAccount(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ vectorAgentServiceAccount := createVectorAgentServiceAccount(vectorCR)
+
+ _, err := k8sutils.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, rclient)
+
+ return helper.ReconcileResult(err)
+}
+
+func ensureVectorAgentClusterRole(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ vectorAgentClusterRole := createVectorAgentClusterRole(vectorCR)
+
+ _, err := k8sutils.CreateOrUpdateClusterRole(vectorAgentClusterRole, rclient)
+
+ return helper.ReconcileResult(err)
+}
+
+func ensureVectorAgentClusterRoleBinding(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ vectorAgentClusterRoleBinding := createVectorAgentClusterRoleBinding(vectorCR)
+
+ _, err := k8sutils.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, rclient)
+
+ return helper.ReconcileResult(err)
+}
+
+func ensureVectorAgentService(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-agent-service", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Agent Service")
+
+ vectorAgentService := createVectorAgentService(vectorCR)
+
+ _, err := k8sutils.CreateOrUpdateService(vectorAgentService, rclient)
+
+ return helper.ReconcileResult(err)
+}
+
+func ensureVectorAgentConfig(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-agent-secret", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Agent Secret")
+
+ vectorAgentSecret, err := createVectorAgentConfig(ctx, vectorCR, rclient)
+ if err != nil {
+ return helper.ReconcileResult(err)
+ }
+
+ _, err = k8sutils.CreateOrUpdateSecret(vectorAgentSecret, rclient)
+
+ return helper.ReconcileResult(err)
+}
+
+func ensureVectorAgentDaemonSet(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ ctx := context.Background()
+ log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", vectorCR.Name)
+
+ log.Info("start Reconcile Vector Agent DaemonSet")
+
+ vectorAgentDaemonSet := createVectorAgentDaemonSet(vectorCR)
+
+ _, err := k8sutils.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, rclient)
+
+ return helper.ReconcileResult(err)
+}
+
+func labelsForVectorAgent(name string) map[string]string {
+ return map[string]string{
+ label.ManagedByLabelKey: "vector-operator",
+ label.NameLabelKey: "vector",
+ label.ComponentLabelKey: "Agent",
+ label.InstanceLabelKey: name,
+ label.VectorExcludeLabel: "true",
+ }
+}
+
+func objectMetaVectorAgent(v *vectorv1alpha1.Vector, labels map[string]string) metav1.ObjectMeta {
+ return metav1.ObjectMeta{
+ Name: v.Name + "-agent",
+ Namespace: v.Namespace,
+ Labels: labels,
+ OwnerReferences: getControllerReference(v),
+ }
+}
+
+func getNameVectorAgent(v *vectorv1alpha1.Vector) string {
+ name := v.Name + "-agent"
+ return name
+}
+
+func getControllerReference(owner *vectorv1alpha1.Vector) []metav1.OwnerReference {
+ return []metav1.OwnerReference{
+ {
+ APIVersion: owner.APIVersion,
+ Kind: owner.Kind,
+ Name: owner.GetName(),
+ UID: owner.GetUID(),
+ BlockOwnerDeletion: pointer.BoolPtr(true),
+ Controller: pointer.BoolPtr(true),
+ },
+ }
+}
diff --git a/controllers/vector_agent_daemonset.go b/controllers/factory/vectoragent/vector_agent_daemonset.go
similarity index 95%
rename from controllers/vector_agent_daemonset.go
rename to controllers/factory/vectoragent/vector_agent_daemonset.go
index 9a83ec75..57309d29 100644
--- a/controllers/vector_agent_daemonset.go
+++ b/controllers/factory/vectoragent/vector_agent_daemonset.go
@@ -1,4 +1,4 @@
-package controllers
+package vectoragent
import (
appsv1 "k8s.io/api/apps/v1"
@@ -8,7 +8,7 @@ import (
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
)
-func (r *VectorReconciler) createVectorAgentDaemonSet(v *vectorv1alpha1.Vector) *appsv1.DaemonSet {
+func createVectorAgentDaemonSet(v *vectorv1alpha1.Vector) *appsv1.DaemonSet {
labels := labelsForVectorAgent(v.Name)
daemonset := &appsv1.DaemonSet{
@@ -25,7 +25,7 @@ func (r *VectorReconciler) createVectorAgentDaemonSet(v *vectorv1alpha1.Vector)
{
Name: getNameVectorAgent(v),
Image: v.Spec.Agent.Image,
- Args: []string{"--config-dir", "/etc/vector/"},
+ Args: []string{"--config-dir", "/etc/vector/", "--watch-config"},
Env: generateVectorAgentEnvs(v),
Ports: []corev1.ContainerPort{
{
diff --git a/controllers/vector_agent_rbac.go b/controllers/factory/vectoragent/vector_agent_rbac.go
similarity index 75%
rename from controllers/vector_agent_rbac.go
rename to controllers/factory/vectoragent/vector_agent_rbac.go
index f72137ae..6ea637b4 100644
--- a/controllers/vector_agent_rbac.go
+++ b/controllers/factory/vectoragent/vector_agent_rbac.go
@@ -1,4 +1,4 @@
-package controllers
+package vectoragent
import (
corev1 "k8s.io/api/core/v1"
@@ -7,7 +7,7 @@ import (
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
)
-func (r *VectorReconciler) createVectorAgentServiceAccount(v *vectorv1alpha1.Vector) *corev1.ServiceAccount {
+func createVectorAgentServiceAccount(v *vectorv1alpha1.Vector) *corev1.ServiceAccount {
labels := labelsForVectorAgent(v.Name)
serviceAccount := &corev1.ServiceAccount{
@@ -17,7 +17,7 @@ func (r *VectorReconciler) createVectorAgentServiceAccount(v *vectorv1alpha1.Vec
return serviceAccount
}
-func (r *VectorReconciler) createVectorAgentClusterRole(v *vectorv1alpha1.Vector) *rbacv1.ClusterRole {
+func createVectorAgentClusterRole(v *vectorv1alpha1.Vector) *rbacv1.ClusterRole {
labels := labelsForVectorAgent(v.Name)
clusterRole := &rbacv1.ClusterRole{
@@ -34,7 +34,7 @@ func (r *VectorReconciler) createVectorAgentClusterRole(v *vectorv1alpha1.Vector
return clusterRole
}
-func (r *VectorReconciler) createVectorAgentClusterRoleBinding(v *vectorv1alpha1.Vector) *rbacv1.ClusterRoleBinding {
+func createVectorAgentClusterRoleBinding(v *vectorv1alpha1.Vector) *rbacv1.ClusterRoleBinding {
labels := labelsForVectorAgent(v.Name)
clusterRoleBinding := &rbacv1.ClusterRoleBinding{
diff --git a/controllers/vector_agent_service.go b/controllers/factory/vectoragent/vector_agent_service.go
similarity index 82%
rename from controllers/vector_agent_service.go
rename to controllers/factory/vectoragent/vector_agent_service.go
index 44060865..c30909bd 100644
--- a/controllers/vector_agent_service.go
+++ b/controllers/factory/vectoragent/vector_agent_service.go
@@ -1,4 +1,4 @@
-package controllers
+package vectoragent
import (
corev1 "k8s.io/api/core/v1"
@@ -7,7 +7,7 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)
-func (r *VectorReconciler) createVectorAgentService(v *vectorv1alpha1.Vector) *corev1.Service {
+func createVectorAgentService(v *vectorv1alpha1.Vector) *corev1.Service {
labels := labelsForVectorAgent(v.Name)
service := &corev1.Service{
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
new file mode 100644
index 00000000..11dc31ea
--- /dev/null
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -0,0 +1,38 @@
+package vectorpipeline
+
+import (
+ "context"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+func Select(ctx context.Context, rclient client.Client) (map[string]*vectorv1alpha1.VectorPipeline, error) {
+
+ res := make(map[string]*vectorv1alpha1.VectorPipeline)
+
+ var vectorPipelinesCombined []vectorv1alpha1.VectorPipeline
+
+ objlist := vectorv1alpha1.VectorPipelineList{}
+ err := rclient.List(ctx, &objlist)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, item := range objlist.Items {
+ if !item.DeletionTimestamp.IsZero() {
+ continue
+ }
+ vectorPipelinesCombined = append(vectorPipelinesCombined, item)
+ }
+
+ for _, vectorPipeline := range vectorPipelinesCombined {
+ m := vectorPipeline.DeepCopy()
+ res[generateName(&vectorPipeline)] = m
+ }
+ return res, nil
+}
+
+func generateName(pipelineCR *vectorv1alpha1.VectorPipeline) string {
+ return pipelineCR.Namespace + "-" + pipelineCR.Name
+}
diff --git a/controllers/vector_agent_controller.go b/controllers/vector_agent_controller.go
deleted file mode 100644
index 8f3dae1c..00000000
--- a/controllers/vector_agent_controller.go
+++ /dev/null
@@ -1,162 +0,0 @@
-package controllers
-
-import (
- "context"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/label"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
- "sigs.k8s.io/controller-runtime/pkg/log"
-)
-
-func (r *VectorReconciler) ensureVectorAgent(vectorCR *vectorv1alpha1.Vector) (done bool, result ctrl.Result, err error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent", vectorCR.Name)
-
- log.Info("start Reconcile Vector Agent")
-
- if done, result, err = r.ensureVectorAgentRBAC(vectorCR); done {
- return
- }
-
- if vectorCR.Spec.Agent.Service {
- if done, result, err = r.ensureVectorAgentService(vectorCR); done {
- return
- }
- }
-
- if done, result, err = r.ensureVectorAgentSecret(vectorCR); done {
- return
- }
-
- if done, result, err = r.ensureVectorAgentDaemonSet(vectorCR); done {
- return
- }
-
- return
-}
-
-func (r *VectorReconciler) ensureVectorAgentRBAC(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-rbac", vectorCR.Name)
-
- log.Info("start Reconcile Vector Agent RBAC")
-
- if done, _, err := r.ensureVectorAgentServiceAccount(vectorCR); done {
- return ReconcileResult(err)
- }
- if done, _, err := r.ensureVectorAgentClusterRole(vectorCR); done {
- return ReconcileResult(err)
- }
- if done, _, err := r.ensureVectorAgentClusterRoleBinding(vectorCR); done {
- return ReconcileResult(err)
- }
-
- return ReconcileResult(nil)
-}
-
-func (r *VectorReconciler) ensureVectorAgentServiceAccount(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- vectorAgentServiceAccount := r.createVectorAgentServiceAccount(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAgentServiceAccount, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateServiceAccount(vectorAgentServiceAccount)
-
- return ReconcileResult(err)
-}
-
-func (r *VectorReconciler) ensureVectorAgentClusterRole(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- vectorAgentClusterRole := r.createVectorAgentClusterRole(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAgentClusterRole, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateClusterRole(vectorAgentClusterRole)
-
- return ReconcileResult(err)
-}
-
-func (r *VectorReconciler) ensureVectorAgentClusterRoleBinding(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- vectorAgentClusterRoleBinding := r.createVectorAgentClusterRoleBinding(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAgentClusterRoleBinding, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding)
-
- return ReconcileResult(err)
-}
-
-func (r *VectorReconciler) ensureVectorAgentService(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-service", vectorCR.Name)
-
- log.Info("start Reconcile Vector Agent Service")
-
- vectorAgentService := r.createVectorAgentService(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAgentService, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateService(vectorAgentService)
-
- return ReconcileResult(err)
-}
-
-func (r *VectorReconciler) ensureVectorAgentSecret(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-secret", vectorCR.Name)
-
- log.Info("start Reconcile Vector Agent Secret")
-
- vectorAgentSecret := r.createVectorAgentSecret(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAgentSecret, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateSecret(vectorAgentSecret)
-
- return ReconcileResult(err)
-}
-
-func (r *VectorReconciler) ensureVectorAgentDaemonSet(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", vectorCR.Name)
-
- log.Info("start Reconcile Vector Agent DaemonSet")
-
- vectorAgentDaemonSet := r.createVectorAgentDaemonSet(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAgentDaemonSet, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateDaemonSet(vectorAgentDaemonSet)
-
- return ReconcileResult(err)
-}
-
-func labelsForVectorAgent(name string) map[string]string {
- return map[string]string{
- label.ManagedByLabelKey: "vector-operator",
- label.NameLabelKey: "vector",
- label.ComponentLabelKey: "Agent",
- label.InstanceLabelKey: name,
- label.VectorExcludeLabel: "true",
- }
-}
-
-func objectMetaVectorAgent(v *vectorv1alpha1.Vector, labels map[string]string) metav1.ObjectMeta {
- return metav1.ObjectMeta{
- Name: v.Name + "-agent",
- Namespace: v.Namespace,
- Labels: labels,
- }
-}
-
-func getNameVectorAgent(v *vectorv1alpha1.Vector) string {
- name := v.Name + "-agent"
- return name
-}
diff --git a/controllers/vector_agent_secret.go b/controllers/vector_agent_secret.go
deleted file mode 100644
index f4657efb..00000000
--- a/controllers/vector_agent_secret.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package controllers
-
-import (
- corev1 "k8s.io/api/core/v1"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
-)
-
-var vectorAgentConfig = `
-data_dir: /vector-data-dir
-api:
- enabled: true
- address: 127.0.0.1:8686
- playground: false
-sources:
- kubernetes_logs:
- type: kubernetes_logs
-sinks:
- stdout:
- type: console
- inputs: [kubernetes_logs]
- encoding:
- codec: json
- vector:
- type: vector
- inputs: [kubernetes_logs]
- address: vector-sample-aggregator:6000
-`
-
-func (r *VectorReconciler) createVectorAgentSecret(v *vectorv1alpha1.Vector) *corev1.Secret {
- labels := labelsForVectorAgent(v.Name)
-
- config := map[string][]byte{
- "agent.yaml": []byte(vectorAgentConfig),
- }
-
- secret := &corev1.Secret{
- ObjectMeta: objectMetaVectorAgent(v, labels),
- Data: config,
- }
- return secret
-}
diff --git a/controllers/vector_aggregator_controller.go b/controllers/vector_aggregator_controller.go
deleted file mode 100644
index ed5e2597..00000000
--- a/controllers/vector_aggregator_controller.go
+++ /dev/null
@@ -1,132 +0,0 @@
-package controllers
-
-import (
- "context"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/label"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
- "sigs.k8s.io/controller-runtime/pkg/log"
-)
-
-func (r *VectorReconciler) ensureVectorAggregator(vectorCR *vectorv1alpha1.Vector) (done bool, result ctrl.Result, err error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-aggregator", vectorCR.Name)
-
- log.Info("start Reconcile Vector Aggregator")
-
- if done, result, err = r.ensureVectorRBAC(vectorCR); done {
- return
- }
-
- if done, result, err = r.ensureVectorAggregatorService(vectorCR); done {
- return
- }
-
- if done, result, err = r.ensureVectorAggregatorSecret(vectorCR); done {
- return
- }
-
- if done, result, err = r.ensureVectorAggregatorStatefulSet(vectorCR); done {
- return
- }
-
- return
-}
-
-func (r *VectorReconciler) ensureVectorRBAC(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-aggregator-rbac", vectorCR.Name)
-
- log.Info("start Reconcile Vector Aggregator RBAC")
-
- if done, _, err := r.ensureVectorAggregatorServiceAccount(vectorCR); done {
- return ReconcileResult(err)
- }
-
- return ReconcileResult(nil)
-}
-
-func (r *VectorReconciler) ensureVectorAggregatorServiceAccount(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- vectorAggregatorServiceAccount := r.createVectorAggregatorServiceAccount(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAggregatorServiceAccount, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateServiceAccount(vectorAggregatorServiceAccount)
-
- return ReconcileResult(err)
-}
-
-func (r *VectorReconciler) ensureVectorAggregatorService(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-aggregator-service", vectorCR.Name)
-
- log.Info("start Reconcile Vector Aggregator Service")
-
- vectorAggregatorService := r.createVectorAggregatorService(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAggregatorService, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateService(vectorAggregatorService)
-
- return ReconcileResult(err)
-}
-
-func (r *VectorReconciler) ensureVectorAggregatorSecret(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-aggregator-secret", vectorCR.Name)
-
- log.Info("start Reconcile Vector Aggregator Secret")
-
- vectorAggregatorSecret := r.createVectorAggregatorSecret(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAggregatorSecret, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateSecret(vectorAggregatorSecret)
-
- return ReconcileResult(err)
-}
-
-func (r *VectorReconciler) ensureVectorAggregatorStatefulSet(vectorCR *vectorv1alpha1.Vector) (bool, ctrl.Result, error) {
- ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-aggregator-statefulset", vectorCR.Name)
-
- log.Info("start Reconcile Vector Aggregator StatefulSet")
-
- vectorAggregatorStatefulSet := r.createVectorAggregatorStatefulSet(vectorCR)
-
- if err := controllerutil.SetControllerReference(vectorCR, vectorAggregatorStatefulSet, r.Scheme); err != nil {
- return ReconcileResult(err)
- }
- _, err := r.CreateOrUpdateStatefulSet(vectorAggregatorStatefulSet)
-
- return ReconcileResult(err)
-}
-
-func labelsForVectorAggregator(name string) map[string]string {
- return map[string]string{
- label.ManagedByLabelKey: "vector-operator",
- label.NameLabelKey: "vector",
- label.ComponentLabelKey: "Aggregator",
- label.InstanceLabelKey: name,
- label.VectorExcludeLabel: "true",
- }
-}
-
-func objectMetaVectorAggregator(v *vectorv1alpha1.Vector, labels map[string]string) metav1.ObjectMeta {
- return metav1.ObjectMeta{
- Name: v.Name + "-aggregator",
- Namespace: v.Namespace,
- Labels: labels,
- }
-}
-
-func getNameVectorAggregator(v *vectorv1alpha1.Vector) string {
- name := v.Name + "-aggregator"
- return name
-}
diff --git a/controllers/vector_aggregator_rbac.go b/controllers/vector_aggregator_rbac.go
deleted file mode 100644
index 67511128..00000000
--- a/controllers/vector_aggregator_rbac.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package controllers
-
-import (
- corev1 "k8s.io/api/core/v1"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
-)
-
-func (r *VectorReconciler) createVectorAggregatorServiceAccount(v *vectorv1alpha1.Vector) *corev1.ServiceAccount {
- labels := labelsForVectorAggregator(v.Name)
-
- serviceAccount := &corev1.ServiceAccount{
- ObjectMeta: objectMetaVectorAggregator(v, labels),
- }
-
- return serviceAccount
-}
diff --git a/controllers/vector_aggregator_secret.go b/controllers/vector_aggregator_secret.go
deleted file mode 100644
index 60bef159..00000000
--- a/controllers/vector_aggregator_secret.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package controllers
-
-import (
- corev1 "k8s.io/api/core/v1"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
-)
-
-var vectorAggregatorConfig = `
-data_dir: /vector-data-dir
-api:
- enabled: true
- address: 127.0.0.1:8686
- playground: false
-sources:
- vector:
- address: 0.0.0.0:6000
- type: vector
- version: "2"
-sinks:
- stdout:
- type: console
- inputs: [vector]
- encoding:
- codec: json
-`
-
-func (r *VectorReconciler) createVectorAggregatorSecret(v *vectorv1alpha1.Vector) *corev1.Secret {
- labels := labelsForVectorAggregator(v.Name)
-
- config := map[string][]byte{
- "aggregator.yaml": []byte(vectorAggregatorConfig),
- }
-
- secret := &corev1.Secret{
- ObjectMeta: objectMetaVectorAggregator(v, labels),
- Data: config,
- }
- return secret
-}
diff --git a/controllers/vector_aggregator_service.go b/controllers/vector_aggregator_service.go
deleted file mode 100644
index 2e500c12..00000000
--- a/controllers/vector_aggregator_service.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package controllers
-
-import (
- corev1 "k8s.io/api/core/v1"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "k8s.io/apimachinery/pkg/util/intstr"
-)
-
-func (r *VectorReconciler) createVectorAggregatorService(v *vectorv1alpha1.Vector) *corev1.Service {
- labels := labelsForVectorAggregator(v.Name)
-
- service := &corev1.Service{
- ObjectMeta: objectMetaVectorAggregator(v, labels),
- Spec: corev1.ServiceSpec{
- Ports: []corev1.ServicePort{
- {
- Name: "vector",
- Protocol: corev1.Protocol("TCP"),
- Port: 6000,
- TargetPort: intstr.FromInt(6000),
- },
- },
- Selector: labels,
- },
- }
- return service
-}
diff --git a/controllers/vector_aggregator_statefulset.go b/controllers/vector_aggregator_statefulset.go
deleted file mode 100644
index 232b7e92..00000000
--- a/controllers/vector_aggregator_statefulset.go
+++ /dev/null
@@ -1,82 +0,0 @@
-package controllers
-
-import (
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- appsv1 "k8s.io/api/apps/v1"
- corev1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-func (r *VectorReconciler) createVectorAggregatorStatefulSet(v *vectorv1alpha1.Vector) *appsv1.StatefulSet {
- labels := labelsForVectorAggregator(v.Name)
- replicas := int32(v.Spec.Aggregator.Replicas)
- statefulset := &appsv1.StatefulSet{
- ObjectMeta: objectMetaVectorAggregator(v, labels),
- Spec: appsv1.StatefulSetSpec{
- Selector: &metav1.LabelSelector{MatchLabels: labels},
- Replicas: &replicas,
- Template: corev1.PodTemplateSpec{
- ObjectMeta: objectMetaVectorAggregator(v, labels),
- Spec: corev1.PodSpec{
- ServiceAccountName: getNameVectorAggregator(v),
- Volumes: generateVectorAggregatorVolume(v),
- SecurityContext: &corev1.PodSecurityContext{},
- Containers: []corev1.Container{
- {
- Name: getNameVectorAggregator(v),
- Image: v.Spec.Aggregator.Image,
- Args: []string{"--config-dir", "/etc/vector/"},
- Ports: []corev1.ContainerPort{
- {
- Name: "vector",
- ContainerPort: 6000,
- Protocol: "TCP",
- },
- },
- VolumeMounts: generateVectorAggregatorVolumeMounts(v),
- SecurityContext: &corev1.SecurityContext{},
- },
- },
- },
- },
- },
- }
-
- return statefulset
-}
-
-func generateVectorAggregatorVolume(v *vectorv1alpha1.Vector) []corev1.Volume {
- volume := []corev1.Volume{
- {
- Name: "config",
- VolumeSource: corev1.VolumeSource{
- Secret: &corev1.SecretVolumeSource{
- SecretName: getNameVectorAggregator(v),
- },
- },
- },
- {
- Name: "data",
- VolumeSource: corev1.VolumeSource{
- EmptyDir: &corev1.EmptyDirVolumeSource{},
- },
- },
- }
-
- return volume
-}
-
-func generateVectorAggregatorVolumeMounts(spec *vectorv1alpha1.Vector) []corev1.VolumeMount {
- volumeMount := []corev1.VolumeMount{
- {
- Name: "config",
- MountPath: "/etc/vector/",
- },
- {
- Name: "data",
- MountPath: "/vector-data-dir",
- },
- }
-
- return volumeMount
-}
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 29a40413..d3c5c9a9 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -20,6 +20,7 @@ import (
"context"
"time"
+ "github.com/kaasops/vector-operator/controllers/factory/vectoragent"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
@@ -34,6 +35,8 @@ import (
type VectorReconciler struct {
client.Client
Scheme *runtime.Scheme
+ // Config *VectorConfig
+ // Status *VectorPipelineReconcileStatus
}
//+kubebuilder:rbac:groups=observability.kaasops.io,resources=vectors,verbs=get;list;watch;create;update;patch;delete
@@ -60,17 +63,11 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return result, err
}
- if done, result, err = r.ensureVectorAgent(vectorCR); done {
- return result, err
+ if vectorCR.Spec.Agent.DataDir == "" {
+ vectorCR.Spec.Agent.DataDir = "/vector-data-dir"
}
- if vectorCR.Spec.Aggregator.Enable {
- if done, result, err = r.ensureVectorAggregator(vectorCR); done {
- return result, err
- }
- }
-
- return ctrl.Result{RequeueAfter: 5 * time.Second}, nil
+ return CreateOrUpdateVector(ctx, vectorCR, r.Client)
}
func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.Vector, bool, ctrl.Result, error) {
@@ -99,3 +96,11 @@ func (r *VectorReconciler) SetupWithManager(mgr ctrl.Manager) error {
For(&vectorv1alpha1.Vector{}).
Complete(r)
}
+
+func CreateOrUpdateVector(ctx context.Context, vector *vectorv1alpha1.Vector, rclient client.Client) (ctrl.Result, error) {
+ if done, result, err := vectoragent.EnsureVectorAgent(vector, rclient); done {
+ return result, err
+ }
+
+ return ctrl.Result{RequeueAfter: 60 * time.Second}, nil
+}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 13f4b773..11c83e69 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -24,7 +24,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
- observabilityv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
)
// VectorPipelineReconciler reconciles a VectorPipeline object
@@ -48,8 +48,29 @@ type VectorPipelineReconciler struct {
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.2/pkg/reconcile
func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = log.FromContext(ctx)
+ log := log.FromContext(ctx).WithValues("VectorPipeline", req.NamespacedName)
- // TODO(user): your logic here
+ log.Info("start Reconcile VectorPipeline")
+
+ vectorInstances := &vectorv1alpha1.VectorList{}
+ err := r.List(ctx, vectorInstances)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
+ if len(vectorInstances.Items) == 0 {
+ log.Info("Vertors not found")
+ return ctrl.Result{}, nil
+ }
+
+ for _, vector := range vectorInstances.Items {
+ if vector.DeletionTimestamp != nil {
+ continue
+ }
+ currentVector := &vector
+ CreateOrUpdateVector(ctx, currentVector, r.Client)
+
+ }
return ctrl.Result{}, nil
}
@@ -57,6 +78,6 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// SetupWithManager sets up the controller with the Manager.
func (r *VectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
- For(&observabilityv1alpha1.VectorPipeline{}).
+ For(&vectorv1alpha1.VectorPipeline{}).
Complete(r)
}
diff --git a/go.mod b/go.mod
index d981895a..f5a02560 100644
--- a/go.mod
+++ b/go.mod
@@ -6,6 +6,7 @@ require (
github.com/go-logr/logr v1.2.0
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.18.1
+ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
k8s.io/api v0.24.2
k8s.io/apimachinery v0.24.2
k8s.io/client-go v0.24.2
@@ -71,7 +72,6 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/apiextensions-apiserver v0.24.2 // indirect
k8s.io/component-base v0.24.2 // indirect
k8s.io/klog/v2 v2.60.1 // indirect
From 524b6fee1f22584890a36ab8d6bf39e4b0080090 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Wed, 19 Oct 2022 17:34:05 +0300
Subject: [PATCH 006/316] Custom api for all objects (#6)
* custom api for all components in vector config
---
api/v1alpha1/vectorpipeline_types.go | 40 +-----
api/v1alpha1/zz_generated.deepcopy.go | 128 ++---------------
...ervability.kaasops.io_vectorpipelines.yaml | 52 +------
.../observability_v1alpha1_vector.yaml | 2 +-
...observability_v1alpha1_vectorpipeline.yaml | 21 ++-
controllers/factory/vector/config_build.go | 130 +++++++++++-------
controllers/factory/vector/types.go | 12 +-
go.mod | 4 +-
8 files changed, 126 insertions(+), 263 deletions(-)
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index f7216988..8d5b4a36 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -18,6 +18,7 @@ package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
@@ -25,39 +26,12 @@ import (
// VectorPipelineSpec defines the desired state of VectorPipeline
type VectorPipelineSpec struct {
- Source map[string]SourceSpec `json:"source,omitempty"`
- Transforms map[string]TransformSpec `json:"transforms,omitempty"`
- Sink map[string]SinkSpec `json:"sinks,omitempty"`
-}
-
-type TransformSpec struct {
- Type string `json:"type,omitempty"`
- Inputs []string `json:"inputs,omitempty"`
- Condition *Condition `json:"condition,omitempty"`
-}
-
-type Condition struct {
- Type string `json:"type,omitempty"`
- Source string `json:"source,omitempty"`
-}
-
-type SourceSpec struct {
- Type string `json:"type,omitempty"`
- ExtraLabelSelector string `json:"extra_label_selector,omitempty"`
- ExtraFieldSelector string `json:"extra_field_selector,omitempty"`
-}
-
-type SinkSpec struct {
- Type string `json:"type,omitempty"`
- Address string `json:"address,omitempty"`
- Inputs []string `json:"inputs,omitempty"`
- Encoding *Encoding `json:"encoding,omitempty"`
- Rate *int32 `json:"rate,omitempty"`
- PrintIntervalSecs int32 `json:"print_interval_secs,omitempty"`
-}
-
-type Encoding struct {
- Codec string `json:"codec,omitempty"`
+ // +kubebuilder:pruning:PreserveUnknownFields
+ Sources *runtime.RawExtension `json:"sources,omitempty"`
+ // +kubebuilder:pruning:PreserveUnknownFields
+ Transforms *runtime.RawExtension `json:"transforms,omitempty"`
+ // +kubebuilder:pruning:PreserveUnknownFields
+ Sinks *runtime.RawExtension `json:"sinks,omitempty"`
}
// VectorPipelineStatus defines the observed state of VectorPipeline
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index c51b2b8a..7740556c 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -22,109 +22,9 @@ limitations under the License.
package v1alpha1
import (
- runtime "k8s.io/apimachinery/pkg/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 *Condition) DeepCopyInto(out *Condition) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
-func (in *Condition) DeepCopy() *Condition {
- if in == nil {
- return nil
- }
- out := new(Condition)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Encoding) DeepCopyInto(out *Encoding) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Encoding.
-func (in *Encoding) DeepCopy() *Encoding {
- if in == nil {
- return nil
- }
- out := new(Encoding)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SinkSpec) DeepCopyInto(out *SinkSpec) {
- *out = *in
- if in.Inputs != nil {
- in, out := &in.Inputs, &out.Inputs
- *out = make([]string, len(*in))
- copy(*out, *in)
- }
- if in.Encoding != nil {
- in, out := &in.Encoding, &out.Encoding
- *out = new(Encoding)
- **out = **in
- }
- if in.Rate != nil {
- in, out := &in.Rate, &out.Rate
- *out = new(int32)
- **out = **in
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SinkSpec.
-func (in *SinkSpec) DeepCopy() *SinkSpec {
- if in == nil {
- return nil
- }
- out := new(SinkSpec)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SourceSpec) DeepCopyInto(out *SourceSpec) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceSpec.
-func (in *SourceSpec) DeepCopy() *SourceSpec {
- if in == nil {
- return nil
- }
- out := new(SourceSpec)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *TransformSpec) DeepCopyInto(out *TransformSpec) {
- *out = *in
- if in.Inputs != nil {
- in, out := &in.Inputs, &out.Inputs
- *out = make([]string, len(*in))
- copy(*out, *in)
- }
- if in.Condition != nil {
- in, out := &in.Condition, &out.Condition
- *out = new(Condition)
- **out = **in
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TransformSpec.
-func (in *TransformSpec) DeepCopy() *TransformSpec {
- if in == nil {
- return nil
- }
- out := new(TransformSpec)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Vector) DeepCopyInto(out *Vector) {
*out = *in
@@ -276,26 +176,20 @@ func (in *VectorPipelineList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VectorPipelineSpec) DeepCopyInto(out *VectorPipelineSpec) {
*out = *in
- if in.Source != nil {
- in, out := &in.Source, &out.Source
- *out = make(map[string]SourceSpec, len(*in))
- for key, val := range *in {
- (*out)[key] = val
- }
+ if in.Sources != nil {
+ in, out := &in.Sources, &out.Sources
+ *out = new(runtime.RawExtension)
+ (*in).DeepCopyInto(*out)
}
if in.Transforms != nil {
in, out := &in.Transforms, &out.Transforms
- *out = make(map[string]TransformSpec, len(*in))
- for key, val := range *in {
- (*out)[key] = *val.DeepCopy()
- }
+ *out = new(runtime.RawExtension)
+ (*in).DeepCopyInto(*out)
}
- if in.Sink != nil {
- in, out := &in.Sink, &out.Sink
- *out = make(map[string]SinkSpec, len(*in))
- for key, val := range *in {
- (*out)[key] = *val.DeepCopy()
- }
+ if in.Sinks != nil {
+ in, out := &in.Sinks, &out.Sinks
+ *out = new(runtime.RawExtension)
+ (*in).DeepCopyInto(*out)
}
}
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
index c6c317f1..74844416 100644
--- a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -36,58 +36,14 @@ spec:
description: VectorPipelineSpec defines the desired state of VectorPipeline
properties:
sinks:
- additionalProperties:
- properties:
- address:
- type: string
- encoding:
- properties:
- codec:
- type: string
- type: object
- inputs:
- items:
- type: string
- type: array
- print_interval_secs:
- format: int32
- type: integer
- rate:
- format: int32
- type: integer
- type:
- type: string
- type: object
type: object
- source:
- additionalProperties:
- properties:
- extra_field_selector:
- type: string
- extra_label_selector:
- type: string
- type:
- type: string
- type: object
+ x-kubernetes-preserve-unknown-fields: true
+ sources:
type: object
+ x-kubernetes-preserve-unknown-fields: true
transforms:
- additionalProperties:
- properties:
- condition:
- properties:
- source:
- type: string
- type:
- type: string
- type: object
- inputs:
- items:
- type: string
- type: array
- type:
- type: string
- type: object
type: object
+ x-kubernetes-preserve-unknown-fields: true
type: object
status:
description: VectorPipelineStatus defines the observed state of VectorPipeline
diff --git a/config/samples/observability_v1alpha1_vector.yaml b/config/samples/observability_v1alpha1_vector.yaml
index b667b124..3a7845c3 100644
--- a/config/samples/observability_v1alpha1_vector.yaml
+++ b/config/samples/observability_v1alpha1_vector.yaml
@@ -2,7 +2,7 @@ apiVersion: observability.kaasops.io/v1alpha1
kind: Vector
metadata:
name: vector-sample
- namespace: vector-operator-system
+ namespace: vector
spec:
agent:
service: true
diff --git a/config/samples/observability_v1alpha1_vectorpipeline.yaml b/config/samples/observability_v1alpha1_vectorpipeline.yaml
index d56874f5..9b043123 100644
--- a/config/samples/observability_v1alpha1_vectorpipeline.yaml
+++ b/config/samples/observability_v1alpha1_vectorpipeline.yaml
@@ -3,25 +3,36 @@ kind: VectorPipeline
metadata:
name: vectorpipeline-sample
spec:
- source:
+ sources:
test1:
type: "kubernetes_logs"
extra_label_selector: "app!=testdeployment"
+ test2:
+ type: "kubernetes_logs"
+ extra_label_selector: "app!=testdeployment1"
transforms:
- test:
+ test11:
type: "filter"
inputs:
- test1
+ - test2
+ condition:
+ type: "vrl"
+ source: ".status != 200"
+ test33:
+ type: "filter"
+ inputs:
+ - test11
condition:
type: "vrl"
source: ".status != 200"
sinks:
- test2:
+ test222:
type: "console"
encoding:
codec: "json"
inputs:
- - test1
+ - test33
---
apiVersion: observability.kaasops.io/v1alpha1
kind: VectorPipeline
@@ -29,7 +40,7 @@ metadata:
name: vectorpipeline-sample1
namespace: kube-system
spec:
- source:
+ sources:
test1:
type: "kubernetes_logs"
extra_label_selector: "app!=testdeployment2"
diff --git a/controllers/factory/vector/config_build.go b/controllers/factory/vector/config_build.go
index f2064bb6..98f37b7b 100644
--- a/controllers/factory/vector/config_build.go
+++ b/controllers/factory/vector/config_build.go
@@ -2,21 +2,23 @@ package vector
import (
"encoding/json"
+ "log"
"github.com/kaasops/vector-operator/api/v1alpha1"
+ "k8s.io/apimachinery/pkg/runtime"
)
var (
- sourceDefault = v1alpha1.SourceSpec{
- Type: "kubernetes_logs",
+ sourceDefault = map[string]interface{}{
+ "type": "kubernetes_logs",
}
rate int32 = 100
- sinkDefault = v1alpha1.SinkSpec{
- Type: "blackhole",
- Inputs: []string{"defaultSource"},
- Rate: &rate,
- PrintIntervalSecs: 60,
+ sinkDefault = map[string]interface{}{
+ "type": "blackhole",
+ "inputs": []string{"defaultSource"},
+ "rate": rate,
+ "printIntervalSecs": 60,
}
)
@@ -25,16 +27,15 @@ func GenerateConfig(
vp map[string]*v1alpha1.VectorPipeline,
) ([]byte, error) {
cfg := NewVectorConfig(cr.Spec.Agent.DataDir, cr.Spec.Agent.ApiEnabled)
- sources, transforms, sinks := getComponents(vp)
+ sources, transforms, sinks, err := getComponents(vp)
+ if err != nil {
+ log.Fatal(err)
+ }
if len(sources) == 0 {
- sources = map[string]*v1alpha1.SourceSpec{
- "defaultSource": &sourceDefault,
- }
+ sources = sourceDefault
}
if len(sinks) == 0 {
- sinks = map[string]*v1alpha1.SinkSpec{
- "defaultSink": &sinkDefault,
- }
+ sinks = sinkDefault
}
cfg.Sinks = sinks
@@ -45,8 +46,8 @@ func GenerateConfig(
}
func NewVectorConfig(dataDir string, apiEnabled bool) *VectorConfig {
- sources := make(map[string]*v1alpha1.SourceSpec)
- sinks := make(map[string]*v1alpha1.SinkSpec)
+ sources := make(map[string]interface{})
+ sinks := make(map[string]interface{})
return &VectorConfig{
DataDir: dataDir,
@@ -58,50 +59,46 @@ func NewVectorConfig(dataDir string, apiEnabled bool) *VectorConfig {
}
}
-func getComponents(vps map[string]*v1alpha1.VectorPipeline) (map[string]*v1alpha1.SourceSpec, map[string]*v1alpha1.TransformSpec, map[string]*v1alpha1.SinkSpec) {
- sources := make(map[string]*v1alpha1.SourceSpec)
- transforms := make(map[string]*v1alpha1.TransformSpec)
- sinks := make(map[string]*v1alpha1.SinkSpec)
+func getComponents(vps map[string]*v1alpha1.VectorPipeline) (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
+ sources := make(map[string]interface{})
+ transforms := make(map[string]interface{})
+ sinks := make(map[string]interface{})
for name, vp := range vps {
- for sourceName, source := range vp.Spec.Source {
- sources[name+"-"+sourceName+"-source"] = &source
+ if vp.Spec.Sources != nil {
+ data, err := decode(vp.Spec.Sources)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ vp_sources := uniqWithPrefix(data, name)
+ for source_k, source_v := range vp_sources {
+ sources[source_k] = source_v
+ }
}
-
- for sinkName, sink := range vp.Spec.Sink {
- inputs := make([]string, 0)
- for _, i := range sink.Inputs {
- newInput := name + "-" + i + "-source"
- inputs = append(inputs, newInput)
+ if vp.Spec.Transforms != nil {
+ data, err := decode(vp.Spec.Transforms)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ vp_transforms := uniqWithPrefix(data, name)
+ for transform_k, transform_v := range vp_transforms {
+ transforms[transform_k] = transform_v
}
-
- sink.Inputs = inputs
- sinks[name+"-"+sinkName+"-source"] = &sink
}
-
- for transformName, transform := range vp.Spec.Transforms {
- inputs := make([]string, 0)
- for _, i := range transform.Inputs {
- newInput := name + "-" + i + "-source"
- inputs = append(inputs, newInput)
+ if vp.Spec.Sinks != nil {
+ data, err := decode(vp.Spec.Sinks)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ vp_sinks := uniqWithPrefix(data, name)
+ for sink_k, sink_v := range vp_sinks {
+ sinks[sink_k] = sink_v
}
-
- transform.Inputs = inputs
- transforms[name+"-"+transformName+"-transform"] = &transform
-
}
}
- return sources, transforms, sinks
+ return sources, transforms, sinks, nil
}
-// func createKeyValuePairs(m map[string]string) string {
-// b := new(bytes.Buffer)
-// for key, value := range m {
-// fmt.Fprintf(b, "%s=\"%s\",", key, value)
-// }
-// return b.String()
-// }
-
func vectorConfigToJson(conf *VectorConfig) ([]byte, error) {
data, err := json.Marshal(conf)
if err != nil {
@@ -110,3 +107,36 @@ func vectorConfigToJson(conf *VectorConfig) ([]byte, error) {
return data, nil
}
+
+func uniqWithPrefix(in map[string]interface{}, prefix string) map[string]interface{} {
+ out := make(map[string]interface{})
+ for k_in, v_in := range in {
+ spec := v_in.(map[string]interface{})
+ out[addPrefix(prefix, k_in)] = spec
+ for k_spec, v_spec := range spec {
+ if k_spec == "inputs" {
+ inputs := make([]string, 0)
+ for _, i := range v_spec.([]interface{}) {
+ newInput := addPrefix(prefix, i.(string))
+ inputs = append(inputs, newInput)
+ }
+ spec[k_spec] = inputs
+ continue
+ }
+ }
+ }
+ return out
+}
+
+func addPrefix(prefix string, name string) string {
+ return prefix + "-" + name
+}
+
+func decode(data *runtime.RawExtension) (map[string]interface{}, error) {
+ out := make(map[string]interface{})
+ err := json.Unmarshal(data.Raw, &out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
diff --git a/controllers/factory/vector/types.go b/controllers/factory/vector/types.go
index 6440c56f..c273d9b6 100644
--- a/controllers/factory/vector/types.go
+++ b/controllers/factory/vector/types.go
@@ -1,13 +1,11 @@
package vector
-import "github.com/kaasops/vector-operator/api/v1alpha1"
-
type VectorConfig struct {
- DataDir string `json:"data_dir,omitempty"`
- Api *ApiSpec `json:"api,omitempty"`
- Sources map[string]*v1alpha1.SourceSpec `json:"sources,omitempty"`
- Transforms map[string]*v1alpha1.TransformSpec `json:"transforms,omitempty"`
- Sinks map[string]*v1alpha1.SinkSpec `json:"sinks,omitempty"`
+ DataDir string `json:"data_dir,omitempty"`
+ Api *ApiSpec `json:"api,omitempty"`
+ Sources map[string]interface{} `json:"sources,omitempty"`
+ Transforms map[string]interface{} `json:"transforms,omitempty"`
+ Sinks map[string]interface{} `json:"sinks,omitempty"`
}
type ApiSpec struct {
diff --git a/go.mod b/go.mod
index f5a02560..3eb591f8 100644
--- a/go.mod
+++ b/go.mod
@@ -6,10 +6,10 @@ require (
github.com/go-logr/logr v1.2.0
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.18.1
- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
k8s.io/api v0.24.2
k8s.io/apimachinery v0.24.2
k8s.io/client-go v0.24.2
+ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
sigs.k8s.io/controller-runtime v0.12.2
)
@@ -72,11 +72,11 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/apiextensions-apiserver v0.24.2 // indirect
k8s.io/component-base v0.24.2 // indirect
k8s.io/klog/v2 v2.60.1 // indirect
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect
- k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
From c2bc376e6378380eccf3952cf87a2fe93b69ed1a Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 20 Oct 2022 09:15:03 +0300
Subject: [PATCH 007/316] disable cache for K8s resources
Signed-off-by: Zemtsov Vladimir
---
main.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/main.go b/main.go
index 5bed1890..ac07ebd3 100644
--- a/main.go
+++ b/main.go
@@ -22,7 +22,10 @@ import (
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
_ "k8s.io/client-go/plugin/pkg/client/auth"
+ "sigs.k8s.io/controller-runtime/pkg/client"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -72,6 +75,8 @@ func main() {
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "79cbe7f3.kaasops.io",
+ ClientDisableCacheFor: []client.Object{&corev1.Secret{}, &corev1.ConfigMap{}, &corev1.Pod{}, &appsv1.Deployment{},
+ &appsv1.StatefulSet{}},
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
// when the Manager ends. This requires the binary to immediately end when the
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
From ee447a1edb37e1b28a4895e2026d0185d87455b8 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 20 Oct 2022 09:16:01 +0300
Subject: [PATCH 008/316] add vscode to gitignore
Signed-off-by: Zemtsov Vladimir
---
.gitignore | 1 +
.vscode/launch.json | 15 ---------------
2 files changed, 1 insertion(+), 15 deletions(-)
delete mode 100644 .vscode/launch.json
diff --git a/.gitignore b/.gitignore
index c0a7a54c..c2b8826e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,4 @@ testbin/*
*.swp
*.swo
*~
+.vscode
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 6deb9a6b..00000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "name": "Launch Package",
- "type": "go",
- "request": "launch",
- "mode": "auto",
- "program": "main.go"
- }
- ]
-}
\ No newline at end of file
From af1eb6cf23e1744eb972960908404adb619d495b Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 20 Oct 2022 09:17:24 +0300
Subject: [PATCH 009/316] Add K8s Tolerations to vector agent
Signed-off-by: Zemtsov Vladimir
---
api/v1alpha1/vector_types.go | 10 ++++++----
.../factory/vectoragent/vector_agent_daemonset.go | 1 +
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index d9704da7..3fd76030 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1
import (
+ v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -42,10 +43,11 @@ type VectorStatus struct {
// VectorAgent is the Schema for the Vector Agent
type VectorAgent struct {
// +kubebuilder:default:="timberio/vector:0.24.0-distroless-libc"
- Image string `json:"image,omitempty"`
- DataDir string `json:"dataDir,omitempty"`
- ApiEnabled bool `json:"ApiEnabled,omitempty"`
- Service bool `json:"service,omitempty"`
+ Image string `json:"image,omitempty"`
+ DataDir string `json:"dataDir,omitempty"`
+ ApiEnabled bool `json:"ApiEnabled,omitempty"`
+ Service bool `json:"service,omitempty"`
+ Tolerations []v1.Toleration `json:"tolerations,omitempty"`
}
// VectorAggregator is the Schema for the Vector Aggregator
diff --git a/controllers/factory/vectoragent/vector_agent_daemonset.go b/controllers/factory/vectoragent/vector_agent_daemonset.go
index 57309d29..f06e4804 100644
--- a/controllers/factory/vectoragent/vector_agent_daemonset.go
+++ b/controllers/factory/vectoragent/vector_agent_daemonset.go
@@ -21,6 +21,7 @@ func createVectorAgentDaemonSet(v *vectorv1alpha1.Vector) *appsv1.DaemonSet {
ServiceAccountName: getNameVectorAgent(v),
Volumes: generateVectorAgentVolume(v),
SecurityContext: &corev1.PodSecurityContext{},
+ Tolerations: v.Spec.Agent.Tolerations,
Containers: []corev1.Container{
{
Name: getNameVectorAgent(v),
From 1a0dcf17c3946d2696925a582669044a3d336585 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 20 Oct 2022 09:54:48 +0300
Subject: [PATCH 010/316] Push tolerations crd in vector agent
Signed-off-by: Zemtsov Vladimir
---
.../observability.kaasops.io_vectors.yaml | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index f24190e7..6ed6924c 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -48,6 +48,46 @@ spec:
type: string
service:
type: boolean
+ tolerations:
+ items:
+ description: The pod this Toleration is attached to tolerates
+ any taint that matches the triple using
+ the matching operator .
+ properties:
+ effect:
+ description: Effect indicates the taint effect to match.
+ Empty means match all taint effects. When specified, allowed
+ values are NoSchedule, PreferNoSchedule and NoExecute.
+ type: string
+ key:
+ description: Key is the taint key that the toleration applies
+ to. Empty means match all taint keys. If the key is empty,
+ operator must be Exists; this combination means to match
+ all values and all keys.
+ type: string
+ operator:
+ description: Operator represents a key's relationship to
+ the value. Valid operators are Exists and Equal. Defaults
+ to Equal. Exists is equivalent to wildcard for value,
+ so that a pod can tolerate all taints of a particular
+ category.
+ type: string
+ tolerationSeconds:
+ description: TolerationSeconds represents the period of
+ time the toleration (which must be of effect NoExecute,
+ otherwise this field is ignored) tolerates the taint.
+ By default, it is not set, which means tolerate the taint
+ forever (do not evict). Zero and negative values will
+ be treated as 0 (evict immediately) by the system.
+ format: int64
+ type: integer
+ value:
+ description: Value is the taint value the toleration matches
+ to. If the operator is Exists, the value should be empty,
+ otherwise just a regular string.
+ type: string
+ type: object
+ type: array
type: object
type: object
status:
From c2fa240dc184be286ea6ca31df4bc2d453bfdda0 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 22 Oct 2022 15:27:51 +0300
Subject: [PATCH 011/316] Add configcheck & Cleanup
Signed-off-by: Zemtsov Vladimir
---
api/v1alpha1/vector_types.go | 3 +-
api/v1alpha1/vectorpipeline_types.go | 3 +-
api/v1alpha1/zz_generated.deepcopy.go | 24 ++-
...ervability.kaasops.io_vectorpipelines.yaml | 3 +
.../observability.kaasops.io_vectors.yaml | 3 +
.../{vector => config}/config_build.go | 62 ++++---
.../factory/config/configcheck/configcheck.go | 154 ++++++++++++++++
.../config/configcheck/configcheck_config.go | 25 +++
.../config/configcheck/configcheck_pod.go | 170 ++++++++++++++++++
.../config/configcheck/configcheck_rbac.go | 20 +++
controllers/factory/k8sutils/utils.go | 21 +++
controllers/factory/vector/vector.go | 15 ++
.../vectoragent/vector_agent_config.go | 30 ++--
.../vectoragent/vector_agent_controller.go | 66 ++++---
.../factory/vectorpipeline/vectorpipeline.go | 26 ++-
controllers/vector_controller.go | 24 +--
controllers/vectorpipeline_controller.go | 72 +++++++-
17 files changed, 623 insertions(+), 98 deletions(-)
rename controllers/factory/{vector => config}/config_build.go (66%)
create mode 100644 controllers/factory/config/configcheck/configcheck.go
create mode 100644 controllers/factory/config/configcheck/configcheck_config.go
create mode 100644 controllers/factory/config/configcheck/configcheck_pod.go
create mode 100644 controllers/factory/config/configcheck/configcheck_rbac.go
create mode 100644 controllers/factory/vector/vector.go
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index 3fd76030..c955b8bf 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -36,8 +36,7 @@ type VectorSpec struct {
// VectorStatus defines the observed state of Vector
type VectorStatus struct {
- // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
- // Important: Run "make" to regenerate code after modifying this file
+ ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
}
// VectorAgent is the Schema for the Vector Agent
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index 8d5b4a36..7bd66bdc 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -36,8 +36,7 @@ type VectorPipelineSpec struct {
// VectorPipelineStatus defines the observed state of VectorPipeline
type VectorPipelineStatus struct {
- // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
- // Important: Run "make" to regenerate code after modifying this file
+ ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
}
//+kubebuilder:object:root=true
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 7740556c..b72ba00d 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -22,6 +22,7 @@ limitations under the License.
package v1alpha1
import (
+ "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
)
@@ -31,7 +32,7 @@ func (in *Vector) DeepCopyInto(out *Vector) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
- out.Status = in.Status
+ in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Vector.
@@ -55,6 +56,13 @@ func (in *Vector) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VectorAgent) DeepCopyInto(out *VectorAgent) {
*out = *in
+ if in.Tolerations != nil {
+ in, out := &in.Tolerations, &out.Tolerations
+ *out = make([]v1.Toleration, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorAgent.
@@ -120,7 +128,7 @@ func (in *VectorPipeline) DeepCopyInto(out *VectorPipeline) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
- out.Status = in.Status
+ in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorPipeline.
@@ -206,6 +214,11 @@ func (in *VectorPipelineSpec) DeepCopy() *VectorPipelineSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VectorPipelineStatus) DeepCopyInto(out *VectorPipelineStatus) {
*out = *in
+ if in.ConfigCheckResult != nil {
+ in, out := &in.ConfigCheckResult, &out.ConfigCheckResult
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorPipelineStatus.
@@ -224,7 +237,7 @@ func (in *VectorSpec) DeepCopyInto(out *VectorSpec) {
if in.Agent != nil {
in, out := &in.Agent, &out.Agent
*out = new(VectorAgent)
- **out = **in
+ (*in).DeepCopyInto(*out)
}
}
@@ -241,6 +254,11 @@ func (in *VectorSpec) DeepCopy() *VectorSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VectorStatus) DeepCopyInto(out *VectorStatus) {
*out = *in
+ if in.ConfigCheckResult != nil {
+ in, out := &in.ConfigCheckResult, &out.ConfigCheckResult
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorStatus.
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
index 74844416..35b81682 100644
--- a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -47,6 +47,9 @@ spec:
type: object
status:
description: VectorPipelineStatus defines the observed state of VectorPipeline
+ properties:
+ configCheckResult:
+ type: boolean
type: object
type: object
served: true
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index 6ed6924c..bcf4a695 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -92,6 +92,9 @@ spec:
type: object
status:
description: VectorStatus defines the observed state of Vector
+ properties:
+ configCheckResult:
+ type: boolean
type: object
type: object
served: true
diff --git a/controllers/factory/vector/config_build.go b/controllers/factory/config/config_build.go
similarity index 66%
rename from controllers/factory/vector/config_build.go
rename to controllers/factory/config/config_build.go
index 98f37b7b..5dead386 100644
--- a/controllers/factory/vector/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -1,33 +1,55 @@
-package vector
+package config
import (
+ "context"
"encoding/json"
"log"
- "github.com/kaasops/vector-operator/api/v1alpha1"
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/vector"
+ "github.com/kaasops/vector-operator/controllers/factory/vectorpipeline"
"k8s.io/apimachinery/pkg/runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
)
var (
sourceDefault = map[string]interface{}{
- "type": "kubernetes_logs",
+ "defaultSource": map[string]string{
+ "type": "kubernetes_logs",
+ },
}
rate int32 = 100
sinkDefault = map[string]interface{}{
- "type": "blackhole",
- "inputs": []string{"defaultSource"},
- "rate": rate,
- "printIntervalSecs": 60,
+ "defaultSink": map[string]interface{}{
+ "type": "blackhole",
+ "inputs": []string{"defaultSource"},
+ "rate": rate,
+ "print_interval_secs": 60,
+ },
}
)
+func Get(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) ([]byte, error) {
+ vps, err := vectorpipeline.SelectSucceesed(ctx, c)
+ if err != nil {
+ return nil, err
+ }
+
+ cfg, err := GenerateConfig(v, vps)
+ if err != nil {
+ return nil, err
+ }
+
+ return cfg, nil
+}
+
func GenerateConfig(
- cr *v1alpha1.Vector,
- vp map[string]*v1alpha1.VectorPipeline,
+ v *vectorv1alpha1.Vector,
+ vps map[string]*vectorv1alpha1.VectorPipeline,
) ([]byte, error) {
- cfg := NewVectorConfig(cr.Spec.Agent.DataDir, cr.Spec.Agent.ApiEnabled)
- sources, transforms, sinks, err := getComponents(vp)
+ cfg := vector.New(v.Spec.Agent.DataDir, v.Spec.Agent.ApiEnabled)
+ sources, transforms, sinks, err := getComponents(vps)
if err != nil {
log.Fatal(err)
}
@@ -45,21 +67,7 @@ func GenerateConfig(
return vectorConfigToJson(cfg)
}
-func NewVectorConfig(dataDir string, apiEnabled bool) *VectorConfig {
- sources := make(map[string]interface{})
- sinks := make(map[string]interface{})
-
- return &VectorConfig{
- DataDir: dataDir,
- Api: &ApiSpec{
- Enabled: &apiEnabled,
- },
- Sources: sources,
- Sinks: sinks,
- }
-}
-
-func getComponents(vps map[string]*v1alpha1.VectorPipeline) (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
+func getComponents(vps map[string]*vectorv1alpha1.VectorPipeline) (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
sources := make(map[string]interface{})
transforms := make(map[string]interface{})
sinks := make(map[string]interface{})
@@ -99,7 +107,7 @@ func getComponents(vps map[string]*v1alpha1.VectorPipeline) (map[string]interfac
return sources, transforms, sinks, nil
}
-func vectorConfigToJson(conf *VectorConfig) ([]byte, error) {
+func vectorConfigToJson(conf *vector.VectorConfig) ([]byte, error) {
data, err := json.Marshal(conf)
if err != nil {
return nil, err
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
new file mode 100644
index 00000000..c181f291
--- /dev/null
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -0,0 +1,154 @@
+package configcheck
+
+import (
+ "context"
+ "errors"
+ "math/rand"
+ "time"
+
+ "github.com/kaasops/vector-operator/controllers/factory/helper"
+ "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
+ "github.com/kaasops/vector-operator/controllers/factory/label"
+ corev1 "k8s.io/api/core/v1"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+)
+
+var (
+ ErrConfigCheck = errors.New("Config Check finish with errors")
+)
+
+func Run(
+ cfg []byte,
+ c client.Client,
+ name,
+ namespace,
+ image string,
+) error {
+ log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", name)
+
+ log.Info("start ConfigCheck Vector")
+
+ err := ensureVectorConfigCheckRBAC(c, namespace)
+ if err != nil {
+ return err
+ }
+
+ hash := randStringRunes()
+
+ err = ensureVectorConfigCheckConfig(c, cfg, name, namespace, hash)
+ if err != nil {
+ return err
+ }
+
+ err = ensureVectorConfigCheckPod(c, name, namespace, image, hash)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func ensureVectorConfigCheckRBAC(c client.Client, ns string) error {
+ // ctx := context.Background()
+ // log := log.FromContext(ctx).WithValues("vector-config-check-rbac", "ConfigCheck")
+
+ // log.Info("start Reconcile Vector Config Check RBAC")
+
+ if done, _, err := ensureVectorConfigCheckServiceAccount(c, ns); done {
+ return err
+ }
+
+ return nil
+}
+
+func ensureVectorConfigCheckServiceAccount(c client.Client, ns string) (bool, ctrl.Result, error) {
+ vectorAgentServiceAccount := createVectorConfigCheckServiceAccount(ns)
+
+ _, err := k8sutils.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, c)
+
+ return helper.ReconcileResult(err)
+}
+func ensureVectorConfigCheckConfig(c client.Client, cfg []byte, name, ns, hash string) error {
+ // ctx := context.Background()
+ // log := log.FromContext(ctx).WithValues("vector-config-check-secret", "ConfigCheck")
+
+ // log.Info("start Create Config Check Secret")
+
+ vectorConfigCheckSecret, err := createVectorConfigCheckConfig(cfg, name, ns, hash)
+ if err != nil {
+ return err
+ }
+
+ _, err = k8sutils.CreateOrUpdateSecret(vectorConfigCheckSecret, c)
+
+ return err
+}
+
+func ensureVectorConfigCheckPod(c client.Client, name, ns, image, hash string) error {
+ // ctx := context.Background()
+ // log := log.FromContext(ctx).WithValues("vector-config-check-pod", "ConfigCheck")
+
+ // log.Info("start Vector Config Check Pod")
+
+ vectorConfigCheckPod := createVectorConfigCheckPod(name, ns, image, hash)
+
+ err := k8sutils.CreatePod(vectorConfigCheckPod, c)
+ if err != nil {
+ return err
+ }
+
+ err = getCheckResult(vectorConfigCheckPod, c)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func labelsForVectorConfigCheck() map[string]string {
+ return map[string]string{
+ label.ManagedByLabelKey: "vector-operator",
+ label.NameLabelKey: "vector-configcheck",
+ label.ComponentLabelKey: "ConfigCheck",
+ label.VectorExcludeLabel: "true",
+ }
+}
+
+func getNameVectorConfigCheck(name, hash string) string {
+ n := "configcheck-" + name + "-" + hash
+ return n
+}
+
+func randStringRunes() string {
+ var letterRunes = []rune("abcdefghijklmnopqrstuvwxyz")
+
+ b := make([]rune, 5)
+ for i := range b {
+ b[i] = letterRunes[rand.Intn(len(letterRunes))]
+ }
+ return string(b)
+}
+
+func getCheckResult(pod *corev1.Pod, c client.Client) error {
+ log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", pod.Name)
+
+ for {
+ existing, err := k8sutils.GetPod(pod, c)
+ if err != nil {
+ return err
+ }
+
+ switch existing.Status.Phase {
+ case "Pending":
+ log.Info("wait Validate Vector Config Result")
+ time.Sleep(5 * time.Second)
+ case "Failed":
+ return ErrConfigCheck
+ case "Succeeded":
+ log.Info("Config Check completed successfully")
+ return nil
+ }
+ }
+}
diff --git a/controllers/factory/config/configcheck/configcheck_config.go b/controllers/factory/config/configcheck/configcheck_config.go
new file mode 100644
index 00000000..85a0a0e1
--- /dev/null
+++ b/controllers/factory/config/configcheck/configcheck_config.go
@@ -0,0 +1,25 @@
+package configcheck
+
+import (
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func createVectorConfigCheckConfig(cfg []byte, name, ns, hash string) (*corev1.Secret, error) {
+ labels := labelsForVectorConfigCheck()
+
+ config := map[string][]byte{
+ "agent.json": cfg,
+ }
+
+ secret := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: getNameVectorConfigCheck(name, hash),
+ Namespace: ns,
+ Labels: labels,
+ },
+ Data: config,
+ }
+
+ return secret, nil
+}
diff --git a/controllers/factory/config/configcheck/configcheck_pod.go b/controllers/factory/config/configcheck/configcheck_pod.go
new file mode 100644
index 00000000..8fe883b5
--- /dev/null
+++ b/controllers/factory/config/configcheck/configcheck_pod.go
@@ -0,0 +1,170 @@
+package configcheck
+
+import (
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func createVectorConfigCheckPod(name, ns, image, hash string) *corev1.Pod {
+ labels := labelsForVectorConfigCheck()
+
+ pod := &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: getNameVectorConfigCheck(name, hash),
+ Namespace: ns,
+ Labels: labels,
+ },
+ Spec: corev1.PodSpec{
+ ServiceAccountName: "vector-configcheck",
+ Volumes: generateVectorConfigCheckVolume(name, hash),
+ SecurityContext: &corev1.PodSecurityContext{},
+ Containers: []corev1.Container{
+ {
+ Name: "config-check",
+ Image: image,
+ Args: []string{"validate", "/etc/vector/*.json"},
+ Env: generateVectorConfigCheckEnvs(),
+ Ports: []corev1.ContainerPort{
+ {
+ Name: "prom-exporter",
+ ContainerPort: 9090,
+ Protocol: "TCP",
+ },
+ },
+ VolumeMounts: generateVectorConfigCheckVolumeMounts(),
+ },
+ },
+ RestartPolicy: "Never",
+ },
+ }
+
+ return pod
+}
+
+func generateVectorConfigCheckVolume(name, hash string) []corev1.Volume {
+ volume := []corev1.Volume{
+ {
+ Name: "config",
+ VolumeSource: corev1.VolumeSource{
+ Secret: &corev1.SecretVolumeSource{
+ SecretName: getNameVectorConfigCheck(name, hash),
+ },
+ },
+ },
+ {
+ Name: "data",
+ VolumeSource: corev1.VolumeSource{
+ HostPath: &corev1.HostPathVolumeSource{
+ Path: "/var/lib/vector",
+ },
+ },
+ },
+ {
+ Name: "var-log",
+ VolumeSource: corev1.VolumeSource{
+ HostPath: &corev1.HostPathVolumeSource{
+ Path: "/var/log/",
+ },
+ },
+ },
+ {
+ Name: "var-lib",
+ VolumeSource: corev1.VolumeSource{
+ HostPath: &corev1.HostPathVolumeSource{
+ Path: "/var/lib/",
+ },
+ },
+ },
+ {
+ Name: "procfs",
+ VolumeSource: corev1.VolumeSource{
+ HostPath: &corev1.HostPathVolumeSource{
+ Path: "/proc",
+ },
+ },
+ },
+ {
+ Name: "sysfs",
+ VolumeSource: corev1.VolumeSource{
+ HostPath: &corev1.HostPathVolumeSource{
+ Path: "/sys",
+ },
+ },
+ },
+ }
+
+ return volume
+}
+
+func generateVectorConfigCheckVolumeMounts() []corev1.VolumeMount {
+ volumeMount := []corev1.VolumeMount{
+ {
+ Name: "config",
+ MountPath: "/etc/vector/",
+ },
+ {
+ Name: "data",
+ MountPath: "/vector-data-dir",
+ },
+ {
+ Name: "var-log",
+ MountPath: "/var/log/",
+ },
+ {
+ Name: "var-lib",
+ MountPath: "/var/lib/",
+ },
+ {
+ Name: "procfs",
+ MountPath: "/host/proc",
+ },
+ {
+ Name: "sysfs",
+ MountPath: "/host/sys",
+ },
+ }
+
+ return volumeMount
+}
+
+func generateVectorConfigCheckEnvs() []corev1.EnvVar {
+ envs := []corev1.EnvVar{
+ {
+ Name: "VECTOR_SELF_NODE_NAME",
+ ValueFrom: &corev1.EnvVarSource{
+ FieldRef: &corev1.ObjectFieldSelector{
+ APIVersion: "v1",
+ FieldPath: "spec.nodeName",
+ },
+ },
+ },
+ {
+ Name: "VECTOR_SELF_POD_NAME",
+ ValueFrom: &corev1.EnvVarSource{
+ FieldRef: &corev1.ObjectFieldSelector{
+ APIVersion: "v1",
+ FieldPath: "metadata.name",
+ },
+ },
+ },
+ {
+ Name: "VECTOR_SELF_POD_NAMESPACE",
+ ValueFrom: &corev1.EnvVarSource{
+ FieldRef: &corev1.ObjectFieldSelector{
+ APIVersion: "v1",
+ FieldPath: "metadata.namespace",
+ },
+ },
+ },
+ {
+ Name: "PROCFS_ROOT",
+ Value: "/host/proc",
+ },
+ {
+ Name: "SYSFS_ROOT",
+ Value: "/host/sys",
+ },
+ }
+
+ return envs
+}
diff --git a/controllers/factory/config/configcheck/configcheck_rbac.go b/controllers/factory/config/configcheck/configcheck_rbac.go
new file mode 100644
index 00000000..84d06b35
--- /dev/null
+++ b/controllers/factory/config/configcheck/configcheck_rbac.go
@@ -0,0 +1,20 @@
+package configcheck
+
+import (
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func createVectorConfigCheckServiceAccount(ns string) *corev1.ServiceAccount {
+ labels := labelsForVectorConfigCheck()
+
+ serviceAccount := &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "vector-configcheck",
+ Namespace: ns,
+ Labels: labels,
+ },
+ }
+
+ return serviceAccount
+}
diff --git a/controllers/factory/k8sutils/utils.go b/controllers/factory/k8sutils/utils.go
index d34c444e..75c70932 100644
--- a/controllers/factory/k8sutils/utils.go
+++ b/controllers/factory/k8sutils/utils.go
@@ -41,6 +41,27 @@ func CreateOrUpdateClusterRoleBinding(secret *rbacv1.ClusterRoleBinding, c clien
return reconcileClusterRoleBinding(secret, c)
}
+func CreatePod(pod *corev1.Pod, c client.Client) error {
+ err := c.Create(context.TODO(), pod)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func GetPod(pod *corev1.Pod, c client.Client) (*corev1.Pod, error) {
+ result := &corev1.Pod{}
+ err := c.Get(context.TODO(), client.ObjectKeyFromObject(pod), result)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func UpdateStatus(ctx context.Context, obj client.Object, c client.Client) error {
+ return c.Status().Update(ctx, obj)
+}
+
func reconcileService(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
existing := &corev1.Service{}
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
new file mode 100644
index 00000000..29070e88
--- /dev/null
+++ b/controllers/factory/vector/vector.go
@@ -0,0 +1,15 @@
+package vector
+
+func New(dataDir string, apiEnabled bool) *VectorConfig {
+ sources := make(map[string]interface{})
+ sinks := make(map[string]interface{})
+
+ return &VectorConfig{
+ DataDir: dataDir,
+ Api: &ApiSpec{
+ Enabled: &apiEnabled,
+ },
+ Sources: sources,
+ Sinks: sinks,
+ }
+}
diff --git a/controllers/factory/vectoragent/vector_agent_config.go b/controllers/factory/vectoragent/vector_agent_config.go
index 6e2868a4..d544725c 100644
--- a/controllers/factory/vectoragent/vector_agent_config.go
+++ b/controllers/factory/vectoragent/vector_agent_config.go
@@ -7,16 +7,27 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/vector"
- "github.com/kaasops/vector-operator/controllers/factory/vectorpipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/config"
+ "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
)
func createVectorAgentConfig(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) (*corev1.Secret, error) {
- cfg, err := getConfig(ctx, v, c)
+ cfg, err := config.Get(ctx, v, c)
if err != nil {
return nil, err
}
+ err = configcheck.Run(cfg, c, v.Name, v.Namespace, v.Spec.Agent.Image)
+ if err == configcheck.ErrConfigCheck {
+ setFailedStatus(ctx, v, c)
+ return nil, err
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ setSucceesStatus(ctx, v, c)
+
labels := labelsForVectorAgent(v.Name)
config := map[string][]byte{
"agent.json": cfg,
@@ -29,16 +40,3 @@ func createVectorAgentConfig(ctx context.Context, v *vectorv1alpha1.Vector, c cl
return secret, nil
}
-
-func getConfig(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) ([]byte, error) {
- vps, err := vectorpipeline.Select(ctx, c)
- if err != nil {
- return nil, err
- }
- cfg, err := vector.GenerateConfig(v, vps)
- if err != nil {
- return nil, err
- }
-
- return cfg, nil
-}
diff --git a/controllers/factory/vectoragent/vector_agent_controller.go b/controllers/factory/vectoragent/vector_agent_controller.go
index 68c1578d..a0fd8290 100644
--- a/controllers/factory/vectoragent/vector_agent_controller.go
+++ b/controllers/factory/vectoragent/vector_agent_controller.go
@@ -14,96 +14,96 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
)
-func EnsureVectorAgent(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (done bool, result ctrl.Result, err error) {
+func EnsureVectorAgent(v *vectorv1alpha1.Vector, rclient client.Client) (done bool, result ctrl.Result, err error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent", vectorCR.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent", v.Name)
log.Info("start Reconcile Vector Agent")
- if done, result, err = ensureVectorAgentRBAC(vectorCR, rclient); done {
+ if done, result, err = ensureVectorAgentRBAC(v, rclient); done {
return
}
- if vectorCR.Spec.Agent.Service {
- if done, result, err = ensureVectorAgentService(vectorCR, rclient); done {
+ if v.Spec.Agent.Service {
+ if done, result, err = ensureVectorAgentService(v, rclient); done {
return
}
}
- if done, result, err = ensureVectorAgentConfig(vectorCR, rclient); done {
+ if done, result, err = ensureVectorAgentConfig(v, rclient); done {
return
}
- if done, result, err = ensureVectorAgentDaemonSet(vectorCR, rclient); done {
+ if done, result, err = ensureVectorAgentDaemonSet(v, rclient); done {
return
}
return
}
-func ensureVectorAgentRBAC(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+func ensureVectorAgentRBAC(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-rbac", vectorCR.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-rbac", v.Name)
log.Info("start Reconcile Vector Agent RBAC")
- if done, _, err := ensureVectorAgentServiceAccount(vectorCR, rclient); done {
+ if done, _, err := ensureVectorAgentServiceAccount(v, rclient); done {
return helper.ReconcileResult(err)
}
- if done, _, err := ensureVectorAgentClusterRole(vectorCR, rclient); done {
+ if done, _, err := ensureVectorAgentClusterRole(v, rclient); done {
return helper.ReconcileResult(err)
}
- if done, _, err := ensureVectorAgentClusterRoleBinding(vectorCR, rclient); done {
+ if done, _, err := ensureVectorAgentClusterRoleBinding(v, rclient); done {
return helper.ReconcileResult(err)
}
return helper.ReconcileResult(nil)
}
-func ensureVectorAgentServiceAccount(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
- vectorAgentServiceAccount := createVectorAgentServiceAccount(vectorCR)
+func ensureVectorAgentServiceAccount(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ vectorAgentServiceAccount := createVectorAgentServiceAccount(v)
_, err := k8sutils.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, rclient)
return helper.ReconcileResult(err)
}
-func ensureVectorAgentClusterRole(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
- vectorAgentClusterRole := createVectorAgentClusterRole(vectorCR)
+func ensureVectorAgentClusterRole(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ vectorAgentClusterRole := createVectorAgentClusterRole(v)
_, err := k8sutils.CreateOrUpdateClusterRole(vectorAgentClusterRole, rclient)
return helper.ReconcileResult(err)
}
-func ensureVectorAgentClusterRoleBinding(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
- vectorAgentClusterRoleBinding := createVectorAgentClusterRoleBinding(vectorCR)
+func ensureVectorAgentClusterRoleBinding(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+ vectorAgentClusterRoleBinding := createVectorAgentClusterRoleBinding(v)
_, err := k8sutils.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, rclient)
return helper.ReconcileResult(err)
}
-func ensureVectorAgentService(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+func ensureVectorAgentService(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-service", vectorCR.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-service", v.Name)
log.Info("start Reconcile Vector Agent Service")
- vectorAgentService := createVectorAgentService(vectorCR)
+ vectorAgentService := createVectorAgentService(v)
_, err := k8sutils.CreateOrUpdateService(vectorAgentService, rclient)
return helper.ReconcileResult(err)
}
-func ensureVectorAgentConfig(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+func ensureVectorAgentConfig(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-secret", vectorCR.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-secret", v.Name)
log.Info("start Reconcile Vector Agent Secret")
- vectorAgentSecret, err := createVectorAgentConfig(ctx, vectorCR, rclient)
+ vectorAgentSecret, err := createVectorAgentConfig(ctx, v, rclient)
if err != nil {
return helper.ReconcileResult(err)
}
@@ -113,13 +113,13 @@ func ensureVectorAgentConfig(vectorCR *vectorv1alpha1.Vector, rclient client.Cli
return helper.ReconcileResult(err)
}
-func ensureVectorAgentDaemonSet(vectorCR *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+func ensureVectorAgentDaemonSet(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", vectorCR.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", v.Name)
log.Info("start Reconcile Vector Agent DaemonSet")
- vectorAgentDaemonSet := createVectorAgentDaemonSet(vectorCR)
+ vectorAgentDaemonSet := createVectorAgentDaemonSet(v)
_, err := k8sutils.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, rclient)
@@ -162,3 +162,15 @@ func getControllerReference(owner *vectorv1alpha1.Vector) []metav1.OwnerReferenc
},
}
}
+
+func setSucceesStatus(ctx context.Context, vp *vectorv1alpha1.Vector, c client.Client) {
+ var status = true
+ vp.Status.ConfigCheckResult = &status
+ k8sutils.UpdateStatus(ctx, vp, c)
+}
+
+func setFailedStatus(ctx context.Context, vp *vectorv1alpha1.Vector, c client.Client) {
+ var status = false
+ vp.Status.ConfigCheckResult = &status
+ k8sutils.UpdateStatus(ctx, vp, c)
+}
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
index 11dc31ea..65d513ba 100644
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -4,10 +4,11 @@ import (
"context"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
"sigs.k8s.io/controller-runtime/pkg/client"
)
-func Select(ctx context.Context, rclient client.Client) (map[string]*vectorv1alpha1.VectorPipeline, error) {
+func SelectSucceesed(ctx context.Context, rclient client.Client) (map[string]*vectorv1alpha1.VectorPipeline, error) {
res := make(map[string]*vectorv1alpha1.VectorPipeline)
@@ -23,7 +24,12 @@ func Select(ctx context.Context, rclient client.Client) (map[string]*vectorv1alp
if !item.DeletionTimestamp.IsZero() {
continue
}
- vectorPipelinesCombined = append(vectorPipelinesCombined, item)
+ if item.Status.ConfigCheckResult != nil {
+ if *item.Status.ConfigCheckResult {
+ vectorPipelinesCombined = append(vectorPipelinesCombined, item)
+ }
+ }
+
}
for _, vectorPipeline := range vectorPipelinesCombined {
@@ -33,6 +39,18 @@ func Select(ctx context.Context, rclient client.Client) (map[string]*vectorv1alp
return res, nil
}
-func generateName(pipelineCR *vectorv1alpha1.VectorPipeline) string {
- return pipelineCR.Namespace + "-" + pipelineCR.Name
+func generateName(vp *vectorv1alpha1.VectorPipeline) string {
+ return vp.Namespace + "-" + vp.Name
+}
+
+func SetSucceesStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) {
+ var status = true
+ vp.Status.ConfigCheckResult = &status
+ k8sutils.UpdateStatus(ctx, vp, c)
+}
+
+func SetFailedStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) {
+ var status = false
+ vp.Status.ConfigCheckResult = &status
+ k8sutils.UpdateStatus(ctx, vp, c)
}
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index d3c5c9a9..77c5a947 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -58,22 +58,22 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
log.Info("start Reconcile Vector")
- vectorCR, done, result, err := r.findVectorCustomResourceInstance(ctx, log, req)
+ v, done, result, err := r.findVectorCustomResourceInstance(ctx, log, req)
if done {
return result, err
}
- if vectorCR.Spec.Agent.DataDir == "" {
- vectorCR.Spec.Agent.DataDir = "/vector-data-dir"
+ if v.Spec.Agent.DataDir == "" {
+ v.Spec.Agent.DataDir = "/vector-data-dir"
}
- return CreateOrUpdateVector(ctx, vectorCR, r.Client)
+ return CreateOrUpdateVector(ctx, v, r.Client)
}
func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.Vector, bool, ctrl.Result, error) {
// fetch the master instance
- vectorCR := &vectorv1alpha1.Vector{}
- err := r.Get(ctx, req.NamespacedName, vectorCR)
+ v := &vectorv1alpha1.Vector{}
+ err := r.Get(ctx, req.NamespacedName, v)
if err != nil {
if errors.IsNotFound(err) {
// Request object not found, could have been deleted after reconcile request.
@@ -83,11 +83,11 @@ func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context,
return nil, true, ctrl.Result{}, nil
}
// Error reading the object - requeue the request.
- log.Error(err, "Failed to get VectorCR")
+ log.Error(err, "Failed to get Vector")
return nil, true, ctrl.Result{}, err
}
- log.Info("Get Vector " + vectorCR.Name)
- return vectorCR, false, ctrl.Result{}, nil
+
+ return v, false, ctrl.Result{}, nil
}
// SetupWithManager sets up the controller with the Manager.
@@ -97,10 +97,10 @@ func (r *VectorReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}
-func CreateOrUpdateVector(ctx context.Context, vector *vectorv1alpha1.Vector, rclient client.Client) (ctrl.Result, error) {
- if done, result, err := vectoragent.EnsureVectorAgent(vector, rclient); done {
+func CreateOrUpdateVector(ctx context.Context, v *vectorv1alpha1.Vector, rclient client.Client) (ctrl.Result, error) {
+ if done, result, err := vectoragent.EnsureVectorAgent(v, rclient); done {
return result, err
}
- return ctrl.Result{RequeueAfter: 60 * time.Second}, nil
+ return ctrl.Result{RequeueAfter: 15 * time.Second}, nil
}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 11c83e69..52102e48 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -19,12 +19,17 @@ package controllers
import (
"context"
+ "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
+ "github.com/go-logr/logr"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/config"
+ "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
+ "github.com/kaasops/vector-operator/controllers/factory/vectorpipeline"
)
// VectorPipelineReconciler reconciles a VectorPipeline object
@@ -52,8 +57,13 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
log.Info("start Reconcile VectorPipeline")
+ vp, done, result, err := r.findVectorCustomResourceInstance(ctx, log, req)
+ if done {
+ return result, err
+ }
+
vectorInstances := &vectorv1alpha1.VectorList{}
- err := r.List(ctx, vectorInstances)
+ err = r.List(ctx, vectorInstances)
if err != nil {
return ctrl.Result{}, err
}
@@ -63,21 +73,73 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, nil
}
- for _, vector := range vectorInstances.Items {
- if vector.DeletionTimestamp != nil {
+ for _, v := range vectorInstances.Items {
+ if v.DeletionTimestamp != nil {
continue
}
- currentVector := &vector
- CreateOrUpdateVector(ctx, currentVector, r.Client)
+
+ err = checkConfig(ctx, &v, vp, r.Client)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
}
+ log.Info("finish Reconcile VectorPipeline")
return ctrl.Result{}, nil
}
+func (r *VectorPipelineReconciler) findVectorCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.VectorPipeline, bool, ctrl.Result, error) {
+ // fetch the master instance
+ vp := &vectorv1alpha1.VectorPipeline{}
+ err := r.Get(ctx, req.NamespacedName, vp)
+ if err != nil {
+ if errors.IsNotFound(err) {
+ // Request object not found, could have been deleted after reconcile request.
+ // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
+ // Return and don't requeue
+ log.Info("VectorPipeline CR not found. Ignoring since object must be deleted")
+ return nil, true, ctrl.Result{}, nil
+ }
+ // Error reading the object - requeue the request.
+ log.Error(err, "Failed to get Vector")
+ return nil, true, ctrl.Result{}, err
+ }
+ log.Info("Get Vector Pipeline" + vp.Name)
+ return vp, false, ctrl.Result{}, nil
+}
+
// SetupWithManager sets up the controller with the Manager.
func (r *VectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&vectorv1alpha1.VectorPipeline{}).
Complete(r)
}
+
+func checkConfig(ctx context.Context, v *vectorv1alpha1.Vector, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
+ log := log.FromContext(context.TODO()).WithValues("Vector Pipeline", "ConfigCheck")
+
+ vpName := vp.Namespace + "-" + vp.Name
+ vps := map[string]*vectorv1alpha1.VectorPipeline{
+ vpName: vp,
+ }
+
+ cfg, err := config.GenerateConfig(v, vps)
+ if err != nil {
+ return err
+ }
+
+ err = configcheck.Run(cfg, c, vp.Name, vp.Namespace, v.Spec.Agent.Image)
+ if err == configcheck.ErrConfigCheck {
+ vectorpipeline.SetFailedStatus(ctx, vp, c)
+ log.Error(err, "Vector Config has error")
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+
+ vectorpipeline.SetSucceesStatus(ctx, vp, c)
+
+ return nil
+}
From d16261f07838a3eb9beae269265e70b5c00ca642 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Tue, 25 Oct 2022 09:39:57 +0300
Subject: [PATCH 012/316] Parse config as structs
---
controllers/factory/config/config_build.go | 87 +++++--------
controllers/factory/vector/types.go | 24 ++++
controllers/factory/vector/vector.go | 36 ++++++
.../factory/vectorpipeline/vectorpipeline.go | 115 +++++++++++++++---
controllers/vectorpipeline_controller.go | 10 +-
go.mod | 1 +
go.sum | 2 +
7 files changed, 195 insertions(+), 80 deletions(-)
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index 5dead386..281d7580 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -8,7 +8,6 @@ import (
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/vector"
"github.com/kaasops/vector-operator/controllers/factory/vectorpipeline"
- "k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -46,7 +45,7 @@ func Get(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) ([]byte
func GenerateConfig(
v *vectorv1alpha1.Vector,
- vps map[string]*vectorv1alpha1.VectorPipeline,
+ vps []*vectorv1alpha1.VectorPipeline,
) ([]byte, error) {
cfg := vector.New(v.Spec.Agent.DataDir, v.Spec.Agent.ApiEnabled)
sources, transforms, sinks, err := getComponents(vps)
@@ -67,44 +66,47 @@ func GenerateConfig(
return vectorConfigToJson(cfg)
}
-func getComponents(vps map[string]*vectorv1alpha1.VectorPipeline) (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
- sources := make(map[string]interface{})
- transforms := make(map[string]interface{})
- sinks := make(map[string]interface{})
+func getComponents(vps []*vectorv1alpha1.VectorPipeline) (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
+ sourcesMap := make(map[string]interface{})
+ transformsMap := make(map[string]interface{})
+ sinksMap := make(map[string]interface{})
- for name, vp := range vps {
- if vp.Spec.Sources != nil {
- data, err := decode(vp.Spec.Sources)
+ for _, vp := range vps {
+ sources, err := vectorpipeline.GetSources(vp, nil)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ for _, source := range sources {
+ spec, err := vector.Decoder(source)
if err != nil {
return nil, nil, nil, err
}
- vp_sources := uniqWithPrefix(data, name)
- for source_k, source_v := range vp_sources {
- sources[source_k] = source_v
- }
+ sourcesMap[source.Name] = spec
+ }
+ transforms, err := vectorpipeline.GetTransforms(vp)
+ if err != nil {
+ return nil, nil, nil, err
}
- if vp.Spec.Transforms != nil {
- data, err := decode(vp.Spec.Transforms)
+ for _, transform := range transforms {
+ spec, err := vector.Decoder(transform)
if err != nil {
return nil, nil, nil, err
}
- vp_transforms := uniqWithPrefix(data, name)
- for transform_k, transform_v := range vp_transforms {
- transforms[transform_k] = transform_v
- }
+ transformsMap[transform.Name] = spec
+ }
+ sinks, err := vectorpipeline.GetSinks(vp)
+ if err != nil {
+ return nil, nil, nil, err
}
- if vp.Spec.Sinks != nil {
- data, err := decode(vp.Spec.Sinks)
+ for _, sink := range sinks {
+ spec, err := vector.Decoder(sink)
if err != nil {
return nil, nil, nil, err
}
- vp_sinks := uniqWithPrefix(data, name)
- for sink_k, sink_v := range vp_sinks {
- sinks[sink_k] = sink_v
- }
+ sinksMap[sink.Name] = spec
}
}
- return sources, transforms, sinks, nil
+ return sourcesMap, transformsMap, sinksMap, nil
}
func vectorConfigToJson(conf *vector.VectorConfig) ([]byte, error) {
@@ -115,36 +117,3 @@ func vectorConfigToJson(conf *vector.VectorConfig) ([]byte, error) {
return data, nil
}
-
-func uniqWithPrefix(in map[string]interface{}, prefix string) map[string]interface{} {
- out := make(map[string]interface{})
- for k_in, v_in := range in {
- spec := v_in.(map[string]interface{})
- out[addPrefix(prefix, k_in)] = spec
- for k_spec, v_spec := range spec {
- if k_spec == "inputs" {
- inputs := make([]string, 0)
- for _, i := range v_spec.([]interface{}) {
- newInput := addPrefix(prefix, i.(string))
- inputs = append(inputs, newInput)
- }
- spec[k_spec] = inputs
- continue
- }
- }
- }
- return out
-}
-
-func addPrefix(prefix string, name string) string {
- return prefix + "-" + name
-}
-
-func decode(data *runtime.RawExtension) (map[string]interface{}, error) {
- out := make(map[string]interface{})
- err := json.Unmarshal(data.Raw, &out)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
diff --git a/controllers/factory/vector/types.go b/controllers/factory/vector/types.go
index c273d9b6..dd9eefde 100644
--- a/controllers/factory/vector/types.go
+++ b/controllers/factory/vector/types.go
@@ -13,3 +13,27 @@ type ApiSpec struct {
Address *string `json:"address,omitempty"`
Playground *bool `json:"playground,omitempty"`
}
+
+type Source struct {
+ Name string
+ Type string `mapper:"type"`
+ Options map[string]interface{} `mapstructure:",remain"`
+}
+
+type Transform struct {
+ Name string
+ Type string `mapper:"type"`
+ Inputs []string `mapper:"inputs"`
+ Options map[string]interface{} `mapstructure:",remain"`
+}
+
+type Sink struct {
+ Name string
+ Type string `mapper:"type"`
+ Inputs []string `mapper:"inputs"`
+ Options map[string]interface{} `mapstructure:",remain"`
+}
+
+type ConfigComponent interface {
+ GetOptions() map[string]interface{}
+}
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
index 29070e88..c82c350b 100644
--- a/controllers/factory/vector/vector.go
+++ b/controllers/factory/vector/vector.go
@@ -1,5 +1,9 @@
package vector
+import (
+ "github.com/mitchellh/mapstructure"
+)
+
func New(dataDir string, apiEnabled bool) *VectorConfig {
sources := make(map[string]interface{})
sinks := make(map[string]interface{})
@@ -13,3 +17,35 @@ func New(dataDir string, apiEnabled bool) *VectorConfig {
Sinks: sinks,
}
}
+
+func Decoder(c ConfigComponent) (map[string]interface{}, error) {
+ spec := make(map[string]interface{})
+ spec = c.GetOptions()
+ config := &mapstructure.DecoderConfig{
+ Result: &spec,
+ ZeroFields: false,
+ TagName: "mapper",
+ IgnoreUntaggedFields: true,
+ }
+ decoder, err := mapstructure.NewDecoder(config)
+ if err != nil {
+ return nil, err
+ }
+ err = decoder.Decode(c)
+ if err != nil {
+ return nil, err
+ }
+ return spec, nil
+}
+
+func (t Source) GetOptions() map[string]interface{} {
+ return t.Options
+}
+
+func (t Transform) GetOptions() map[string]interface{} {
+ return t.Options
+}
+
+func (t Sink) GetOptions() map[string]interface{} {
+ return t.Options
+}
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
index 65d513ba..710ec798 100644
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -2,17 +2,18 @@ package vectorpipeline
import (
"context"
+ "encoding/json"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/k8sutils"
+ "github.com/kaasops/vector-operator/controllers/factory/vector"
+ "github.com/mitchellh/mapstructure"
"sigs.k8s.io/controller-runtime/pkg/client"
)
-func SelectSucceesed(ctx context.Context, rclient client.Client) (map[string]*vectorv1alpha1.VectorPipeline, error) {
+func SelectSucceesed(ctx context.Context, rclient client.Client) ([]*vectorv1alpha1.VectorPipeline, error) {
- res := make(map[string]*vectorv1alpha1.VectorPipeline)
-
- var vectorPipelinesCombined []vectorv1alpha1.VectorPipeline
+ var vectorPipelinesCombined []*vectorv1alpha1.VectorPipeline
objlist := vectorv1alpha1.VectorPipelineList{}
err := rclient.List(ctx, &objlist)
@@ -26,21 +27,12 @@ func SelectSucceesed(ctx context.Context, rclient client.Client) (map[string]*ve
}
if item.Status.ConfigCheckResult != nil {
if *item.Status.ConfigCheckResult {
- vectorPipelinesCombined = append(vectorPipelinesCombined, item)
+ vectorPipelinesCombined = append(vectorPipelinesCombined, item.DeepCopy())
}
}
}
-
- for _, vectorPipeline := range vectorPipelinesCombined {
- m := vectorPipeline.DeepCopy()
- res[generateName(&vectorPipeline)] = m
- }
- return res, nil
-}
-
-func generateName(vp *vectorv1alpha1.VectorPipeline) string {
- return vp.Namespace + "-" + vp.Name
+ return vectorPipelinesCombined, nil
}
func SetSucceesStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) {
@@ -54,3 +46,96 @@ func SetFailedStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c c
vp.Status.ConfigCheckResult = &status
k8sutils.UpdateStatus(ctx, vp, c)
}
+
+func GetSources(vp *vectorv1alpha1.VectorPipeline, filter []string) ([]vector.Source, error) {
+ var sources []vector.Source
+ sourcesMap, err := decodeRaw(vp.Spec.Sources.Raw)
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range sourcesMap {
+ if len(filter) != 0 {
+ if !contains(filter, k) {
+ continue
+ }
+ }
+ var source vector.Source
+ if err := mapstructure.Decode(v, &source); err != nil {
+ return nil, err
+ }
+ source.Name = addPrefix(vp, k)
+ sources = append(sources, source)
+ }
+ return sources, nil
+}
+
+func GetTransforms(vp *vectorv1alpha1.VectorPipeline) ([]vector.Transform, error) {
+ if vp.Spec.Transforms == nil {
+ return nil, nil
+ }
+ transformsMap, err := decodeRaw(vp.Spec.Transforms.Raw)
+ if err != nil {
+ return nil, err
+ }
+ var transforms []vector.Transform
+ if err := json.Unmarshal(vp.Spec.Transforms.Raw, &transformsMap); err != nil {
+ return nil, err
+ }
+ for k, v := range transformsMap {
+ var transform vector.Transform
+ if err := mapstructure.Decode(v, &transform); err != nil {
+ return nil, err
+ }
+ transform.Name = addPrefix(vp, k)
+ for i, inputName := range transform.Inputs {
+ transform.Inputs[i] = addPrefix(vp, inputName)
+ }
+ transforms = append(transforms, transform)
+ }
+ return transforms, nil
+}
+
+func GetSinks(vp *vectorv1alpha1.VectorPipeline) ([]vector.Sink, error) {
+ sinksMap, err := decodeRaw(vp.Spec.Sinks.Raw)
+ if err != nil {
+ return nil, err
+ }
+ var sinks []vector.Sink
+ for k, v := range sinksMap {
+ var sink vector.Sink
+ if err := mapstructure.Decode(v, &sink); err != nil {
+ return nil, err
+ }
+ sink.Name = addPrefix(vp, k)
+ for i, inputName := range sink.Inputs {
+ sink.Inputs[i] = addPrefix(vp, inputName)
+ }
+ sinks = append(sinks, sink)
+ }
+ return sinks, nil
+}
+
+func decodeRaw(raw []byte) (map[string]interface{}, error) {
+ result := make(map[string]interface{})
+ if err := json.Unmarshal(raw, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func addPrefix(vp *vectorv1alpha1.VectorPipeline, name string) string {
+ return generateName(vp) + "-" + name
+}
+
+func generateName(vp *vectorv1alpha1.VectorPipeline) string {
+ return vp.Namespace + "-" + vp.Name
+}
+
+func contains(elems []string, v string) bool {
+ for _, s := range elems {
+ if v == s {
+ return true
+ }
+ }
+ return false
+}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 52102e48..12d83d12 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -57,7 +57,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
log.Info("start Reconcile VectorPipeline")
- vp, done, result, err := r.findVectorCustomResourceInstance(ctx, log, req)
+ vp, done, result, err := r.findVectorPipelineCustomResourceInstance(ctx, log, req)
if done {
return result, err
}
@@ -89,7 +89,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, nil
}
-func (r *VectorPipelineReconciler) findVectorCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.VectorPipeline, bool, ctrl.Result, error) {
+func (r *VectorPipelineReconciler) findVectorPipelineCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.VectorPipeline, bool, ctrl.Result, error) {
// fetch the master instance
vp := &vectorv1alpha1.VectorPipeline{}
err := r.Get(ctx, req.NamespacedName, vp)
@@ -119,10 +119,8 @@ func (r *VectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
func checkConfig(ctx context.Context, v *vectorv1alpha1.Vector, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
log := log.FromContext(context.TODO()).WithValues("Vector Pipeline", "ConfigCheck")
- vpName := vp.Namespace + "-" + vp.Name
- vps := map[string]*vectorv1alpha1.VectorPipeline{
- vpName: vp,
- }
+ var vps []*vectorv1alpha1.VectorPipeline
+ vps = append(vps, vp)
cfg, err := config.GenerateConfig(v, vps)
if err != nil {
diff --git a/go.mod b/go.mod
index 3eb591f8..d9825a97 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.18
require (
github.com/go-logr/logr v1.2.0
+ github.com/mitchellh/mapstructure v1.5.0
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.18.1
k8s.io/api v0.24.2
diff --git a/go.sum b/go.sum
index c27022bf..250a18ed 100644
--- a/go.sum
+++ b/go.sum
@@ -341,6 +341,8 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
From 107aa3682ad0fbc1cc372ec52fb362e2c035c2d8 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Tue, 25 Oct 2022 15:01:29 +0300
Subject: [PATCH 013/316] Add field reason to CRs
Signed-off-by: Zemtsov Vladimir
---
CHANGELOG.md | 3 ++
api/v1alpha1/vector_types.go | 3 +-
api/v1alpha1/vectorpipeline_types.go | 3 +-
api/v1alpha1/zz_generated.deepcopy.go | 10 +++++++
...ervability.kaasops.io_vectorpipelines.yaml | 2 ++
.../observability.kaasops.io_vectors.yaml | 2 ++
.../factory/config/configcheck/configcheck.go | 28 +++++++++----------
.../config/configcheck/configcheck_error.go | 14 ++++++++++
controllers/factory/k8sutils/utils.go | 26 +++++++++++++++++
.../vectoragent/vector_agent_config.go | 9 +++---
.../vectoragent/vector_agent_controller.go | 23 ++++++++-------
.../factory/vectorpipeline/vectorpipeline.go | 7 +++--
controllers/vector_controller.go | 12 ++++----
controllers/vectorpipeline_controller.go | 16 +++++++----
main.go | 20 +++++++++----
15 files changed, 130 insertions(+), 48 deletions(-)
create mode 100644 controllers/factory/config/configcheck/configcheck_error.go
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb970329..1ae96357 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,7 @@
### Added
+- Feature: Add field reason to CR Vector and VectorPipeline
+- Feature: Add ConfigCheck for Vector
+- Feature: Add ConfigCheck for VectorPipeline
- Feature: Add utils for reconciling Kubernetes resources
- Cleanup: Update Kustomize version in Makefile to v4.2.0 (for amd64 support)
- Agent: Init Vector Agent Controller
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index c955b8bf..7d107148 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -36,7 +36,8 @@ type VectorSpec struct {
// VectorStatus defines the observed state of Vector
type VectorStatus struct {
- ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
+ ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
+ Reason *string `json:"reason,omitempty"`
}
// VectorAgent is the Schema for the Vector Agent
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index 7bd66bdc..64cf4602 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -36,7 +36,8 @@ type VectorPipelineSpec struct {
// VectorPipelineStatus defines the observed state of VectorPipeline
type VectorPipelineStatus struct {
- ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
+ ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
+ Reason *string `json:"reason,omitempty"`
}
//+kubebuilder:object:root=true
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index b72ba00d..bd0d017c 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -219,6 +219,11 @@ func (in *VectorPipelineStatus) DeepCopyInto(out *VectorPipelineStatus) {
*out = new(bool)
**out = **in
}
+ if in.Reason != nil {
+ in, out := &in.Reason, &out.Reason
+ *out = new(string)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorPipelineStatus.
@@ -259,6 +264,11 @@ func (in *VectorStatus) DeepCopyInto(out *VectorStatus) {
*out = new(bool)
**out = **in
}
+ if in.Reason != nil {
+ in, out := &in.Reason, &out.Reason
+ *out = new(string)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorStatus.
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
index 35b81682..f8be050b 100644
--- a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -50,6 +50,8 @@ spec:
properties:
configCheckResult:
type: boolean
+ reason:
+ type: string
type: object
type: object
served: true
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index bcf4a695..5edb2458 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -95,6 +95,8 @@ spec:
properties:
configCheckResult:
type: boolean
+ reason:
+ type: string
type: object
type: object
served: true
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index c181f291..4cbc9a90 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -2,7 +2,6 @@ package configcheck
import (
"context"
- "errors"
"math/rand"
"time"
@@ -10,18 +9,16 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/k8sutils"
"github.com/kaasops/vector-operator/controllers/factory/label"
corev1 "k8s.io/api/core/v1"
+ "k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)
-var (
- ErrConfigCheck = errors.New("Config Check finish with errors")
-)
-
func Run(
cfg []byte,
c client.Client,
+ cs *kubernetes.Clientset,
name,
namespace,
image string,
@@ -42,7 +39,7 @@ func Run(
return err
}
- err = ensureVectorConfigCheckPod(c, name, namespace, image, hash)
+ err = checkVectorConfigCheckPod(c, cs, name, namespace, image, hash)
if err != nil {
return err
}
@@ -86,12 +83,7 @@ func ensureVectorConfigCheckConfig(c client.Client, cfg []byte, name, ns, hash s
return err
}
-func ensureVectorConfigCheckPod(c client.Client, name, ns, image, hash string) error {
- // ctx := context.Background()
- // log := log.FromContext(ctx).WithValues("vector-config-check-pod", "ConfigCheck")
-
- // log.Info("start Vector Config Check Pod")
-
+func checkVectorConfigCheckPod(c client.Client, cs *kubernetes.Clientset, name, ns, image, hash string) error {
vectorConfigCheckPod := createVectorConfigCheckPod(name, ns, image, hash)
err := k8sutils.CreatePod(vectorConfigCheckPod, c)
@@ -99,7 +91,7 @@ func ensureVectorConfigCheckPod(c client.Client, name, ns, image, hash string) e
return err
}
- err = getCheckResult(vectorConfigCheckPod, c)
+ err = getCheckResult(vectorConfigCheckPod, c, cs)
if err != nil {
return err
}
@@ -131,7 +123,7 @@ func randStringRunes() string {
return string(b)
}
-func getCheckResult(pod *corev1.Pod, c client.Client) error {
+func getCheckResult(pod *corev1.Pod, c client.Client, cs *kubernetes.Clientset) error {
log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", pod.Name)
for {
@@ -145,7 +137,13 @@ func getCheckResult(pod *corev1.Pod, c client.Client) error {
log.Info("wait Validate Vector Config Result")
time.Sleep(5 * time.Second)
case "Failed":
- return ErrConfigCheck
+ reason, err := k8sutils.GetPodLogs(pod, cs)
+ if err != nil {
+ return err
+ }
+ return &ErrConfigCheck{
+ Reason: reason,
+ }
case "Succeeded":
log.Info("Config Check completed successfully")
return nil
diff --git a/controllers/factory/config/configcheck/configcheck_error.go b/controllers/factory/config/configcheck/configcheck_error.go
new file mode 100644
index 00000000..37b3265d
--- /dev/null
+++ b/controllers/factory/config/configcheck/configcheck_error.go
@@ -0,0 +1,14 @@
+package configcheck
+
+type error interface {
+ Error() string
+}
+
+type ErrConfigCheck struct {
+ Reason string
+ Err error
+}
+
+func (e *ErrConfigCheck) Error() string {
+ return e.Reason
+}
diff --git a/controllers/factory/k8sutils/utils.go b/controllers/factory/k8sutils/utils.go
index 75c70932..a2e0e321 100644
--- a/controllers/factory/k8sutils/utils.go
+++ b/controllers/factory/k8sutils/utils.go
@@ -1,7 +1,9 @@
package k8sutils
import (
+ "bytes"
"context"
+ "io"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
@@ -9,6 +11,7 @@ import (
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
@@ -58,6 +61,29 @@ func GetPod(pod *corev1.Pod, c client.Client) (*corev1.Pod, error) {
return result, nil
}
+func GetPodLogs(pod *corev1.Pod, cs *kubernetes.Clientset) (string, error) {
+ count := int64(100)
+ podLogOptions := corev1.PodLogOptions{
+ TailLines: &count,
+ }
+
+ req := cs.CoreV1().Pods(pod.Namespace).GetLogs(pod.Name, &podLogOptions)
+ podLogs, err := req.Stream(context.TODO())
+ if err != nil {
+ return "", err
+ }
+ defer podLogs.Close()
+
+ buf := new(bytes.Buffer)
+ _, err = io.Copy(buf, podLogs)
+ if err != nil {
+ return "", err
+ }
+ str := buf.String()
+
+ return str, nil
+}
+
func UpdateStatus(ctx context.Context, obj client.Object, c client.Client) error {
return c.Status().Update(ctx, obj)
}
diff --git a/controllers/factory/vectoragent/vector_agent_config.go b/controllers/factory/vectoragent/vector_agent_config.go
index d544725c..7e203aac 100644
--- a/controllers/factory/vectoragent/vector_agent_config.go
+++ b/controllers/factory/vectoragent/vector_agent_config.go
@@ -4,6 +4,7 @@ import (
"context"
corev1 "k8s.io/api/core/v1"
+ "k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
@@ -11,15 +12,15 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
)
-func createVectorAgentConfig(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) (*corev1.Secret, error) {
+func createVectorAgentConfig(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client, cs *kubernetes.Clientset) (*corev1.Secret, error) {
cfg, err := config.Get(ctx, v, c)
if err != nil {
return nil, err
}
- err = configcheck.Run(cfg, c, v.Name, v.Namespace, v.Spec.Agent.Image)
- if err == configcheck.ErrConfigCheck {
- setFailedStatus(ctx, v, c)
+ err = configcheck.Run(cfg, c, cs, v.Name, v.Namespace, v.Spec.Agent.Image)
+ if _, ok := err.(*configcheck.ErrConfigCheck); ok {
+ setFailedStatus(ctx, v, c, err)
return nil, err
}
if err != nil {
diff --git a/controllers/factory/vectoragent/vector_agent_controller.go b/controllers/factory/vectoragent/vector_agent_controller.go
index a0fd8290..43c5e10a 100644
--- a/controllers/factory/vectoragent/vector_agent_controller.go
+++ b/controllers/factory/vectoragent/vector_agent_controller.go
@@ -8,13 +8,14 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/k8sutils"
"github.com/kaasops/vector-operator/controllers/factory/label"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/client-go/kubernetes"
"k8s.io/utils/pointer"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)
-func EnsureVectorAgent(v *vectorv1alpha1.Vector, rclient client.Client) (done bool, result ctrl.Result, err error) {
+func EnsureVectorAgent(v *vectorv1alpha1.Vector, rclient client.Client, cs *kubernetes.Clientset) (done bool, result ctrl.Result, err error) {
ctx := context.Background()
log := log.FromContext(ctx).WithValues("vector-agent", v.Name)
@@ -30,7 +31,7 @@ func EnsureVectorAgent(v *vectorv1alpha1.Vector, rclient client.Client) (done bo
}
}
- if done, result, err = ensureVectorAgentConfig(v, rclient); done {
+ if done, result, err = ensureVectorAgentConfig(v, rclient, cs); done {
return
}
@@ -97,13 +98,13 @@ func ensureVectorAgentService(v *vectorv1alpha1.Vector, rclient client.Client) (
return helper.ReconcileResult(err)
}
-func ensureVectorAgentConfig(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+func ensureVectorAgentConfig(v *vectorv1alpha1.Vector, rclient client.Client, cs *kubernetes.Clientset) (bool, ctrl.Result, error) {
ctx := context.Background()
log := log.FromContext(ctx).WithValues("vector-agent-secret", v.Name)
log.Info("start Reconcile Vector Agent Secret")
- vectorAgentSecret, err := createVectorAgentConfig(ctx, v, rclient)
+ vectorAgentSecret, err := createVectorAgentConfig(ctx, v, rclient, cs)
if err != nil {
return helper.ReconcileResult(err)
}
@@ -163,14 +164,16 @@ func getControllerReference(owner *vectorv1alpha1.Vector) []metav1.OwnerReferenc
}
}
-func setSucceesStatus(ctx context.Context, vp *vectorv1alpha1.Vector, c client.Client) {
+func setSucceesStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) {
var status = true
- vp.Status.ConfigCheckResult = &status
- k8sutils.UpdateStatus(ctx, vp, c)
+ v.Status.ConfigCheckResult = &status
+ k8sutils.UpdateStatus(ctx, v, c)
}
-func setFailedStatus(ctx context.Context, vp *vectorv1alpha1.Vector, c client.Client) {
+func setFailedStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client, err error) error {
var status = false
- vp.Status.ConfigCheckResult = &status
- k8sutils.UpdateStatus(ctx, vp, c)
+ var reason = err.Error()
+ v.Status.ConfigCheckResult = &status
+ v.Status.Reason = &reason
+ return k8sutils.UpdateStatus(ctx, v, c)
}
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
index 710ec798..cab7811e 100644
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -41,10 +41,13 @@ func SetSucceesStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c
k8sutils.UpdateStatus(ctx, vp, c)
}
-func SetFailedStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) {
+func SetFailedStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client, err error) error {
var status = false
+ var reason = err.Error()
vp.Status.ConfigCheckResult = &status
- k8sutils.UpdateStatus(ctx, vp, c)
+ vp.Status.Reason = &reason
+
+ return k8sutils.UpdateStatus(ctx, vp, c)
}
func GetSources(vp *vectorv1alpha1.VectorPipeline, filter []string) ([]vector.Source, error) {
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 77c5a947..c179ece6 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -23,6 +23,7 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/vectoragent"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
@@ -35,8 +36,9 @@ import (
type VectorReconciler struct {
client.Client
Scheme *runtime.Scheme
- // Config *VectorConfig
- // Status *VectorPipelineReconcileStatus
+
+ // Temp. Wait this issue - https://github.com/kubernetes-sigs/controller-runtime/issues/452
+ Clientset *kubernetes.Clientset
}
//+kubebuilder:rbac:groups=observability.kaasops.io,resources=vectors,verbs=get;list;watch;create;update;patch;delete
@@ -67,7 +69,7 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
v.Spec.Agent.DataDir = "/vector-data-dir"
}
- return CreateOrUpdateVector(ctx, v, r.Client)
+ return CreateOrUpdateVector(ctx, v, r.Client, r.Clientset)
}
func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.Vector, bool, ctrl.Result, error) {
@@ -97,8 +99,8 @@ func (r *VectorReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}
-func CreateOrUpdateVector(ctx context.Context, v *vectorv1alpha1.Vector, rclient client.Client) (ctrl.Result, error) {
- if done, result, err := vectoragent.EnsureVectorAgent(v, rclient); done {
+func CreateOrUpdateVector(ctx context.Context, v *vectorv1alpha1.Vector, rclient client.Client, cs *kubernetes.Clientset) (ctrl.Result, error) {
+ if done, result, err := vectoragent.EnsureVectorAgent(v, rclient, cs); done {
return result, err
}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 12d83d12..af119778 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -21,6 +21,7 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
@@ -36,6 +37,9 @@ import (
type VectorPipelineReconciler struct {
client.Client
Scheme *runtime.Scheme
+
+ // Temp. Wait this issue - https://github.com/kubernetes-sigs/controller-runtime/issues/452
+ Clientset *kubernetes.Clientset
}
//+kubebuilder:rbac:groups=observability.kaasops.io,resources=vectorpipelines,verbs=get;list;watch;create;update;patch;delete
@@ -78,7 +82,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
continue
}
- err = checkConfig(ctx, &v, vp, r.Client)
+ err = checkConfig(ctx, &v, vp, r.Client, r.Clientset)
if err != nil {
return ctrl.Result{}, err
}
@@ -116,7 +120,7 @@ func (r *VectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}
-func checkConfig(ctx context.Context, v *vectorv1alpha1.Vector, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
+func checkConfig(ctx context.Context, v *vectorv1alpha1.Vector, vp *vectorv1alpha1.VectorPipeline, c client.Client, cs *kubernetes.Clientset) error {
log := log.FromContext(context.TODO()).WithValues("Vector Pipeline", "ConfigCheck")
var vps []*vectorv1alpha1.VectorPipeline
@@ -127,9 +131,11 @@ func checkConfig(ctx context.Context, v *vectorv1alpha1.Vector, vp *vectorv1alph
return err
}
- err = configcheck.Run(cfg, c, vp.Name, vp.Namespace, v.Spec.Agent.Image)
- if err == configcheck.ErrConfigCheck {
- vectorpipeline.SetFailedStatus(ctx, vp, c)
+ err = configcheck.Run(cfg, c, cs, vp.Name, vp.Namespace, v.Spec.Agent.Image)
+ if _, ok := err.(*configcheck.ErrConfigCheck); ok {
+ if err := vectorpipeline.SetFailedStatus(ctx, vp, c, err); err != nil {
+ return err
+ }
log.Error(err, "Vector Config has error")
return nil
}
diff --git a/main.go b/main.go
index ac07ebd3..aa5c9188 100644
--- a/main.go
+++ b/main.go
@@ -24,6 +24,7 @@ import (
// to ensure that exec-entrypoint and run can make use of them.
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
+ "k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -68,7 +69,14 @@ func main() {
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
- mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
+ config := ctrl.GetConfigOrDie()
+
+ clientset, err := kubernetes.NewForConfig(config)
+ if err != nil {
+ panic(err)
+ }
+
+ mgr, err := ctrl.NewManager(config, ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443,
@@ -95,15 +103,17 @@ func main() {
}
if err = (&controllers.VectorReconciler{
- Client: mgr.GetClient(),
- Scheme: mgr.GetScheme(),
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ Clientset: clientset,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Vector")
os.Exit(1)
}
if err = (&controllers.VectorPipelineReconciler{
- Client: mgr.GetClient(),
- Scheme: mgr.GetScheme(),
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ Clientset: clientset,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "VectorPipeline")
os.Exit(1)
From 50f2fbeffa4463151311d24ad3d72ec3c48684de Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Tue, 25 Oct 2022 11:33:56 +0300
Subject: [PATCH 014/316] return err on set status
---
controllers/factory/vectorpipeline/vectorpipeline.go | 7 +++++--
controllers/vectorpipeline_controller.go | 4 +++-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
index cab7811e..d0bd8f71 100644
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -35,10 +35,13 @@ func SelectSucceesed(ctx context.Context, rclient client.Client) ([]*vectorv1alp
return vectorPipelinesCombined, nil
}
-func SetSucceesStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) {
+func SetSucceesStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
var status = true
vp.Status.ConfigCheckResult = &status
- k8sutils.UpdateStatus(ctx, vp, c)
+ if err := k8sutils.UpdateStatus(ctx, vp, c); err != nil {
+ return err
+ }
+ return nil
}
func SetFailedStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client, err error) error {
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index af119778..93d18913 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -143,7 +143,9 @@ func checkConfig(ctx context.Context, v *vectorv1alpha1.Vector, vp *vectorv1alph
return err
}
- vectorpipeline.SetSucceesStatus(ctx, vp, c)
+ if err := vectorpipeline.SetSucceesStatus(ctx, vp, c); err != nil {
+ return err
+ }
return nil
}
From 4c22b65ae8ce745629c020158bf538e2b82fb262 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Tue, 25 Oct 2022 15:21:31 +0300
Subject: [PATCH 015/316] check hash before checkconfig
---
api/v1alpha1/vectorpipeline_types.go | 5 +++--
api/v1alpha1/zz_generated.deepcopy.go | 5 +++++
...ervability.kaasops.io_vectorpipelines.yaml | 3 +++
controllers/factory/config/config_build.go | 6 ++---
controllers/factory/vector/vector.go | 2 +-
controllers/factory/vectorpipeline/hash.go | 22 +++++++++++++++++++
.../factory/vectorpipeline/vectorpipeline.go | 12 ++++++++++
controllers/vectorpipeline_controller.go | 16 ++++++++++----
8 files changed, 61 insertions(+), 10 deletions(-)
create mode 100644 controllers/factory/vectorpipeline/hash.go
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index 64cf4602..368f7477 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -36,8 +36,9 @@ type VectorPipelineSpec struct {
// VectorPipelineStatus defines the observed state of VectorPipeline
type VectorPipelineStatus struct {
- ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
- Reason *string `json:"reason,omitempty"`
+ ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
+ Reason *string `json:"reason,omitempty"`
+ LastAppliedConfigHash *uint32 `json:"lastAppliedConfigHash,omitempty"`
}
//+kubebuilder:object:root=true
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index bd0d017c..7e48bce9 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -224,6 +224,11 @@ func (in *VectorPipelineStatus) DeepCopyInto(out *VectorPipelineStatus) {
*out = new(string)
**out = **in
}
+ if in.LastAppliedConfigHash != nil {
+ in, out := &in.LastAppliedConfigHash, &out.LastAppliedConfigHash
+ *out = new(uint32)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorPipelineStatus.
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
index f8be050b..cb238823 100644
--- a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -52,6 +52,9 @@ spec:
type: boolean
reason:
type: string
+ lastAppliedConfigHash:
+ format: int32
+ type: integer
type: object
type: object
served: true
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index 281d7580..58ce5fde 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -77,7 +77,7 @@ func getComponents(vps []*vectorv1alpha1.VectorPipeline) (map[string]interface{}
return nil, nil, nil, err
}
for _, source := range sources {
- spec, err := vector.Decoder(source)
+ spec, err := vector.Mapper(source)
if err != nil {
return nil, nil, nil, err
}
@@ -88,7 +88,7 @@ func getComponents(vps []*vectorv1alpha1.VectorPipeline) (map[string]interface{}
return nil, nil, nil, err
}
for _, transform := range transforms {
- spec, err := vector.Decoder(transform)
+ spec, err := vector.Mapper(transform)
if err != nil {
return nil, nil, nil, err
}
@@ -99,7 +99,7 @@ func getComponents(vps []*vectorv1alpha1.VectorPipeline) (map[string]interface{}
return nil, nil, nil, err
}
for _, sink := range sinks {
- spec, err := vector.Decoder(sink)
+ spec, err := vector.Mapper(sink)
if err != nil {
return nil, nil, nil, err
}
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
index c82c350b..5582e688 100644
--- a/controllers/factory/vector/vector.go
+++ b/controllers/factory/vector/vector.go
@@ -18,7 +18,7 @@ func New(dataDir string, apiEnabled bool) *VectorConfig {
}
}
-func Decoder(c ConfigComponent) (map[string]interface{}, error) {
+func Mapper(c ConfigComponent) (map[string]interface{}, error) {
spec := make(map[string]interface{})
spec = c.GetOptions()
config := &mapstructure.DecoderConfig{
diff --git a/controllers/factory/vectorpipeline/hash.go b/controllers/factory/vectorpipeline/hash.go
new file mode 100644
index 00000000..1f86249f
--- /dev/null
+++ b/controllers/factory/vectorpipeline/hash.go
@@ -0,0 +1,22 @@
+package vectorpipeline
+
+import (
+ "encoding/json"
+ "hash/crc32"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+)
+
+func GetHash(input []byte) uint32 {
+ crc32q := crc32.MakeTable(crc32.IEEE)
+ return crc32.Checksum(input, crc32q)
+}
+
+func GetVpSpecHash(vp *vectorv1alpha1.VectorPipeline) (*uint32, error) {
+ a, err := json.Marshal(vp.Spec)
+ if err != nil {
+ return nil, err
+ }
+ hash := GetHash(a)
+ return &hash, nil
+}
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
index d0bd8f71..d9fd24e0 100644
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -53,6 +53,18 @@ func SetFailedStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c c
return k8sutils.UpdateStatus(ctx, vp, c)
}
+func SetLastAppliedConfigStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
+ hash, err := GetVpSpecHash(vp)
+ if err != nil {
+ return err
+ }
+ vp.Status.LastAppliedConfigHash = hash
+ if err := k8sutils.UpdateStatus(ctx, vp, c); err != nil {
+ return err
+ }
+ return nil
+}
+
func GetSources(vp *vectorv1alpha1.VectorPipeline, filter []string) ([]vector.Source, error) {
var sources []vector.Source
sourcesMap, err := decodeRaw(vp.Spec.Sources.Raw)
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 93d18913..e3b9ebc1 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -77,14 +77,22 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, nil
}
+ hash, err := vectorpipeline.GetVpSpecHash(vp)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
for _, v := range vectorInstances.Items {
if v.DeletionTimestamp != nil {
continue
}
-
- err = checkConfig(ctx, &v, vp, r.Client, r.Clientset)
- if err != nil {
- return ctrl.Result{}, err
+ if vp.Status.LastAppliedConfigHash == nil || *hash != *vp.Status.LastAppliedConfigHash {
+ if err = checkConfig(ctx, &v, vp, r.Client, r.Clientset); err != nil {
+ return ctrl.Result{}, err
+ }
+ if err = vectorpipeline.SetLastAppliedConfigStatus(ctx, vp, r.Client); err != nil {
+ return ctrl.Result{}, err
+ }
}
}
From 3ff0782d785b6e1617ae2623639a76acef25c608 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Tue, 25 Oct 2022 17:01:21 +0300
Subject: [PATCH 016/316] init README.md
---
README.md | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index ad182354..f1e9c6ea 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,18 @@
# vector-operator
-// TODO(user): Add simple overview of use/purpose
+Operator for Kubernetes to deploy and manage [Vector](https://vector.dev/).
## Description
-// TODO(user): An in-depth paragraph about your project and overview of use
+The operator deploys and configures a vector agent daemonset on every node to collect container and application logs from the node file system.
+
+## Features
+
+- [x] Building vector config from namespaced custom resources (kind: VectorPipeline)
+- [x] Configuration validation
+- [x] Full support of vector config options
+- [ ] Namespace isolation
+- [ ] Garbage collection
+- [ ] Vector config optimization
+- [ ] Vector aggregator support
## Getting Started
You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster.
@@ -18,13 +28,13 @@ kubectl apply -f config/samples/
2. Build and push your image to the location specified by `IMG`:
```sh
-make docker-build docker-push IMG=/vector-operator:tag
+make docker-build docker-push IMG=docker pull kaasops/vector-operator:latest
```
3. Deploy the controller to the cluster with the image specified by `IMG`:
```sh
-make deploy IMG=/vector-operator:tag
+make deploy IMG=docker pull kaasops/vector-operator:latest
```
### Uninstall CRDs
@@ -42,7 +52,6 @@ make undeploy
```
## Contributing
-// TODO(user): Add detailed information on how you would like others to contribute to this project
### How it works
This project aims to follow the Kubernetes [Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/)
From fe53f0bf4562a59562171cd07eb950277d4760ef Mon Sep 17 00:00:00 2001
From: Vladimir <31961982+zvlb@users.noreply.github.com>
Date: Tue, 25 Oct 2022 16:04:56 +0200
Subject: [PATCH 017/316] Pretty fix
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f1e9c6ea..c33a4a1a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# vector-operator
+# Vector Operator
Operator for Kubernetes to deploy and manage [Vector](https://vector.dev/).
## Description
From 78c7d8a9605ce0cce202b036789488ad8f7864fe Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Wed, 26 Oct 2022 13:01:13 +0300
Subject: [PATCH 018/316] rename lastapplied confighash to pipelinehash
---
api/v1alpha1/vectorpipeline_types.go | 6 +++---
api/v1alpha1/zz_generated.deepcopy.go | 4 ++--
.../crd/bases/observability.kaasops.io_vectorpipelines.yaml | 4 ++--
controllers/factory/vectorpipeline/vectorpipeline.go | 2 +-
controllers/vectorpipeline_controller.go | 2 +-
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index 368f7477..dd971317 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -36,9 +36,9 @@ type VectorPipelineSpec struct {
// VectorPipelineStatus defines the observed state of VectorPipeline
type VectorPipelineStatus struct {
- ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
- Reason *string `json:"reason,omitempty"`
- LastAppliedConfigHash *uint32 `json:"lastAppliedConfigHash,omitempty"`
+ ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
+ Reason *string `json:"reason,omitempty"`
+ LastAppliedPipelineHash *uint32 `json:"lastAppliedConfigHash,omitempty"`
}
//+kubebuilder:object:root=true
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 7e48bce9..1e64dc9f 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -224,8 +224,8 @@ func (in *VectorPipelineStatus) DeepCopyInto(out *VectorPipelineStatus) {
*out = new(string)
**out = **in
}
- if in.LastAppliedConfigHash != nil {
- in, out := &in.LastAppliedConfigHash, &out.LastAppliedConfigHash
+ if in.LastAppliedPipelineHash != nil {
+ in, out := &in.LastAppliedPipelineHash, &out.LastAppliedPipelineHash
*out = new(uint32)
**out = **in
}
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
index cb238823..7a500dc7 100644
--- a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -50,11 +50,11 @@ spec:
properties:
configCheckResult:
type: boolean
- reason:
- type: string
lastAppliedConfigHash:
format: int32
type: integer
+ reason:
+ type: string
type: object
type: object
served: true
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
index d9fd24e0..33472cb2 100644
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -58,7 +58,7 @@ func SetLastAppliedConfigStatus(ctx context.Context, vp *vectorv1alpha1.VectorPi
if err != nil {
return err
}
- vp.Status.LastAppliedConfigHash = hash
+ vp.Status.LastAppliedPipelineHash = hash
if err := k8sutils.UpdateStatus(ctx, vp, c); err != nil {
return err
}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index e3b9ebc1..4cb162ef 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -86,7 +86,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
if v.DeletionTimestamp != nil {
continue
}
- if vp.Status.LastAppliedConfigHash == nil || *hash != *vp.Status.LastAppliedConfigHash {
+ if vp.Status.LastAppliedPipelineHash == nil || *hash != *vp.Status.LastAppliedPipelineHash {
if err = checkConfig(ctx, &v, vp, r.Client, r.Clientset); err != nil {
return ctrl.Result{}, err
}
From 5d6a2a0d757849015002cbae1f456af5a59b2815 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Wed, 26 Oct 2022 13:04:14 +0300
Subject: [PATCH 019/316] fix lastappliedpipelinehash json tag name
---
api/v1alpha1/vectorpipeline_types.go | 2 +-
.../crd/bases/observability.kaasops.io_vectorpipelines.yaml | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index dd971317..f64a0b4e 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -38,7 +38,7 @@ type VectorPipelineSpec struct {
type VectorPipelineStatus struct {
ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
Reason *string `json:"reason,omitempty"`
- LastAppliedPipelineHash *uint32 `json:"lastAppliedConfigHash,omitempty"`
+ LastAppliedPipelineHash *uint32 `json:"LastAppliedPipelineHash,omitempty"`
}
//+kubebuilder:object:root=true
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
index 7a500dc7..52b7ff41 100644
--- a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -48,11 +48,11 @@ spec:
status:
description: VectorPipelineStatus defines the observed state of VectorPipeline
properties:
- configCheckResult:
- type: boolean
- lastAppliedConfigHash:
+ LastAppliedPipelineHash:
format: int32
type: integer
+ configCheckResult:
+ type: boolean
reason:
type: string
type: object
From 1db8675c609dd4c8ed38e21eed991fbd12e95ecc Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Wed, 26 Oct 2022 13:45:20 +0300
Subject: [PATCH 020/316] check hash before vector config check
---
api/v1alpha1/vector_types.go | 5 +--
api/v1alpha1/zz_generated.deepcopy.go | 5 +++
.../observability.kaasops.io_vectors.yaml | 3 ++
controllers/factory/utils/utils.go | 8 +++++
.../vectoragent/vector_agent_config.go | 32 +++++++++++++------
.../vectoragent/vector_agent_controller.go | 13 ++++++--
controllers/factory/vectorpipeline/hash.go | 9 ++----
.../factory/vectorpipeline/vectorpipeline.go | 2 +-
controllers/vectorpipeline_controller.go | 2 +-
9 files changed, 57 insertions(+), 22 deletions(-)
create mode 100644 controllers/factory/utils/utils.go
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index 7d107148..91740b7c 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -36,8 +36,9 @@ type VectorSpec struct {
// VectorStatus defines the observed state of Vector
type VectorStatus struct {
- ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
- Reason *string `json:"reason,omitempty"`
+ ConfigCheckResult *bool `json:"configCheckResult,omitempty"`
+ Reason *string `json:"reason,omitempty"`
+ LastAppliedConfigHash *uint32 `json:"LastAppliedConfigHash,omitempty"`
}
// VectorAgent is the Schema for the Vector Agent
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 1e64dc9f..f36d6c1f 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -274,6 +274,11 @@ func (in *VectorStatus) DeepCopyInto(out *VectorStatus) {
*out = new(string)
**out = **in
}
+ if in.LastAppliedConfigHash != nil {
+ in, out := &in.LastAppliedConfigHash, &out.LastAppliedConfigHash
+ *out = new(uint32)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorStatus.
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index 5edb2458..7b1a9a6b 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -93,6 +93,9 @@ spec:
status:
description: VectorStatus defines the observed state of Vector
properties:
+ LastAppliedConfigHash:
+ format: int32
+ type: integer
configCheckResult:
type: boolean
reason:
diff --git a/controllers/factory/utils/utils.go b/controllers/factory/utils/utils.go
new file mode 100644
index 00000000..a3c1486c
--- /dev/null
+++ b/controllers/factory/utils/utils.go
@@ -0,0 +1,8 @@
+package utils
+
+import "hash/crc32"
+
+func GetHash(input []byte) uint32 {
+ crc32q := crc32.MakeTable(crc32.IEEE)
+ return crc32.Checksum(input, crc32q)
+}
diff --git a/controllers/factory/vectoragent/vector_agent_config.go b/controllers/factory/vectoragent/vector_agent_config.go
index 7e203aac..3270bc6e 100644
--- a/controllers/factory/vectoragent/vector_agent_config.go
+++ b/controllers/factory/vectoragent/vector_agent_config.go
@@ -10,6 +10,7 @@ import (
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/config"
"github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
+ "github.com/kaasops/vector-operator/controllers/factory/utils"
)
func createVectorAgentConfig(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client, cs *kubernetes.Clientset) (*corev1.Secret, error) {
@@ -18,16 +19,29 @@ func createVectorAgentConfig(ctx context.Context, v *vectorv1alpha1.Vector, c cl
return nil, err
}
- err = configcheck.Run(cfg, c, cs, v.Name, v.Namespace, v.Spec.Agent.Image)
- if _, ok := err.(*configcheck.ErrConfigCheck); ok {
- setFailedStatus(ctx, v, c, err)
- return nil, err
- }
- if err != nil {
- return nil, err
- }
+ cfgHash := utils.GetHash(cfg)
- setSucceesStatus(ctx, v, c)
+ if v.Status.LastAppliedConfigHash == nil || *v.Status.LastAppliedConfigHash != cfgHash {
+ err = configcheck.Run(cfg, c, cs, v.Name, v.Namespace, v.Spec.Agent.Image)
+ if _, ok := err.(*configcheck.ErrConfigCheck); ok {
+ if err := setFailedStatus(ctx, v, c, err); err != nil {
+ return nil, err
+ }
+ return nil, err
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ if err := SetLastAppliedPipelineStatus(ctx, v, c, &cfgHash); err != nil {
+ return nil, err
+ }
+
+ if err := setSucceesStatus(ctx, v, c); err != nil {
+ return nil, err
+ }
+
+ }
labels := labelsForVectorAgent(v.Name)
config := map[string][]byte{
diff --git a/controllers/factory/vectoragent/vector_agent_controller.go b/controllers/factory/vectoragent/vector_agent_controller.go
index 43c5e10a..cf644302 100644
--- a/controllers/factory/vectoragent/vector_agent_controller.go
+++ b/controllers/factory/vectoragent/vector_agent_controller.go
@@ -164,10 +164,10 @@ func getControllerReference(owner *vectorv1alpha1.Vector) []metav1.OwnerReferenc
}
}
-func setSucceesStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) {
+func setSucceesStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) error {
var status = true
v.Status.ConfigCheckResult = &status
- k8sutils.UpdateStatus(ctx, v, c)
+ return k8sutils.UpdateStatus(ctx, v, c)
}
func setFailedStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client, err error) error {
@@ -177,3 +177,12 @@ func setFailedStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Cli
v.Status.Reason = &reason
return k8sutils.UpdateStatus(ctx, v, c)
}
+
+func SetLastAppliedPipelineStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client, hash *uint32) error {
+
+ v.Status.LastAppliedConfigHash = hash
+ if err := k8sutils.UpdateStatus(ctx, v, c); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/controllers/factory/vectorpipeline/hash.go b/controllers/factory/vectorpipeline/hash.go
index 1f86249f..8e6a83d9 100644
--- a/controllers/factory/vectorpipeline/hash.go
+++ b/controllers/factory/vectorpipeline/hash.go
@@ -2,21 +2,16 @@ package vectorpipeline
import (
"encoding/json"
- "hash/crc32"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/utils"
)
-func GetHash(input []byte) uint32 {
- crc32q := crc32.MakeTable(crc32.IEEE)
- return crc32.Checksum(input, crc32q)
-}
-
func GetVpSpecHash(vp *vectorv1alpha1.VectorPipeline) (*uint32, error) {
a, err := json.Marshal(vp.Spec)
if err != nil {
return nil, err
}
- hash := GetHash(a)
+ hash := utils.GetHash(a)
return &hash, nil
}
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
index 33472cb2..5338fd1f 100644
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -53,7 +53,7 @@ func SetFailedStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c c
return k8sutils.UpdateStatus(ctx, vp, c)
}
-func SetLastAppliedConfigStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
+func SetLastAppliedPipelineStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
hash, err := GetVpSpecHash(vp)
if err != nil {
return err
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 4cb162ef..954b386d 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -90,7 +90,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
if err = checkConfig(ctx, &v, vp, r.Client, r.Clientset); err != nil {
return ctrl.Result{}, err
}
- if err = vectorpipeline.SetLastAppliedConfigStatus(ctx, vp, r.Client); err != nil {
+ if err = vectorpipeline.SetLastAppliedPipelineStatus(ctx, vp, r.Client); err != nil {
return ctrl.Result{}, err
}
}
From 5a1ef4aba8d241b2f3db8033b51622055594378c Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Wed, 26 Oct 2022 13:48:35 +0300
Subject: [PATCH 021/316] add short name vectorpipeline
---
api/v1alpha1/vectorpipeline_types.go | 1 +
config/crd/bases/observability.kaasops.io_vectorpipelines.yaml | 2 ++
2 files changed, 3 insertions(+)
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index f64a0b4e..9941d176 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -43,6 +43,7 @@ type VectorPipelineStatus struct {
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
+//+kubebuilder:resource:shortName=vp
// VectorPipeline is the Schema for the vectorpipelines API
type VectorPipeline struct {
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
index 52b7ff41..7c53b8f9 100644
--- a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -12,6 +12,8 @@ spec:
kind: VectorPipeline
listKind: VectorPipelineList
plural: vectorpipelines
+ shortNames:
+ - vp
singular: vectorpipeline
scope: Namespaced
versions:
From eab0cebc445099569f678e307bf6d2ca611ae576 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Wed, 26 Oct 2022 14:46:48 +0300
Subject: [PATCH 022/316] Add additionalPrinterColumns for configCheckResult
and age
Signed-off-by: Zemtsov Vladimir
---
api/v1alpha1/vector_types.go | 2 ++
api/v1alpha1/vectorpipeline_types.go | 2 ++
.../bases/observability.kaasops.io_vectorpipelines.yaml | 9 ++++++++-
config/crd/bases/observability.kaasops.io_vectors.yaml | 9 ++++++++-
4 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index 91740b7c..a2cc0249 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -61,6 +61,8 @@ type VectorAggregator struct {
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
+//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
+//+kubebuilder:printcolumn:name="Status",type="boolean",JSONPath=".status.configCheckResult"
// Vector is the Schema for the vectors API
type Vector struct {
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index 9941d176..b65340f3 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -44,6 +44,8 @@ type VectorPipelineStatus struct {
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName=vp
+//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
+//+kubebuilder:printcolumn:name="Status",type="boolean",JSONPath=".status.configCheckResult"
// VectorPipeline is the Schema for the vectorpipelines API
type VectorPipeline struct {
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
index 7c53b8f9..0577b656 100644
--- a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -17,7 +17,14 @@ spec:
singular: vectorpipeline
scope: Namespaced
versions:
- - name: v1alpha1
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ - jsonPath: .status.configCheckResult
+ name: Status
+ type: boolean
+ name: v1alpha1
schema:
openAPIV3Schema:
description: VectorPipeline is the Schema for the vectorpipelines API
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index 7b1a9a6b..e4f237ff 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -15,7 +15,14 @@ spec:
singular: vector
scope: Namespaced
versions:
- - name: v1alpha1
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ - jsonPath: .status.configCheckResult
+ name: Status
+ type: boolean
+ name: v1alpha1
schema:
openAPIV3Schema:
description: Vector is the Schema for the vectors API
From be54d60a0bfc801498b35ccbddbc87bf28f39096 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Wed, 26 Oct 2022 14:53:36 +0300
Subject: [PATCH 023/316] Clean field reason
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/vectoragent/vector_agent_controller.go | 3 +++
controllers/factory/vectorpipeline/vectorpipeline.go | 7 +++----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/controllers/factory/vectoragent/vector_agent_controller.go b/controllers/factory/vectoragent/vector_agent_controller.go
index cf644302..ed6436af 100644
--- a/controllers/factory/vectoragent/vector_agent_controller.go
+++ b/controllers/factory/vectoragent/vector_agent_controller.go
@@ -167,6 +167,8 @@ func getControllerReference(owner *vectorv1alpha1.Vector) []metav1.OwnerReferenc
func setSucceesStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) error {
var status = true
v.Status.ConfigCheckResult = &status
+ v.Status.Reason = nil
+
return k8sutils.UpdateStatus(ctx, v, c)
}
@@ -175,6 +177,7 @@ func setFailedStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Cli
var reason = err.Error()
v.Status.ConfigCheckResult = &status
v.Status.Reason = &reason
+
return k8sutils.UpdateStatus(ctx, v, c)
}
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
index 5338fd1f..224342c2 100644
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -38,10 +38,9 @@ func SelectSucceesed(ctx context.Context, rclient client.Client) ([]*vectorv1alp
func SetSucceesStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
var status = true
vp.Status.ConfigCheckResult = &status
- if err := k8sutils.UpdateStatus(ctx, vp, c); err != nil {
- return err
- }
- return nil
+ vp.Status.Reason = nil
+
+ return k8sutils.UpdateStatus(ctx, vp, c)
}
func SetFailedStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client, err error) error {
From 57e804dfa5e86687f4c5c64671f44238c116dce0 Mon Sep 17 00:00:00 2001
From: Vladimir <31961982+zvlb@users.noreply.github.com>
Date: Wed, 26 Oct 2022 16:11:52 +0200
Subject: [PATCH 024/316] Create LICENSE.md
---
LICENSE.md | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 201 insertions(+)
create mode 100644 LICENSE.md
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 00000000..261eeb9e
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
From 5954717dabe6261905848500c83da90bde3a72af Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Wed, 26 Oct 2022 17:23:57 +0300
Subject: [PATCH 025/316] Update ReadMe
Signed-off-by: Zemtsov Vladimir
---
README.md | 82 +++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 64 insertions(+), 18 deletions(-)
diff --git a/README.md b/README.md
index c33a4a1a..e2bc1ff9 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,9 @@
-# Vector Operator
-Operator for Kubernetes to deploy and manage [Vector](https://vector.dev/).
+
+
+
+
+
+
## Description
The operator deploys and configures a vector agent daemonset on every node to collect container and application logs from the node file system.
@@ -14,6 +18,7 @@ The operator deploys and configures a vector agent daemonset on every node to co
- [ ] Vector config optimization
- [ ] Vector aggregator support
+
## Getting Started
You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster.
**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows).
@@ -51,6 +56,63 @@ UnDeploy the controller to the cluster:
make undeploy
```
+## Configuration Examples
+Configuration for CR Vector:
+```yaml
+apiVersion: observability.kaasops.io/v1alpha1
+kind: Vector
+metadata:
+ name: vector-sample
+ namespace: vector
+spec:
+ agent:
+ service: true
+ image: "timberio/vector:0.24.0-distroless-libc"
+```
+
+Configuration for CR VectorPipeline:
+```yaml
+apiVersion: observability.kaasops.io/v1alpha1
+kind: VectorPipeline
+metadata:
+ name: vectorpipeline-sample
+spec:
+ sources:
+ source1:
+ type: "kubernetes_logs"
+ extra_label_selector: "app!=testdeployment"
+ source2:
+ type: "kubernetes_logs"
+ extra_label_selector: "app!=testdeployment1"
+ transforms:
+ remap:
+ type: "remap"
+ inputs:
+ - source1
+ source: |
+ .@timestamp = del(.timestamp)
+
+ .testField = "testValuevalue"
+ filter:
+ type: "filter"
+ inputs:
+ - source2
+ condition:
+ type: "vrl"
+ source: ".status != 200"
+ sinks:
+ test222:
+ type: "console"
+ encoding:
+ codec: "json"
+ inputs:
+ - filter
+ - remap
+```
+
+
+
+
## Contributing
### How it works
@@ -85,19 +147,3 @@ make manifests
More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html)
-## License
-
-Copyright 2022.
-
-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.
-
From 469a4d815a53eac0beb8522cb25a9368d9b3530d Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Wed, 26 Oct 2022 19:55:18 +0300
Subject: [PATCH 026/316] added github workflow to build image (#14)
* added github workflow to build image
---
.github/workflows/main.yaml | 43 +++++++++++++++++++++++++++++++++++++
Makefile | 2 +-
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 .github/workflows/main.yaml
diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
new file mode 100644
index 00000000..c6cec786
--- /dev/null
+++ b/.github/workflows/main.yaml
@@ -0,0 +1,43 @@
+name: Build and Test
+
+# This workflow will run on master branch and on any pull requests targeting master
+on:
+ push:
+ tags:
+ - '*'
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+jobs:
+ build-and-push-docker-image:
+ name: Build and push Docker image
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Get tag
+ id: tag
+ run: echo "TAG=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
+
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v1
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+
+ - name: Login to DockerHub
+ uses: docker/login-action@v2
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Build image and push to Docker Hub
+ uses: docker/build-push-action@v2
+ with:
+ context: .
+ platforms: linux/amd64,linux/arm64
+ push: true
+ tags: ${{ github.repository }}:${{ steps.tag.outputs.TAG }}
\ No newline at end of file
diff --git a/Makefile b/Makefile
index a5157b83..c8419f6d 100644
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,7 @@ BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL)
#
# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both
# kaasops.io/vector-operator-bundle:$VERSION and kaasops.io/vector-operator-catalog:$VERSION.
-IMAGE_TAG_BASE ?= kaasops.io/vector-operator
+IMAGE_TAG_BASE ?= kaasops/vector-operator
# BUNDLE_IMG defines the image:tag used for the bundle.
# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:)
From 31711f17c4580ea950cbc9a7dbc23320bd65600b Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 27 Oct 2022 09:39:38 +0300
Subject: [PATCH 027/316] Refactor VectorAgent Reconciler
Signed-off-by: Zemtsov Vladimir
---
.../vectoragent/vector_agent_config.go | 21 ++--
.../vectoragent/vector_agent_controller.go | 108 ++++++++++--------
.../vectoragent/vector_agent_daemonset.go | 32 +++---
.../factory/vectoragent/vector_agent_rbac.go | 26 ++---
.../vectoragent/vector_agent_service.go | 7 +-
controllers/vector_controller.go | 8 +-
6 files changed, 106 insertions(+), 96 deletions(-)
diff --git a/controllers/factory/vectoragent/vector_agent_config.go b/controllers/factory/vectoragent/vector_agent_config.go
index 3270bc6e..2cca9e42 100644
--- a/controllers/factory/vectoragent/vector_agent_config.go
+++ b/controllers/factory/vectoragent/vector_agent_config.go
@@ -4,27 +4,24 @@ import (
"context"
corev1 "k8s.io/api/core/v1"
- "k8s.io/client-go/kubernetes"
- "sigs.k8s.io/controller-runtime/pkg/client"
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/config"
"github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
"github.com/kaasops/vector-operator/controllers/factory/utils"
)
-func createVectorAgentConfig(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client, cs *kubernetes.Clientset) (*corev1.Secret, error) {
- cfg, err := config.Get(ctx, v, c)
+func (vr *VectorAgentReconciler) createVectorAgentConfig(ctx context.Context) (*corev1.Secret, error) {
+ cfg, err := config.Get(ctx, vr.Vector, vr.Client)
if err != nil {
return nil, err
}
cfgHash := utils.GetHash(cfg)
- if v.Status.LastAppliedConfigHash == nil || *v.Status.LastAppliedConfigHash != cfgHash {
- err = configcheck.Run(cfg, c, cs, v.Name, v.Namespace, v.Spec.Agent.Image)
+ if vr.Vector.Status.LastAppliedConfigHash == nil || *vr.Vector.Status.LastAppliedConfigHash != cfgHash {
+ err = configcheck.Run(cfg, vr.Client, vr.Clientset, vr.Vector.Name, vr.Vector.Namespace, vr.Vector.Spec.Agent.Image)
if _, ok := err.(*configcheck.ErrConfigCheck); ok {
- if err := setFailedStatus(ctx, v, c, err); err != nil {
+ if err := setFailedStatus(ctx, vr.Vector, vr.Client, err); err != nil {
return nil, err
}
return nil, err
@@ -33,23 +30,23 @@ func createVectorAgentConfig(ctx context.Context, v *vectorv1alpha1.Vector, c cl
return nil, err
}
- if err := SetLastAppliedPipelineStatus(ctx, v, c, &cfgHash); err != nil {
+ if err := SetLastAppliedPipelineStatus(ctx, vr.Vector, vr.Client, &cfgHash); err != nil {
return nil, err
}
- if err := setSucceesStatus(ctx, v, c); err != nil {
+ if err := setSucceesStatus(ctx, vr.Vector, vr.Client); err != nil {
return nil, err
}
}
- labels := labelsForVectorAgent(v.Name)
+ labels := vr.labelsForVectorAgent()
config := map[string][]byte{
"agent.json": cfg,
}
secret := &corev1.Secret{
- ObjectMeta: objectMetaVectorAgent(v, labels),
+ ObjectMeta: vr.objectMetaVectorAgent(labels),
Data: config,
}
diff --git a/controllers/factory/vectoragent/vector_agent_controller.go b/controllers/factory/vectoragent/vector_agent_controller.go
index ed6436af..7ad079f5 100644
--- a/controllers/factory/vectoragent/vector_agent_controller.go
+++ b/controllers/factory/vectoragent/vector_agent_controller.go
@@ -15,149 +15,165 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
)
-func EnsureVectorAgent(v *vectorv1alpha1.Vector, rclient client.Client, cs *kubernetes.Clientset) (done bool, result ctrl.Result, err error) {
+type VectorAgentReconciler struct {
+ client.Client
+ Vector *vectorv1alpha1.Vector
+
+ // Temp. Wait this issue - https://github.com/kubernetes-sigs/controller-runtime/issues/452
+ Clientset *kubernetes.Clientset
+}
+
+func NewReconciler(v *vectorv1alpha1.Vector, c client.Client, cs *kubernetes.Clientset) *VectorAgentReconciler {
+ return &VectorAgentReconciler{
+ Client: c,
+ Vector: v,
+ Clientset: cs,
+ }
+}
+
+func (vr *VectorAgentReconciler) EnsureVectorAgent() (done bool, result ctrl.Result, err error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent", v.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent", vr.Vector.Name)
log.Info("start Reconcile Vector Agent")
- if done, result, err = ensureVectorAgentRBAC(v, rclient); done {
+ if done, result, err = vr.ensureVectorAgentRBAC(); done {
return
}
- if v.Spec.Agent.Service {
- if done, result, err = ensureVectorAgentService(v, rclient); done {
+ if vr.Vector.Spec.Agent.Service {
+ if done, result, err = vr.ensureVectorAgentService(); done {
return
}
}
- if done, result, err = ensureVectorAgentConfig(v, rclient, cs); done {
+ if done, result, err = vr.ensureVectorAgentConfig(); done {
return
}
- if done, result, err = ensureVectorAgentDaemonSet(v, rclient); done {
+ if done, result, err = vr.ensureVectorAgentDaemonSet(); done {
return
}
return
}
-func ensureVectorAgentRBAC(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+func (vr *VectorAgentReconciler) ensureVectorAgentRBAC() (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-rbac", v.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-rbac", vr.Vector.Name)
log.Info("start Reconcile Vector Agent RBAC")
- if done, _, err := ensureVectorAgentServiceAccount(v, rclient); done {
+ if done, _, err := vr.ensureVectorAgentServiceAccount(); done {
return helper.ReconcileResult(err)
}
- if done, _, err := ensureVectorAgentClusterRole(v, rclient); done {
+ if done, _, err := vr.ensureVectorAgentClusterRole(); done {
return helper.ReconcileResult(err)
}
- if done, _, err := ensureVectorAgentClusterRoleBinding(v, rclient); done {
+ if done, _, err := vr.ensureVectorAgentClusterRoleBinding(); done {
return helper.ReconcileResult(err)
}
return helper.ReconcileResult(nil)
}
-func ensureVectorAgentServiceAccount(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
- vectorAgentServiceAccount := createVectorAgentServiceAccount(v)
+func (vr *VectorAgentReconciler) ensureVectorAgentServiceAccount() (bool, ctrl.Result, error) {
+ vectorAgentServiceAccount := vr.createVectorAgentServiceAccount()
- _, err := k8sutils.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, rclient)
+ _, err := k8sutils.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, vr.Client)
return helper.ReconcileResult(err)
}
-func ensureVectorAgentClusterRole(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
- vectorAgentClusterRole := createVectorAgentClusterRole(v)
+func (vr *VectorAgentReconciler) ensureVectorAgentClusterRole() (bool, ctrl.Result, error) {
+ vectorAgentClusterRole := vr.createVectorAgentClusterRole()
- _, err := k8sutils.CreateOrUpdateClusterRole(vectorAgentClusterRole, rclient)
+ _, err := k8sutils.CreateOrUpdateClusterRole(vectorAgentClusterRole, vr.Client)
return helper.ReconcileResult(err)
}
-func ensureVectorAgentClusterRoleBinding(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
- vectorAgentClusterRoleBinding := createVectorAgentClusterRoleBinding(v)
+func (vr *VectorAgentReconciler) ensureVectorAgentClusterRoleBinding() (bool, ctrl.Result, error) {
+ vectorAgentClusterRoleBinding := vr.createVectorAgentClusterRoleBinding()
- _, err := k8sutils.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, rclient)
+ _, err := k8sutils.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, vr.Client)
return helper.ReconcileResult(err)
}
-func ensureVectorAgentService(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+func (vr *VectorAgentReconciler) ensureVectorAgentService() (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-service", v.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-service", vr.Vector.Name)
log.Info("start Reconcile Vector Agent Service")
- vectorAgentService := createVectorAgentService(v)
+ vectorAgentService := vr.createVectorAgentService()
- _, err := k8sutils.CreateOrUpdateService(vectorAgentService, rclient)
+ _, err := k8sutils.CreateOrUpdateService(vectorAgentService, vr.Client)
return helper.ReconcileResult(err)
}
-func ensureVectorAgentConfig(v *vectorv1alpha1.Vector, rclient client.Client, cs *kubernetes.Clientset) (bool, ctrl.Result, error) {
+func (vr *VectorAgentReconciler) ensureVectorAgentConfig() (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-secret", v.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-secret", vr.Vector.Name)
log.Info("start Reconcile Vector Agent Secret")
- vectorAgentSecret, err := createVectorAgentConfig(ctx, v, rclient, cs)
+ vectorAgentSecret, err := vr.createVectorAgentConfig(ctx)
if err != nil {
return helper.ReconcileResult(err)
}
- _, err = k8sutils.CreateOrUpdateSecret(vectorAgentSecret, rclient)
+ _, err = k8sutils.CreateOrUpdateSecret(vectorAgentSecret, vr.Client)
return helper.ReconcileResult(err)
}
-func ensureVectorAgentDaemonSet(v *vectorv1alpha1.Vector, rclient client.Client) (bool, ctrl.Result, error) {
+func (vr *VectorAgentReconciler) ensureVectorAgentDaemonSet() (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", v.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", vr.Vector.Name)
log.Info("start Reconcile Vector Agent DaemonSet")
- vectorAgentDaemonSet := createVectorAgentDaemonSet(v)
+ vectorAgentDaemonSet := vr.createVectorAgentDaemonSet()
- _, err := k8sutils.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, rclient)
+ _, err := k8sutils.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, vr.Client)
return helper.ReconcileResult(err)
}
-func labelsForVectorAgent(name string) map[string]string {
+func (vr *VectorAgentReconciler) labelsForVectorAgent() map[string]string {
return map[string]string{
label.ManagedByLabelKey: "vector-operator",
label.NameLabelKey: "vector",
label.ComponentLabelKey: "Agent",
- label.InstanceLabelKey: name,
+ label.InstanceLabelKey: vr.Vector.Name,
label.VectorExcludeLabel: "true",
}
}
-func objectMetaVectorAgent(v *vectorv1alpha1.Vector, labels map[string]string) metav1.ObjectMeta {
+func (vr *VectorAgentReconciler) objectMetaVectorAgent(labels map[string]string) metav1.ObjectMeta {
return metav1.ObjectMeta{
- Name: v.Name + "-agent",
- Namespace: v.Namespace,
+ Name: vr.Vector.Name + "-agent",
+ Namespace: vr.Vector.Namespace,
Labels: labels,
- OwnerReferences: getControllerReference(v),
+ OwnerReferences: vr.getControllerReference(),
}
}
-func getNameVectorAgent(v *vectorv1alpha1.Vector) string {
- name := v.Name + "-agent"
+func (vr *VectorAgentReconciler) getNameVectorAgent() string {
+ name := vr.Vector.Name + "-agent"
return name
}
-func getControllerReference(owner *vectorv1alpha1.Vector) []metav1.OwnerReference {
+func (vr *VectorAgentReconciler) getControllerReference() []metav1.OwnerReference {
return []metav1.OwnerReference{
{
- APIVersion: owner.APIVersion,
- Kind: owner.Kind,
- Name: owner.GetName(),
- UID: owner.GetUID(),
+ APIVersion: vr.Vector.APIVersion,
+ Kind: vr.Vector.Kind,
+ Name: vr.Vector.GetName(),
+ UID: vr.Vector.GetUID(),
BlockOwnerDeletion: pointer.BoolPtr(true),
Controller: pointer.BoolPtr(true),
},
diff --git a/controllers/factory/vectoragent/vector_agent_daemonset.go b/controllers/factory/vectoragent/vector_agent_daemonset.go
index f06e4804..3029c919 100644
--- a/controllers/factory/vectoragent/vector_agent_daemonset.go
+++ b/controllers/factory/vectoragent/vector_agent_daemonset.go
@@ -4,30 +4,28 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
)
-func createVectorAgentDaemonSet(v *vectorv1alpha1.Vector) *appsv1.DaemonSet {
- labels := labelsForVectorAgent(v.Name)
+func (vr *VectorAgentReconciler) createVectorAgentDaemonSet() *appsv1.DaemonSet {
+ labels := vr.labelsForVectorAgent()
daemonset := &appsv1.DaemonSet{
- ObjectMeta: objectMetaVectorAgent(v, labels),
+ ObjectMeta: vr.objectMetaVectorAgent(labels),
Spec: appsv1.DaemonSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: labels},
Template: corev1.PodTemplateSpec{
- ObjectMeta: objectMetaVectorAgent(v, labels),
+ ObjectMeta: vr.objectMetaVectorAgent(labels),
Spec: corev1.PodSpec{
- ServiceAccountName: getNameVectorAgent(v),
- Volumes: generateVectorAgentVolume(v),
+ ServiceAccountName: vr.getNameVectorAgent(),
+ Volumes: vr.generateVectorAgentVolume(),
SecurityContext: &corev1.PodSecurityContext{},
- Tolerations: v.Spec.Agent.Tolerations,
+ Tolerations: vr.Vector.Spec.Agent.Tolerations,
Containers: []corev1.Container{
{
- Name: getNameVectorAgent(v),
- Image: v.Spec.Agent.Image,
+ Name: vr.getNameVectorAgent(),
+ Image: vr.Vector.Spec.Agent.Image,
Args: []string{"--config-dir", "/etc/vector/", "--watch-config"},
- Env: generateVectorAgentEnvs(v),
+ Env: vr.generateVectorAgentEnvs(),
Ports: []corev1.ContainerPort{
{
Name: "prom-exporter",
@@ -35,7 +33,7 @@ func createVectorAgentDaemonSet(v *vectorv1alpha1.Vector) *appsv1.DaemonSet {
Protocol: "TCP",
},
},
- VolumeMounts: generateVectorAgentVolumeMounts(v),
+ VolumeMounts: vr.generateVectorAgentVolumeMounts(),
SecurityContext: &corev1.SecurityContext{},
},
},
@@ -47,13 +45,13 @@ func createVectorAgentDaemonSet(v *vectorv1alpha1.Vector) *appsv1.DaemonSet {
return daemonset
}
-func generateVectorAgentVolume(v *vectorv1alpha1.Vector) []corev1.Volume {
+func (vr *VectorAgentReconciler) generateVectorAgentVolume() []corev1.Volume {
volume := []corev1.Volume{
{
Name: "config",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
- SecretName: getNameVectorAgent(v),
+ SecretName: vr.getNameVectorAgent(),
},
},
},
@@ -102,7 +100,7 @@ func generateVectorAgentVolume(v *vectorv1alpha1.Vector) []corev1.Volume {
return volume
}
-func generateVectorAgentVolumeMounts(spec *vectorv1alpha1.Vector) []corev1.VolumeMount {
+func (vr *VectorAgentReconciler) generateVectorAgentVolumeMounts() []corev1.VolumeMount {
volumeMount := []corev1.VolumeMount{
{
Name: "config",
@@ -133,7 +131,7 @@ func generateVectorAgentVolumeMounts(spec *vectorv1alpha1.Vector) []corev1.Volum
return volumeMount
}
-func generateVectorAgentEnvs(spec *vectorv1alpha1.Vector) []corev1.EnvVar {
+func (vr *VectorAgentReconciler) generateVectorAgentEnvs() []corev1.EnvVar {
envs := []corev1.EnvVar{
{
Name: "VECTOR_SELF_NODE_NAME",
diff --git a/controllers/factory/vectoragent/vector_agent_rbac.go b/controllers/factory/vectoragent/vector_agent_rbac.go
index 6ea637b4..6baf21ad 100644
--- a/controllers/factory/vectoragent/vector_agent_rbac.go
+++ b/controllers/factory/vectoragent/vector_agent_rbac.go
@@ -3,25 +3,23 @@ package vectoragent
import (
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
)
-func createVectorAgentServiceAccount(v *vectorv1alpha1.Vector) *corev1.ServiceAccount {
- labels := labelsForVectorAgent(v.Name)
+func (vr *VectorAgentReconciler) createVectorAgentServiceAccount() *corev1.ServiceAccount {
+ labels := vr.labelsForVectorAgent()
serviceAccount := &corev1.ServiceAccount{
- ObjectMeta: objectMetaVectorAgent(v, labels),
+ ObjectMeta: vr.objectMetaVectorAgent(labels),
}
return serviceAccount
}
-func createVectorAgentClusterRole(v *vectorv1alpha1.Vector) *rbacv1.ClusterRole {
- labels := labelsForVectorAgent(v.Name)
+func (vr *VectorAgentReconciler) createVectorAgentClusterRole() *rbacv1.ClusterRole {
+ labels := vr.labelsForVectorAgent()
clusterRole := &rbacv1.ClusterRole{
- ObjectMeta: objectMetaVectorAgent(v, labels),
+ ObjectMeta: vr.objectMetaVectorAgent(labels),
Rules: []rbacv1.PolicyRule{
{
APIGroups: []string{""},
@@ -34,21 +32,21 @@ func createVectorAgentClusterRole(v *vectorv1alpha1.Vector) *rbacv1.ClusterRole
return clusterRole
}
-func createVectorAgentClusterRoleBinding(v *vectorv1alpha1.Vector) *rbacv1.ClusterRoleBinding {
- labels := labelsForVectorAgent(v.Name)
+func (vr *VectorAgentReconciler) createVectorAgentClusterRoleBinding() *rbacv1.ClusterRoleBinding {
+ labels := vr.labelsForVectorAgent()
clusterRoleBinding := &rbacv1.ClusterRoleBinding{
- ObjectMeta: objectMetaVectorAgent(v, labels),
+ ObjectMeta: vr.objectMetaVectorAgent(labels),
RoleRef: rbacv1.RoleRef{
Kind: "ClusterRole",
APIGroup: "rbac.authorization.k8s.io",
- Name: getNameVectorAgent(v),
+ Name: vr.getNameVectorAgent(),
},
Subjects: []rbacv1.Subject{
{
Kind: "ServiceAccount",
- Name: getNameVectorAgent(v),
- Namespace: v.Namespace,
+ Name: vr.getNameVectorAgent(),
+ Namespace: vr.Vector.Namespace,
},
},
}
diff --git a/controllers/factory/vectoragent/vector_agent_service.go b/controllers/factory/vectoragent/vector_agent_service.go
index c30909bd..6d84d3d3 100644
--- a/controllers/factory/vectoragent/vector_agent_service.go
+++ b/controllers/factory/vectoragent/vector_agent_service.go
@@ -3,15 +3,14 @@ package vectoragent
import (
corev1 "k8s.io/api/core/v1"
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"k8s.io/apimachinery/pkg/util/intstr"
)
-func createVectorAgentService(v *vectorv1alpha1.Vector) *corev1.Service {
- labels := labelsForVectorAgent(v.Name)
+func (vr *VectorAgentReconciler) createVectorAgentService() *corev1.Service {
+ labels := vr.labelsForVectorAgent()
service := &corev1.Service{
- ObjectMeta: objectMetaVectorAgent(v, labels),
+ ObjectMeta: vr.objectMetaVectorAgent(labels),
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index c179ece6..57a5a91e 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -69,7 +69,7 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
v.Spec.Agent.DataDir = "/vector-data-dir"
}
- return CreateOrUpdateVector(ctx, v, r.Client, r.Clientset)
+ return r.CreateOrUpdateVector(v)
}
func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.Vector, bool, ctrl.Result, error) {
@@ -99,8 +99,10 @@ func (r *VectorReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}
-func CreateOrUpdateVector(ctx context.Context, v *vectorv1alpha1.Vector, rclient client.Client, cs *kubernetes.Clientset) (ctrl.Result, error) {
- if done, result, err := vectoragent.EnsureVectorAgent(v, rclient, cs); done {
+func (r *VectorReconciler) CreateOrUpdateVector(v *vectorv1alpha1.Vector) (ctrl.Result, error) {
+ vectorAgentReconciler := vectoragent.NewReconciler(v, r.Client, r.Clientset)
+
+ if done, result, err := vectorAgentReconciler.EnsureVectorAgent(); done {
return result, err
}
From f4a6f159bb9d1193b6649c53270435d370f4cf45 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 27 Oct 2022 09:45:13 +0300
Subject: [PATCH 028/316] Add licensed block to all go-files
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/config/config_build.go | 16 ++++++++++++++++
.../factory/config/configcheck/configcheck.go | 16 ++++++++++++++++
.../config/configcheck/configcheck_config.go | 16 ++++++++++++++++
.../config/configcheck/configcheck_error.go | 16 ++++++++++++++++
.../config/configcheck/configcheck_pod.go | 16 ++++++++++++++++
.../config/configcheck/configcheck_rbac.go | 16 ++++++++++++++++
controllers/factory/helper/helper.go | 16 ++++++++++++++++
controllers/factory/k8sutils/utils.go | 16 ++++++++++++++++
controllers/factory/label/label.go | 16 ++++++++++++++++
controllers/factory/utils/utils.go | 16 ++++++++++++++++
controllers/factory/vector/types.go | 16 ++++++++++++++++
controllers/factory/vector/vector.go | 16 ++++++++++++++++
.../factory/vectoragent/vector_agent_config.go | 16 ++++++++++++++++
.../vectoragent/vector_agent_controller.go | 16 ++++++++++++++++
.../vectoragent/vector_agent_daemonset.go | 16 ++++++++++++++++
.../factory/vectoragent/vector_agent_rbac.go | 16 ++++++++++++++++
.../factory/vectoragent/vector_agent_service.go | 16 ++++++++++++++++
controllers/factory/vectorpipeline/hash.go | 16 ++++++++++++++++
.../factory/vectorpipeline/vectorpipeline.go | 16 ++++++++++++++++
19 files changed, 304 insertions(+)
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index 58ce5fde..5a67f397 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 config
import (
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index 4cbc9a90..16616087 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 configcheck
import (
diff --git a/controllers/factory/config/configcheck/configcheck_config.go b/controllers/factory/config/configcheck/configcheck_config.go
index 85a0a0e1..4b5e6fc9 100644
--- a/controllers/factory/config/configcheck/configcheck_config.go
+++ b/controllers/factory/config/configcheck/configcheck_config.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 configcheck
import (
diff --git a/controllers/factory/config/configcheck/configcheck_error.go b/controllers/factory/config/configcheck/configcheck_error.go
index 37b3265d..2fd40672 100644
--- a/controllers/factory/config/configcheck/configcheck_error.go
+++ b/controllers/factory/config/configcheck/configcheck_error.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 configcheck
type error interface {
diff --git a/controllers/factory/config/configcheck/configcheck_pod.go b/controllers/factory/config/configcheck/configcheck_pod.go
index 8fe883b5..0bbd6c16 100644
--- a/controllers/factory/config/configcheck/configcheck_pod.go
+++ b/controllers/factory/config/configcheck/configcheck_pod.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 configcheck
import (
diff --git a/controllers/factory/config/configcheck/configcheck_rbac.go b/controllers/factory/config/configcheck/configcheck_rbac.go
index 84d06b35..08317c7f 100644
--- a/controllers/factory/config/configcheck/configcheck_rbac.go
+++ b/controllers/factory/config/configcheck/configcheck_rbac.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 configcheck
import (
diff --git a/controllers/factory/helper/helper.go b/controllers/factory/helper/helper.go
index 5247a1ef..5e3e0c64 100644
--- a/controllers/factory/helper/helper.go
+++ b/controllers/factory/helper/helper.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 helper
import ctrl "sigs.k8s.io/controller-runtime"
diff --git a/controllers/factory/k8sutils/utils.go b/controllers/factory/k8sutils/utils.go
index a2e0e321..01d77300 100644
--- a/controllers/factory/k8sutils/utils.go
+++ b/controllers/factory/k8sutils/utils.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 k8sutils
import (
diff --git a/controllers/factory/label/label.go b/controllers/factory/label/label.go
index 3d21f139..7dd3cf71 100644
--- a/controllers/factory/label/label.go
+++ b/controllers/factory/label/label.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 label
const (
diff --git a/controllers/factory/utils/utils.go b/controllers/factory/utils/utils.go
index a3c1486c..4f9ceb7d 100644
--- a/controllers/factory/utils/utils.go
+++ b/controllers/factory/utils/utils.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 utils
import "hash/crc32"
diff --git a/controllers/factory/vector/types.go b/controllers/factory/vector/types.go
index dd9eefde..80806517 100644
--- a/controllers/factory/vector/types.go
+++ b/controllers/factory/vector/types.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 vector
type VectorConfig struct {
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
index 5582e688..963cc0b3 100644
--- a/controllers/factory/vector/vector.go
+++ b/controllers/factory/vector/vector.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 vector
import (
diff --git a/controllers/factory/vectoragent/vector_agent_config.go b/controllers/factory/vectoragent/vector_agent_config.go
index 2cca9e42..b7a5044d 100644
--- a/controllers/factory/vectoragent/vector_agent_config.go
+++ b/controllers/factory/vectoragent/vector_agent_config.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 vectoragent
import (
diff --git a/controllers/factory/vectoragent/vector_agent_controller.go b/controllers/factory/vectoragent/vector_agent_controller.go
index 7ad079f5..1939859a 100644
--- a/controllers/factory/vectoragent/vector_agent_controller.go
+++ b/controllers/factory/vectoragent/vector_agent_controller.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 vectoragent
import (
diff --git a/controllers/factory/vectoragent/vector_agent_daemonset.go b/controllers/factory/vectoragent/vector_agent_daemonset.go
index 3029c919..88a3593a 100644
--- a/controllers/factory/vectoragent/vector_agent_daemonset.go
+++ b/controllers/factory/vectoragent/vector_agent_daemonset.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 vectoragent
import (
diff --git a/controllers/factory/vectoragent/vector_agent_rbac.go b/controllers/factory/vectoragent/vector_agent_rbac.go
index 6baf21ad..7cad24b4 100644
--- a/controllers/factory/vectoragent/vector_agent_rbac.go
+++ b/controllers/factory/vectoragent/vector_agent_rbac.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 vectoragent
import (
diff --git a/controllers/factory/vectoragent/vector_agent_service.go b/controllers/factory/vectoragent/vector_agent_service.go
index 6d84d3d3..93d14c24 100644
--- a/controllers/factory/vectoragent/vector_agent_service.go
+++ b/controllers/factory/vectoragent/vector_agent_service.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 vectoragent
import (
diff --git a/controllers/factory/vectorpipeline/hash.go b/controllers/factory/vectorpipeline/hash.go
index 8e6a83d9..946f7353 100644
--- a/controllers/factory/vectorpipeline/hash.go
+++ b/controllers/factory/vectorpipeline/hash.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 vectorpipeline
import (
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
index 224342c2..f468f247 100644
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/vectorpipeline/vectorpipeline.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 vectorpipeline
import (
From bae4f8dfc198a7f35438e96b128dcf3243d7cd53 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 27 Oct 2022 09:46:41 +0300
Subject: [PATCH 029/316] Add __debug_bin to gitignore
Signed-off-by: Zemtsov Vladimir
---
.gitignore | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index c2b8826e..bf6f53ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,4 +23,5 @@ testbin/*
*.swp
*.swo
*~
-.vscode
\ No newline at end of file
+.vscode
+__debug_bin
From 6785c7a9d41519c93f887ae6630fc4569ea516ae Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Thu, 27 Oct 2022 09:52:43 +0300
Subject: [PATCH 030/316] init clustervectorpipeline
---
PROJECT | 9 ++
api/v1alpha1/clustervectorpipeline_types.go | 64 +++++++++++++
api/v1alpha1/zz_generated.deepcopy.go | 89 +++++++++++++++++++
...ity.kaasops.io_clustervectorpipelines.yaml | 52 +++++++++++
config/crd/kustomization.yaml | 3 +
...cainjection_in_clustervectorpipelines.yaml | 7 ++
.../webhook_in_clustervectorpipelines.yaml | 16 ++++
.../clustervectorpipeline_editor_role.yaml | 24 +++++
.../clustervectorpipeline_viewer_role.yaml | 20 +++++
config/rbac/role.yaml | 26 ++++++
config/samples/kustomization.yaml | 1 +
...bility_v1alpha1_clustervectorpipeline.yaml | 6 ++
.../clustervectorpipeline_controller.go | 62 +++++++++++++
main.go | 7 ++
14 files changed, 386 insertions(+)
create mode 100644 api/v1alpha1/clustervectorpipeline_types.go
create mode 100644 config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
create mode 100644 config/crd/patches/cainjection_in_clustervectorpipelines.yaml
create mode 100644 config/crd/patches/webhook_in_clustervectorpipelines.yaml
create mode 100644 config/rbac/clustervectorpipeline_editor_role.yaml
create mode 100644 config/rbac/clustervectorpipeline_viewer_role.yaml
create mode 100644 config/samples/observability_v1alpha1_clustervectorpipeline.yaml
create mode 100644 controllers/clustervectorpipeline_controller.go
diff --git a/PROJECT b/PROJECT
index 05c036cc..fca8aa8e 100644
--- a/PROJECT
+++ b/PROJECT
@@ -25,4 +25,13 @@ resources:
kind: VectorPipeline
path: github.com/kaasops/vector-operator/api/v1alpha1
version: v1alpha1
+- api:
+ crdVersion: v1
+ namespaced: true
+ controller: true
+ domain: kaasops.io
+ group: observability
+ kind: ClusterVectorPipeline
+ path: github.com/kaasops/vector-operator/api/v1alpha1
+ version: v1alpha1
version: "3"
diff --git a/api/v1alpha1/clustervectorpipeline_types.go b/api/v1alpha1/clustervectorpipeline_types.go
new file mode 100644
index 00000000..d56e3db7
--- /dev/null
+++ b/api/v1alpha1/clustervectorpipeline_types.go
@@ -0,0 +1,64 @@
+/*
+Copyright 2022.
+
+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
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
+// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
+
+// ClusterVectorPipelineSpec defines the desired state of ClusterVectorPipeline
+type ClusterVectorPipelineSpec struct {
+ // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+
+ // Foo is an example field of ClusterVectorPipeline. Edit clustervectorpipeline_types.go to remove/update
+ Foo string `json:"foo,omitempty"`
+}
+
+// ClusterVectorPipelineStatus defines the observed state of ClusterVectorPipeline
+type ClusterVectorPipelineStatus struct {
+ // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+}
+
+//+kubebuilder:object:root=true
+//+kubebuilder:subresource:status
+
+// ClusterVectorPipeline is the Schema for the clustervectorpipelines API
+type ClusterVectorPipeline struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec ClusterVectorPipelineSpec `json:"spec,omitempty"`
+ Status ClusterVectorPipelineStatus `json:"status,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// ClusterVectorPipelineList contains a list of ClusterVectorPipeline
+type ClusterVectorPipelineList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []ClusterVectorPipeline `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&ClusterVectorPipeline{}, &ClusterVectorPipelineList{})
+}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index f36d6c1f..ce334621 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -26,6 +26,95 @@ import (
"k8s.io/apimachinery/pkg/runtime"
)
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ClusterVectorPipeline) DeepCopyInto(out *ClusterVectorPipeline) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ out.Spec = in.Spec
+ out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVectorPipeline.
+func (in *ClusterVectorPipeline) DeepCopy() *ClusterVectorPipeline {
+ if in == nil {
+ return nil
+ }
+ out := new(ClusterVectorPipeline)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *ClusterVectorPipeline) 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 *ClusterVectorPipelineList) DeepCopyInto(out *ClusterVectorPipelineList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]ClusterVectorPipeline, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVectorPipelineList.
+func (in *ClusterVectorPipelineList) DeepCopy() *ClusterVectorPipelineList {
+ if in == nil {
+ return nil
+ }
+ out := new(ClusterVectorPipelineList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *ClusterVectorPipelineList) 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 *ClusterVectorPipelineSpec) DeepCopyInto(out *ClusterVectorPipelineSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVectorPipelineSpec.
+func (in *ClusterVectorPipelineSpec) DeepCopy() *ClusterVectorPipelineSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(ClusterVectorPipelineSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ClusterVectorPipelineStatus) DeepCopyInto(out *ClusterVectorPipelineStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVectorPipelineStatus.
+func (in *ClusterVectorPipelineStatus) DeepCopy() *ClusterVectorPipelineStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(ClusterVectorPipelineStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Vector) DeepCopyInto(out *Vector) {
*out = *in
diff --git a/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
new file mode 100644
index 00000000..0836390a
--- /dev/null
+++ b/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
@@ -0,0 +1,52 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.9.2
+ creationTimestamp: null
+ name: clustervectorpipelines.observability.kaasops.io
+spec:
+ group: observability.kaasops.io
+ names:
+ kind: ClusterVectorPipeline
+ listKind: ClusterVectorPipelineList
+ plural: clustervectorpipelines
+ singular: clustervectorpipeline
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: ClusterVectorPipeline is the Schema for the clustervectorpipelines
+ API
+ 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: ClusterVectorPipelineSpec defines the desired state of ClusterVectorPipeline
+ properties:
+ foo:
+ description: Foo is an example field of ClusterVectorPipeline. Edit
+ clustervectorpipeline_types.go to remove/update
+ type: string
+ type: object
+ status:
+ description: ClusterVectorPipelineStatus defines the observed state of
+ ClusterVectorPipeline
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 0121c8b1..d86cff3a 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -4,6 +4,7 @@
resources:
- bases/observability.kaasops.io_vectors.yaml
- bases/observability.kaasops.io_vectorpipelines.yaml
+- bases/observability.kaasops.io_clustervectorpipelines.yaml
#+kubebuilder:scaffold:crdkustomizeresource
patchesStrategicMerge:
@@ -11,12 +12,14 @@ patchesStrategicMerge:
# patches here are for enabling the conversion webhook for each CRD
#- patches/webhook_in_vectors.yaml
#- patches/webhook_in_vectorpipelines.yaml
+#- patches/webhook_in_clustervectorpipelines.yaml
#+kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
#- patches/cainjection_in_vectors.yaml
#- patches/cainjection_in_vectorpipelines.yaml
+#- patches/cainjection_in_clustervectorpipelines.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
# the following config is for teaching kustomize how to do kustomization for CRDs.
diff --git a/config/crd/patches/cainjection_in_clustervectorpipelines.yaml b/config/crd/patches/cainjection_in_clustervectorpipelines.yaml
new file mode 100644
index 00000000..7b4b6265
--- /dev/null
+++ b/config/crd/patches/cainjection_in_clustervectorpipelines.yaml
@@ -0,0 +1,7 @@
+# The following patch adds a directive for certmanager to inject CA into the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+ name: clustervectorpipelines.observability.kaasops.io
diff --git a/config/crd/patches/webhook_in_clustervectorpipelines.yaml b/config/crd/patches/webhook_in_clustervectorpipelines.yaml
new file mode 100644
index 00000000..634883c6
--- /dev/null
+++ b/config/crd/patches/webhook_in_clustervectorpipelines.yaml
@@ -0,0 +1,16 @@
+# The following patch enables a conversion webhook for the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ name: clustervectorpipelines.observability.kaasops.io
+spec:
+ conversion:
+ strategy: Webhook
+ webhook:
+ clientConfig:
+ service:
+ namespace: system
+ name: webhook-service
+ path: /convert
+ conversionReviewVersions:
+ - v1
diff --git a/config/rbac/clustervectorpipeline_editor_role.yaml b/config/rbac/clustervectorpipeline_editor_role.yaml
new file mode 100644
index 00000000..6f7b4e4b
--- /dev/null
+++ b/config/rbac/clustervectorpipeline_editor_role.yaml
@@ -0,0 +1,24 @@
+# permissions for end users to edit clustervectorpipelines.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: clustervectorpipeline-editor-role
+rules:
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - clustervectorpipelines
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - clustervectorpipelines/status
+ verbs:
+ - get
diff --git a/config/rbac/clustervectorpipeline_viewer_role.yaml b/config/rbac/clustervectorpipeline_viewer_role.yaml
new file mode 100644
index 00000000..95ab58ce
--- /dev/null
+++ b/config/rbac/clustervectorpipeline_viewer_role.yaml
@@ -0,0 +1,20 @@
+# permissions for end users to view clustervectorpipelines.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: clustervectorpipeline-viewer-role
+rules:
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - clustervectorpipelines
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - clustervectorpipelines/status
+ verbs:
+ - get
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index 9b633876..276b6e63 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -5,6 +5,32 @@ metadata:
creationTimestamp: null
name: manager-role
rules:
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - clustervectorpipelines
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - clustervectorpipelines/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - clustervectorpipelines/status
+ verbs:
+ - get
+ - patch
+ - update
- apiGroups:
- observability.kaasops.io
resources:
diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml
index ab24709f..2dc737f5 100644
--- a/config/samples/kustomization.yaml
+++ b/config/samples/kustomization.yaml
@@ -2,4 +2,5 @@
resources:
- observability_v1alpha1_vector.yaml
- observability_v1alpha1_vectorpipeline.yaml
+- observability_v1alpha1_clustervectorpipeline.yaml
#+kubebuilder:scaffold:manifestskustomizesamples
diff --git a/config/samples/observability_v1alpha1_clustervectorpipeline.yaml b/config/samples/observability_v1alpha1_clustervectorpipeline.yaml
new file mode 100644
index 00000000..4a453702
--- /dev/null
+++ b/config/samples/observability_v1alpha1_clustervectorpipeline.yaml
@@ -0,0 +1,6 @@
+apiVersion: observability.kaasops.io/v1alpha1
+kind: ClusterVectorPipeline
+metadata:
+ name: clustervectorpipeline-sample
+spec:
+ # TODO(user): Add fields here
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
new file mode 100644
index 00000000..ca3691b0
--- /dev/null
+++ b/controllers/clustervectorpipeline_controller.go
@@ -0,0 +1,62 @@
+/*
+Copyright 2022.
+
+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 controllers
+
+import (
+ "context"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+
+ observabilityv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+)
+
+// ClusterVectorPipelineReconciler reconciles a ClusterVectorPipeline object
+type ClusterVectorPipelineReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+}
+
+//+kubebuilder:rbac:groups=observability.kaasops.io,resources=clustervectorpipelines,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=observability.kaasops.io,resources=clustervectorpipelines/status,verbs=get;update;patch
+//+kubebuilder:rbac:groups=observability.kaasops.io,resources=clustervectorpipelines/finalizers,verbs=update
+
+// Reconcile is part of the main kubernetes reconciliation loop which aims to
+// move the current state of the cluster closer to the desired state.
+// TODO(user): Modify the Reconcile function to compare the state specified by
+// the ClusterVectorPipeline object against the actual cluster state, and then
+// perform operations to make the cluster state reflect the state specified by
+// the user.
+//
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.2/pkg/reconcile
+func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+ _ = log.FromContext(ctx)
+
+ // TODO(user): your logic here
+
+ return ctrl.Result{}, nil
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (r *ClusterVectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&observabilityv1alpha1.ClusterVectorPipeline{}).
+ Complete(r)
+}
diff --git a/main.go b/main.go
index aa5c9188..9cf88ce9 100644
--- a/main.go
+++ b/main.go
@@ -118,6 +118,13 @@ func main() {
setupLog.Error(err, "unable to create controller", "controller", "VectorPipeline")
os.Exit(1)
}
+ if err = (&controllers.ClusterVectorPipelineReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "ClusterVectorPipeline")
+ os.Exit(1)
+ }
//+kubebuilder:scaffold:builder
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
From eb83ff9ad90a04d07ac0271c925de2a2ccc45b18 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 27 Oct 2022 16:41:36 +0300
Subject: [PATCH 031/316] Refactor Pipeline
Signed-off-by: Zemtsov Vladimir
---
CHANGELOG.md | 1 +
LICENSE.md => LICENSE | 0
api/v1alpha1/clustervectorpipeline_types.go | 22 +-
api/v1alpha1/zz_generated.deepcopy.go | 34 +--
...ity.kaasops.io_clustervectorpipelines.yaml | 37 ++-
.../clustervectorpipeline_controller.go | 72 ++++-
controllers/factory/config/config_build.go | 34 +--
controllers/factory/config/config_check.go | 64 +++++
.../factory/config/configcheck/configcheck.go | 5 -
.../clustervectorpipeline/vectorpipeline.go | 75 ++++++
.../{vectorpipeline => pipeline}/hash.go | 21 +-
controllers/factory/pipeline/pipeline.go | 255 ++++++++++++++++++
.../pipeline/vectorpipeline/vectorpipeline.go | 75 ++++++
controllers/factory/vector/types.go | 7 +-
.../vectoragent/vector_agent_config.go | 18 +-
.../vectoragent/vector_agent_controller.go | 98 +++----
.../vectoragent/vector_agent_daemonset.go | 30 +--
.../factory/vectoragent/vector_agent_rbac.go | 24 +-
.../vectoragent/vector_agent_service.go | 6 +-
.../factory/vectorpipeline/vectorpipeline.go | 174 ------------
controllers/vector_controller.go | 2 +-
controllers/vectorpipeline_controller.go | 70 ++---
main.go | 5 +-
23 files changed, 728 insertions(+), 401 deletions(-)
rename LICENSE.md => LICENSE (100%)
create mode 100644 controllers/factory/config/config_check.go
create mode 100644 controllers/factory/pipeline/clustervectorpipeline/vectorpipeline.go
rename controllers/factory/{vectorpipeline => pipeline}/hash.go (59%)
create mode 100644 controllers/factory/pipeline/pipeline.go
create mode 100644 controllers/factory/pipeline/vectorpipeline/vectorpipeline.go
delete mode 100644 controllers/factory/vectorpipeline/vectorpipeline.go
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1ae96357..0b943256 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
### Added
+- Refactor: Refactor Pipeline for add ClusterVectorPipeline and checks
- Feature: Add field reason to CR Vector and VectorPipeline
- Feature: Add ConfigCheck for Vector
- Feature: Add ConfigCheck for VectorPipeline
diff --git a/LICENSE.md b/LICENSE
similarity index 100%
rename from LICENSE.md
rename to LICENSE
diff --git a/api/v1alpha1/clustervectorpipeline_types.go b/api/v1alpha1/clustervectorpipeline_types.go
index d56e3db7..2a3c088e 100644
--- a/api/v1alpha1/clustervectorpipeline_types.go
+++ b/api/v1alpha1/clustervectorpipeline_types.go
@@ -23,31 +23,19 @@ import (
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
-// ClusterVectorPipelineSpec defines the desired state of ClusterVectorPipeline
-type ClusterVectorPipelineSpec struct {
- // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
- // Important: Run "make" to regenerate code after modifying this file
-
- // Foo is an example field of ClusterVectorPipeline. Edit clustervectorpipeline_types.go to remove/update
- Foo string `json:"foo,omitempty"`
-}
-
-// ClusterVectorPipelineStatus defines the observed state of ClusterVectorPipeline
-type ClusterVectorPipelineStatus struct {
- // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
- // Important: Run "make" to regenerate code after modifying this file
-}
-
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
+//+kubebuilder:resource:shortName=cvp
+//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
+//+kubebuilder:printcolumn:name="Status",type="boolean",JSONPath=".status.configCheckResult"
// ClusterVectorPipeline is the Schema for the clustervectorpipelines API
type ClusterVectorPipeline struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
- Spec ClusterVectorPipelineSpec `json:"spec,omitempty"`
- Status ClusterVectorPipelineStatus `json:"status,omitempty"`
+ Spec VectorPipelineSpec `json:"spec,omitempty"`
+ Status VectorPipelineStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index ce334621..746cbf3f 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -31,8 +31,8 @@ func (in *ClusterVectorPipeline) DeepCopyInto(out *ClusterVectorPipeline) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
- out.Status = in.Status
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVectorPipeline.
@@ -85,36 +85,6 @@ func (in *ClusterVectorPipelineList) DeepCopyObject() runtime.Object {
return nil
}
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ClusterVectorPipelineSpec) DeepCopyInto(out *ClusterVectorPipelineSpec) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVectorPipelineSpec.
-func (in *ClusterVectorPipelineSpec) DeepCopy() *ClusterVectorPipelineSpec {
- if in == nil {
- return nil
- }
- out := new(ClusterVectorPipelineSpec)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ClusterVectorPipelineStatus) DeepCopyInto(out *ClusterVectorPipelineStatus) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVectorPipelineStatus.
-func (in *ClusterVectorPipelineStatus) DeepCopy() *ClusterVectorPipelineStatus {
- if in == nil {
- return nil
- }
- out := new(ClusterVectorPipelineStatus)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Vector) DeepCopyInto(out *Vector) {
*out = *in
diff --git a/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
index 0836390a..f22f7cbe 100644
--- a/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
@@ -12,10 +12,19 @@ spec:
kind: ClusterVectorPipeline
listKind: ClusterVectorPipelineList
plural: clustervectorpipelines
+ shortNames:
+ - cvp
singular: clustervectorpipeline
scope: Namespaced
versions:
- - name: v1alpha1
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ - jsonPath: .status.configCheckResult
+ name: Status
+ type: boolean
+ name: v1alpha1
schema:
openAPIV3Schema:
description: ClusterVectorPipeline is the Schema for the clustervectorpipelines
@@ -34,16 +43,28 @@ spec:
metadata:
type: object
spec:
- description: ClusterVectorPipelineSpec defines the desired state of ClusterVectorPipeline
+ description: VectorPipelineSpec defines the desired state of VectorPipeline
properties:
- foo:
- description: Foo is an example field of ClusterVectorPipeline. Edit
- clustervectorpipeline_types.go to remove/update
- type: string
+ sinks:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ sources:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ transforms:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
type: object
status:
- description: ClusterVectorPipelineStatus defines the observed state of
- ClusterVectorPipeline
+ description: VectorPipelineStatus defines the observed state of VectorPipeline
+ properties:
+ LastAppliedPipelineHash:
+ format: int32
+ type: integer
+ configCheckResult:
+ type: boolean
+ reason:
+ type: string
type: object
type: object
served: true
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
index ca3691b0..16339b4c 100644
--- a/controllers/clustervectorpipeline_controller.go
+++ b/controllers/clustervectorpipeline_controller.go
@@ -19,18 +19,24 @@ package controllers
import (
"context"
+ "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
- observabilityv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/go-logr/logr"
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
)
// ClusterVectorPipelineReconciler reconciles a ClusterVectorPipeline object
type ClusterVectorPipelineReconciler struct {
client.Client
Scheme *runtime.Scheme
+
+ // Temp. Wait this issue - https://github.com/kubernetes-sigs/controller-runtime/issues/452
+ Clientset *kubernetes.Clientset
}
//+kubebuilder:rbac:groups=observability.kaasops.io,resources=clustervectorpipelines,verbs=get;list;watch;create;update;patch;delete
@@ -47,16 +53,74 @@ type ClusterVectorPipelineReconciler struct {
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.2/pkg/reconcile
func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
- _ = log.FromContext(ctx)
+ log := log.FromContext(ctx).WithValues("VectorPipeline", req.Name)
+
+ log.Info("start Reconcile ClusterVectorPipeline")
+
+ // cvp, done, result, err := r.findClusterVectorPipelineCustomResourceInstance(ctx, log, req)
+ // if done {
+ // return result, err
+ // }
+ // hash, err := vectorpipeline.GetSpecHash(cvp.Spec)
+ // if err != nil {
+ // return ctrl.Result{}, err
+ // }
+ // if cvp.Status.LastAppliedPipelineHash != nil && *hash == *cvp.Status.LastAppliedPipelineHash {
+ // log.Info("ClusterVectorPipeline has no changes. Finish Reconcile ClusterVectorPipeline")
+ // return ctrl.Result{}, nil
+ // }
+
+ // vectorInstances := &vectorv1alpha1.VectorList{}
+ // err = r.List(ctx, vectorInstances)
+ // if err != nil {
+ // return ctrl.Result{}, err
+ // }
- // TODO(user): your logic here
+ // if len(vectorInstances.Items) == 0 {
+ // log.Info("Vertors not found")
+ // return ctrl.Result{}, nil
+ // }
+ // for _, v := range vectorInstances.Items {
+ // if v.DeletionTimestamp != nil {
+ // continue
+ // }
+ // if err = checkConfig(ctx, &v, vp, r.Client, r.Clientset); err != nil {
+ // return ctrl.Result{}, err
+ // }
+ // if err = vectorpipeline.SetLastAppliedPipelineStatus(ctx, vp, r.Client); err != nil {
+ // return ctrl.Result{}, err
+ // }
+
+ // }
+
+ log.Info("finish Reconcile ClusterVectorPipeline")
return ctrl.Result{}, nil
}
+func (r *ClusterVectorPipelineReconciler) findClusterVectorPipelineCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.ClusterVectorPipeline, bool, ctrl.Result, error) {
+ // fetch the master instance
+ cvp := &vectorv1alpha1.ClusterVectorPipeline{}
+ err := r.Get(ctx, req.NamespacedName, cvp)
+ if err != nil {
+ if errors.IsNotFound(err) {
+ // Request object not found, could have been deleted after reconcile request.
+ // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
+ // Return and don't requeue
+ log.Info("ClusterVectorPipeline CR not found. Ignoring since object must be deleted")
+ return nil, true, ctrl.Result{}, nil
+ }
+ // Error reading the object - requeue the request.
+ log.Error(err, "Failed to get Vector")
+ return nil, true, ctrl.Result{}, err
+ }
+ log.Info("Get Vector Pipeline" + cvp.Name)
+ return cvp, false, ctrl.Result{}, nil
+}
+
// SetupWithManager sets up the controller with the Manager.
func (r *ClusterVectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
- For(&observabilityv1alpha1.ClusterVectorPipeline{}).
+ For(&vectorv1alpha1.ClusterVectorPipeline{}).
Complete(r)
}
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index 5a67f397..f326a5e0 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -19,11 +19,10 @@ package config
import (
"context"
"encoding/json"
- "log"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector"
- "github.com/kaasops/vector-operator/controllers/factory/vectorpipeline"
"sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -46,27 +45,28 @@ var (
)
func Get(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) ([]byte, error) {
- vps, err := vectorpipeline.SelectSucceesed(ctx, c)
+ vCtrl := pipeline.NewController(ctx, c, nil)
+ pipelines, err := vCtrl.SelectSucceesed()
if err != nil {
return nil, err
}
- cfg, err := GenerateConfig(v, vps)
+ cfg, err := GenerateVectorConfig(v, pipelines)
if err != nil {
return nil, err
}
- return cfg, nil
+ return VectorConfigToJson(cfg)
}
-func GenerateConfig(
+func GenerateVectorConfig(
v *vectorv1alpha1.Vector,
- vps []*vectorv1alpha1.VectorPipeline,
-) ([]byte, error) {
+ vCtrls []pipeline.Controller,
+) (*vector.VectorConfig, error) {
cfg := vector.New(v.Spec.Agent.DataDir, v.Spec.Agent.ApiEnabled)
- sources, transforms, sinks, err := getComponents(vps)
+ sources, transforms, sinks, err := getComponents(vCtrls)
if err != nil {
- log.Fatal(err)
+ return nil, err
}
if len(sources) == 0 {
sources = sourceDefault
@@ -79,16 +79,16 @@ func GenerateConfig(
cfg.Sources = sources
cfg.Transforms = transforms
- return vectorConfigToJson(cfg)
+ return cfg, nil
}
-func getComponents(vps []*vectorv1alpha1.VectorPipeline) (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
+func getComponents(vCtrls []pipeline.Controller) (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
sourcesMap := make(map[string]interface{})
transformsMap := make(map[string]interface{})
sinksMap := make(map[string]interface{})
- for _, vp := range vps {
- sources, err := vectorpipeline.GetSources(vp, nil)
+ for _, vCtrl := range vCtrls {
+ sources, err := vCtrl.GetSources(nil)
if err != nil {
return nil, nil, nil, err
}
@@ -99,7 +99,7 @@ func getComponents(vps []*vectorv1alpha1.VectorPipeline) (map[string]interface{}
}
sourcesMap[source.Name] = spec
}
- transforms, err := vectorpipeline.GetTransforms(vp)
+ transforms, err := vCtrl.GetTransforms()
if err != nil {
return nil, nil, nil, err
}
@@ -110,7 +110,7 @@ func getComponents(vps []*vectorv1alpha1.VectorPipeline) (map[string]interface{}
}
transformsMap[transform.Name] = spec
}
- sinks, err := vectorpipeline.GetSinks(vp)
+ sinks, err := vCtrl.GetSinks()
if err != nil {
return nil, nil, nil, err
}
@@ -125,7 +125,7 @@ func getComponents(vps []*vectorv1alpha1.VectorPipeline) (map[string]interface{}
return sourcesMap, transformsMap, sinksMap, nil
}
-func vectorConfigToJson(conf *vector.VectorConfig) ([]byte, error) {
+func VectorConfigToJson(conf *vector.VectorConfig) ([]byte, error) {
data, err := json.Marshal(conf)
if err != nil {
return nil, err
diff --git a/controllers/factory/config/config_check.go b/controllers/factory/config/config_check.go
new file mode 100644
index 00000000..68921970
--- /dev/null
+++ b/controllers/factory/config/config_check.go
@@ -0,0 +1,64 @@
+/*
+Copyright 2022.
+
+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 config
+
+import (
+ "context"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline"
+ "k8s.io/client-go/kubernetes"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+)
+
+func Check(ctx context.Context, v *vectorv1alpha1.Vector, vCtrl *pipeline.Controller, c client.Client, cs *kubernetes.Clientset) error {
+
+ log := log.FromContext(context.TODO()).WithValues("ConfigCheck Vector Pipeline", vCtrl.Pipeline.Name())
+
+ var vCtrls []pipeline.Controller
+ vCtrls = append(vCtrls, *vCtrl)
+
+ cfg, err := GenerateVectorConfig(v, vCtrls)
+ if err != nil {
+ return err
+ }
+
+ // if p.Type() == vectorpipeline.Type {
+ // log.Info("It's VectorPipeline")
+ // }
+
+ cfgJson, err := VectorConfigToJson(cfg)
+ if err != nil {
+ return err
+ }
+
+ err = configcheck.Run(cfgJson, c, cs, v.Name, v.Namespace, v.Spec.Agent.Image)
+ if _, ok := err.(*configcheck.ErrConfigCheck); ok {
+ if err := vCtrl.SetFailedStatus(err); err != nil {
+ return err
+ }
+ log.Error(err, "Vector Config has error")
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+
+ return vCtrl.SetSucceesStatus()
+}
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index 16616087..5204c01b 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -84,11 +84,6 @@ func ensureVectorConfigCheckServiceAccount(c client.Client, ns string) (bool, ct
return helper.ReconcileResult(err)
}
func ensureVectorConfigCheckConfig(c client.Client, cfg []byte, name, ns, hash string) error {
- // ctx := context.Background()
- // log := log.FromContext(ctx).WithValues("vector-config-check-secret", "ConfigCheck")
-
- // log.Info("start Create Config Check Secret")
-
vectorConfigCheckSecret, err := createVectorConfigCheckConfig(cfg, name, ns, hash)
if err != nil {
return err
diff --git a/controllers/factory/pipeline/clustervectorpipeline/vectorpipeline.go b/controllers/factory/pipeline/clustervectorpipeline/vectorpipeline.go
new file mode 100644
index 00000000..993d15a4
--- /dev/null
+++ b/controllers/factory/pipeline/clustervectorpipeline/vectorpipeline.go
@@ -0,0 +1,75 @@
+/*
+Copyright 2022.
+
+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 clustervectorpipeline
+
+import (
+ "context"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+var (
+ Type = "cluster"
+)
+
+type Controller struct {
+ ClusterVectorPipeline *vectorv1alpha1.ClusterVectorPipeline
+}
+
+func (ctrl *Controller) Spec() vectorv1alpha1.VectorPipelineSpec {
+ return ctrl.ClusterVectorPipeline.Spec
+}
+
+func (ctrl *Controller) Name() string {
+ return ctrl.ClusterVectorPipeline.Name
+}
+
+func (ctrl *Controller) Namespace() string {
+ return ctrl.ClusterVectorPipeline.Namespace
+}
+
+func (ctrl *Controller) Type() string {
+ return Type
+}
+
+func (ctrl *Controller) SetConfigCheck(value bool) {
+ ctrl.ClusterVectorPipeline.Status.ConfigCheckResult = &value
+}
+
+func (ctrl *Controller) SetReason(reason *string) {
+ ctrl.ClusterVectorPipeline.Status.Reason = reason
+}
+
+func (ctrl *Controller) GetLastAppliedPipeline() *uint32 {
+ return ctrl.ClusterVectorPipeline.Status.LastAppliedPipelineHash
+}
+
+func (ctrl *Controller) SetLastAppliedPipeline(hash *uint32) {
+ ctrl.ClusterVectorPipeline.Status.LastAppliedPipelineHash = hash
+}
+
+func (ctrl *Controller) UpdateStatus(ctx context.Context, c client.Client) error {
+ return k8sutils.UpdateStatus(ctx, ctrl.ClusterVectorPipeline, c)
+}
+
+func NewController(cvp *vectorv1alpha1.ClusterVectorPipeline) *Controller {
+ return &Controller{
+ ClusterVectorPipeline: cvp,
+ }
+}
diff --git a/controllers/factory/vectorpipeline/hash.go b/controllers/factory/pipeline/hash.go
similarity index 59%
rename from controllers/factory/vectorpipeline/hash.go
rename to controllers/factory/pipeline/hash.go
index 946f7353..bfb73065 100644
--- a/controllers/factory/vectorpipeline/hash.go
+++ b/controllers/factory/pipeline/hash.go
@@ -14,20 +14,33 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package vectorpipeline
+package pipeline
import (
"encoding/json"
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/utils"
)
-func GetVpSpecHash(vp *vectorv1alpha1.VectorPipeline) (*uint32, error) {
- a, err := json.Marshal(vp.Spec)
+func (ctrl *Controller) GetSpecHash() (*uint32, error) {
+ a, err := json.Marshal(ctrl.Pipeline.Spec())
if err != nil {
return nil, err
}
hash := utils.GetHash(a)
return &hash, nil
}
+
+// CheckHash returns true, if hash in .status.lastAppliedPipelineHash matches with spec Hash
+func (ctrl *Controller) CheckHash() (bool, error) {
+ hash, err := ctrl.GetSpecHash()
+ if err != nil {
+ return false, err
+ }
+
+ if ctrl.Pipeline.GetLastAppliedPipeline() != nil && *hash == *ctrl.Pipeline.GetLastAppliedPipeline() {
+ return true, nil
+ }
+
+ return false, nil
+}
diff --git a/controllers/factory/pipeline/pipeline.go b/controllers/factory/pipeline/pipeline.go
new file mode 100644
index 00000000..f6108ddf
--- /dev/null
+++ b/controllers/factory/pipeline/pipeline.go
@@ -0,0 +1,255 @@
+/*
+Copyright 2022.
+
+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 pipeline
+
+import (
+ "context"
+ "encoding/json"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline/clustervectorpipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline/vectorpipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/vector"
+ "github.com/mitchellh/mapstructure"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+type Pipeline interface {
+ Spec() vectorv1alpha1.VectorPipelineSpec
+ Name() string
+ Namespace() string
+ Type() string
+ SetConfigCheck(bool)
+ SetReason(*string)
+ GetLastAppliedPipeline() *uint32
+ SetLastAppliedPipeline(*uint32)
+ UpdateStatus(context.Context, client.Client) error
+}
+
+type Controller struct {
+ Pipeline Pipeline
+ Ctx context.Context
+ Client client.Client
+}
+
+func NewController(ctx context.Context, c client.Client, p Pipeline) *Controller {
+ return &Controller{
+ Pipeline: p,
+ Ctx: ctx,
+ Client: c,
+ }
+}
+
+func (ctrl *Controller) SelectSucceesed() ([]Controller, error) {
+ var combined []Controller
+
+ vpCombined, err := ctrl.SelectVectorPipelineSucceesed()
+ if err != nil {
+ return nil, err
+ }
+
+ cvpCombined, err := ctrl.SelectClusterVectorPipelineSucceesed()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, vp := range vpCombined {
+ combined = append(combined, Controller{
+ Pipeline: vp,
+ })
+ }
+ for _, cvp := range cvpCombined {
+ combined = append(combined, Controller{
+ Pipeline: cvp,
+ })
+ }
+
+ return combined, nil
+
+}
+
+func (ctrl *Controller) SelectVectorPipelineSucceesed() ([]*vectorpipeline.Controller, error) {
+ var vpCombined []*vectorpipeline.Controller
+
+ vps := vectorv1alpha1.VectorPipelineList{}
+ err := ctrl.Client.List(ctrl.Ctx, &vps)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, vp := range vps.Items {
+ if !vp.DeletionTimestamp.IsZero() {
+ continue
+ }
+ if vp.Status.ConfigCheckResult != nil {
+ if *vp.Status.ConfigCheckResult {
+ vpCombined = append(vpCombined, &vectorpipeline.Controller{
+ VectorPipeline: vp.DeepCopy(),
+ })
+ }
+ }
+
+ }
+ return vpCombined, nil
+}
+
+func (ctrl *Controller) SelectClusterVectorPipelineSucceesed() ([]*clustervectorpipeline.Controller, error) {
+ var cvpCombined []*clustervectorpipeline.Controller
+
+ cvps := vectorv1alpha1.ClusterVectorPipelineList{}
+ err := ctrl.Client.List(ctrl.Ctx, &cvps)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, cvp := range cvps.Items {
+ if !cvp.DeletionTimestamp.IsZero() {
+ continue
+ }
+ if cvp.Status.ConfigCheckResult != nil {
+ if *cvp.Status.ConfigCheckResult {
+ cvpCombined = append(cvpCombined, &clustervectorpipeline.Controller{
+ ClusterVectorPipeline: cvp.DeepCopy(),
+ })
+ }
+ }
+
+ }
+ return cvpCombined, nil
+}
+
+func (ctrl *Controller) GetSources(filter []string) ([]vector.Source, error) {
+ var sources []vector.Source
+ sourcesMap, err := decodeRaw(ctrl.Pipeline.Spec().Sources.Raw)
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range sourcesMap {
+ if len(filter) != 0 {
+ if !contains(filter, k) {
+ continue
+ }
+ }
+ var source vector.Source
+ if err := mapstructure.Decode(v, &source); err != nil {
+ return nil, err
+ }
+ source.Name = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), k)
+ sources = append(sources, source)
+ }
+ return sources, nil
+}
+
+func (ctrl *Controller) GetTransforms() ([]vector.Transform, error) {
+ if ctrl.Pipeline.Spec().Transforms == nil {
+ return nil, nil
+ }
+ transformsMap, err := decodeRaw(ctrl.Pipeline.Spec().Transforms.Raw)
+ if err != nil {
+ return nil, err
+ }
+ var transforms []vector.Transform
+ if err := json.Unmarshal(ctrl.Pipeline.Spec().Transforms.Raw, &transformsMap); err != nil {
+ return nil, err
+ }
+ for k, v := range transformsMap {
+ var transform vector.Transform
+ if err := mapstructure.Decode(v, &transform); err != nil {
+ return nil, err
+ }
+ transform.Name = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), k)
+ for i, inputName := range transform.Inputs {
+ transform.Inputs[i] = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), inputName)
+ }
+ transforms = append(transforms, transform)
+ }
+ return transforms, nil
+}
+
+func (ctrl *Controller) GetSinks() ([]vector.Sink, error) {
+ sinksMap, err := decodeRaw(ctrl.Pipeline.Spec().Sinks.Raw)
+ if err != nil {
+ return nil, err
+ }
+ var sinks []vector.Sink
+ for k, v := range sinksMap {
+ var sink vector.Sink
+ if err := mapstructure.Decode(v, &sink); err != nil {
+ return nil, err
+ }
+ sink.Name = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), k)
+ for i, inputName := range sink.Inputs {
+ sink.Inputs[i] = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), inputName)
+ }
+ sinks = append(sinks, sink)
+ }
+ return sinks, nil
+}
+
+func (ctrl *Controller) SetSucceesStatus() error {
+ var status = true
+
+ ctrl.Pipeline.SetConfigCheck(status)
+ ctrl.Pipeline.SetReason(nil)
+
+ return ctrl.Pipeline.UpdateStatus(ctrl.Ctx, ctrl.Client)
+}
+
+func (ctrl *Controller) SetFailedStatus(err error) error {
+ var status = false
+ var reason = err.Error()
+
+ ctrl.Pipeline.SetConfigCheck(status)
+ ctrl.Pipeline.SetReason(&reason)
+
+ return ctrl.Pipeline.UpdateStatus(ctrl.Ctx, ctrl.Client)
+}
+
+func (ctrl *Controller) SetLastAppliedPipelineStatus() error {
+ hash, err := ctrl.GetSpecHash()
+ if err != nil {
+ return err
+ }
+ ctrl.Pipeline.SetLastAppliedPipeline(hash)
+
+ return ctrl.Pipeline.UpdateStatus(ctrl.Ctx, ctrl.Client)
+}
+
+func decodeRaw(raw []byte) (map[string]interface{}, error) {
+ result := make(map[string]interface{})
+ if err := json.Unmarshal(raw, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func contains(elems []string, v string) bool {
+ for _, s := range elems {
+ if v == s {
+ return true
+ }
+ }
+ return false
+}
+
+func addPrefix(Namespace, Name, componentName string) string {
+ return generateName(Namespace, Name) + "-" + componentName
+}
+
+func generateName(Namespace, Name string) string {
+ return Namespace + "-" + Name
+}
diff --git a/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go b/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go
new file mode 100644
index 00000000..2503d90e
--- /dev/null
+++ b/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go
@@ -0,0 +1,75 @@
+/*
+Copyright 2022.
+
+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 vectorpipeline
+
+import (
+ "context"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+var (
+ Type = "noCluster"
+)
+
+type Controller struct {
+ VectorPipeline *vectorv1alpha1.VectorPipeline
+}
+
+func (ctrl *Controller) Spec() vectorv1alpha1.VectorPipelineSpec {
+ return ctrl.VectorPipeline.Spec
+}
+
+func (ctrl *Controller) Name() string {
+ return ctrl.VectorPipeline.Name
+}
+
+func (ctrl *Controller) Namespace() string {
+ return ctrl.VectorPipeline.Namespace
+}
+
+func (ctrl *Controller) Type() string {
+ return Type
+}
+
+func (ctrl *Controller) SetConfigCheck(value bool) {
+ ctrl.VectorPipeline.Status.ConfigCheckResult = &value
+}
+
+func (ctrl *Controller) SetReason(reason *string) {
+ ctrl.VectorPipeline.Status.Reason = reason
+}
+
+func (ctrl *Controller) GetLastAppliedPipeline() *uint32 {
+ return ctrl.VectorPipeline.Status.LastAppliedPipelineHash
+}
+
+func (ctrl *Controller) SetLastAppliedPipeline(hash *uint32) {
+ ctrl.VectorPipeline.Status.LastAppliedPipelineHash = hash
+}
+
+func (ctrl *Controller) UpdateStatus(ctx context.Context, c client.Client) error {
+ return k8sutils.UpdateStatus(ctx, ctrl.VectorPipeline, c)
+}
+
+func NewController(vp *vectorv1alpha1.VectorPipeline) *Controller {
+ return &Controller{
+ VectorPipeline: vp,
+ }
+}
diff --git a/controllers/factory/vector/types.go b/controllers/factory/vector/types.go
index 80806517..f766446b 100644
--- a/controllers/factory/vector/types.go
+++ b/controllers/factory/vector/types.go
@@ -31,9 +31,10 @@ type ApiSpec struct {
}
type Source struct {
- Name string
- Type string `mapper:"type"`
- Options map[string]interface{} `mapstructure:",remain"`
+ Name string
+ Type string `mapper:"type"`
+ ExtraNamespaceLabelSelector string `mapper:"extra_namespace_label_selector"`
+ Options map[string]interface{} `mapstructure:",remain"`
}
type Transform struct {
diff --git a/controllers/factory/vectoragent/vector_agent_config.go b/controllers/factory/vectoragent/vector_agent_config.go
index b7a5044d..b1979239 100644
--- a/controllers/factory/vectoragent/vector_agent_config.go
+++ b/controllers/factory/vectoragent/vector_agent_config.go
@@ -26,18 +26,18 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/utils"
)
-func (vr *VectorAgentReconciler) createVectorAgentConfig(ctx context.Context) (*corev1.Secret, error) {
- cfg, err := config.Get(ctx, vr.Vector, vr.Client)
+func (ctrl *Controller) createVectorAgentConfig(ctx context.Context) (*corev1.Secret, error) {
+ cfg, err := config.Get(ctx, ctrl.Vector, ctrl.Client)
if err != nil {
return nil, err
}
cfgHash := utils.GetHash(cfg)
- if vr.Vector.Status.LastAppliedConfigHash == nil || *vr.Vector.Status.LastAppliedConfigHash != cfgHash {
- err = configcheck.Run(cfg, vr.Client, vr.Clientset, vr.Vector.Name, vr.Vector.Namespace, vr.Vector.Spec.Agent.Image)
+ if ctrl.Vector.Status.LastAppliedConfigHash == nil || *ctrl.Vector.Status.LastAppliedConfigHash != cfgHash {
+ err = configcheck.Run(cfg, ctrl.Client, ctrl.Clientset, ctrl.Vector.Name, ctrl.Vector.Namespace, ctrl.Vector.Spec.Agent.Image)
if _, ok := err.(*configcheck.ErrConfigCheck); ok {
- if err := setFailedStatus(ctx, vr.Vector, vr.Client, err); err != nil {
+ if err := setFailedStatus(ctx, ctrl.Vector, ctrl.Client, err); err != nil {
return nil, err
}
return nil, err
@@ -46,23 +46,23 @@ func (vr *VectorAgentReconciler) createVectorAgentConfig(ctx context.Context) (*
return nil, err
}
- if err := SetLastAppliedPipelineStatus(ctx, vr.Vector, vr.Client, &cfgHash); err != nil {
+ if err := SetLastAppliedPipelineStatus(ctx, ctrl.Vector, ctrl.Client, &cfgHash); err != nil {
return nil, err
}
- if err := setSucceesStatus(ctx, vr.Vector, vr.Client); err != nil {
+ if err := setSucceesStatus(ctx, ctrl.Vector, ctrl.Client); err != nil {
return nil, err
}
}
- labels := vr.labelsForVectorAgent()
+ labels := ctrl.labelsForVectorAgent()
config := map[string][]byte{
"agent.json": cfg,
}
secret := &corev1.Secret{
- ObjectMeta: vr.objectMetaVectorAgent(labels),
+ ObjectMeta: ctrl.objectMetaVectorAgent(labels),
Data: config,
}
diff --git a/controllers/factory/vectoragent/vector_agent_controller.go b/controllers/factory/vectoragent/vector_agent_controller.go
index 1939859a..e747dddc 100644
--- a/controllers/factory/vectoragent/vector_agent_controller.go
+++ b/controllers/factory/vectoragent/vector_agent_controller.go
@@ -31,7 +31,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
)
-type VectorAgentReconciler struct {
+type Controller struct {
client.Client
Vector *vectorv1alpha1.Vector
@@ -39,157 +39,157 @@ type VectorAgentReconciler struct {
Clientset *kubernetes.Clientset
}
-func NewReconciler(v *vectorv1alpha1.Vector, c client.Client, cs *kubernetes.Clientset) *VectorAgentReconciler {
- return &VectorAgentReconciler{
+func NewController(v *vectorv1alpha1.Vector, c client.Client, cs *kubernetes.Clientset) *Controller {
+ return &Controller{
Client: c,
Vector: v,
Clientset: cs,
}
}
-func (vr *VectorAgentReconciler) EnsureVectorAgent() (done bool, result ctrl.Result, err error) {
+func (ctrl *Controller) EnsureVectorAgent() (done bool, result ctrl.Result, err error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent", vr.Vector.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent")
- if done, result, err = vr.ensureVectorAgentRBAC(); done {
+ if done, result, err = ctrl.ensureVectorAgentRBAC(); done {
return
}
- if vr.Vector.Spec.Agent.Service {
- if done, result, err = vr.ensureVectorAgentService(); done {
+ if ctrl.Vector.Spec.Agent.Service {
+ if done, result, err = ctrl.ensureVectorAgentService(); done {
return
}
}
- if done, result, err = vr.ensureVectorAgentConfig(); done {
+ if done, result, err = ctrl.ensureVectorAgentConfig(); done {
return
}
- if done, result, err = vr.ensureVectorAgentDaemonSet(); done {
+ if done, result, err = ctrl.ensureVectorAgentDaemonSet(); done {
return
}
return
}
-func (vr *VectorAgentReconciler) ensureVectorAgentRBAC() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentRBAC() (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-rbac", vr.Vector.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-rbac", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent RBAC")
- if done, _, err := vr.ensureVectorAgentServiceAccount(); done {
+ if done, _, err := ctrl.ensureVectorAgentServiceAccount(); done {
return helper.ReconcileResult(err)
}
- if done, _, err := vr.ensureVectorAgentClusterRole(); done {
+ if done, _, err := ctrl.ensureVectorAgentClusterRole(); done {
return helper.ReconcileResult(err)
}
- if done, _, err := vr.ensureVectorAgentClusterRoleBinding(); done {
+ if done, _, err := ctrl.ensureVectorAgentClusterRoleBinding(); done {
return helper.ReconcileResult(err)
}
return helper.ReconcileResult(nil)
}
-func (vr *VectorAgentReconciler) ensureVectorAgentServiceAccount() (bool, ctrl.Result, error) {
- vectorAgentServiceAccount := vr.createVectorAgentServiceAccount()
+func (ctrl *Controller) ensureVectorAgentServiceAccount() (bool, ctrl.Result, error) {
+ vectorAgentServiceAccount := ctrl.createVectorAgentServiceAccount()
- _, err := k8sutils.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, vr.Client)
+ _, err := k8sutils.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, ctrl.Client)
return helper.ReconcileResult(err)
}
-func (vr *VectorAgentReconciler) ensureVectorAgentClusterRole() (bool, ctrl.Result, error) {
- vectorAgentClusterRole := vr.createVectorAgentClusterRole()
+func (ctrl *Controller) ensureVectorAgentClusterRole() (bool, ctrl.Result, error) {
+ vectorAgentClusterRole := ctrl.createVectorAgentClusterRole()
- _, err := k8sutils.CreateOrUpdateClusterRole(vectorAgentClusterRole, vr.Client)
+ _, err := k8sutils.CreateOrUpdateClusterRole(vectorAgentClusterRole, ctrl.Client)
return helper.ReconcileResult(err)
}
-func (vr *VectorAgentReconciler) ensureVectorAgentClusterRoleBinding() (bool, ctrl.Result, error) {
- vectorAgentClusterRoleBinding := vr.createVectorAgentClusterRoleBinding()
+func (ctrl *Controller) ensureVectorAgentClusterRoleBinding() (bool, ctrl.Result, error) {
+ vectorAgentClusterRoleBinding := ctrl.createVectorAgentClusterRoleBinding()
- _, err := k8sutils.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, vr.Client)
+ _, err := k8sutils.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, ctrl.Client)
return helper.ReconcileResult(err)
}
-func (vr *VectorAgentReconciler) ensureVectorAgentService() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentService() (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-service", vr.Vector.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-service", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent Service")
- vectorAgentService := vr.createVectorAgentService()
+ vectorAgentService := ctrl.createVectorAgentService()
- _, err := k8sutils.CreateOrUpdateService(vectorAgentService, vr.Client)
+ _, err := k8sutils.CreateOrUpdateService(vectorAgentService, ctrl.Client)
return helper.ReconcileResult(err)
}
-func (vr *VectorAgentReconciler) ensureVectorAgentConfig() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentConfig() (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-secret", vr.Vector.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-secret", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent Secret")
- vectorAgentSecret, err := vr.createVectorAgentConfig(ctx)
+ vectorAgentSecret, err := ctrl.createVectorAgentConfig(ctx)
if err != nil {
return helper.ReconcileResult(err)
}
- _, err = k8sutils.CreateOrUpdateSecret(vectorAgentSecret, vr.Client)
+ _, err = k8sutils.CreateOrUpdateSecret(vectorAgentSecret, ctrl.Client)
return helper.ReconcileResult(err)
}
-func (vr *VectorAgentReconciler) ensureVectorAgentDaemonSet() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentDaemonSet() (bool, ctrl.Result, error) {
ctx := context.Background()
- log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", vr.Vector.Name)
+ log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent DaemonSet")
- vectorAgentDaemonSet := vr.createVectorAgentDaemonSet()
+ vectorAgentDaemonSet := ctrl.createVectorAgentDaemonSet()
- _, err := k8sutils.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, vr.Client)
+ _, err := k8sutils.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, ctrl.Client)
return helper.ReconcileResult(err)
}
-func (vr *VectorAgentReconciler) labelsForVectorAgent() map[string]string {
+func (ctrl *Controller) labelsForVectorAgent() map[string]string {
return map[string]string{
label.ManagedByLabelKey: "vector-operator",
label.NameLabelKey: "vector",
label.ComponentLabelKey: "Agent",
- label.InstanceLabelKey: vr.Vector.Name,
+ label.InstanceLabelKey: ctrl.Vector.Name,
label.VectorExcludeLabel: "true",
}
}
-func (vr *VectorAgentReconciler) objectMetaVectorAgent(labels map[string]string) metav1.ObjectMeta {
+func (ctrl *Controller) objectMetaVectorAgent(labels map[string]string) metav1.ObjectMeta {
return metav1.ObjectMeta{
- Name: vr.Vector.Name + "-agent",
- Namespace: vr.Vector.Namespace,
+ Name: ctrl.Vector.Name + "-agent",
+ Namespace: ctrl.Vector.Namespace,
Labels: labels,
- OwnerReferences: vr.getControllerReference(),
+ OwnerReferences: ctrl.getControllerReference(),
}
}
-func (vr *VectorAgentReconciler) getNameVectorAgent() string {
- name := vr.Vector.Name + "-agent"
+func (ctrl *Controller) getNameVectorAgent() string {
+ name := ctrl.Vector.Name + "-agent"
return name
}
-func (vr *VectorAgentReconciler) getControllerReference() []metav1.OwnerReference {
+func (ctrl *Controller) getControllerReference() []metav1.OwnerReference {
return []metav1.OwnerReference{
{
- APIVersion: vr.Vector.APIVersion,
- Kind: vr.Vector.Kind,
- Name: vr.Vector.GetName(),
- UID: vr.Vector.GetUID(),
+ APIVersion: ctrl.Vector.APIVersion,
+ Kind: ctrl.Vector.Kind,
+ Name: ctrl.Vector.GetName(),
+ UID: ctrl.Vector.GetUID(),
BlockOwnerDeletion: pointer.BoolPtr(true),
Controller: pointer.BoolPtr(true),
},
diff --git a/controllers/factory/vectoragent/vector_agent_daemonset.go b/controllers/factory/vectoragent/vector_agent_daemonset.go
index 88a3593a..e551b8df 100644
--- a/controllers/factory/vectoragent/vector_agent_daemonset.go
+++ b/controllers/factory/vectoragent/vector_agent_daemonset.go
@@ -22,26 +22,26 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-func (vr *VectorAgentReconciler) createVectorAgentDaemonSet() *appsv1.DaemonSet {
- labels := vr.labelsForVectorAgent()
+func (ctrl *Controller) createVectorAgentDaemonSet() *appsv1.DaemonSet {
+ labels := ctrl.labelsForVectorAgent()
daemonset := &appsv1.DaemonSet{
- ObjectMeta: vr.objectMetaVectorAgent(labels),
+ ObjectMeta: ctrl.objectMetaVectorAgent(labels),
Spec: appsv1.DaemonSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: labels},
Template: corev1.PodTemplateSpec{
- ObjectMeta: vr.objectMetaVectorAgent(labels),
+ ObjectMeta: ctrl.objectMetaVectorAgent(labels),
Spec: corev1.PodSpec{
- ServiceAccountName: vr.getNameVectorAgent(),
- Volumes: vr.generateVectorAgentVolume(),
+ ServiceAccountName: ctrl.getNameVectorAgent(),
+ Volumes: ctrl.generateVectorAgentVolume(),
SecurityContext: &corev1.PodSecurityContext{},
- Tolerations: vr.Vector.Spec.Agent.Tolerations,
+ Tolerations: ctrl.Vector.Spec.Agent.Tolerations,
Containers: []corev1.Container{
{
- Name: vr.getNameVectorAgent(),
- Image: vr.Vector.Spec.Agent.Image,
+ Name: ctrl.getNameVectorAgent(),
+ Image: ctrl.Vector.Spec.Agent.Image,
Args: []string{"--config-dir", "/etc/vector/", "--watch-config"},
- Env: vr.generateVectorAgentEnvs(),
+ Env: ctrl.generateVectorAgentEnvs(),
Ports: []corev1.ContainerPort{
{
Name: "prom-exporter",
@@ -49,7 +49,7 @@ func (vr *VectorAgentReconciler) createVectorAgentDaemonSet() *appsv1.DaemonSet
Protocol: "TCP",
},
},
- VolumeMounts: vr.generateVectorAgentVolumeMounts(),
+ VolumeMounts: ctrl.generateVectorAgentVolumeMounts(),
SecurityContext: &corev1.SecurityContext{},
},
},
@@ -61,13 +61,13 @@ func (vr *VectorAgentReconciler) createVectorAgentDaemonSet() *appsv1.DaemonSet
return daemonset
}
-func (vr *VectorAgentReconciler) generateVectorAgentVolume() []corev1.Volume {
+func (ctrl *Controller) generateVectorAgentVolume() []corev1.Volume {
volume := []corev1.Volume{
{
Name: "config",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
- SecretName: vr.getNameVectorAgent(),
+ SecretName: ctrl.getNameVectorAgent(),
},
},
},
@@ -116,7 +116,7 @@ func (vr *VectorAgentReconciler) generateVectorAgentVolume() []corev1.Volume {
return volume
}
-func (vr *VectorAgentReconciler) generateVectorAgentVolumeMounts() []corev1.VolumeMount {
+func (ctrl *Controller) generateVectorAgentVolumeMounts() []corev1.VolumeMount {
volumeMount := []corev1.VolumeMount{
{
Name: "config",
@@ -147,7 +147,7 @@ func (vr *VectorAgentReconciler) generateVectorAgentVolumeMounts() []corev1.Volu
return volumeMount
}
-func (vr *VectorAgentReconciler) generateVectorAgentEnvs() []corev1.EnvVar {
+func (ctrl *Controller) generateVectorAgentEnvs() []corev1.EnvVar {
envs := []corev1.EnvVar{
{
Name: "VECTOR_SELF_NODE_NAME",
diff --git a/controllers/factory/vectoragent/vector_agent_rbac.go b/controllers/factory/vectoragent/vector_agent_rbac.go
index 7cad24b4..190c2d8a 100644
--- a/controllers/factory/vectoragent/vector_agent_rbac.go
+++ b/controllers/factory/vectoragent/vector_agent_rbac.go
@@ -21,21 +21,21 @@ import (
rbacv1 "k8s.io/api/rbac/v1"
)
-func (vr *VectorAgentReconciler) createVectorAgentServiceAccount() *corev1.ServiceAccount {
- labels := vr.labelsForVectorAgent()
+func (ctrl *Controller) createVectorAgentServiceAccount() *corev1.ServiceAccount {
+ labels := ctrl.labelsForVectorAgent()
serviceAccount := &corev1.ServiceAccount{
- ObjectMeta: vr.objectMetaVectorAgent(labels),
+ ObjectMeta: ctrl.objectMetaVectorAgent(labels),
}
return serviceAccount
}
-func (vr *VectorAgentReconciler) createVectorAgentClusterRole() *rbacv1.ClusterRole {
- labels := vr.labelsForVectorAgent()
+func (ctrl *Controller) createVectorAgentClusterRole() *rbacv1.ClusterRole {
+ labels := ctrl.labelsForVectorAgent()
clusterRole := &rbacv1.ClusterRole{
- ObjectMeta: vr.objectMetaVectorAgent(labels),
+ ObjectMeta: ctrl.objectMetaVectorAgent(labels),
Rules: []rbacv1.PolicyRule{
{
APIGroups: []string{""},
@@ -48,21 +48,21 @@ func (vr *VectorAgentReconciler) createVectorAgentClusterRole() *rbacv1.ClusterR
return clusterRole
}
-func (vr *VectorAgentReconciler) createVectorAgentClusterRoleBinding() *rbacv1.ClusterRoleBinding {
- labels := vr.labelsForVectorAgent()
+func (ctrl *Controller) createVectorAgentClusterRoleBinding() *rbacv1.ClusterRoleBinding {
+ labels := ctrl.labelsForVectorAgent()
clusterRoleBinding := &rbacv1.ClusterRoleBinding{
- ObjectMeta: vr.objectMetaVectorAgent(labels),
+ ObjectMeta: ctrl.objectMetaVectorAgent(labels),
RoleRef: rbacv1.RoleRef{
Kind: "ClusterRole",
APIGroup: "rbac.authorization.k8s.io",
- Name: vr.getNameVectorAgent(),
+ Name: ctrl.getNameVectorAgent(),
},
Subjects: []rbacv1.Subject{
{
Kind: "ServiceAccount",
- Name: vr.getNameVectorAgent(),
- Namespace: vr.Vector.Namespace,
+ Name: ctrl.getNameVectorAgent(),
+ Namespace: ctrl.Vector.Namespace,
},
},
}
diff --git a/controllers/factory/vectoragent/vector_agent_service.go b/controllers/factory/vectoragent/vector_agent_service.go
index 93d14c24..24f33ed7 100644
--- a/controllers/factory/vectoragent/vector_agent_service.go
+++ b/controllers/factory/vectoragent/vector_agent_service.go
@@ -22,11 +22,11 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)
-func (vr *VectorAgentReconciler) createVectorAgentService() *corev1.Service {
- labels := vr.labelsForVectorAgent()
+func (ctrl *Controller) createVectorAgentService() *corev1.Service {
+ labels := ctrl.labelsForVectorAgent()
service := &corev1.Service{
- ObjectMeta: vr.objectMetaVectorAgent(labels),
+ ObjectMeta: ctrl.objectMetaVectorAgent(labels),
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
diff --git a/controllers/factory/vectorpipeline/vectorpipeline.go b/controllers/factory/vectorpipeline/vectorpipeline.go
deleted file mode 100644
index f468f247..00000000
--- a/controllers/factory/vectorpipeline/vectorpipeline.go
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
-Copyright 2022.
-
-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 vectorpipeline
-
-import (
- "context"
- "encoding/json"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
- "github.com/kaasops/vector-operator/controllers/factory/vector"
- "github.com/mitchellh/mapstructure"
- "sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-func SelectSucceesed(ctx context.Context, rclient client.Client) ([]*vectorv1alpha1.VectorPipeline, error) {
-
- var vectorPipelinesCombined []*vectorv1alpha1.VectorPipeline
-
- objlist := vectorv1alpha1.VectorPipelineList{}
- err := rclient.List(ctx, &objlist)
- if err != nil {
- return nil, err
- }
-
- for _, item := range objlist.Items {
- if !item.DeletionTimestamp.IsZero() {
- continue
- }
- if item.Status.ConfigCheckResult != nil {
- if *item.Status.ConfigCheckResult {
- vectorPipelinesCombined = append(vectorPipelinesCombined, item.DeepCopy())
- }
- }
-
- }
- return vectorPipelinesCombined, nil
-}
-
-func SetSucceesStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
- var status = true
- vp.Status.ConfigCheckResult = &status
- vp.Status.Reason = nil
-
- return k8sutils.UpdateStatus(ctx, vp, c)
-}
-
-func SetFailedStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client, err error) error {
- var status = false
- var reason = err.Error()
- vp.Status.ConfigCheckResult = &status
- vp.Status.Reason = &reason
-
- return k8sutils.UpdateStatus(ctx, vp, c)
-}
-
-func SetLastAppliedPipelineStatus(ctx context.Context, vp *vectorv1alpha1.VectorPipeline, c client.Client) error {
- hash, err := GetVpSpecHash(vp)
- if err != nil {
- return err
- }
- vp.Status.LastAppliedPipelineHash = hash
- if err := k8sutils.UpdateStatus(ctx, vp, c); err != nil {
- return err
- }
- return nil
-}
-
-func GetSources(vp *vectorv1alpha1.VectorPipeline, filter []string) ([]vector.Source, error) {
- var sources []vector.Source
- sourcesMap, err := decodeRaw(vp.Spec.Sources.Raw)
- if err != nil {
- return nil, err
- }
- for k, v := range sourcesMap {
- if len(filter) != 0 {
- if !contains(filter, k) {
- continue
- }
- }
- var source vector.Source
- if err := mapstructure.Decode(v, &source); err != nil {
- return nil, err
- }
- source.Name = addPrefix(vp, k)
- sources = append(sources, source)
- }
- return sources, nil
-}
-
-func GetTransforms(vp *vectorv1alpha1.VectorPipeline) ([]vector.Transform, error) {
- if vp.Spec.Transforms == nil {
- return nil, nil
- }
- transformsMap, err := decodeRaw(vp.Spec.Transforms.Raw)
- if err != nil {
- return nil, err
- }
- var transforms []vector.Transform
- if err := json.Unmarshal(vp.Spec.Transforms.Raw, &transformsMap); err != nil {
- return nil, err
- }
- for k, v := range transformsMap {
- var transform vector.Transform
- if err := mapstructure.Decode(v, &transform); err != nil {
- return nil, err
- }
- transform.Name = addPrefix(vp, k)
- for i, inputName := range transform.Inputs {
- transform.Inputs[i] = addPrefix(vp, inputName)
- }
- transforms = append(transforms, transform)
- }
- return transforms, nil
-}
-
-func GetSinks(vp *vectorv1alpha1.VectorPipeline) ([]vector.Sink, error) {
- sinksMap, err := decodeRaw(vp.Spec.Sinks.Raw)
- if err != nil {
- return nil, err
- }
- var sinks []vector.Sink
- for k, v := range sinksMap {
- var sink vector.Sink
- if err := mapstructure.Decode(v, &sink); err != nil {
- return nil, err
- }
- sink.Name = addPrefix(vp, k)
- for i, inputName := range sink.Inputs {
- sink.Inputs[i] = addPrefix(vp, inputName)
- }
- sinks = append(sinks, sink)
- }
- return sinks, nil
-}
-
-func decodeRaw(raw []byte) (map[string]interface{}, error) {
- result := make(map[string]interface{})
- if err := json.Unmarshal(raw, &result); err != nil {
- return nil, err
- }
- return result, nil
-}
-
-func addPrefix(vp *vectorv1alpha1.VectorPipeline, name string) string {
- return generateName(vp) + "-" + name
-}
-
-func generateName(vp *vectorv1alpha1.VectorPipeline) string {
- return vp.Namespace + "-" + vp.Name
-}
-
-func contains(elems []string, v string) bool {
- for _, s := range elems {
- if v == s {
- return true
- }
- }
- return false
-}
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 57a5a91e..df3446a4 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -100,7 +100,7 @@ func (r *VectorReconciler) SetupWithManager(mgr ctrl.Manager) error {
}
func (r *VectorReconciler) CreateOrUpdateVector(v *vectorv1alpha1.Vector) (ctrl.Result, error) {
- vectorAgentReconciler := vectoragent.NewReconciler(v, r.Client, r.Clientset)
+ vectorAgentReconciler := vectoragent.NewController(v, r.Client, r.Clientset)
if done, result, err := vectorAgentReconciler.EnsureVectorAgent(); done {
return result, err
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 954b386d..43262678 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -29,8 +29,8 @@ import (
"github.com/go-logr/logr"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/config"
- "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
- "github.com/kaasops/vector-operator/controllers/factory/vectorpipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline/vectorpipeline"
)
// VectorPipelineReconciler reconciles a VectorPipeline object
@@ -56,8 +56,7 @@ type VectorPipelineReconciler struct {
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.2/pkg/reconcile
func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
- _ = log.FromContext(ctx)
- log := log.FromContext(ctx).WithValues("VectorPipeline", req.NamespacedName)
+ log := log.FromContext(ctx).WithValues("VectorPipeline", req.Name)
log.Info("start Reconcile VectorPipeline")
@@ -66,6 +65,21 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return result, err
}
+ // Generate VectorPipeline Controller
+ vpCtrl := vectorpipeline.NewController(vp)
+ // Generate Pipeline Controller
+ vCtrl := pipeline.NewController(ctx, r.Client, vpCtrl)
+
+ // Check Pipeline hash
+ checkResult, err := vCtrl.CheckHash()
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+ if checkResult {
+ log.Info("VectorPipeline has no changes. Finish Reconcile VectorPipeline")
+ return ctrl.Result{}, nil
+ }
+
vectorInstances := &vectorv1alpha1.VectorList{}
err = r.List(ctx, vectorInstances)
if err != nil {
@@ -77,22 +91,16 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, nil
}
- hash, err := vectorpipeline.GetVpSpecHash(vp)
- if err != nil {
- return ctrl.Result{}, err
- }
-
for _, v := range vectorInstances.Items {
if v.DeletionTimestamp != nil {
continue
}
- if vp.Status.LastAppliedPipelineHash == nil || *hash != *vp.Status.LastAppliedPipelineHash {
- if err = checkConfig(ctx, &v, vp, r.Client, r.Clientset); err != nil {
- return ctrl.Result{}, err
- }
- if err = vectorpipeline.SetLastAppliedPipelineStatus(ctx, vp, r.Client); err != nil {
- return ctrl.Result{}, err
- }
+ if err = config.Check(ctx, &v, vCtrl, r.Client, r.Clientset); err != nil {
+ return ctrl.Result{}, err
+ }
+
+ if err = vCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ return ctrl.Result{}, err
}
}
@@ -127,33 +135,3 @@ func (r *VectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
For(&vectorv1alpha1.VectorPipeline{}).
Complete(r)
}
-
-func checkConfig(ctx context.Context, v *vectorv1alpha1.Vector, vp *vectorv1alpha1.VectorPipeline, c client.Client, cs *kubernetes.Clientset) error {
- log := log.FromContext(context.TODO()).WithValues("Vector Pipeline", "ConfigCheck")
-
- var vps []*vectorv1alpha1.VectorPipeline
- vps = append(vps, vp)
-
- cfg, err := config.GenerateConfig(v, vps)
- if err != nil {
- return err
- }
-
- err = configcheck.Run(cfg, c, cs, vp.Name, vp.Namespace, v.Spec.Agent.Image)
- if _, ok := err.(*configcheck.ErrConfigCheck); ok {
- if err := vectorpipeline.SetFailedStatus(ctx, vp, c, err); err != nil {
- return err
- }
- log.Error(err, "Vector Config has error")
- return nil
- }
- if err != nil {
- return err
- }
-
- if err := vectorpipeline.SetSucceesStatus(ctx, vp, c); err != nil {
- return err
- }
-
- return nil
-}
diff --git a/main.go b/main.go
index 9cf88ce9..c1cf1585 100644
--- a/main.go
+++ b/main.go
@@ -119,8 +119,9 @@ func main() {
os.Exit(1)
}
if err = (&controllers.ClusterVectorPipelineReconciler{
- Client: mgr.GetClient(),
- Scheme: mgr.GetScheme(),
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ Clientset: clientset,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "ClusterVectorPipeline")
os.Exit(1)
From caf62e1163d5d91bc26d3047e1c2a1fb79425782 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 27 Oct 2022 16:42:47 +0300
Subject: [PATCH 032/316] Update ReadMe
Signed-off-by: Zemtsov Vladimir
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index e2bc1ff9..a80a0a6f 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,8 @@
+# Vector Operator
+
## Description
The operator deploys and configures a vector agent daemonset on every node to collect container and application logs from the node file system.
From 28350b8175b45d09b38d1ee32c80ee7884035a5b Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 28 Oct 2022 15:24:51 +0300
Subject: [PATCH 033/316] RefactorConfigCheck
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/config/config.go | 86 ++++++++++++
controllers/factory/config/config_build.go | 53 ++------
.../factory/config/configcheck/configcheck.go | 123 +++++++++++-------
.../config/configcheck/configcheck_config.go | 8 +-
.../config/configcheck/configcheck_pod.go | 18 +--
.../config/configcheck/configcheck_rbac.go | 4 +-
...orpipeline.go => clustervectorpipeline.go} | 5 +-
controllers/factory/pipeline/hash.go | 4 +-
.../pipeline/vectorpipeline/vectorpipeline.go | 5 +-
.../factory/utils/{utils.go => hash/hash.go} | 4 +-
.../factory/{ => utils}/helper/helper.go | 0
.../{k8sutils/utils.go => utils/k8s/k8s.go} | 2 +-
.../factory/{label => utils/k8s}/label.go | 2 +-
controllers/factory/vector/vector.go | 3 +-
.../factory/vector/vectoragent/vectoragent.go | 67 ++++++++++
.../vectoragent/vectoragent_config.go} | 20 ++-
.../vectoragent/vectoragent_controller.go} | 72 ++--------
.../vectoragent/vectoragent_daemonset.go} | 0
.../vectoragent/vectoragent_rbac.go} | 0
.../vectoragent/vectoragent_service.go} | 0
controllers/vector_controller.go | 27 +++-
controllers/vectorpipeline_controller.go | 51 +++++++-
22 files changed, 360 insertions(+), 194 deletions(-)
create mode 100644 controllers/factory/config/config.go
rename controllers/factory/pipeline/clustervectorpipeline/{vectorpipeline.go => clustervectorpipeline.go} (92%)
rename controllers/factory/utils/{utils.go => hash/hash.go} (92%)
rename controllers/factory/{ => utils}/helper/helper.go (100%)
rename controllers/factory/{k8sutils/utils.go => utils/k8s/k8s.go} (99%)
rename controllers/factory/{label => utils/k8s}/label.go (99%)
create mode 100644 controllers/factory/vector/vectoragent/vectoragent.go
rename controllers/factory/{vectoragent/vector_agent_config.go => vector/vectoragent/vectoragent_config.go} (66%)
rename controllers/factory/{vectoragent/vector_agent_controller.go => vector/vectoragent/vectoragent_controller.go} (67%)
rename controllers/factory/{vectoragent/vector_agent_daemonset.go => vector/vectoragent/vectoragent_daemonset.go} (100%)
rename controllers/factory/{vectoragent/vector_agent_rbac.go => vector/vectoragent/vectoragent_rbac.go} (100%)
rename controllers/factory/{vectoragent/vector_agent_service.go => vector/vectoragent/vectoragent_service.go} (100%)
diff --git a/controllers/factory/config/config.go b/controllers/factory/config/config.go
new file mode 100644
index 00000000..8abb097d
--- /dev/null
+++ b/controllers/factory/config/config.go
@@ -0,0 +1,86 @@
+/*
+Copyright 2022.
+
+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 config
+
+import (
+ "context"
+ "encoding/json"
+
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/vector"
+ "github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
+)
+
+type Config struct {
+ Name string
+
+ Ctx context.Context
+ vaCtrl *vectoragent.Controller
+ pCtrls []pipeline.Controller
+
+ VectorConfig *vector.VectorConfig
+}
+
+func New(ctx context.Context, vaCtrl *vectoragent.Controller) (*Config, error) {
+ cfg := &Config{
+ Ctx: ctx,
+ vaCtrl: vaCtrl,
+ }
+
+ return cfg, nil
+}
+
+func (cfg *Config) FillForVectorAgent() error {
+ cfg.Name = cfg.vaCtrl.Vector.Name
+
+ pCtrl := pipeline.NewController(cfg.Ctx, cfg.vaCtrl.Client, nil)
+ pCtrls, err := pCtrl.SelectSucceesed()
+ if err != nil {
+ return err
+ }
+ cfg.pCtrls = pCtrls
+
+ if err := cfg.GenerateVectorConfig(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (cfg *Config) FillForVectorPipeline(vCtrl *pipeline.Controller) error {
+ cfg.Name = vCtrl.Pipeline.Name()
+
+ pCtrls := make([]pipeline.Controller, 1)
+ pCtrls[0] = *vCtrl
+
+ cfg.pCtrls = pCtrls
+
+ if err := cfg.GenerateVectorConfig(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (cfg *Config) GetByteConfig() ([]byte, error) {
+ data, err := json.Marshal(cfg.VectorConfig)
+ if err != nil {
+ return nil, err
+ }
+
+ return data, nil
+}
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index f326a5e0..7672fe7c 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -17,13 +17,7 @@ limitations under the License.
package config
import (
- "context"
- "encoding/json"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector"
- "sigs.k8s.io/controller-runtime/pkg/client"
)
var (
@@ -44,30 +38,14 @@ var (
}
)
-func Get(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) ([]byte, error) {
- vCtrl := pipeline.NewController(ctx, c, nil)
- pipelines, err := vCtrl.SelectSucceesed()
- if err != nil {
- return nil, err
- }
+func (cfg *Config) GenerateVectorConfig() error {
+ vectorConfig := vector.New(cfg.vaCtrl.Vector.Spec.Agent.DataDir, cfg.vaCtrl.Vector.Spec.Agent.ApiEnabled)
- cfg, err := GenerateVectorConfig(v, pipelines)
+ sources, transforms, sinks, err := cfg.getComponents()
if err != nil {
- return nil, err
+ return err
}
- return VectorConfigToJson(cfg)
-}
-
-func GenerateVectorConfig(
- v *vectorv1alpha1.Vector,
- vCtrls []pipeline.Controller,
-) (*vector.VectorConfig, error) {
- cfg := vector.New(v.Spec.Agent.DataDir, v.Spec.Agent.ApiEnabled)
- sources, transforms, sinks, err := getComponents(vCtrls)
- if err != nil {
- return nil, err
- }
if len(sources) == 0 {
sources = sourceDefault
}
@@ -75,19 +53,21 @@ func GenerateVectorConfig(
sinks = sinkDefault
}
- cfg.Sinks = sinks
- cfg.Sources = sources
- cfg.Transforms = transforms
+ vectorConfig.Sinks = sinks
+ vectorConfig.Sources = sources
+ vectorConfig.Transforms = transforms
- return cfg, nil
+ cfg.VectorConfig = vectorConfig
+
+ return nil
}
-func getComponents(vCtrls []pipeline.Controller) (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
+func (cfg *Config) getComponents() (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
sourcesMap := make(map[string]interface{})
transformsMap := make(map[string]interface{})
sinksMap := make(map[string]interface{})
- for _, vCtrl := range vCtrls {
+ for _, vCtrl := range cfg.pCtrls {
sources, err := vCtrl.GetSources(nil)
if err != nil {
return nil, nil, nil, err
@@ -124,12 +104,3 @@ func getComponents(vCtrls []pipeline.Controller) (map[string]interface{}, map[st
}
return sourcesMap, transformsMap, sinksMap, nil
}
-
-func VectorConfigToJson(conf *vector.VectorConfig) ([]byte, error) {
- data, err := json.Marshal(conf)
- if err != nil {
- return nil, err
- }
-
- return data, nil
-}
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index 5204c01b..9ecfc337 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -21,9 +21,8 @@ import (
"math/rand"
"time"
- "github.com/kaasops/vector-operator/controllers/factory/helper"
- "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
- "github.com/kaasops/vector-operator/controllers/factory/label"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/helper"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
@@ -31,78 +30,110 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
)
-func Run(
- cfg []byte,
- c client.Client,
- cs *kubernetes.Clientset,
- name,
- namespace,
- image string,
-) error {
- log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", name)
+type ConfigCheck struct {
+ Ctx context.Context
- log.Info("start ConfigCheck Vector")
+ Config []byte
- err := ensureVectorConfigCheckRBAC(c, namespace)
- if err != nil {
+ Client client.Client
+ ClientSet *kubernetes.Clientset
+
+ Name string
+ Namespace string
+ Image string
+ Hash string
+}
+
+func New(ctx context.Context, config []byte, c client.Client, cs *kubernetes.Clientset, name, namespace, image string) *ConfigCheck {
+ return &ConfigCheck{
+ Ctx: ctx,
+ Config: config,
+ Client: c,
+ ClientSet: cs,
+ Name: name,
+ Namespace: namespace,
+ Image: image,
+ }
+}
+
+// func (cfg *Config) StartCheck() error {
+
+// log := log.FromContext(context.TODO()).WithValues("ConfigCheck Vector Pipeline", cfg.vaCtrl.Vector.Name)
+
+// configCheck := configcheck.New(cfg.Ctx, cfg.ByteConfig, cfg.vaCtrl.Client, cfg.vaCtrl.ClientSet, cfg.Name, cfg.vaCtrl.Vector.Namespace, cfg.vaCtrl.Vector.Spec.Agent.Image)
+
+// err := configCheck.Run()
+// if _, ok := err.(*configcheck.ErrConfigCheck); ok {
+// if err := cfg.vaCtrl.SetFailedStatus(cfg.Ctx, err); err != nil {
+// return err
+// }
+// log.Error(err, "Vector Config has error")
+// return nil
+// }
+// if err != nil {
+// return err
+// }
+
+// return cfg.vaCtrl.SetSucceesStatus(cfg.Ctx)
+// }
+
+func (cc *ConfigCheck) Run() error {
+ log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", cc.Name)
+
+ log.Info("start ConfigCheck")
+
+ if err := cc.ensureVectorConfigCheckRBAC(); err != nil {
return err
}
- hash := randStringRunes()
+ cc.Hash = randStringRunes()
- err = ensureVectorConfigCheckConfig(c, cfg, name, namespace, hash)
- if err != nil {
+ if err := cc.ensureVectorConfigCheckConfig(); err != nil {
return err
}
- err = checkVectorConfigCheckPod(c, cs, name, namespace, image, hash)
- if err != nil {
+ if err := cc.checkVectorConfigCheckPod(); err != nil {
return err
}
return nil
}
-func ensureVectorConfigCheckRBAC(c client.Client, ns string) error {
- // ctx := context.Background()
- // log := log.FromContext(ctx).WithValues("vector-config-check-rbac", "ConfigCheck")
-
- // log.Info("start Reconcile Vector Config Check RBAC")
-
- if done, _, err := ensureVectorConfigCheckServiceAccount(c, ns); done {
+func (cc *ConfigCheck) ensureVectorConfigCheckRBAC() error {
+ if done, _, err := cc.ensureVectorConfigCheckServiceAccount(); done {
return err
}
return nil
}
-func ensureVectorConfigCheckServiceAccount(c client.Client, ns string) (bool, ctrl.Result, error) {
- vectorAgentServiceAccount := createVectorConfigCheckServiceAccount(ns)
+func (cc *ConfigCheck) ensureVectorConfigCheckServiceAccount() (bool, ctrl.Result, error) {
+ vectorAgentServiceAccount := cc.createVectorConfigCheckServiceAccount()
- _, err := k8sutils.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, c)
+ _, err := k8s.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, cc.Client)
return helper.ReconcileResult(err)
}
-func ensureVectorConfigCheckConfig(c client.Client, cfg []byte, name, ns, hash string) error {
- vectorConfigCheckSecret, err := createVectorConfigCheckConfig(cfg, name, ns, hash)
+func (cc *ConfigCheck) ensureVectorConfigCheckConfig() error {
+ vectorConfigCheckSecret, err := cc.createVectorConfigCheckConfig()
if err != nil {
return err
}
- _, err = k8sutils.CreateOrUpdateSecret(vectorConfigCheckSecret, c)
+ _, err = k8s.CreateOrUpdateSecret(vectorConfigCheckSecret, cc.Client)
return err
}
-func checkVectorConfigCheckPod(c client.Client, cs *kubernetes.Clientset, name, ns, image, hash string) error {
- vectorConfigCheckPod := createVectorConfigCheckPod(name, ns, image, hash)
+func (cc *ConfigCheck) checkVectorConfigCheckPod() error {
+ vectorConfigCheckPod := cc.createVectorConfigCheckPod()
- err := k8sutils.CreatePod(vectorConfigCheckPod, c)
+ err := k8s.CreatePod(vectorConfigCheckPod, cc.Client)
if err != nil {
return err
}
- err = getCheckResult(vectorConfigCheckPod, c, cs)
+ err = cc.getCheckResult(vectorConfigCheckPod)
if err != nil {
return err
}
@@ -112,15 +143,15 @@ func checkVectorConfigCheckPod(c client.Client, cs *kubernetes.Clientset, name,
func labelsForVectorConfigCheck() map[string]string {
return map[string]string{
- label.ManagedByLabelKey: "vector-operator",
- label.NameLabelKey: "vector-configcheck",
- label.ComponentLabelKey: "ConfigCheck",
- label.VectorExcludeLabel: "true",
+ k8s.ManagedByLabelKey: "vector-operator",
+ k8s.NameLabelKey: "vector-configcheck",
+ k8s.ComponentLabelKey: "ConfigCheck",
+ k8s.VectorExcludeLabel: "true",
}
}
-func getNameVectorConfigCheck(name, hash string) string {
- n := "configcheck-" + name + "-" + hash
+func (cc *ConfigCheck) getNameVectorConfigCheck() string {
+ n := "configcheck-" + "-" + cc.Name + "-" + cc.Hash
return n
}
@@ -134,11 +165,11 @@ func randStringRunes() string {
return string(b)
}
-func getCheckResult(pod *corev1.Pod, c client.Client, cs *kubernetes.Clientset) error {
+func (cc *ConfigCheck) getCheckResult(pod *corev1.Pod) error {
log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", pod.Name)
for {
- existing, err := k8sutils.GetPod(pod, c)
+ existing, err := k8s.GetPod(pod, cc.Client)
if err != nil {
return err
}
@@ -148,7 +179,7 @@ func getCheckResult(pod *corev1.Pod, c client.Client, cs *kubernetes.Clientset)
log.Info("wait Validate Vector Config Result")
time.Sleep(5 * time.Second)
case "Failed":
- reason, err := k8sutils.GetPodLogs(pod, cs)
+ reason, err := k8s.GetPodLogs(pod, cc.ClientSet)
if err != nil {
return err
}
diff --git a/controllers/factory/config/configcheck/configcheck_config.go b/controllers/factory/config/configcheck/configcheck_config.go
index 4b5e6fc9..d7a0caa8 100644
--- a/controllers/factory/config/configcheck/configcheck_config.go
+++ b/controllers/factory/config/configcheck/configcheck_config.go
@@ -21,17 +21,17 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-func createVectorConfigCheckConfig(cfg []byte, name, ns, hash string) (*corev1.Secret, error) {
+func (cc *ConfigCheck) createVectorConfigCheckConfig() (*corev1.Secret, error) {
labels := labelsForVectorConfigCheck()
config := map[string][]byte{
- "agent.json": cfg,
+ "agent.json": cc.Config,
}
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: getNameVectorConfigCheck(name, hash),
- Namespace: ns,
+ Name: cc.getNameVectorConfigCheck(),
+ Namespace: cc.Namespace,
Labels: labels,
},
Data: config,
diff --git a/controllers/factory/config/configcheck/configcheck_pod.go b/controllers/factory/config/configcheck/configcheck_pod.go
index 0bbd6c16..1a2c5540 100644
--- a/controllers/factory/config/configcheck/configcheck_pod.go
+++ b/controllers/factory/config/configcheck/configcheck_pod.go
@@ -21,23 +21,23 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-func createVectorConfigCheckPod(name, ns, image, hash string) *corev1.Pod {
+func (cc *ConfigCheck) createVectorConfigCheckPod() *corev1.Pod {
labels := labelsForVectorConfigCheck()
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
- Name: getNameVectorConfigCheck(name, hash),
- Namespace: ns,
+ Name: cc.getNameVectorConfigCheck(),
+ Namespace: cc.Namespace,
Labels: labels,
},
Spec: corev1.PodSpec{
ServiceAccountName: "vector-configcheck",
- Volumes: generateVectorConfigCheckVolume(name, hash),
+ Volumes: cc.generateVectorConfigCheckVolume(),
SecurityContext: &corev1.PodSecurityContext{},
Containers: []corev1.Container{
{
Name: "config-check",
- Image: image,
+ Image: cc.Image,
Args: []string{"validate", "/etc/vector/*.json"},
Env: generateVectorConfigCheckEnvs(),
Ports: []corev1.ContainerPort{
@@ -47,7 +47,7 @@ func createVectorConfigCheckPod(name, ns, image, hash string) *corev1.Pod {
Protocol: "TCP",
},
},
- VolumeMounts: generateVectorConfigCheckVolumeMounts(),
+ VolumeMounts: cc.generateVectorConfigCheckVolumeMounts(),
},
},
RestartPolicy: "Never",
@@ -57,13 +57,13 @@ func createVectorConfigCheckPod(name, ns, image, hash string) *corev1.Pod {
return pod
}
-func generateVectorConfigCheckVolume(name, hash string) []corev1.Volume {
+func (cc *ConfigCheck) generateVectorConfigCheckVolume() []corev1.Volume {
volume := []corev1.Volume{
{
Name: "config",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
- SecretName: getNameVectorConfigCheck(name, hash),
+ SecretName: cc.getNameVectorConfigCheck(),
},
},
},
@@ -112,7 +112,7 @@ func generateVectorConfigCheckVolume(name, hash string) []corev1.Volume {
return volume
}
-func generateVectorConfigCheckVolumeMounts() []corev1.VolumeMount {
+func (cc *ConfigCheck) generateVectorConfigCheckVolumeMounts() []corev1.VolumeMount {
volumeMount := []corev1.VolumeMount{
{
Name: "config",
diff --git a/controllers/factory/config/configcheck/configcheck_rbac.go b/controllers/factory/config/configcheck/configcheck_rbac.go
index 08317c7f..0b4fb80b 100644
--- a/controllers/factory/config/configcheck/configcheck_rbac.go
+++ b/controllers/factory/config/configcheck/configcheck_rbac.go
@@ -21,13 +21,13 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-func createVectorConfigCheckServiceAccount(ns string) *corev1.ServiceAccount {
+func (cc *ConfigCheck) createVectorConfigCheckServiceAccount() *corev1.ServiceAccount {
labels := labelsForVectorConfigCheck()
serviceAccount := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "vector-configcheck",
- Namespace: ns,
+ Namespace: cc.Namespace,
Labels: labels,
},
}
diff --git a/controllers/factory/pipeline/clustervectorpipeline/vectorpipeline.go b/controllers/factory/pipeline/clustervectorpipeline/clustervectorpipeline.go
similarity index 92%
rename from controllers/factory/pipeline/clustervectorpipeline/vectorpipeline.go
rename to controllers/factory/pipeline/clustervectorpipeline/clustervectorpipeline.go
index 993d15a4..40b5e97c 100644
--- a/controllers/factory/pipeline/clustervectorpipeline/vectorpipeline.go
+++ b/controllers/factory/pipeline/clustervectorpipeline/clustervectorpipeline.go
@@ -20,7 +20,7 @@ import (
"context"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
"sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -30,6 +30,7 @@ var (
type Controller struct {
ClusterVectorPipeline *vectorv1alpha1.ClusterVectorPipeline
+ Config []byte
}
func (ctrl *Controller) Spec() vectorv1alpha1.VectorPipelineSpec {
@@ -65,7 +66,7 @@ func (ctrl *Controller) SetLastAppliedPipeline(hash *uint32) {
}
func (ctrl *Controller) UpdateStatus(ctx context.Context, c client.Client) error {
- return k8sutils.UpdateStatus(ctx, ctrl.ClusterVectorPipeline, c)
+ return k8s.UpdateStatus(ctx, ctrl.ClusterVectorPipeline, c)
}
func NewController(cvp *vectorv1alpha1.ClusterVectorPipeline) *Controller {
diff --git a/controllers/factory/pipeline/hash.go b/controllers/factory/pipeline/hash.go
index bfb73065..56ae2669 100644
--- a/controllers/factory/pipeline/hash.go
+++ b/controllers/factory/pipeline/hash.go
@@ -19,7 +19,7 @@ package pipeline
import (
"encoding/json"
- "github.com/kaasops/vector-operator/controllers/factory/utils"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/hash"
)
func (ctrl *Controller) GetSpecHash() (*uint32, error) {
@@ -27,7 +27,7 @@ func (ctrl *Controller) GetSpecHash() (*uint32, error) {
if err != nil {
return nil, err
}
- hash := utils.GetHash(a)
+ hash := hash.Get(a)
return &hash, nil
}
diff --git a/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go b/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go
index 2503d90e..8c9d9922 100644
--- a/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go
+++ b/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go
@@ -20,7 +20,7 @@ import (
"context"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
"sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -30,6 +30,7 @@ var (
type Controller struct {
VectorPipeline *vectorv1alpha1.VectorPipeline
+ Config []byte
}
func (ctrl *Controller) Spec() vectorv1alpha1.VectorPipelineSpec {
@@ -65,7 +66,7 @@ func (ctrl *Controller) SetLastAppliedPipeline(hash *uint32) {
}
func (ctrl *Controller) UpdateStatus(ctx context.Context, c client.Client) error {
- return k8sutils.UpdateStatus(ctx, ctrl.VectorPipeline, c)
+ return k8s.UpdateStatus(ctx, ctrl.VectorPipeline, c)
}
func NewController(vp *vectorv1alpha1.VectorPipeline) *Controller {
diff --git a/controllers/factory/utils/utils.go b/controllers/factory/utils/hash/hash.go
similarity index 92%
rename from controllers/factory/utils/utils.go
rename to controllers/factory/utils/hash/hash.go
index 4f9ceb7d..cde0db8d 100644
--- a/controllers/factory/utils/utils.go
+++ b/controllers/factory/utils/hash/hash.go
@@ -14,11 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package utils
+package hash
import "hash/crc32"
-func GetHash(input []byte) uint32 {
+func Get(input []byte) uint32 {
crc32q := crc32.MakeTable(crc32.IEEE)
return crc32.Checksum(input, crc32q)
}
diff --git a/controllers/factory/helper/helper.go b/controllers/factory/utils/helper/helper.go
similarity index 100%
rename from controllers/factory/helper/helper.go
rename to controllers/factory/utils/helper/helper.go
diff --git a/controllers/factory/k8sutils/utils.go b/controllers/factory/utils/k8s/k8s.go
similarity index 99%
rename from controllers/factory/k8sutils/utils.go
rename to controllers/factory/utils/k8s/k8s.go
index 01d77300..dff1bf29 100644
--- a/controllers/factory/k8sutils/utils.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package k8sutils
+package k8s
import (
"bytes"
diff --git a/controllers/factory/label/label.go b/controllers/factory/utils/k8s/label.go
similarity index 99%
rename from controllers/factory/label/label.go
rename to controllers/factory/utils/k8s/label.go
index 7dd3cf71..b9b86563 100644
--- a/controllers/factory/label/label.go
+++ b/controllers/factory/utils/k8s/label.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package label
+package k8s
const (
// The following labels are recommended by kubernetes https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
index 963cc0b3..29d206c6 100644
--- a/controllers/factory/vector/vector.go
+++ b/controllers/factory/vector/vector.go
@@ -35,8 +35,7 @@ func New(dataDir string, apiEnabled bool) *VectorConfig {
}
func Mapper(c ConfigComponent) (map[string]interface{}, error) {
- spec := make(map[string]interface{})
- spec = c.GetOptions()
+ spec := c.GetOptions()
config := &mapstructure.DecoderConfig{
Result: &spec,
ZeroFields: false,
diff --git a/controllers/factory/vector/vectoragent/vectoragent.go b/controllers/factory/vector/vectoragent/vectoragent.go
new file mode 100644
index 00000000..68f4616b
--- /dev/null
+++ b/controllers/factory/vector/vectoragent/vectoragent.go
@@ -0,0 +1,67 @@
+/*
+Copyright 2022.
+
+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 vectoragent
+
+import (
+ "context"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
+ "k8s.io/client-go/kubernetes"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+type Controller struct {
+ client.Client
+ Vector *vectorv1alpha1.Vector
+
+ Config []byte
+ // Temp. Wait this issue - https://github.com/kubernetes-sigs/controller-runtime/issues/452
+ ClientSet *kubernetes.Clientset
+}
+
+func NewController(v *vectorv1alpha1.Vector, c client.Client, cs *kubernetes.Clientset) *Controller {
+ return &Controller{
+ Client: c,
+ Vector: v,
+ ClientSet: cs,
+ }
+}
+
+func (ctrl *Controller) SetSucceesStatus(ctx context.Context) error {
+ var status = true
+ ctrl.Vector.Status.ConfigCheckResult = &status
+ ctrl.Vector.Status.Reason = nil
+
+ return k8s.UpdateStatus(ctx, ctrl.Vector, ctrl.Client)
+}
+
+func (ctrl *Controller) SetFailedStatus(ctx context.Context, err error) error {
+ var status = false
+ var reason = err.Error()
+ ctrl.Vector.Status.ConfigCheckResult = &status
+ ctrl.Vector.Status.Reason = &reason
+
+ return k8s.UpdateStatus(ctx, ctrl.Vector, ctrl.Client)
+}
+
+func (ctrl *Controller) SetLastAppliedPipelineStatus(ctx context.Context, hash *uint32) error {
+
+ ctrl.Vector.Status.LastAppliedConfigHash = hash
+
+ return k8s.UpdateStatus(ctx, ctrl.Vector, ctrl.Client)
+}
diff --git a/controllers/factory/vectoragent/vector_agent_config.go b/controllers/factory/vector/vectoragent/vectoragent_config.go
similarity index 66%
rename from controllers/factory/vectoragent/vector_agent_config.go
rename to controllers/factory/vector/vectoragent/vectoragent_config.go
index b1979239..cc47bcf9 100644
--- a/controllers/factory/vectoragent/vector_agent_config.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_config.go
@@ -21,23 +21,19 @@ import (
corev1 "k8s.io/api/core/v1"
- "github.com/kaasops/vector-operator/controllers/factory/config"
"github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
- "github.com/kaasops/vector-operator/controllers/factory/utils"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/hash"
)
func (ctrl *Controller) createVectorAgentConfig(ctx context.Context) (*corev1.Secret, error) {
- cfg, err := config.Get(ctx, ctrl.Vector, ctrl.Client)
- if err != nil {
- return nil, err
- }
+ cfgHash := hash.Get(ctrl.Config)
- cfgHash := utils.GetHash(cfg)
+ configCheck := configcheck.New(ctx, ctrl.Config, ctrl.Client, ctrl.ClientSet, ctrl.Vector.Name, ctrl.Vector.Namespace, ctrl.Vector.Spec.Agent.Image)
if ctrl.Vector.Status.LastAppliedConfigHash == nil || *ctrl.Vector.Status.LastAppliedConfigHash != cfgHash {
- err = configcheck.Run(cfg, ctrl.Client, ctrl.Clientset, ctrl.Vector.Name, ctrl.Vector.Namespace, ctrl.Vector.Spec.Agent.Image)
+ err := configCheck.Run()
if _, ok := err.(*configcheck.ErrConfigCheck); ok {
- if err := setFailedStatus(ctx, ctrl.Vector, ctrl.Client, err); err != nil {
+ if err := ctrl.SetFailedStatus(ctx, err); err != nil {
return nil, err
}
return nil, err
@@ -46,11 +42,11 @@ func (ctrl *Controller) createVectorAgentConfig(ctx context.Context) (*corev1.Se
return nil, err
}
- if err := SetLastAppliedPipelineStatus(ctx, ctrl.Vector, ctrl.Client, &cfgHash); err != nil {
+ if err := ctrl.SetLastAppliedPipelineStatus(ctx, &cfgHash); err != nil {
return nil, err
}
- if err := setSucceesStatus(ctx, ctrl.Vector, ctrl.Client); err != nil {
+ if err := ctrl.SetSucceesStatus(ctx); err != nil {
return nil, err
}
@@ -58,7 +54,7 @@ func (ctrl *Controller) createVectorAgentConfig(ctx context.Context) (*corev1.Se
labels := ctrl.labelsForVectorAgent()
config := map[string][]byte{
- "agent.json": cfg,
+ "agent.json": ctrl.Config,
}
secret := &corev1.Secret{
diff --git a/controllers/factory/vectoragent/vector_agent_controller.go b/controllers/factory/vector/vectoragent/vectoragent_controller.go
similarity index 67%
rename from controllers/factory/vectoragent/vector_agent_controller.go
rename to controllers/factory/vector/vectoragent/vectoragent_controller.go
index e747dddc..0badbf26 100644
--- a/controllers/factory/vectoragent/vector_agent_controller.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_controller.go
@@ -19,34 +19,14 @@ package vectoragent
import (
"context"
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/helper"
- "github.com/kaasops/vector-operator/controllers/factory/k8sutils"
- "github.com/kaasops/vector-operator/controllers/factory/label"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/helper"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/client-go/kubernetes"
"k8s.io/utils/pointer"
ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)
-type Controller struct {
- client.Client
- Vector *vectorv1alpha1.Vector
-
- // Temp. Wait this issue - https://github.com/kubernetes-sigs/controller-runtime/issues/452
- Clientset *kubernetes.Clientset
-}
-
-func NewController(v *vectorv1alpha1.Vector, c client.Client, cs *kubernetes.Clientset) *Controller {
- return &Controller{
- Client: c,
- Vector: v,
- Clientset: cs,
- }
-}
-
func (ctrl *Controller) EnsureVectorAgent() (done bool, result ctrl.Result, err error) {
ctx := context.Background()
log := log.FromContext(ctx).WithValues("vector-agent", ctrl.Vector.Name)
@@ -96,7 +76,7 @@ func (ctrl *Controller) ensureVectorAgentRBAC() (bool, ctrl.Result, error) {
func (ctrl *Controller) ensureVectorAgentServiceAccount() (bool, ctrl.Result, error) {
vectorAgentServiceAccount := ctrl.createVectorAgentServiceAccount()
- _, err := k8sutils.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, ctrl.Client)
+ _, err := k8s.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, ctrl.Client)
return helper.ReconcileResult(err)
}
@@ -104,7 +84,7 @@ func (ctrl *Controller) ensureVectorAgentServiceAccount() (bool, ctrl.Result, er
func (ctrl *Controller) ensureVectorAgentClusterRole() (bool, ctrl.Result, error) {
vectorAgentClusterRole := ctrl.createVectorAgentClusterRole()
- _, err := k8sutils.CreateOrUpdateClusterRole(vectorAgentClusterRole, ctrl.Client)
+ _, err := k8s.CreateOrUpdateClusterRole(vectorAgentClusterRole, ctrl.Client)
return helper.ReconcileResult(err)
}
@@ -112,7 +92,7 @@ func (ctrl *Controller) ensureVectorAgentClusterRole() (bool, ctrl.Result, error
func (ctrl *Controller) ensureVectorAgentClusterRoleBinding() (bool, ctrl.Result, error) {
vectorAgentClusterRoleBinding := ctrl.createVectorAgentClusterRoleBinding()
- _, err := k8sutils.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, ctrl.Client)
+ _, err := k8s.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, ctrl.Client)
return helper.ReconcileResult(err)
}
@@ -125,7 +105,7 @@ func (ctrl *Controller) ensureVectorAgentService() (bool, ctrl.Result, error) {
vectorAgentService := ctrl.createVectorAgentService()
- _, err := k8sutils.CreateOrUpdateService(vectorAgentService, ctrl.Client)
+ _, err := k8s.CreateOrUpdateService(vectorAgentService, ctrl.Client)
return helper.ReconcileResult(err)
}
@@ -141,7 +121,7 @@ func (ctrl *Controller) ensureVectorAgentConfig() (bool, ctrl.Result, error) {
return helper.ReconcileResult(err)
}
- _, err = k8sutils.CreateOrUpdateSecret(vectorAgentSecret, ctrl.Client)
+ _, err = k8s.CreateOrUpdateSecret(vectorAgentSecret, ctrl.Client)
return helper.ReconcileResult(err)
}
@@ -154,18 +134,18 @@ func (ctrl *Controller) ensureVectorAgentDaemonSet() (bool, ctrl.Result, error)
vectorAgentDaemonSet := ctrl.createVectorAgentDaemonSet()
- _, err := k8sutils.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, ctrl.Client)
+ _, err := k8s.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, ctrl.Client)
return helper.ReconcileResult(err)
}
func (ctrl *Controller) labelsForVectorAgent() map[string]string {
return map[string]string{
- label.ManagedByLabelKey: "vector-operator",
- label.NameLabelKey: "vector",
- label.ComponentLabelKey: "Agent",
- label.InstanceLabelKey: ctrl.Vector.Name,
- label.VectorExcludeLabel: "true",
+ k8s.ManagedByLabelKey: "vector-operator",
+ k8s.NameLabelKey: "vector",
+ k8s.ComponentLabelKey: "Agent",
+ k8s.InstanceLabelKey: ctrl.Vector.Name,
+ k8s.VectorExcludeLabel: "true",
}
}
@@ -195,29 +175,3 @@ func (ctrl *Controller) getControllerReference() []metav1.OwnerReference {
},
}
}
-
-func setSucceesStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client) error {
- var status = true
- v.Status.ConfigCheckResult = &status
- v.Status.Reason = nil
-
- return k8sutils.UpdateStatus(ctx, v, c)
-}
-
-func setFailedStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client, err error) error {
- var status = false
- var reason = err.Error()
- v.Status.ConfigCheckResult = &status
- v.Status.Reason = &reason
-
- return k8sutils.UpdateStatus(ctx, v, c)
-}
-
-func SetLastAppliedPipelineStatus(ctx context.Context, v *vectorv1alpha1.Vector, c client.Client, hash *uint32) error {
-
- v.Status.LastAppliedConfigHash = hash
- if err := k8sutils.UpdateStatus(ctx, v, c); err != nil {
- return err
- }
- return nil
-}
diff --git a/controllers/factory/vectoragent/vector_agent_daemonset.go b/controllers/factory/vector/vectoragent/vectoragent_daemonset.go
similarity index 100%
rename from controllers/factory/vectoragent/vector_agent_daemonset.go
rename to controllers/factory/vector/vectoragent/vectoragent_daemonset.go
diff --git a/controllers/factory/vectoragent/vector_agent_rbac.go b/controllers/factory/vector/vectoragent/vectoragent_rbac.go
similarity index 100%
rename from controllers/factory/vectoragent/vector_agent_rbac.go
rename to controllers/factory/vector/vectoragent/vectoragent_rbac.go
diff --git a/controllers/factory/vectoragent/vector_agent_service.go b/controllers/factory/vector/vectoragent/vectoragent_service.go
similarity index 100%
rename from controllers/factory/vectoragent/vector_agent_service.go
rename to controllers/factory/vector/vectoragent/vectoragent_service.go
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index df3446a4..84572ff1 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -20,7 +20,8 @@ import (
"context"
"time"
- "github.com/kaasops/vector-operator/controllers/factory/vectoragent"
+ "github.com/kaasops/vector-operator/controllers/factory/config"
+ "github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
@@ -69,7 +70,7 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
v.Spec.Agent.DataDir = "/vector-data-dir"
}
- return r.CreateOrUpdateVector(v)
+ return r.CreateOrUpdateVector(ctx, v)
}
func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.Vector, bool, ctrl.Result, error) {
@@ -99,10 +100,26 @@ func (r *VectorReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}
-func (r *VectorReconciler) CreateOrUpdateVector(v *vectorv1alpha1.Vector) (ctrl.Result, error) {
- vectorAgentReconciler := vectoragent.NewController(v, r.Client, r.Clientset)
+func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1alpha1.Vector) (ctrl.Result, error) {
+ // Init Controller for Vector Agent
+ vaCtrl := vectoragent.NewController(v, r.Client, r.Clientset)
- if done, result, err := vectorAgentReconciler.EnsureVectorAgent(); done {
+ // Get Vector Config file
+ config, err := config.New(ctx, vaCtrl)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+ config.FillForVectorAgent()
+
+ // Get Config in Json ([]byte)
+ byteCongif, err := config.GetByteConfig()
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+ vaCtrl.Config = byteCongif
+
+ // Start Reconcile Vector Agent
+ if done, result, err := vaCtrl.EnsureVectorAgent(); done {
return result, err
}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 43262678..b94278bc 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -29,8 +29,10 @@ import (
"github.com/go-logr/logr"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/config"
+ "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
"github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/pipeline/vectorpipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
)
// VectorPipelineReconciler reconciles a VectorPipeline object
@@ -60,6 +62,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
log.Info("start Reconcile VectorPipeline")
+ // Get CR VectorPipeline
vp, done, result, err := r.findVectorPipelineCustomResourceInstance(ctx, log, req)
if done {
return result, err
@@ -68,10 +71,10 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// Generate VectorPipeline Controller
vpCtrl := vectorpipeline.NewController(vp)
// Generate Pipeline Controller
- vCtrl := pipeline.NewController(ctx, r.Client, vpCtrl)
+ pCtrl := pipeline.NewController(ctx, r.Client, vpCtrl)
// Check Pipeline hash
- checkResult, err := vCtrl.CheckHash()
+ checkResult, err := pCtrl.CheckHash()
if err != nil {
return ctrl.Result{}, err
}
@@ -80,6 +83,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, nil
}
+ // Generate Pipeline ConfigCheck for all Vectors
vectorInstances := &vectorv1alpha1.VectorList{}
err = r.List(ctx, vectorInstances)
if err != nil {
@@ -95,11 +99,46 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
if v.DeletionTimestamp != nil {
continue
}
- if err = config.Check(ctx, &v, vCtrl, r.Client, r.Clientset); err != nil {
+
+ // Init Controller for Vector Agent
+ vaCtrl := vectoragent.NewController(&v, r.Client, r.Clientset)
+
+ // Get Vector Config file
+ config, err := config.New(ctx, vaCtrl)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+ config.FillForVectorPipeline(pCtrl)
+
+ // Get Config in Json ([]byte)
+ byteConfig, err := config.GetByteConfig()
+ if err != nil {
return ctrl.Result{}, err
}
- if err = vCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ // Init CheckConfig
+ configCheck := configcheck.New(ctx, byteConfig, vaCtrl.Client, vaCtrl.ClientSet, vaCtrl.Vector.Name, vaCtrl.Vector.Namespace, vaCtrl.Vector.Spec.Agent.Image)
+
+ // Start ConfigCheck
+ err = configCheck.Run()
+ if _, ok := err.(*configcheck.ErrConfigCheck); ok {
+ if err := pCtrl.SetFailedStatus(err); err != nil {
+ return ctrl.Result{}, err
+ }
+ if err = pCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ return ctrl.Result{}, err
+ }
+ return ctrl.Result{}, nil
+ }
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
+ if err = pCtrl.SetSucceesStatus(); err != nil {
+ return ctrl.Result{}, err
+ }
+
+ if err = pCtrl.SetLastAppliedPipelineStatus(); err != nil {
return ctrl.Result{}, err
}
@@ -135,3 +174,7 @@ func (r *VectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
For(&vectorv1alpha1.VectorPipeline{}).
Complete(r)
}
+
+func checkHash() {
+
+}
From e826bd1bce72a802836ef9141a98cf4da9e7de8e Mon Sep 17 00:00:00 2001
From: Vladimir <31961982+zvlb@users.noreply.github.com>
Date: Fri, 28 Oct 2022 14:26:42 +0200
Subject: [PATCH 034/316] CleanUp
---
controllers/vectorpipeline_controller.go | 3 ---
1 file changed, 3 deletions(-)
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index b94278bc..96afc3ca 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -175,6 +175,3 @@ func (r *VectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}
-func checkHash() {
-
-}
From fc7bc1182c24fa530483f6c54fe3584e37394454 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 28 Oct 2022 15:38:07 +0300
Subject: [PATCH 035/316] Delete config_check.go
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/config/config_check.go | 64 ----------------------
1 file changed, 64 deletions(-)
delete mode 100644 controllers/factory/config/config_check.go
diff --git a/controllers/factory/config/config_check.go b/controllers/factory/config/config_check.go
deleted file mode 100644
index 68921970..00000000
--- a/controllers/factory/config/config_check.go
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Copyright 2022.
-
-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 config
-
-import (
- "context"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
- "github.com/kaasops/vector-operator/controllers/factory/pipeline"
- "k8s.io/client-go/kubernetes"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/log"
-)
-
-func Check(ctx context.Context, v *vectorv1alpha1.Vector, vCtrl *pipeline.Controller, c client.Client, cs *kubernetes.Clientset) error {
-
- log := log.FromContext(context.TODO()).WithValues("ConfigCheck Vector Pipeline", vCtrl.Pipeline.Name())
-
- var vCtrls []pipeline.Controller
- vCtrls = append(vCtrls, *vCtrl)
-
- cfg, err := GenerateVectorConfig(v, vCtrls)
- if err != nil {
- return err
- }
-
- // if p.Type() == vectorpipeline.Type {
- // log.Info("It's VectorPipeline")
- // }
-
- cfgJson, err := VectorConfigToJson(cfg)
- if err != nil {
- return err
- }
-
- err = configcheck.Run(cfgJson, c, cs, v.Name, v.Namespace, v.Spec.Agent.Image)
- if _, ok := err.(*configcheck.ErrConfigCheck); ok {
- if err := vCtrl.SetFailedStatus(err); err != nil {
- return err
- }
- log.Error(err, "Vector Config has error")
- return nil
- }
- if err != nil {
- return err
- }
-
- return vCtrl.SetSucceesStatus()
-}
From e1ef26d0b406fe6f45b376e3203655c9e01ca809 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 28 Oct 2022 16:44:18 +0300
Subject: [PATCH 036/316] Cleanup findCustomResourceInstance method
Signed-off-by: Zemtsov Vladimir
---
.../clustervectorpipeline_controller.go | 27 ++++++++---------
controllers/vector_controller.go | 30 +++++++++----------
controllers/vectorpipeline_controller.go | 28 ++++++++---------
3 files changed, 38 insertions(+), 47 deletions(-)
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
index 16339b4c..f196f660 100644
--- a/controllers/clustervectorpipeline_controller.go
+++ b/controllers/clustervectorpipeline_controller.go
@@ -26,7 +26,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
- "github.com/go-logr/logr"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
)
@@ -57,9 +56,14 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
log.Info("start Reconcile ClusterVectorPipeline")
- // cvp, done, result, err := r.findClusterVectorPipelineCustomResourceInstance(ctx, log, req)
- // if done {
- // return result, err
+ // cvp, err := r.findClusterVectorPipelineCustomResourceInstance(ctx, req)
+ // if err != nil {
+ // log.Error(err, "Failed to get Cluster Vector Pipeline")
+ // return ctrl.Result{}, err
+ // }
+ // if cvp == nil {
+ // log.Info("Cluster Vector Pipeline CR not found. Ignoring since object must be deleted")
+ // return ctrl.Result{}, nil
// }
// hash, err := vectorpipeline.GetSpecHash(cvp.Spec)
// if err != nil {
@@ -98,24 +102,17 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, nil
}
-func (r *ClusterVectorPipelineReconciler) findClusterVectorPipelineCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.ClusterVectorPipeline, bool, ctrl.Result, error) {
+func (r *ClusterVectorPipelineReconciler) findClusterVectorPipelineCustomResourceInstance(ctx context.Context, req ctrl.Request) (*vectorv1alpha1.ClusterVectorPipeline, error) {
// fetch the master instance
cvp := &vectorv1alpha1.ClusterVectorPipeline{}
err := r.Get(ctx, req.NamespacedName, cvp)
if err != nil {
if errors.IsNotFound(err) {
- // Request object not found, could have been deleted after reconcile request.
- // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
- // Return and don't requeue
- log.Info("ClusterVectorPipeline CR not found. Ignoring since object must be deleted")
- return nil, true, ctrl.Result{}, nil
+ return nil, nil
}
- // Error reading the object - requeue the request.
- log.Error(err, "Failed to get Vector")
- return nil, true, ctrl.Result{}, err
+ return nil, err
}
- log.Info("Get Vector Pipeline" + cvp.Name)
- return cvp, false, ctrl.Result{}, nil
+ return cvp, nil
}
// SetupWithManager sets up the controller with the Manager.
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 84572ff1..67a0eb2b 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -29,7 +29,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
- "github.com/go-logr/logr"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
)
@@ -61,9 +60,14 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
log.Info("start Reconcile Vector")
- v, done, result, err := r.findVectorCustomResourceInstance(ctx, log, req)
- if done {
- return result, err
+ v, err := r.findVectorCustomResourceInstance(ctx, req)
+ if err != nil {
+ log.Error(err, "Failed to get Vector")
+ return ctrl.Result{}, err
+ }
+ if v == nil {
+ log.Info("Vector CR not found. Ignoring since object must be deleted")
+ return ctrl.Result{}, nil
}
if v.Spec.Agent.DataDir == "" {
@@ -73,24 +77,18 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return r.CreateOrUpdateVector(ctx, v)
}
-func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.Vector, bool, ctrl.Result, error) {
+func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context, req ctrl.Request) (*vectorv1alpha1.Vector, error) {
// fetch the master instance
v := &vectorv1alpha1.Vector{}
err := r.Get(ctx, req.NamespacedName, v)
if err != nil {
if errors.IsNotFound(err) {
- // Request object not found, could have been deleted after reconcile request.
- // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
- // Return and don't requeue
- log.Info("Vector CR not found. Ignoring since object must be deleted")
- return nil, true, ctrl.Result{}, nil
+ return nil, nil
}
- // Error reading the object - requeue the request.
- log.Error(err, "Failed to get Vector")
- return nil, true, ctrl.Result{}, err
+ return nil, err
}
- return v, false, ctrl.Result{}, nil
+ return v, nil
}
// SetupWithManager sets up the controller with the Manager.
@@ -112,11 +110,11 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
config.FillForVectorAgent()
// Get Config in Json ([]byte)
- byteCongif, err := config.GetByteConfig()
+ byteConfig, err := config.GetByteConfig()
if err != nil {
return ctrl.Result{}, err
}
- vaCtrl.Config = byteCongif
+ vaCtrl.Config = byteConfig
// Start Reconcile Vector Agent
if done, result, err := vaCtrl.EnsureVectorAgent(); done {
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 96afc3ca..72791e69 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -26,7 +26,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
- "github.com/go-logr/logr"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/config"
"github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
@@ -63,9 +62,14 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
log.Info("start Reconcile VectorPipeline")
// Get CR VectorPipeline
- vp, done, result, err := r.findVectorPipelineCustomResourceInstance(ctx, log, req)
- if done {
- return result, err
+ vp, err := r.findVectorPipelineCustomResourceInstance(ctx, req)
+ if err != nil {
+ log.Error(err, "Failed to get Vector Pipeline")
+ return ctrl.Result{}, err
+ }
+ if vp == nil {
+ log.Info("VectorPIpeline CR not found. Ignoring since object must be deleted")
+ return ctrl.Result{}, nil
}
// Generate VectorPipeline Controller
@@ -148,24 +152,17 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, nil
}
-func (r *VectorPipelineReconciler) findVectorPipelineCustomResourceInstance(ctx context.Context, log logr.Logger, req ctrl.Request) (*vectorv1alpha1.VectorPipeline, bool, ctrl.Result, error) {
+func (r *VectorPipelineReconciler) findVectorPipelineCustomResourceInstance(ctx context.Context, req ctrl.Request) (*vectorv1alpha1.VectorPipeline, error) {
// fetch the master instance
vp := &vectorv1alpha1.VectorPipeline{}
err := r.Get(ctx, req.NamespacedName, vp)
if err != nil {
if errors.IsNotFound(err) {
- // Request object not found, could have been deleted after reconcile request.
- // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
- // Return and don't requeue
- log.Info("VectorPipeline CR not found. Ignoring since object must be deleted")
- return nil, true, ctrl.Result{}, nil
+ return nil, nil
}
- // Error reading the object - requeue the request.
- log.Error(err, "Failed to get Vector")
- return nil, true, ctrl.Result{}, err
+ return nil, err
}
- log.Info("Get Vector Pipeline" + vp.Name)
- return vp, false, ctrl.Result{}, nil
+ return vp, nil
}
// SetupWithManager sets up the controller with the Manager.
@@ -174,4 +171,3 @@ func (r *VectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
For(&vectorv1alpha1.VectorPipeline{}).
Complete(r)
}
-
From 150dfb2e2931fe60359d0e78d862abe9375e71a1 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 28 Oct 2022 17:18:51 +0300
Subject: [PATCH 037/316] Init tests for hash
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/utils/hash/hash_test.go | 21 +++++++++++++++++++++
go.mod | 4 +++-
2 files changed, 24 insertions(+), 1 deletion(-)
create mode 100644 controllers/factory/utils/hash/hash_test.go
diff --git a/controllers/factory/utils/hash/hash_test.go b/controllers/factory/utils/hash/hash_test.go
new file mode 100644
index 00000000..a5d913ff
--- /dev/null
+++ b/controllers/factory/utils/hash/hash_test.go
@@ -0,0 +1,21 @@
+package hash
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestGet(t *testing.T) {
+ hashCase := func(bytes []byte, want uint32) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ result := Get(bytes)
+ req.Equal(result, want)
+ }
+ }
+
+ t.Run("Simple case", hashCase([]byte("test"), uint32(3632233996)))
+ t.Run("Zero case", hashCase([]byte(""), uint32(0)))
+}
diff --git a/go.mod b/go.mod
index d9825a97..a2c10637 100644
--- a/go.mod
+++ b/go.mod
@@ -3,10 +3,10 @@ module github.com/kaasops/vector-operator
go 1.18
require (
- github.com/go-logr/logr v1.2.0
github.com/mitchellh/mapstructure v1.5.0
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.18.1
+ github.com/stretchr/testify v1.7.0
k8s.io/api v0.24.2
k8s.io/apimachinery v0.24.2
k8s.io/client-go v0.24.2
@@ -31,6 +31,7 @@ require (
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
+ github.com/go-logr/logr v1.2.0 // indirect
github.com/go-logr/zapr v1.2.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
@@ -52,6 +53,7 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
From 68328d88f664e07883ecd4a5e04197d361946663 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 28 Oct 2022 17:19:03 +0300
Subject: [PATCH 038/316] remove package helpers
Signed-off-by: Zemtsov Vladimir
---
.../factory/config/configcheck/configcheck.go | 18 +---
controllers/factory/utils/helper/helper.go | 26 ------
controllers/factory/utils/k8s/k8s.go | 83 +++++++++----------
.../vectoragent/vectoragent_controller.go | 76 +++++++----------
controllers/vector_controller.go | 4 +-
5 files changed, 78 insertions(+), 129 deletions(-)
delete mode 100644 controllers/factory/utils/helper/helper.go
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index 9ecfc337..b99c75d2 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -21,11 +21,9 @@ import (
"math/rand"
"time"
- "github.com/kaasops/vector-operator/controllers/factory/utils/helper"
"github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
- ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)
@@ -100,19 +98,13 @@ func (cc *ConfigCheck) Run() error {
}
func (cc *ConfigCheck) ensureVectorConfigCheckRBAC() error {
- if done, _, err := cc.ensureVectorConfigCheckServiceAccount(); done {
- return err
- }
-
- return nil
+ return cc.ensureVectorConfigCheckServiceAccount()
}
-func (cc *ConfigCheck) ensureVectorConfigCheckServiceAccount() (bool, ctrl.Result, error) {
+func (cc *ConfigCheck) ensureVectorConfigCheckServiceAccount() error {
vectorAgentServiceAccount := cc.createVectorConfigCheckServiceAccount()
- _, err := k8s.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, cc.Client)
-
- return helper.ReconcileResult(err)
+ return k8s.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, cc.Client)
}
func (cc *ConfigCheck) ensureVectorConfigCheckConfig() error {
vectorConfigCheckSecret, err := cc.createVectorConfigCheckConfig()
@@ -120,9 +112,7 @@ func (cc *ConfigCheck) ensureVectorConfigCheckConfig() error {
return err
}
- _, err = k8s.CreateOrUpdateSecret(vectorConfigCheckSecret, cc.Client)
-
- return err
+ return k8s.CreateOrUpdateSecret(vectorConfigCheckSecret, cc.Client)
}
func (cc *ConfigCheck) checkVectorConfigCheckPod() error {
diff --git a/controllers/factory/utils/helper/helper.go b/controllers/factory/utils/helper/helper.go
deleted file mode 100644
index 5e3e0c64..00000000
--- a/controllers/factory/utils/helper/helper.go
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-Copyright 2022.
-
-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 helper
-
-import ctrl "sigs.k8s.io/controller-runtime"
-
-func ReconcileResult(err error) (bool, ctrl.Result, error) {
- if err != nil {
- return true, ctrl.Result{}, err
- }
- return false, ctrl.Result{}, nil
-}
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index dff1bf29..c244b739 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -29,34 +29,33 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/reconcile"
)
-func CreateOrUpdateService(svc *corev1.Service, c client.Client) (*reconcile.Result, error) {
+func CreateOrUpdateService(svc *corev1.Service, c client.Client) error {
return reconcileService(svc, c)
}
-func CreateOrUpdateSecret(secret *corev1.Secret, c client.Client) (*reconcile.Result, error) {
+func CreateOrUpdateSecret(secret *corev1.Secret, c client.Client) error {
return reconcileSecret(secret, c)
}
-func CreateOrUpdateDaemonSet(daemonSet *appsv1.DaemonSet, c client.Client) (*reconcile.Result, error) {
+func CreateOrUpdateDaemonSet(daemonSet *appsv1.DaemonSet, c client.Client) error {
return reconcileDaemonSet(daemonSet, c)
}
-func CreateOrUpdateStatefulSet(statefulSet *appsv1.StatefulSet, c client.Client) (*reconcile.Result, error) {
+func CreateOrUpdateStatefulSet(statefulSet *appsv1.StatefulSet, c client.Client) error {
return reconcileStatefulSet(statefulSet, c)
}
-func CreateOrUpdateServiceAccount(secret *corev1.ServiceAccount, c client.Client) (*reconcile.Result, error) {
+func CreateOrUpdateServiceAccount(secret *corev1.ServiceAccount, c client.Client) error {
return reconcileServiceAccount(secret, c)
}
-func CreateOrUpdateClusterRole(secret *rbacv1.ClusterRole, c client.Client) (*reconcile.Result, error) {
+func CreateOrUpdateClusterRole(secret *rbacv1.ClusterRole, c client.Client) error {
return reconcileClusterRole(secret, c)
}
-func CreateOrUpdateClusterRoleBinding(secret *rbacv1.ClusterRoleBinding, c client.Client) (*reconcile.Result, error) {
+func CreateOrUpdateClusterRoleBinding(secret *rbacv1.ClusterRoleBinding, c client.Client) error {
return reconcileClusterRoleBinding(secret, c)
}
@@ -104,7 +103,7 @@ func UpdateStatus(ctx context.Context, obj client.Object, c client.Client) error
return c.Status().Update(ctx, obj)
}
-func reconcileService(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
+func reconcileService(obj runtime.Object, c client.Client) error {
existing := &corev1.Service{}
desired := obj.(*corev1.Service)
@@ -113,23 +112,23 @@ func reconcileService(obj runtime.Object, c client.Client) (*reconcile.Result, e
if err != nil && errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
- return nil, err
+ return err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Spec = desired.Spec
existing.Labels = desired.Labels
err := c.Update(context.TODO(), existing)
- return nil, err
+ return err
}
}
if err != nil && !errors.IsAlreadyExists(err) {
- return nil, err
+ return err
}
- return nil, nil
+ return nil
}
-func reconcileSecret(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
+func reconcileSecret(obj runtime.Object, c client.Client) error {
existing := &corev1.Secret{}
desired := obj.(*corev1.Secret)
@@ -138,23 +137,23 @@ func reconcileSecret(obj runtime.Object, c client.Client) (*reconcile.Result, er
if err != nil && errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
- return nil, err
+ return err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Data = desired.Data
existing.Labels = desired.Labels
err := c.Update(context.TODO(), existing)
- return nil, err
+ return err
}
}
if err != nil && !errors.IsAlreadyExists(err) {
- return nil, err
+ return err
}
- return nil, nil
+ return nil
}
-func reconcileDaemonSet(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
+func reconcileDaemonSet(obj runtime.Object, c client.Client) error {
existing := &appsv1.DaemonSet{}
desired := obj.(*appsv1.DaemonSet)
@@ -163,23 +162,23 @@ func reconcileDaemonSet(obj runtime.Object, c client.Client) (*reconcile.Result,
if err != nil && errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
- return nil, err
+ return err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Spec = desired.Spec
existing.Labels = desired.Labels
err := c.Update(context.TODO(), existing)
- return nil, err
+ return err
}
}
if err != nil && !errors.IsAlreadyExists(err) {
- return nil, err
+ return err
}
- return nil, nil
+ return nil
}
-func reconcileStatefulSet(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
+func reconcileStatefulSet(obj runtime.Object, c client.Client) error {
existing := &appsv1.StatefulSet{}
desired := obj.(*appsv1.StatefulSet)
@@ -188,23 +187,23 @@ func reconcileStatefulSet(obj runtime.Object, c client.Client) (*reconcile.Resul
if err != nil && errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
- return nil, err
+ return err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Spec = desired.Spec
existing.Labels = desired.Labels
err := c.Update(context.TODO(), existing)
- return nil, err
+ return err
}
}
if err != nil && !errors.IsAlreadyExists(err) {
- return nil, err
+ return err
}
- return nil, nil
+ return nil
}
-func reconcileServiceAccount(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
+func reconcileServiceAccount(obj runtime.Object, c client.Client) error {
existing := &corev1.ServiceAccount{}
desired := obj.(*corev1.ServiceAccount)
@@ -213,17 +212,17 @@ func reconcileServiceAccount(obj runtime.Object, c client.Client) (*reconcile.Re
if err != nil && errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
- return nil, err
+ return err
}
}
if err != nil && !errors.IsAlreadyExists(err) {
- return nil, err
+ return err
}
- return nil, nil
+ return nil
}
-func reconcileClusterRole(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
+func reconcileClusterRole(obj runtime.Object, c client.Client) error {
existing := &rbacv1.ClusterRole{}
desired := obj.(*rbacv1.ClusterRole)
@@ -232,22 +231,22 @@ func reconcileClusterRole(obj runtime.Object, c client.Client) (*reconcile.Resul
if err != nil && errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
- return nil, err
+ return err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Rules = desired.Rules
err := c.Update(context.TODO(), existing)
- return nil, err
+ return err
}
}
if err != nil && !errors.IsAlreadyExists(err) {
- return nil, err
+ return err
}
- return nil, nil
+ return nil
}
-func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) (*reconcile.Result, error) {
+func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
existing := &rbacv1.ClusterRoleBinding{}
desired := obj.(*rbacv1.ClusterRoleBinding)
@@ -256,18 +255,18 @@ func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) (*reconcil
if err != nil && errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
- return nil, err
+ return err
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.RoleRef = desired.RoleRef
existing.Subjects = desired.Subjects
err := c.Update(context.TODO(), existing)
- return nil, err
+ return err
}
}
if err != nil && !errors.IsAlreadyExists(err) {
- return nil, err
+ return err
}
- return nil, nil
+ return nil
}
diff --git a/controllers/factory/vector/vectoragent/vectoragent_controller.go b/controllers/factory/vector/vectoragent/vectoragent_controller.go
index 0badbf26..84e75d3b 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_controller.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_controller.go
@@ -19,85 +19,77 @@ package vectoragent
import (
"context"
- "github.com/kaasops/vector-operator/controllers/factory/utils/helper"
"github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"
- ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log"
)
-func (ctrl *Controller) EnsureVectorAgent() (done bool, result ctrl.Result, err error) {
+func (ctrl *Controller) EnsureVectorAgent() error {
ctx := context.Background()
log := log.FromContext(ctx).WithValues("vector-agent", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent")
- if done, result, err = ctrl.ensureVectorAgentRBAC(); done {
- return
+ if err := ctrl.ensureVectorAgentRBAC(); err != nil {
+ return err
}
if ctrl.Vector.Spec.Agent.Service {
- if done, result, err = ctrl.ensureVectorAgentService(); done {
- return
+ if err := ctrl.ensureVectorAgentService(); err != nil {
+ return err
}
}
- if done, result, err = ctrl.ensureVectorAgentConfig(); done {
- return
+ if err := ctrl.ensureVectorAgentConfig(); err != nil {
+ return err
}
- if done, result, err = ctrl.ensureVectorAgentDaemonSet(); done {
- return
+ if err := ctrl.ensureVectorAgentDaemonSet(); err != nil {
+ return err
}
- return
+ return nil
}
-func (ctrl *Controller) ensureVectorAgentRBAC() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentRBAC() error {
ctx := context.Background()
log := log.FromContext(ctx).WithValues("vector-agent-rbac", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent RBAC")
- if done, _, err := ctrl.ensureVectorAgentServiceAccount(); done {
- return helper.ReconcileResult(err)
+ if err := ctrl.ensureVectorAgentServiceAccount(); err != nil {
+ return err
}
- if done, _, err := ctrl.ensureVectorAgentClusterRole(); done {
- return helper.ReconcileResult(err)
+ if err := ctrl.ensureVectorAgentClusterRole(); err != nil {
+ return err
}
- if done, _, err := ctrl.ensureVectorAgentClusterRoleBinding(); done {
- return helper.ReconcileResult(err)
+ if err := ctrl.ensureVectorAgentClusterRoleBinding(); err != nil {
+ return err
}
- return helper.ReconcileResult(nil)
+ return nil
}
-func (ctrl *Controller) ensureVectorAgentServiceAccount() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentServiceAccount() error {
vectorAgentServiceAccount := ctrl.createVectorAgentServiceAccount()
- _, err := k8s.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, ctrl.Client)
-
- return helper.ReconcileResult(err)
+ return k8s.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentClusterRole() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentClusterRole() error {
vectorAgentClusterRole := ctrl.createVectorAgentClusterRole()
- _, err := k8s.CreateOrUpdateClusterRole(vectorAgentClusterRole, ctrl.Client)
-
- return helper.ReconcileResult(err)
+ return k8s.CreateOrUpdateClusterRole(vectorAgentClusterRole, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentClusterRoleBinding() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentClusterRoleBinding() error {
vectorAgentClusterRoleBinding := ctrl.createVectorAgentClusterRoleBinding()
- _, err := k8s.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, ctrl.Client)
-
- return helper.ReconcileResult(err)
+ return k8s.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentService() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentService() error {
ctx := context.Background()
log := log.FromContext(ctx).WithValues("vector-agent-service", ctrl.Vector.Name)
@@ -105,12 +97,10 @@ func (ctrl *Controller) ensureVectorAgentService() (bool, ctrl.Result, error) {
vectorAgentService := ctrl.createVectorAgentService()
- _, err := k8s.CreateOrUpdateService(vectorAgentService, ctrl.Client)
-
- return helper.ReconcileResult(err)
+ return k8s.CreateOrUpdateService(vectorAgentService, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentConfig() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentConfig() error {
ctx := context.Background()
log := log.FromContext(ctx).WithValues("vector-agent-secret", ctrl.Vector.Name)
@@ -118,15 +108,13 @@ func (ctrl *Controller) ensureVectorAgentConfig() (bool, ctrl.Result, error) {
vectorAgentSecret, err := ctrl.createVectorAgentConfig(ctx)
if err != nil {
- return helper.ReconcileResult(err)
+ return err
}
- _, err = k8s.CreateOrUpdateSecret(vectorAgentSecret, ctrl.Client)
-
- return helper.ReconcileResult(err)
+ return k8s.CreateOrUpdateSecret(vectorAgentSecret, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentDaemonSet() (bool, ctrl.Result, error) {
+func (ctrl *Controller) ensureVectorAgentDaemonSet() error {
ctx := context.Background()
log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", ctrl.Vector.Name)
@@ -134,9 +122,7 @@ func (ctrl *Controller) ensureVectorAgentDaemonSet() (bool, ctrl.Result, error)
vectorAgentDaemonSet := ctrl.createVectorAgentDaemonSet()
- _, err := k8s.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, ctrl.Client)
-
- return helper.ReconcileResult(err)
+ return k8s.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, ctrl.Client)
}
func (ctrl *Controller) labelsForVectorAgent() map[string]string {
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 67a0eb2b..efab81ab 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -117,8 +117,8 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
vaCtrl.Config = byteConfig
// Start Reconcile Vector Agent
- if done, result, err := vaCtrl.EnsureVectorAgent(); done {
- return result, err
+ if err := vaCtrl.EnsureVectorAgent(); err != nil {
+ return ctrl.Result{}, err
}
return ctrl.Result{RequeueAfter: 15 * time.Second}, nil
From 217bb0e30dc08384163e969f6ba0a9a3fe9ce339 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 29 Oct 2022 16:14:55 +0300
Subject: [PATCH 039/316] Add test for k8s utils package
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/utils/hash/hash_test.go | 16 +
controllers/factory/utils/k8s/k8s.go | 15 +-
controllers/factory/utils/k8s/k8s_test.go | 564 ++++++++++++++++++++
3 files changed, 585 insertions(+), 10 deletions(-)
create mode 100644 controllers/factory/utils/k8s/k8s_test.go
diff --git a/controllers/factory/utils/hash/hash_test.go b/controllers/factory/utils/hash/hash_test.go
index a5d913ff..615b676d 100644
--- a/controllers/factory/utils/hash/hash_test.go
+++ b/controllers/factory/utils/hash/hash_test.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2022.
+
+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 hash
import (
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index c244b739..5ee3c494 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -142,8 +142,7 @@ func reconcileSecret(obj runtime.Object, c client.Client) error {
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Data = desired.Data
existing.Labels = desired.Labels
- err := c.Update(context.TODO(), existing)
- return err
+ return c.Update(context.TODO(), existing)
}
}
if err != nil && !errors.IsAlreadyExists(err) {
@@ -167,8 +166,7 @@ func reconcileDaemonSet(obj runtime.Object, c client.Client) error {
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Spec = desired.Spec
existing.Labels = desired.Labels
- err := c.Update(context.TODO(), existing)
- return err
+ return c.Update(context.TODO(), existing)
}
}
if err != nil && !errors.IsAlreadyExists(err) {
@@ -192,8 +190,7 @@ func reconcileStatefulSet(obj runtime.Object, c client.Client) error {
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Spec = desired.Spec
existing.Labels = desired.Labels
- err := c.Update(context.TODO(), existing)
- return err
+ return c.Update(context.TODO(), existing)
}
}
if err != nil && !errors.IsAlreadyExists(err) {
@@ -235,8 +232,7 @@ func reconcileClusterRole(obj runtime.Object, c client.Client) error {
}
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Rules = desired.Rules
- err := c.Update(context.TODO(), existing)
- return err
+ return c.Update(context.TODO(), existing)
}
}
if err != nil && !errors.IsAlreadyExists(err) {
@@ -260,8 +256,7 @@ func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
if !equality.Semantic.DeepEqual(existing, desired) {
existing.RoleRef = desired.RoleRef
existing.Subjects = desired.Subjects
- err := c.Update(context.TODO(), existing)
- return err
+ return c.Update(context.TODO(), existing)
}
}
if err != nil && !errors.IsAlreadyExists(err) {
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
new file mode 100644
index 00000000..ed31231d
--- /dev/null
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -0,0 +1,564 @@
+// /*
+// Copyright 2022.
+
+// 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 k8s
+
+import (
+ "context"
+ "testing"
+
+ // . "github.com/onsi/ginkgo/v2"
+ // . "github.com/onsi/gomega"
+ "github.com/stretchr/testify/require"
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ rbacv1 "k8s.io/api/rbac/v1"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/util/validation/field"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
+)
+
+// type objects interface {
+// *corev1.Service | *corev1.Secret | *appsv1.DaemonSet | *appsv1.StatefulSet | *corev1.ServiceAccount | *rbacv1.ClusterRole | *rbacv1.ClusterRoleBinding
+// }
+
+func TestCreatePod(t *testing.T) {
+ createPodCase := func(objInit, obj *corev1.Pod, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ err := CreatePod(obj, cl)
+ req.Equal(err, want)
+ }
+ }
+
+ obj_init := &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ ResourceVersion: "",
+ },
+ }
+ obj_case1 := &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ obj_case2 := &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+ gr_case2 := schema.GroupResource{
+ Group: "",
+ Resource: "pods",
+ }
+ error_case2 := apierrors.NewAlreadyExists(gr_case2, obj_case2.ObjectMeta.Name)
+
+ t.Run("Create not exist pod case", createPodCase(obj_init, obj_case1, nil))
+ t.Run("Create alredy exist pod case", createPodCase(obj_init, obj_case2, error_case2))
+}
+
+// func CreatePod(pod *corev1.Pod, c client.Client) error {
+// err := c.Create(context.TODO(), pod)
+// if err != nil {
+// return err
+// }
+// return nil
+// }
+
+func TestGetPod(t *testing.T) {
+ getPodCase := func(objInit, obj, wantPod *corev1.Pod, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ result, err := GetPod(obj, cl)
+ if result != nil {
+ req.Equal(result.ObjectMeta, wantPod.ObjectMeta)
+ }
+ req.Equal(err, want)
+ }
+ }
+
+ obj_init := &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ ResourceVersion: "",
+ },
+ }
+ obj_case1 := &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ gvr_case1 := schema.GroupVersionResource{
+ Group: "",
+ Version: "v1",
+ Resource: "pods",
+ }
+ error_case1 := apierrors.NewNotFound(gvr_case1.GroupResource(), obj_case1.ObjectMeta.Name)
+ obj_case2 := &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+
+ t.Run("Get not exist pod case", getPodCase(obj_init, obj_case1, nil, error_case1))
+ t.Run("Get exist pod case", getPodCase(obj_init, obj_case2, obj_init, nil))
+}
+
+func TestUpdateStatus(t *testing.T) {
+ updateStatusCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ err := UpdateStatus(context.Background(), obj, cl)
+
+ req.Equal(err, want)
+ }
+ }
+
+ obj_init := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ ResourceVersion: "",
+ },
+ }
+ obj_case1 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ obj_case2 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+ obj_case3 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ }
+ obj_case4 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+
+ obj_case5 := &appsv1.Deployment{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ Status: appsv1.DeploymentStatus{
+ Replicas: 10,
+ },
+ }
+ gvr_case5 := schema.GroupVersionResource{
+ Group: "apps",
+ Version: "v1",
+ Resource: "deployments",
+ }
+ error_case5 := apierrors.NewNotFound(gvr_case5.GroupResource(), obj_case5.ObjectMeta.Name)
+
+ init_obj_case6 := &appsv1.Deployment{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ Status: appsv1.DeploymentStatus{
+ Replicas: 5,
+ },
+ }
+ obj_case6 := &appsv1.Deployment{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ Status: appsv1.DeploymentStatus{
+ Replicas: 10,
+ },
+ }
+
+ t.Run("Update Simple case", updateStatusCase(obj_init, obj_case1, nil))
+ t.Run("Update Alredy exist case", updateStatusCase(obj_init, obj_case2, nil))
+ t.Run("Update with Another Namespace case", updateStatusCase(obj_init, obj_case3, nil))
+ t.Run("Update without Name case", updateStatusCase(obj_init, obj_case4, error_case4))
+ t.Run("Update not exist Deployment with wrong init case", updateStatusCase(obj_init, obj_case5, error_case5))
+ t.Run("Update Deployment case", updateStatusCase(init_obj_case6, obj_case6, nil))
+
+}
+
+func TestCreateOrUpdateService(t *testing.T) {
+ reconcileServiceCase := func(objInit, obj *corev1.Service, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ err := CreateOrUpdateService(obj, cl)
+
+ req.Equal(err, want)
+ }
+ }
+
+ service_init := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ ResourceVersion: "",
+ },
+ }
+
+ service_case1 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ service_case2 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+ service_case3 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ }
+ service_case4 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+
+ t.Run("Create Simple case", reconcileServiceCase(service_init, service_case1, nil))
+ t.Run("Create Alredy exist case", reconcileServiceCase(service_init, service_case2, nil))
+ t.Run("Create with Another Namespace case", reconcileServiceCase(service_init, service_case3, nil))
+ t.Run("Create without Name case", reconcileServiceCase(service_init, service_case4, error_case4))
+}
+
+func TestCreateOrUpdateSecret(t *testing.T) {
+ reconcileSecretCase := func(objInit, obj *corev1.Secret, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ err := CreateOrUpdateSecret(obj, cl)
+
+ req.Equal(err, want)
+ }
+ }
+
+ secret_init := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+
+ secret_case1 := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ secret_case2 := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+ secret_case3 := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ }
+ secret_case4 := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+
+ t.Run("Create Simple case", reconcileSecretCase(secret_init, secret_case1, nil))
+ t.Run("Create Alredy exist case", reconcileSecretCase(secret_init, secret_case2, nil))
+ t.Run("Create with Another Namespace case", reconcileSecretCase(secret_init, secret_case3, nil))
+ t.Run("Create without Name case", reconcileSecretCase(secret_init, secret_case4, error_case4))
+}
+
+func TestCreateOrUpdateDaemonSet(t *testing.T) {
+ reconcileDaemonSetCase := func(objInit, obj *appsv1.DaemonSet, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ err := CreateOrUpdateDaemonSet(obj, cl)
+
+ req.Equal(err, want)
+ }
+ }
+
+ daemonSet_init := &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+
+ daemonSet_case1 := &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ daemonSet_case2 := &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+ daemonSet_case3 := &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ }
+ daemonSet_case4 := &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+
+ t.Run("Create Simple case", reconcileDaemonSetCase(daemonSet_init, daemonSet_case1, nil))
+ t.Run("Create Alredy exist case", reconcileDaemonSetCase(daemonSet_init, daemonSet_case2, nil))
+ t.Run("Create with Another Namespace case", reconcileDaemonSetCase(daemonSet_init, daemonSet_case3, nil))
+ t.Run("Create without Name case", reconcileDaemonSetCase(daemonSet_init, daemonSet_case4, error_case4))
+}
+
+func TestCreateOrUpdateStatefulSet(t *testing.T) {
+ reconcileStatefulSetCase := func(objInit, obj *appsv1.StatefulSet, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ err := CreateOrUpdateStatefulSet(obj, cl)
+
+ req.Equal(err, want)
+ }
+ }
+
+ statefulSet_init := &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+
+ statefulSet_case1 := &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ statefulSet_case2 := &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+ statefulSet_case3 := &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ }
+ statefulSet_case4 := &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+
+ t.Run("Create Simple case", reconcileStatefulSetCase(statefulSet_init, statefulSet_case1, nil))
+ t.Run("Create Alredy exist case", reconcileStatefulSetCase(statefulSet_init, statefulSet_case2, nil))
+ t.Run("Create with Another Namespace case", reconcileStatefulSetCase(statefulSet_init, statefulSet_case3, nil))
+ t.Run("Create without Name case", reconcileStatefulSetCase(statefulSet_init, statefulSet_case4, error_case4))
+}
+
+func TestCreateOrUpdateServiceAccount(t *testing.T) {
+ reconcileServiceAccountCase := func(objInit, obj *corev1.ServiceAccount, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ err := CreateOrUpdateServiceAccount(obj, cl)
+
+ req.Equal(err, want)
+ }
+ }
+
+ serviceAccount_init := &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+
+ serviceAccount_case1 := &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ serviceAccount_case2 := &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+ serviceAccount_case3 := &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ }
+ serviceAccount_case4 := &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+
+ t.Run("Create Simple case", reconcileServiceAccountCase(serviceAccount_init, serviceAccount_case1, nil))
+ t.Run("Create Alredy exist case", reconcileServiceAccountCase(serviceAccount_init, serviceAccount_case2, nil))
+ t.Run("Create with Another Namespace case", reconcileServiceAccountCase(serviceAccount_init, serviceAccount_case3, nil))
+ t.Run("Create without Name case", reconcileServiceAccountCase(serviceAccount_init, serviceAccount_case4, error_case4))
+}
+
+func TestCreateOrUpdateClusterRole(t *testing.T) {
+ reconcileClusterRole := func(objInit, obj *rbacv1.ClusterRole, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ err := CreateOrUpdateClusterRole(obj, cl)
+
+ req.Equal(err, want)
+ }
+ }
+
+ clusterRole_init := &rbacv1.ClusterRole{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+
+ clusterRole_case1 := &rbacv1.ClusterRole{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ clusterRole_case2 := &rbacv1.ClusterRole{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+ clusterRole_case3 := &rbacv1.ClusterRole{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ }
+ clusterRole_case4 := &rbacv1.ClusterRole{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+
+ t.Run("Create Simple case", reconcileClusterRole(clusterRole_init, clusterRole_case1, nil))
+ t.Run("Create Alredy exist case", reconcileClusterRole(clusterRole_init, clusterRole_case2, nil))
+ t.Run("Create with Another Namespace case", reconcileClusterRole(clusterRole_init, clusterRole_case3, nil))
+ t.Run("Create without Name case", reconcileClusterRole(clusterRole_init, clusterRole_case4, error_case4))
+}
+
+func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
+ reconcileClusterRoleBinding := func(objInit, obj *rbacv1.ClusterRoleBinding, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+
+ err := CreateOrUpdateClusterRoleBinding(obj, cl)
+
+ req.Equal(err, want)
+ }
+ }
+
+ clusterRoleBinding_init := &rbacv1.ClusterRoleBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+
+ clusterRoleBinding_case1 := &rbacv1.ClusterRoleBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ }
+ clusterRoleBinding_case2 := &rbacv1.ClusterRoleBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ }
+ clusterRoleBinding_case3 := &rbacv1.ClusterRoleBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ }
+ clusterRoleBinding_case4 := &rbacv1.ClusterRoleBinding{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+
+ t.Run("Create Simple case", reconcileClusterRoleBinding(clusterRoleBinding_init, clusterRoleBinding_case1, nil))
+ t.Run("Create Alredy exist case", reconcileClusterRoleBinding(clusterRoleBinding_init, clusterRoleBinding_case2, nil))
+ t.Run("Create with Another Namespace case", reconcileClusterRoleBinding(clusterRoleBinding_init, clusterRoleBinding_case3, nil))
+ t.Run("Create without Name case", reconcileClusterRoleBinding(clusterRoleBinding_init, clusterRoleBinding_case4, error_case4))
+}
From 08ca16decaad703e13bdffb042e1a7fb98b8ee09 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 29 Oct 2022 17:09:24 +0300
Subject: [PATCH 040/316] Add clusterrole and clusterrolebinding to
ClientDisableCacheFor
Signed-off-by: Zemtsov Vladimir
---
main.go | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/main.go b/main.go
index c1cf1585..870b9be9 100644
--- a/main.go
+++ b/main.go
@@ -22,16 +22,18 @@ import (
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
- appsv1 "k8s.io/api/apps/v1"
- corev1 "k8s.io/api/core/v1"
+
"k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth"
- "sigs.k8s.io/controller-runtime/pkg/client"
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
@@ -84,7 +86,7 @@ func main() {
LeaderElection: enableLeaderElection,
LeaderElectionID: "79cbe7f3.kaasops.io",
ClientDisableCacheFor: []client.Object{&corev1.Secret{}, &corev1.ConfigMap{}, &corev1.Pod{}, &appsv1.Deployment{},
- &appsv1.StatefulSet{}},
+ &appsv1.StatefulSet{}, &rbacv1.ClusterRole{}, &rbacv1.ClusterRoleBinding{}},
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
// when the Manager ends. This requires the binary to immediately end when the
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
From 6cd12143c8a7604c1141bf46fd2a479e58b97a23 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 29 Oct 2022 17:09:52 +0300
Subject: [PATCH 041/316] tmp disable clustevectorpipeline
Signed-off-by: Zemtsov Vladimir
---
.../clustervectorpipeline_controller.go | 25 +++++++++----------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
index f196f660..f785e859 100644
--- a/controllers/clustervectorpipeline_controller.go
+++ b/controllers/clustervectorpipeline_controller.go
@@ -19,7 +19,6 @@ package controllers
import (
"context"
- "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
@@ -102,18 +101,18 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, nil
}
-func (r *ClusterVectorPipelineReconciler) findClusterVectorPipelineCustomResourceInstance(ctx context.Context, req ctrl.Request) (*vectorv1alpha1.ClusterVectorPipeline, error) {
- // fetch the master instance
- cvp := &vectorv1alpha1.ClusterVectorPipeline{}
- err := r.Get(ctx, req.NamespacedName, cvp)
- if err != nil {
- if errors.IsNotFound(err) {
- return nil, nil
- }
- return nil, err
- }
- return cvp, nil
-}
+// func (r *ClusterVectorPipelineReconciler) findClusterVectorPipelineCustomResourceInstance(ctx context.Context, req ctrl.Request) (*vectorv1alpha1.ClusterVectorPipeline, error) {
+// // fetch the master instance
+// cvp := &vectorv1alpha1.ClusterVectorPipeline{}
+// err := r.Get(ctx, req.NamespacedName, cvp)
+// if err != nil {
+// if errors.IsNotFound(err) {
+// return nil, nil
+// }
+// return nil, err
+// }
+// return cvp, nil
+// }
// SetupWithManager sets up the controller with the Manager.
func (r *ClusterVectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
From feea3810aea50844b802f2c23cf5797cbe0fb0ce Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 29 Oct 2022 17:10:23 +0300
Subject: [PATCH 042/316] Fix return errors for fillConfigFile
Signed-off-by: Zemtsov Vladimir
---
controllers/vector_controller.go | 4 +++-
controllers/vectorpipeline_controller.go | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index efab81ab..608f9aaa 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -107,7 +107,9 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
if err != nil {
return ctrl.Result{}, err
}
- config.FillForVectorAgent()
+ if err := config.FillForVectorAgent(); err != nil {
+ return ctrl.Result{}, err
+ }
// Get Config in Json ([]byte)
byteConfig, err := config.GetByteConfig()
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 72791e69..6852e3ff 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -112,7 +112,9 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
if err != nil {
return ctrl.Result{}, err
}
- config.FillForVectorPipeline(pCtrl)
+ if err := config.FillForVectorPipeline(pCtrl); err != nil {
+ return ctrl.Result{}, err
+ }
// Get Config in Json ([]byte)
byteConfig, err := config.GetByteConfig()
From bef38a16fa931c59939a975de383a1ab14e622f8 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 29 Oct 2022 17:16:18 +0300
Subject: [PATCH 043/316] Fix testpackage error
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/utils/hash/hash_test.go | 5 +++--
controllers/factory/utils/k8s/k8s_test.go | 23 +++++++++++----------
2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/controllers/factory/utils/hash/hash_test.go b/controllers/factory/utils/hash/hash_test.go
index 615b676d..19dd69a0 100644
--- a/controllers/factory/utils/hash/hash_test.go
+++ b/controllers/factory/utils/hash/hash_test.go
@@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package hash
+package hash_test
import (
"testing"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/hash"
"github.com/stretchr/testify/require"
)
@@ -27,7 +28,7 @@ func TestGet(t *testing.T) {
return func(t *testing.T) {
req := require.New(t)
- result := Get(bytes)
+ result := hash.Get(bytes)
req.Equal(result, want)
}
}
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index ed31231d..ab45fbbf 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -14,7 +14,7 @@
// limitations under the License.
// */
-package k8s
+package k8s_test
import (
"context"
@@ -22,6 +22,7 @@ import (
// . "github.com/onsi/ginkgo/v2"
// . "github.com/onsi/gomega"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
@@ -45,7 +46,7 @@ func TestCreatePod(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := CreatePod(obj, cl)
+ err := k8s.CreatePod(obj, cl)
req.Equal(err, want)
}
}
@@ -94,7 +95,7 @@ func TestGetPod(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- result, err := GetPod(obj, cl)
+ result, err := k8s.GetPod(obj, cl)
if result != nil {
req.Equal(result.ObjectMeta, wantPod.ObjectMeta)
}
@@ -139,7 +140,7 @@ func TestUpdateStatus(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := UpdateStatus(context.Background(), obj, cl)
+ err := k8s.UpdateStatus(context.Background(), obj, cl)
req.Equal(err, want)
}
@@ -226,7 +227,7 @@ func TestCreateOrUpdateService(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := CreateOrUpdateService(obj, cl)
+ err := k8s.CreateOrUpdateService(obj, cl)
req.Equal(err, want)
}
@@ -276,7 +277,7 @@ func TestCreateOrUpdateSecret(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := CreateOrUpdateSecret(obj, cl)
+ err := k8s.CreateOrUpdateSecret(obj, cl)
req.Equal(err, want)
}
@@ -325,7 +326,7 @@ func TestCreateOrUpdateDaemonSet(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := CreateOrUpdateDaemonSet(obj, cl)
+ err := k8s.CreateOrUpdateDaemonSet(obj, cl)
req.Equal(err, want)
}
@@ -374,7 +375,7 @@ func TestCreateOrUpdateStatefulSet(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := CreateOrUpdateStatefulSet(obj, cl)
+ err := k8s.CreateOrUpdateStatefulSet(obj, cl)
req.Equal(err, want)
}
@@ -423,7 +424,7 @@ func TestCreateOrUpdateServiceAccount(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := CreateOrUpdateServiceAccount(obj, cl)
+ err := k8s.CreateOrUpdateServiceAccount(obj, cl)
req.Equal(err, want)
}
@@ -472,7 +473,7 @@ func TestCreateOrUpdateClusterRole(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := CreateOrUpdateClusterRole(obj, cl)
+ err := k8s.CreateOrUpdateClusterRole(obj, cl)
req.Equal(err, want)
}
@@ -521,7 +522,7 @@ func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := CreateOrUpdateClusterRoleBinding(obj, cl)
+ err := k8s.CreateOrUpdateClusterRoleBinding(obj, cl)
req.Equal(err, want)
}
From d54f4b02d3ab45be42c6cce7d1246b540333dd29 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 29 Oct 2022 17:18:15 +0300
Subject: [PATCH 044/316] Fix nosnakecase error
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/utils/k8s/k8s_test.go | 202 +++++++++++-----------
1 file changed, 101 insertions(+), 101 deletions(-)
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index ab45fbbf..ef3afa20 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -51,33 +51,33 @@ func TestCreatePod(t *testing.T) {
}
}
- obj_init := &corev1.Pod{
+ objInit := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
ResourceVersion: "",
},
}
- obj_case1 := &corev1.Pod{
+ objCase1 := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- obj_case2 := &corev1.Pod{
+ objCase2 := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- gr_case2 := schema.GroupResource{
+ grCase2 := schema.GroupResource{
Group: "",
Resource: "pods",
}
- error_case2 := apierrors.NewAlreadyExists(gr_case2, obj_case2.ObjectMeta.Name)
+ errorCase2 := apierrors.NewAlreadyExists(grCase2, objCase2.ObjectMeta.Name)
- t.Run("Create not exist pod case", createPodCase(obj_init, obj_case1, nil))
- t.Run("Create alredy exist pod case", createPodCase(obj_init, obj_case2, error_case2))
+ t.Run("Create not exist pod case", createPodCase(objInit, objCase1, nil))
+ t.Run("Create alredy exist pod case", createPodCase(objInit, objCase2, errorCase2))
}
// func CreatePod(pod *corev1.Pod, c client.Client) error {
@@ -103,34 +103,34 @@ func TestGetPod(t *testing.T) {
}
}
- obj_init := &corev1.Pod{
+ objInit := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
ResourceVersion: "",
},
}
- obj_case1 := &corev1.Pod{
+ objCase1 := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- gvr_case1 := schema.GroupVersionResource{
+ gvrCase1 := schema.GroupVersionResource{
Group: "",
Version: "v1",
Resource: "pods",
}
- error_case1 := apierrors.NewNotFound(gvr_case1.GroupResource(), obj_case1.ObjectMeta.Name)
- obj_case2 := &corev1.Pod{
+ errorCase1 := apierrors.NewNotFound(gvrCase1.GroupResource(), objCase1.ObjectMeta.Name)
+ objCase2 := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- t.Run("Get not exist pod case", getPodCase(obj_init, obj_case1, nil, error_case1))
- t.Run("Get exist pod case", getPodCase(obj_init, obj_case2, obj_init, nil))
+ t.Run("Get not exist pod case", getPodCase(objInit, objCase1, nil, errorCase1))
+ t.Run("Get exist pod case", getPodCase(objInit, objCase2, objInit, nil))
}
func TestUpdateStatus(t *testing.T) {
@@ -146,37 +146,37 @@ func TestUpdateStatus(t *testing.T) {
}
}
- obj_init := &corev1.Secret{
+ objInit := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
ResourceVersion: "",
},
}
- obj_case1 := &corev1.Service{
+ objCase1 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- obj_case2 := &corev1.Service{
+ objCase2 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- obj_case3 := &corev1.Service{
+ objCase3 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- obj_case4 := &corev1.Service{
+ objCase4 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{},
}
- error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- obj_case5 := &appsv1.Deployment{
+ objCase5 := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
@@ -185,14 +185,14 @@ func TestUpdateStatus(t *testing.T) {
Replicas: 10,
},
}
- gvr_case5 := schema.GroupVersionResource{
+ gvrCase5 := schema.GroupVersionResource{
Group: "apps",
Version: "v1",
Resource: "deployments",
}
- error_case5 := apierrors.NewNotFound(gvr_case5.GroupResource(), obj_case5.ObjectMeta.Name)
+ errorCase5 := apierrors.NewNotFound(gvrCase5.GroupResource(), objCase5.ObjectMeta.Name)
- init_obj_case6 := &appsv1.Deployment{
+ init_objCase6 := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
@@ -201,7 +201,7 @@ func TestUpdateStatus(t *testing.T) {
Replicas: 5,
},
}
- obj_case6 := &appsv1.Deployment{
+ objCase6 := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
@@ -211,12 +211,12 @@ func TestUpdateStatus(t *testing.T) {
},
}
- t.Run("Update Simple case", updateStatusCase(obj_init, obj_case1, nil))
- t.Run("Update Alredy exist case", updateStatusCase(obj_init, obj_case2, nil))
- t.Run("Update with Another Namespace case", updateStatusCase(obj_init, obj_case3, nil))
- t.Run("Update without Name case", updateStatusCase(obj_init, obj_case4, error_case4))
- t.Run("Update not exist Deployment with wrong init case", updateStatusCase(obj_init, obj_case5, error_case5))
- t.Run("Update Deployment case", updateStatusCase(init_obj_case6, obj_case6, nil))
+ t.Run("Update Simple case", updateStatusCase(objInit, objCase1, nil))
+ t.Run("Update Alredy exist case", updateStatusCase(objInit, objCase2, nil))
+ t.Run("Update with Another Namespace case", updateStatusCase(objInit, objCase3, nil))
+ t.Run("Update without Name case", updateStatusCase(objInit, objCase4, errorCase4))
+ t.Run("Update not exist Deployment with wrong init case", updateStatusCase(objInit, objCase5, errorCase5))
+ t.Run("Update Deployment case", updateStatusCase(init_objCase6, objCase6, nil))
}
@@ -233,7 +233,7 @@ func TestCreateOrUpdateService(t *testing.T) {
}
}
- service_init := &corev1.Service{
+ serviceInit := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
@@ -241,33 +241,33 @@ func TestCreateOrUpdateService(t *testing.T) {
},
}
- service_case1 := &corev1.Service{
+ serviceCase1 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- service_case2 := &corev1.Service{
+ serviceCase2 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- service_case3 := &corev1.Service{
+ serviceCase3 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- service_case4 := &corev1.Service{
+ serviceCase4 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{},
}
- error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileServiceCase(service_init, service_case1, nil))
- t.Run("Create Alredy exist case", reconcileServiceCase(service_init, service_case2, nil))
- t.Run("Create with Another Namespace case", reconcileServiceCase(service_init, service_case3, nil))
- t.Run("Create without Name case", reconcileServiceCase(service_init, service_case4, error_case4))
+ t.Run("Create Simple case", reconcileServiceCase(serviceInit, serviceCase1, nil))
+ t.Run("Create Alredy exist case", reconcileServiceCase(serviceInit, serviceCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileServiceCase(serviceInit, serviceCase3, nil))
+ t.Run("Create without Name case", reconcileServiceCase(serviceInit, serviceCase4, errorCase4))
}
func TestCreateOrUpdateSecret(t *testing.T) {
@@ -283,40 +283,40 @@ func TestCreateOrUpdateSecret(t *testing.T) {
}
}
- secret_init := &corev1.Secret{
+ secretInit := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- secret_case1 := &corev1.Secret{
+ secretCase1 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- secret_case2 := &corev1.Secret{
+ secretCase2 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- secret_case3 := &corev1.Secret{
+ secretCase3 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- secret_case4 := &corev1.Secret{
+ secretCase4 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{},
}
- error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileSecretCase(secret_init, secret_case1, nil))
- t.Run("Create Alredy exist case", reconcileSecretCase(secret_init, secret_case2, nil))
- t.Run("Create with Another Namespace case", reconcileSecretCase(secret_init, secret_case3, nil))
- t.Run("Create without Name case", reconcileSecretCase(secret_init, secret_case4, error_case4))
+ t.Run("Create Simple case", reconcileSecretCase(secretInit, secretCase1, nil))
+ t.Run("Create Alredy exist case", reconcileSecretCase(secretInit, secretCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileSecretCase(secretInit, secretCase3, nil))
+ t.Run("Create without Name case", reconcileSecretCase(secretInit, secretCase4, errorCase4))
}
func TestCreateOrUpdateDaemonSet(t *testing.T) {
@@ -332,40 +332,40 @@ func TestCreateOrUpdateDaemonSet(t *testing.T) {
}
}
- daemonSet_init := &appsv1.DaemonSet{
+ daemonSetInit := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- daemonSet_case1 := &appsv1.DaemonSet{
+ daemonSetCase1 := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- daemonSet_case2 := &appsv1.DaemonSet{
+ daemonSetCase2 := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- daemonSet_case3 := &appsv1.DaemonSet{
+ daemonSetCase3 := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- daemonSet_case4 := &appsv1.DaemonSet{
+ daemonSetCase4 := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{},
}
- error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileDaemonSetCase(daemonSet_init, daemonSet_case1, nil))
- t.Run("Create Alredy exist case", reconcileDaemonSetCase(daemonSet_init, daemonSet_case2, nil))
- t.Run("Create with Another Namespace case", reconcileDaemonSetCase(daemonSet_init, daemonSet_case3, nil))
- t.Run("Create without Name case", reconcileDaemonSetCase(daemonSet_init, daemonSet_case4, error_case4))
+ t.Run("Create Simple case", reconcileDaemonSetCase(daemonSetInit, daemonSetCase1, nil))
+ t.Run("Create Alredy exist case", reconcileDaemonSetCase(daemonSetInit, daemonSetCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileDaemonSetCase(daemonSetInit, daemonSetCase3, nil))
+ t.Run("Create without Name case", reconcileDaemonSetCase(daemonSetInit, daemonSetCase4, errorCase4))
}
func TestCreateOrUpdateStatefulSet(t *testing.T) {
@@ -381,40 +381,40 @@ func TestCreateOrUpdateStatefulSet(t *testing.T) {
}
}
- statefulSet_init := &appsv1.StatefulSet{
+ statefulSetInit := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- statefulSet_case1 := &appsv1.StatefulSet{
+ statefulSetCase1 := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- statefulSet_case2 := &appsv1.StatefulSet{
+ statefulSetCase2 := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- statefulSet_case3 := &appsv1.StatefulSet{
+ statefulSetCase3 := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- statefulSet_case4 := &appsv1.StatefulSet{
+ statefulSetCase4 := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{},
}
- error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileStatefulSetCase(statefulSet_init, statefulSet_case1, nil))
- t.Run("Create Alredy exist case", reconcileStatefulSetCase(statefulSet_init, statefulSet_case2, nil))
- t.Run("Create with Another Namespace case", reconcileStatefulSetCase(statefulSet_init, statefulSet_case3, nil))
- t.Run("Create without Name case", reconcileStatefulSetCase(statefulSet_init, statefulSet_case4, error_case4))
+ t.Run("Create Simple case", reconcileStatefulSetCase(statefulSetInit, statefulSetCase1, nil))
+ t.Run("Create Alredy exist case", reconcileStatefulSetCase(statefulSetInit, statefulSetCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileStatefulSetCase(statefulSetInit, statefulSetCase3, nil))
+ t.Run("Create without Name case", reconcileStatefulSetCase(statefulSetInit, statefulSetCase4, errorCase4))
}
func TestCreateOrUpdateServiceAccount(t *testing.T) {
@@ -430,40 +430,40 @@ func TestCreateOrUpdateServiceAccount(t *testing.T) {
}
}
- serviceAccount_init := &corev1.ServiceAccount{
+ serviceAccountInit := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- serviceAccount_case1 := &corev1.ServiceAccount{
+ serviceAccountCase1 := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- serviceAccount_case2 := &corev1.ServiceAccount{
+ serviceAccountCase2 := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- serviceAccount_case3 := &corev1.ServiceAccount{
+ serviceAccountCase3 := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- serviceAccount_case4 := &corev1.ServiceAccount{
+ serviceAccountCase4 := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{},
}
- error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileServiceAccountCase(serviceAccount_init, serviceAccount_case1, nil))
- t.Run("Create Alredy exist case", reconcileServiceAccountCase(serviceAccount_init, serviceAccount_case2, nil))
- t.Run("Create with Another Namespace case", reconcileServiceAccountCase(serviceAccount_init, serviceAccount_case3, nil))
- t.Run("Create without Name case", reconcileServiceAccountCase(serviceAccount_init, serviceAccount_case4, error_case4))
+ t.Run("Create Simple case", reconcileServiceAccountCase(serviceAccountInit, serviceAccountCase1, nil))
+ t.Run("Create Alredy exist case", reconcileServiceAccountCase(serviceAccountInit, serviceAccountCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileServiceAccountCase(serviceAccountInit, serviceAccountCase3, nil))
+ t.Run("Create without Name case", reconcileServiceAccountCase(serviceAccountInit, serviceAccountCase4, errorCase4))
}
func TestCreateOrUpdateClusterRole(t *testing.T) {
@@ -479,40 +479,40 @@ func TestCreateOrUpdateClusterRole(t *testing.T) {
}
}
- clusterRole_init := &rbacv1.ClusterRole{
+ clusterRoleInit := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- clusterRole_case1 := &rbacv1.ClusterRole{
+ clusterRoleCase1 := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- clusterRole_case2 := &rbacv1.ClusterRole{
+ clusterRoleCase2 := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- clusterRole_case3 := &rbacv1.ClusterRole{
+ clusterRoleCase3 := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- clusterRole_case4 := &rbacv1.ClusterRole{
+ clusterRoleCase4 := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{},
}
- error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileClusterRole(clusterRole_init, clusterRole_case1, nil))
- t.Run("Create Alredy exist case", reconcileClusterRole(clusterRole_init, clusterRole_case2, nil))
- t.Run("Create with Another Namespace case", reconcileClusterRole(clusterRole_init, clusterRole_case3, nil))
- t.Run("Create without Name case", reconcileClusterRole(clusterRole_init, clusterRole_case4, error_case4))
+ t.Run("Create Simple case", reconcileClusterRole(clusterRoleInit, clusterRoleCase1, nil))
+ t.Run("Create Alredy exist case", reconcileClusterRole(clusterRoleInit, clusterRoleCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileClusterRole(clusterRoleInit, clusterRoleCase3, nil))
+ t.Run("Create without Name case", reconcileClusterRole(clusterRoleInit, clusterRoleCase4, errorCase4))
}
func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
@@ -528,38 +528,38 @@ func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
}
}
- clusterRoleBinding_init := &rbacv1.ClusterRoleBinding{
+ clusterRoleBindingInit := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- clusterRoleBinding_case1 := &rbacv1.ClusterRoleBinding{
+ clusterRoleBindingCase1 := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- clusterRoleBinding_case2 := &rbacv1.ClusterRoleBinding{
+ clusterRoleBindingCase2 := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- clusterRoleBinding_case3 := &rbacv1.ClusterRoleBinding{
+ clusterRoleBindingCase3 := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- clusterRoleBinding_case4 := &rbacv1.ClusterRoleBinding{
+ clusterRoleBindingCase4 := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{},
}
- error_case4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileClusterRoleBinding(clusterRoleBinding_init, clusterRoleBinding_case1, nil))
- t.Run("Create Alredy exist case", reconcileClusterRoleBinding(clusterRoleBinding_init, clusterRoleBinding_case2, nil))
- t.Run("Create with Another Namespace case", reconcileClusterRoleBinding(clusterRoleBinding_init, clusterRoleBinding_case3, nil))
- t.Run("Create without Name case", reconcileClusterRoleBinding(clusterRoleBinding_init, clusterRoleBinding_case4, error_case4))
+ t.Run("Create Simple case", reconcileClusterRoleBinding(clusterRoleBindingInit, clusterRoleBindingCase1, nil))
+ t.Run("Create Alredy exist case", reconcileClusterRoleBinding(clusterRoleBindingInit, clusterRoleBindingCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileClusterRoleBinding(clusterRoleBindingInit, clusterRoleBindingCase3, nil))
+ t.Run("Create without Name case", reconcileClusterRoleBinding(clusterRoleBindingInit, clusterRoleBindingCase4, errorCase4))
}
From 16abb70c6d85e7237d1aa66af13746761fa09c08 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 29 Oct 2022 17:36:59 +0300
Subject: [PATCH 045/316] Add reconcileObjectCase for k8s-test
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/utils/k8s/k8s_test.go | 501 ++++++++++------------
1 file changed, 238 insertions(+), 263 deletions(-)
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index ef3afa20..9ac356ca 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -39,527 +39,502 @@ import (
// *corev1.Service | *corev1.Secret | *appsv1.DaemonSet | *appsv1.StatefulSet | *corev1.ServiceAccount | *rbacv1.ClusterRole | *rbacv1.ClusterRoleBinding
// }
-func TestCreatePod(t *testing.T) {
- createPodCase := func(objInit, obj *corev1.Pod, want error) func(t *testing.T) {
- return func(t *testing.T) {
- req := require.New(t)
+var reconcileObjectCase = func(objInit, obj interface{}, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ t.Helper()
+ req := require.New(t)
+
+ switch obj.(type) {
+ case *corev1.Service:
+ serviceInit := objInit.(*corev1.Service)
+ service := obj.(*corev1.Service)
+
+ cl := fake.NewClientBuilder().WithObjects(serviceInit).Build()
+ err := k8s.CreateOrUpdateService(service, cl)
+ req.Equal(err, want)
+ case *corev1.Secret:
+ secretInit := objInit.(*corev1.Secret)
+ secret := obj.(*corev1.Secret)
- cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+ cl := fake.NewClientBuilder().WithObjects(secretInit).Build()
+ err := k8s.CreateOrUpdateSecret(secret, cl)
+ req.Equal(err, want)
+ case *appsv1.DaemonSet:
+ daemonSetInit := objInit.(*appsv1.DaemonSet)
+ daemonSet := obj.(*appsv1.DaemonSet)
- err := k8s.CreatePod(obj, cl)
+ cl := fake.NewClientBuilder().WithObjects(daemonSetInit).Build()
+ err := k8s.CreateOrUpdateDaemonSet(daemonSet, cl)
+ req.Equal(err, want)
+ case *appsv1.StatefulSet:
+ statefulSetInit := objInit.(*appsv1.StatefulSet)
+ statefulSet := obj.(*appsv1.StatefulSet)
+
+ cl := fake.NewClientBuilder().WithObjects(statefulSetInit).Build()
+ err := k8s.CreateOrUpdateStatefulSet(statefulSet, cl)
+ req.Equal(err, want)
+ case *corev1.ServiceAccount:
+ serviceAccountInit := objInit.(*corev1.ServiceAccount)
+ serviceAccount := obj.(*corev1.ServiceAccount)
+
+ cl := fake.NewClientBuilder().WithObjects(serviceAccountInit).Build()
+ err := k8s.CreateOrUpdateServiceAccount(serviceAccount, cl)
+ req.Equal(err, want)
+ case *rbacv1.ClusterRole:
+ clusterRoleInit := objInit.(*rbacv1.ClusterRole)
+ clusterRole := obj.(*rbacv1.ClusterRole)
+
+ cl := fake.NewClientBuilder().WithObjects(clusterRoleInit).Build()
+ err := k8s.CreateOrUpdateClusterRole(clusterRole, cl)
+ req.Equal(err, want)
+ case *rbacv1.ClusterRoleBinding:
+ clusterRoleBindingInit := objInit.(*rbacv1.ClusterRoleBinding)
+ clusterRoleBinding := obj.(*rbacv1.ClusterRoleBinding)
+
+ cl := fake.NewClientBuilder().WithObjects(clusterRoleBindingInit).Build()
+ err := k8s.CreateOrUpdateClusterRoleBinding(clusterRoleBinding, cl)
req.Equal(err, want)
}
}
+}
- objInit := &corev1.Pod{
+func TestCreateOrUpdateService(t *testing.T) {
+ serviceInit := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
ResourceVersion: "",
},
}
- objCase1 := &corev1.Pod{
+
+ serviceCase1 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- objCase2 := &corev1.Pod{
+ serviceCase2 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- grCase2 := schema.GroupResource{
- Group: "",
- Resource: "pods",
+ serviceCase3 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
}
- errorCase2 := apierrors.NewAlreadyExists(grCase2, objCase2.ObjectMeta.Name)
+ serviceCase4 := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create not exist pod case", createPodCase(objInit, objCase1, nil))
- t.Run("Create alredy exist pod case", createPodCase(objInit, objCase2, errorCase2))
+ t.Run("Create Simple case", reconcileObjectCase(serviceInit, serviceCase1, nil))
+ t.Run("Create Alredy exist case", reconcileObjectCase(serviceInit, serviceCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileObjectCase(serviceInit, serviceCase3, nil))
+ t.Run("Create without Name case", reconcileObjectCase(serviceInit, serviceCase4, errorCase4))
}
-// func CreatePod(pod *corev1.Pod, c client.Client) error {
-// err := c.Create(context.TODO(), pod)
-// if err != nil {
-// return err
-// }
-// return nil
-// }
-
-func TestGetPod(t *testing.T) {
- getPodCase := func(objInit, obj, wantPod *corev1.Pod, want error) func(t *testing.T) {
- return func(t *testing.T) {
- req := require.New(t)
-
- cl := fake.NewClientBuilder().WithObjects(objInit).Build()
-
- result, err := k8s.GetPod(obj, cl)
- if result != nil {
- req.Equal(result.ObjectMeta, wantPod.ObjectMeta)
- }
- req.Equal(err, want)
- }
- }
-
- objInit := &corev1.Pod{
+func TestCreateOrUpdateSecret(t *testing.T) {
+ secretInit := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- ResourceVersion: "",
+ Name: "init",
+ Namespace: "test-namespace",
},
}
- objCase1 := &corev1.Pod{
+
+ secretCase1 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- gvrCase1 := schema.GroupVersionResource{
- Group: "",
- Version: "v1",
- Resource: "pods",
- }
- errorCase1 := apierrors.NewNotFound(gvrCase1.GroupResource(), objCase1.ObjectMeta.Name)
- objCase2 := &corev1.Pod{
+ secretCase2 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
+ secretCase3 := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ }
+ secretCase4 := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Get not exist pod case", getPodCase(objInit, objCase1, nil, errorCase1))
- t.Run("Get exist pod case", getPodCase(objInit, objCase2, objInit, nil))
+ t.Run("Create Simple case", reconcileObjectCase(secretInit, secretCase1, nil))
+ t.Run("Create Alredy exist case", reconcileObjectCase(secretInit, secretCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileObjectCase(secretInit, secretCase3, nil))
+ t.Run("Create without Name case", reconcileObjectCase(secretInit, secretCase4, errorCase4))
}
-func TestUpdateStatus(t *testing.T) {
- updateStatusCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
- return func(t *testing.T) {
- req := require.New(t)
-
- cl := fake.NewClientBuilder().WithObjects(objInit).Build()
-
- err := k8s.UpdateStatus(context.Background(), obj, cl)
-
- req.Equal(err, want)
- }
- }
-
- objInit := &corev1.Secret{
+func TestCreateOrUpdateDaemonSet(t *testing.T) {
+ daemonSetInit := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- ResourceVersion: "",
+ Name: "init",
+ Namespace: "test-namespace",
},
}
- objCase1 := &corev1.Service{
+
+ daemonSetCase1 := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- objCase2 := &corev1.Service{
+ daemonSetCase2 := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- objCase3 := &corev1.Service{
+ daemonSetCase3 := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- objCase4 := &corev1.Service{
+ daemonSetCase4 := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{},
}
errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- objCase5 := &appsv1.Deployment{
+ t.Run("Create Simple case", reconcileObjectCase(daemonSetInit, daemonSetCase1, nil))
+ t.Run("Create Alredy exist case", reconcileObjectCase(daemonSetInit, daemonSetCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileObjectCase(daemonSetInit, daemonSetCase3, nil))
+ t.Run("Create without Name case", reconcileObjectCase(daemonSetInit, daemonSetCase4, errorCase4))
+}
+
+func TestCreateOrUpdateStatefulSet(t *testing.T) {
+ statefulSetInit := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
- Name: "test",
+ Name: "init",
Namespace: "test-namespace",
},
- Status: appsv1.DeploymentStatus{
- Replicas: 10,
- },
- }
- gvrCase5 := schema.GroupVersionResource{
- Group: "apps",
- Version: "v1",
- Resource: "deployments",
}
- errorCase5 := apierrors.NewNotFound(gvrCase5.GroupResource(), objCase5.ObjectMeta.Name)
- init_objCase6 := &appsv1.Deployment{
+ statefulSetCase1 := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
- Status: appsv1.DeploymentStatus{
- Replicas: 5,
- },
}
- objCase6 := &appsv1.Deployment{
+ statefulSetCase2 := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
- Name: "test",
+ Name: "init",
Namespace: "test-namespace",
},
- Status: appsv1.DeploymentStatus{
- Replicas: 10,
+ }
+ statefulSetCase3 := &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
},
}
+ statefulSetCase4 := &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{},
+ }
+ errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Update Simple case", updateStatusCase(objInit, objCase1, nil))
- t.Run("Update Alredy exist case", updateStatusCase(objInit, objCase2, nil))
- t.Run("Update with Another Namespace case", updateStatusCase(objInit, objCase3, nil))
- t.Run("Update without Name case", updateStatusCase(objInit, objCase4, errorCase4))
- t.Run("Update not exist Deployment with wrong init case", updateStatusCase(objInit, objCase5, errorCase5))
- t.Run("Update Deployment case", updateStatusCase(init_objCase6, objCase6, nil))
-
+ t.Run("Create Simple case", reconcileObjectCase(statefulSetInit, statefulSetCase1, nil))
+ t.Run("Create Alredy exist case", reconcileObjectCase(statefulSetInit, statefulSetCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileObjectCase(statefulSetInit, statefulSetCase3, nil))
+ t.Run("Create without Name case", reconcileObjectCase(statefulSetInit, statefulSetCase4, errorCase4))
}
-func TestCreateOrUpdateService(t *testing.T) {
- reconcileServiceCase := func(objInit, obj *corev1.Service, want error) func(t *testing.T) {
- return func(t *testing.T) {
- req := require.New(t)
-
- cl := fake.NewClientBuilder().WithObjects(objInit).Build()
-
- err := k8s.CreateOrUpdateService(obj, cl)
-
- req.Equal(err, want)
- }
- }
-
- serviceInit := &corev1.Service{
+func TestCreateOrUpdateServiceAccount(t *testing.T) {
+ serviceAccountInit := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- ResourceVersion: "",
+ Name: "init",
+ Namespace: "test-namespace",
},
}
- serviceCase1 := &corev1.Service{
+ serviceAccountCase1 := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- serviceCase2 := &corev1.Service{
+ serviceAccountCase2 := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- serviceCase3 := &corev1.Service{
+ serviceAccountCase3 := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- serviceCase4 := &corev1.Service{
+ serviceAccountCase4 := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{},
}
errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileServiceCase(serviceInit, serviceCase1, nil))
- t.Run("Create Alredy exist case", reconcileServiceCase(serviceInit, serviceCase2, nil))
- t.Run("Create with Another Namespace case", reconcileServiceCase(serviceInit, serviceCase3, nil))
- t.Run("Create without Name case", reconcileServiceCase(serviceInit, serviceCase4, errorCase4))
+ t.Run("Create Simple case", reconcileObjectCase(serviceAccountInit, serviceAccountCase1, nil))
+ t.Run("Create Alredy exist case", reconcileObjectCase(serviceAccountInit, serviceAccountCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileObjectCase(serviceAccountInit, serviceAccountCase3, nil))
+ t.Run("Create without Name case", reconcileObjectCase(serviceAccountInit, serviceAccountCase4, errorCase4))
}
-func TestCreateOrUpdateSecret(t *testing.T) {
- reconcileSecretCase := func(objInit, obj *corev1.Secret, want error) func(t *testing.T) {
- return func(t *testing.T) {
- req := require.New(t)
-
- cl := fake.NewClientBuilder().WithObjects(objInit).Build()
-
- err := k8s.CreateOrUpdateSecret(obj, cl)
-
- req.Equal(err, want)
- }
- }
-
- secretInit := &corev1.Secret{
+func TestCreateOrUpdateClusterRole(t *testing.T) {
+ clusterRoleInit := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- secretCase1 := &corev1.Secret{
+ clusterRoleCase1 := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- secretCase2 := &corev1.Secret{
+ clusterRoleCase2 := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- secretCase3 := &corev1.Secret{
+ clusterRoleCase3 := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- secretCase4 := &corev1.Secret{
+ clusterRoleCase4 := &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{},
}
errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileSecretCase(secretInit, secretCase1, nil))
- t.Run("Create Alredy exist case", reconcileSecretCase(secretInit, secretCase2, nil))
- t.Run("Create with Another Namespace case", reconcileSecretCase(secretInit, secretCase3, nil))
- t.Run("Create without Name case", reconcileSecretCase(secretInit, secretCase4, errorCase4))
+ t.Run("Create Simple case", reconcileObjectCase(clusterRoleInit, clusterRoleCase1, nil))
+ t.Run("Create Alredy exist case", reconcileObjectCase(clusterRoleInit, clusterRoleCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileObjectCase(clusterRoleInit, clusterRoleCase3, nil))
+ t.Run("Create without Name case", reconcileObjectCase(clusterRoleInit, clusterRoleCase4, errorCase4))
}
-func TestCreateOrUpdateDaemonSet(t *testing.T) {
- reconcileDaemonSetCase := func(objInit, obj *appsv1.DaemonSet, want error) func(t *testing.T) {
- return func(t *testing.T) {
- req := require.New(t)
-
- cl := fake.NewClientBuilder().WithObjects(objInit).Build()
-
- err := k8s.CreateOrUpdateDaemonSet(obj, cl)
-
- req.Equal(err, want)
- }
- }
-
- daemonSetInit := &appsv1.DaemonSet{
+func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
+ clusterRoleBindingInit := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- daemonSetCase1 := &appsv1.DaemonSet{
+ clusterRoleBindingCase1 := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- daemonSetCase2 := &appsv1.DaemonSet{
+ clusterRoleBindingCase2 := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- daemonSetCase3 := &appsv1.DaemonSet{
+ clusterRoleBindingCase3 := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- daemonSetCase4 := &appsv1.DaemonSet{
+ clusterRoleBindingCase4 := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{},
}
errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileDaemonSetCase(daemonSetInit, daemonSetCase1, nil))
- t.Run("Create Alredy exist case", reconcileDaemonSetCase(daemonSetInit, daemonSetCase2, nil))
- t.Run("Create with Another Namespace case", reconcileDaemonSetCase(daemonSetInit, daemonSetCase3, nil))
- t.Run("Create without Name case", reconcileDaemonSetCase(daemonSetInit, daemonSetCase4, errorCase4))
+ t.Run("Create Simple case", reconcileObjectCase(clusterRoleBindingInit, clusterRoleBindingCase1, nil))
+ t.Run("Create Alredy exist case", reconcileObjectCase(clusterRoleBindingInit, clusterRoleBindingCase2, nil))
+ t.Run("Create with Another Namespace case", reconcileObjectCase(clusterRoleBindingInit, clusterRoleBindingCase3, nil))
+ t.Run("Create without Name case", reconcileObjectCase(clusterRoleBindingInit, clusterRoleBindingCase4, errorCase4))
}
-func TestCreateOrUpdateStatefulSet(t *testing.T) {
- reconcileStatefulSetCase := func(objInit, obj *appsv1.StatefulSet, want error) func(t *testing.T) {
+func TestCreatePod(t *testing.T) {
+ createPodCase := func(objInit, obj *corev1.Pod, want error) func(t *testing.T) {
return func(t *testing.T) {
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := k8s.CreateOrUpdateStatefulSet(obj, cl)
-
+ err := k8s.CreatePod(obj, cl)
req.Equal(err, want)
}
}
- statefulSetInit := &appsv1.StatefulSet{
+ objInit := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
+ Name: "init",
+ Namespace: "test-namespace",
+ ResourceVersion: "",
},
}
-
- statefulSetCase1 := &appsv1.StatefulSet{
+ objCase1 := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- statefulSetCase2 := &appsv1.StatefulSet{
+ objCase2 := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- statefulSetCase3 := &appsv1.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
- }
- statefulSetCase4 := &appsv1.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{},
+ grCase2 := schema.GroupResource{
+ Group: "",
+ Resource: "pods",
}
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
+ errorCase2 := apierrors.NewAlreadyExists(grCase2, objCase2.ObjectMeta.Name)
- t.Run("Create Simple case", reconcileStatefulSetCase(statefulSetInit, statefulSetCase1, nil))
- t.Run("Create Alredy exist case", reconcileStatefulSetCase(statefulSetInit, statefulSetCase2, nil))
- t.Run("Create with Another Namespace case", reconcileStatefulSetCase(statefulSetInit, statefulSetCase3, nil))
- t.Run("Create without Name case", reconcileStatefulSetCase(statefulSetInit, statefulSetCase4, errorCase4))
+ t.Run("Create not exist pod case", createPodCase(objInit, objCase1, nil))
+ t.Run("Create alredy exist pod case", createPodCase(objInit, objCase2, errorCase2))
}
-func TestCreateOrUpdateServiceAccount(t *testing.T) {
- reconcileServiceAccountCase := func(objInit, obj *corev1.ServiceAccount, want error) func(t *testing.T) {
+// func CreatePod(pod *corev1.Pod, c client.Client) error {
+// err := c.Create(context.TODO(), pod)
+// if err != nil {
+// return err
+// }
+// return nil
+// }
+
+func TestGetPod(t *testing.T) {
+ getPodCase := func(objInit, obj, wantPod *corev1.Pod, want error) func(t *testing.T) {
return func(t *testing.T) {
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := k8s.CreateOrUpdateServiceAccount(obj, cl)
-
+ result, err := k8s.GetPod(obj, cl)
+ if result != nil {
+ req.Equal(result.ObjectMeta, wantPod.ObjectMeta)
+ }
req.Equal(err, want)
}
}
- serviceAccountInit := &corev1.ServiceAccount{
+ objInit := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
+ Name: "init",
+ Namespace: "test-namespace",
+ ResourceVersion: "",
},
}
-
- serviceAccountCase1 := &corev1.ServiceAccount{
+ objCase1 := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- serviceAccountCase2 := &corev1.ServiceAccount{
+ gvrCase1 := schema.GroupVersionResource{
+ Group: "",
+ Version: "v1",
+ Resource: "pods",
+ }
+ errorCase1 := apierrors.NewNotFound(gvrCase1.GroupResource(), objCase1.ObjectMeta.Name)
+ objCase2 := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- serviceAccountCase3 := &corev1.ServiceAccount{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
- }
- serviceAccountCase4 := &corev1.ServiceAccount{
- ObjectMeta: metav1.ObjectMeta{},
- }
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileServiceAccountCase(serviceAccountInit, serviceAccountCase1, nil))
- t.Run("Create Alredy exist case", reconcileServiceAccountCase(serviceAccountInit, serviceAccountCase2, nil))
- t.Run("Create with Another Namespace case", reconcileServiceAccountCase(serviceAccountInit, serviceAccountCase3, nil))
- t.Run("Create without Name case", reconcileServiceAccountCase(serviceAccountInit, serviceAccountCase4, errorCase4))
+ t.Run("Get not exist pod case", getPodCase(objInit, objCase1, nil, errorCase1))
+ t.Run("Get exist pod case", getPodCase(objInit, objCase2, objInit, nil))
}
-func TestCreateOrUpdateClusterRole(t *testing.T) {
- reconcileClusterRole := func(objInit, obj *rbacv1.ClusterRole, want error) func(t *testing.T) {
+func TestUpdateStatus(t *testing.T) {
+ updateStatusCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
return func(t *testing.T) {
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := k8s.CreateOrUpdateClusterRole(obj, cl)
+ err := k8s.UpdateStatus(context.Background(), obj, cl)
req.Equal(err, want)
}
}
- clusterRoleInit := &rbacv1.ClusterRole{
+ objInit := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
+ Name: "init",
+ Namespace: "test-namespace",
+ ResourceVersion: "",
},
}
-
- clusterRoleCase1 := &rbacv1.ClusterRole{
+ objCase1 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
}
- clusterRoleCase2 := &rbacv1.ClusterRole{
+ objCase2 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "init",
Namespace: "test-namespace",
},
}
- clusterRoleCase3 := &rbacv1.ClusterRole{
+ objCase3 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
}
- clusterRoleCase4 := &rbacv1.ClusterRole{
+ objCase4 := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{},
}
errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileClusterRole(clusterRoleInit, clusterRoleCase1, nil))
- t.Run("Create Alredy exist case", reconcileClusterRole(clusterRoleInit, clusterRoleCase2, nil))
- t.Run("Create with Another Namespace case", reconcileClusterRole(clusterRoleInit, clusterRoleCase3, nil))
- t.Run("Create without Name case", reconcileClusterRole(clusterRoleInit, clusterRoleCase4, errorCase4))
-}
-
-func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
- reconcileClusterRoleBinding := func(objInit, obj *rbacv1.ClusterRoleBinding, want error) func(t *testing.T) {
- return func(t *testing.T) {
- req := require.New(t)
-
- cl := fake.NewClientBuilder().WithObjects(objInit).Build()
-
- err := k8s.CreateOrUpdateClusterRoleBinding(obj, cl)
-
- req.Equal(err, want)
- }
- }
-
- clusterRoleBindingInit := &rbacv1.ClusterRoleBinding{
+ objCase5 := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
+ Name: "test",
Namespace: "test-namespace",
},
+ Status: appsv1.DeploymentStatus{
+ Replicas: 10,
+ },
+ }
+ gvrCase5 := schema.GroupVersionResource{
+ Group: "apps",
+ Version: "v1",
+ Resource: "deployments",
}
+ errorCase5 := apierrors.NewNotFound(gvrCase5.GroupResource(), objCase5.ObjectMeta.Name)
- clusterRoleBindingCase1 := &rbacv1.ClusterRoleBinding{
+ init_objCase6 := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
- }
- clusterRoleBindingCase2 := &rbacv1.ClusterRoleBinding{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
+ Status: appsv1.DeploymentStatus{
+ Replicas: 5,
},
}
- clusterRoleBindingCase3 := &rbacv1.ClusterRoleBinding{
+ objCase6 := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
- Namespace: "test-namespace2",
+ Namespace: "test-namespace",
+ },
+ Status: appsv1.DeploymentStatus{
+ Replicas: 10,
},
}
- clusterRoleBindingCase4 := &rbacv1.ClusterRoleBinding{
- ObjectMeta: metav1.ObjectMeta{},
- }
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
- t.Run("Create Simple case", reconcileClusterRoleBinding(clusterRoleBindingInit, clusterRoleBindingCase1, nil))
- t.Run("Create Alredy exist case", reconcileClusterRoleBinding(clusterRoleBindingInit, clusterRoleBindingCase2, nil))
- t.Run("Create with Another Namespace case", reconcileClusterRoleBinding(clusterRoleBindingInit, clusterRoleBindingCase3, nil))
- t.Run("Create without Name case", reconcileClusterRoleBinding(clusterRoleBindingInit, clusterRoleBindingCase4, errorCase4))
+ t.Run("Update Simple case", updateStatusCase(objInit, objCase1, nil))
+ t.Run("Update Alredy exist case", updateStatusCase(objInit, objCase2, nil))
+ t.Run("Update with Another Namespace case", updateStatusCase(objInit, objCase3, nil))
+ t.Run("Update without Name case", updateStatusCase(objInit, objCase4, errorCase4))
+ t.Run("Update not exist Deployment with wrong init case", updateStatusCase(objInit, objCase5, errorCase5))
+ t.Run("Update Deployment case", updateStatusCase(init_objCase6, objCase6, nil))
+
}
From 19c557262848389773147b917b755621cc12f2c9 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 29 Oct 2022 17:38:55 +0300
Subject: [PATCH 046/316] Add t.Helper()
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/utils/hash/hash_test.go | 1 +
controllers/factory/utils/k8s/k8s_test.go | 3 +++
2 files changed, 4 insertions(+)
diff --git a/controllers/factory/utils/hash/hash_test.go b/controllers/factory/utils/hash/hash_test.go
index 19dd69a0..950a06f9 100644
--- a/controllers/factory/utils/hash/hash_test.go
+++ b/controllers/factory/utils/hash/hash_test.go
@@ -26,6 +26,7 @@ import (
func TestGet(t *testing.T) {
hashCase := func(bytes []byte, want uint32) func(t *testing.T) {
return func(t *testing.T) {
+ t.Helper()
req := require.New(t)
result := hash.Get(bytes)
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index 9ac356ca..1683aa38 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -361,6 +361,7 @@ func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
func TestCreatePod(t *testing.T) {
createPodCase := func(objInit, obj *corev1.Pod, want error) func(t *testing.T) {
return func(t *testing.T) {
+ t.Helper()
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
@@ -410,6 +411,7 @@ func TestCreatePod(t *testing.T) {
func TestGetPod(t *testing.T) {
getPodCase := func(objInit, obj, wantPod *corev1.Pod, want error) func(t *testing.T) {
return func(t *testing.T) {
+ t.Helper()
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
@@ -455,6 +457,7 @@ func TestGetPod(t *testing.T) {
func TestUpdateStatus(t *testing.T) {
updateStatusCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
return func(t *testing.T) {
+ t.Helper()
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
From 973021741316b11219ba240afb1fbb44932d4cee Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 08:30:25 +0300
Subject: [PATCH 047/316] Fix varnamelen
Signed-off-by: Zemtsov Vladimir
---
controllers/vector_controller.go | 16 ++++++++--------
controllers/vectorpipeline_controller.go | 18 +++++++++---------
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 608f9aaa..18699f0a 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -60,27 +60,27 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
log.Info("start Reconcile Vector")
- v, err := r.findVectorCustomResourceInstance(ctx, req)
+ vectorCR, err := r.findVectorCustomResourceInstance(ctx, req)
if err != nil {
log.Error(err, "Failed to get Vector")
return ctrl.Result{}, err
}
- if v == nil {
+ if vectorCR == nil {
log.Info("Vector CR not found. Ignoring since object must be deleted")
return ctrl.Result{}, nil
}
- if v.Spec.Agent.DataDir == "" {
- v.Spec.Agent.DataDir = "/vector-data-dir"
+ if vectorCR.Spec.Agent.DataDir == "" {
+ vectorCR.Spec.Agent.DataDir = "/vector-data-dir"
}
- return r.CreateOrUpdateVector(ctx, v)
+ return r.CreateOrUpdateVector(ctx, vectorCR)
}
func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context, req ctrl.Request) (*vectorv1alpha1.Vector, error) {
// fetch the master instance
- v := &vectorv1alpha1.Vector{}
- err := r.Get(ctx, req.NamespacedName, v)
+ vectorCR := &vectorv1alpha1.Vector{}
+ err := r.Get(ctx, req.NamespacedName, vectorCR)
if err != nil {
if errors.IsNotFound(err) {
return nil, nil
@@ -88,7 +88,7 @@ func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context,
return nil, err
}
- return v, nil
+ return vectorCR, nil
}
// SetupWithManager sets up the controller with the Manager.
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 6852e3ff..c4db42bb 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -62,18 +62,18 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
log.Info("start Reconcile VectorPipeline")
// Get CR VectorPipeline
- vp, err := r.findVectorPipelineCustomResourceInstance(ctx, req)
+ vectorPipelineCR, err := r.findVectorPipelineCustomResourceInstance(ctx, req)
if err != nil {
log.Error(err, "Failed to get Vector Pipeline")
return ctrl.Result{}, err
}
- if vp == nil {
+ if vectorPipelineCR == nil {
log.Info("VectorPIpeline CR not found. Ignoring since object must be deleted")
return ctrl.Result{}, nil
}
// Generate VectorPipeline Controller
- vpCtrl := vectorpipeline.NewController(vp)
+ vpCtrl := vectorpipeline.NewController(vectorPipelineCR)
// Generate Pipeline Controller
pCtrl := pipeline.NewController(ctx, r.Client, vpCtrl)
@@ -99,13 +99,13 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, nil
}
- for _, v := range vectorInstances.Items {
- if v.DeletionTimestamp != nil {
+ for _, vector := range vectorInstances.Items {
+ if vector.DeletionTimestamp != nil {
continue
}
// Init Controller for Vector Agent
- vaCtrl := vectoragent.NewController(&v, r.Client, r.Clientset)
+ vaCtrl := vectoragent.NewController(&vector, r.Client, r.Clientset)
// Get Vector Config file
config, err := config.New(ctx, vaCtrl)
@@ -156,15 +156,15 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
func (r *VectorPipelineReconciler) findVectorPipelineCustomResourceInstance(ctx context.Context, req ctrl.Request) (*vectorv1alpha1.VectorPipeline, error) {
// fetch the master instance
- vp := &vectorv1alpha1.VectorPipeline{}
- err := r.Get(ctx, req.NamespacedName, vp)
+ vectorPipelineCR := &vectorv1alpha1.VectorPipeline{}
+ err := r.Get(ctx, req.NamespacedName, vectorPipelineCR)
if err != nil {
if errors.IsNotFound(err) {
return nil, nil
}
return nil, err
}
- return vp, nil
+ return vectorPipelineCR, nil
}
// SetupWithManager sets up the controller with the Manager.
From 7e5a69f158e5577a9ee8621ead6ebe87e18fb6c1 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 31 Oct 2022 10:59:59 +0300
Subject: [PATCH 048/316] refactor config struct (#23)
---
controllers/factory/config/config.go | 45 ++++++++++++++++++-
controllers/factory/config/config_build.go | 52 +++++++++-------------
controllers/factory/vector/types.go | 10 ++---
controllers/factory/vector/vector.go | 4 +-
controllers/vector_controller.go | 4 +-
5 files changed, 76 insertions(+), 39 deletions(-)
diff --git a/controllers/factory/config/config.go b/controllers/factory/config/config.go
index 8abb097d..da4f8159 100644
--- a/controllers/factory/config/config.go
+++ b/controllers/factory/config/config.go
@@ -23,6 +23,7 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector"
"github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
+ "github.com/mitchellh/mapstructure"
)
type Config struct {
@@ -77,10 +78,52 @@ func (cfg *Config) FillForVectorPipeline(vCtrl *pipeline.Controller) error {
}
func (cfg *Config) GetByteConfig() ([]byte, error) {
- data, err := json.Marshal(cfg.VectorConfig)
+ cfgMap, err := CfgToMap(*cfg.VectorConfig)
+ if err != nil {
+ return nil, err
+ }
+ data, err := json.Marshal(cfgMap)
if err != nil {
return nil, err
}
return data, nil
}
+
+func CfgToMap(cfg vector.VectorConfig) (cfgMap map[string]interface{}, err error) {
+ sources := make(map[string]interface{})
+ transforms := make(map[string]interface{})
+ sinks := make(map[string]interface{})
+ for _, source := range cfg.Sources {
+ spec, err := vector.Mapper(source)
+ if err != nil {
+ return nil, err
+ }
+ sources[source.Name] = spec
+ }
+ for _, transform := range cfg.Transforms {
+ spec, err := vector.Mapper(transform)
+ if err != nil {
+ return nil, err
+ }
+ transforms[transform.Name] = spec
+ }
+ for _, sink := range cfg.Sinks {
+ spec, err := vector.Mapper(sink)
+ if err != nil {
+ return nil, err
+ }
+ sinks[sink.Name] = spec
+ }
+
+ err = mapstructure.Decode(cfg, &cfgMap)
+ if err != nil {
+ return nil, err
+ }
+ // TODO: remove hardcoded map keys
+ cfgMap["sources"] = sources
+ cfgMap["transforms"] = transforms
+ cfgMap["sinks"] = sinks
+
+ return cfgMap, nil
+}
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index 7672fe7c..e5a8ce80 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -21,18 +21,16 @@ import (
)
var (
- sourceDefault = map[string]interface{}{
- "defaultSource": map[string]string{
- "type": "kubernetes_logs",
- },
+ sourceDefault = vector.Source{
+ Name: "defaultSource",
+ Type: "kubernetes_logs",
}
-
- rate int32 = 100
- sinkDefault = map[string]interface{}{
- "defaultSink": map[string]interface{}{
- "type": "blackhole",
- "inputs": []string{"defaultSource"},
- "rate": rate,
+ sinkDefault = vector.Sink{
+ Name: "defaultSink",
+ Type: "blackhole",
+ Inputs: []string{"defaultSource"},
+ Options: map[string]interface{}{
+ "rate": 100,
"print_interval_secs": 60,
},
}
@@ -47,10 +45,10 @@ func (cfg *Config) GenerateVectorConfig() error {
}
if len(sources) == 0 {
- sources = sourceDefault
+ sources = []vector.Source{sourceDefault}
}
if len(sinks) == 0 {
- sinks = sinkDefault
+ sinks = []vector.Sink{sinkDefault}
}
vectorConfig.Sinks = sinks
@@ -62,45 +60,39 @@ func (cfg *Config) GenerateVectorConfig() error {
return nil
}
-func (cfg *Config) getComponents() (map[string]interface{}, map[string]interface{}, map[string]interface{}, error) {
- sourcesMap := make(map[string]interface{})
- transformsMap := make(map[string]interface{})
- sinksMap := make(map[string]interface{})
+func (cfg *Config) getComponents() (sources []vector.Source, transforms []vector.Transform, sinks []vector.Sink, err error) {
for _, vCtrl := range cfg.pCtrls {
- sources, err := vCtrl.GetSources(nil)
+ pipelineSources, err := vCtrl.GetSources(nil)
if err != nil {
return nil, nil, nil, err
}
- for _, source := range sources {
- spec, err := vector.Mapper(source)
+ for _, source := range pipelineSources {
if err != nil {
return nil, nil, nil, err
}
- sourcesMap[source.Name] = spec
+ sources = append(sources, source)
}
- transforms, err := vCtrl.GetTransforms()
+ pipelineTransforms, err := vCtrl.GetTransforms()
if err != nil {
return nil, nil, nil, err
}
- for _, transform := range transforms {
- spec, err := vector.Mapper(transform)
+ for _, transform := range pipelineTransforms {
if err != nil {
return nil, nil, nil, err
}
- transformsMap[transform.Name] = spec
+ transforms = append(transforms, transform)
}
- sinks, err := vCtrl.GetSinks()
+ pipelineSinks, err := vCtrl.GetSinks()
if err != nil {
return nil, nil, nil, err
}
- for _, sink := range sinks {
- spec, err := vector.Mapper(sink)
+ for _, sink := range pipelineSinks {
if err != nil {
return nil, nil, nil, err
}
- sinksMap[sink.Name] = spec
+ sinks = append(sinks, sink)
}
}
- return sourcesMap, transformsMap, sinksMap, nil
+ return sources, transforms, sinks, nil
}
diff --git a/controllers/factory/vector/types.go b/controllers/factory/vector/types.go
index f766446b..3349dd19 100644
--- a/controllers/factory/vector/types.go
+++ b/controllers/factory/vector/types.go
@@ -17,11 +17,11 @@ limitations under the License.
package vector
type VectorConfig struct {
- DataDir string `json:"data_dir,omitempty"`
- Api *ApiSpec `json:"api,omitempty"`
- Sources map[string]interface{} `json:"sources,omitempty"`
- Transforms map[string]interface{} `json:"transforms,omitempty"`
- Sinks map[string]interface{} `json:"sinks,omitempty"`
+ DataDir string `mapstructure:"data_dir"`
+ Api *ApiSpec `mapstructure:"api"`
+ Sources []Source `mapstructure:"sources"`
+ Transforms []Transform `mapstructure:"transforms"`
+ Sinks []Sink `mapstructure:"sinks"`
}
type ApiSpec struct {
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
index 29d206c6..fbff5dbb 100644
--- a/controllers/factory/vector/vector.go
+++ b/controllers/factory/vector/vector.go
@@ -21,8 +21,8 @@ import (
)
func New(dataDir string, apiEnabled bool) *VectorConfig {
- sources := make(map[string]interface{})
- sinks := make(map[string]interface{})
+ sources := []Source{}
+ sinks := []Sink{}
return &VectorConfig{
DataDir: dataDir,
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index efab81ab..608f9aaa 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -107,7 +107,9 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
if err != nil {
return ctrl.Result{}, err
}
- config.FillForVectorAgent()
+ if err := config.FillForVectorAgent(); err != nil {
+ return ctrl.Result{}, err
+ }
// Get Config in Json ([]byte)
byteConfig, err := config.GetByteConfig()
From 978e46ffb1e9c07a71109f3b4dc8dfda0bfa40f0 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 12:12:40 +0300
Subject: [PATCH 049/316] refactor k8s utils tests
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/utils/k8s/k8s_test.go | 902 +++++++++++++---------
1 file changed, 539 insertions(+), 363 deletions(-)
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index 1683aa38..4f08a501 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -22,6 +22,7 @@ import (
// . "github.com/onsi/ginkgo/v2"
// . "github.com/onsi/gomega"
+
"github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
@@ -35,12 +36,18 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)
-// type objects interface {
-// *corev1.Service | *corev1.Secret | *appsv1.DaemonSet | *appsv1.StatefulSet | *corev1.ServiceAccount | *rbacv1.ClusterRole | *rbacv1.ClusterRoleBinding
-// }
+func getInitObjectMeta() metav1.ObjectMeta {
+ ObjectMeta := metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ }
+
+ return ObjectMeta
+}
var reconcileObjectCase = func(objInit, obj interface{}, want error) func(t *testing.T) {
return func(t *testing.T) {
+ t.Parallel()
t.Helper()
req := require.New(t)
@@ -98,269 +105,408 @@ var reconcileObjectCase = func(objInit, obj interface{}, want error) func(t *tes
}
}
-func TestCreateOrUpdateService(t *testing.T) {
- serviceInit := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- ResourceVersion: "",
- },
- }
+var nameRequeriedError = apierrors.NewInvalid(
+ schema.GroupKind{},
+ "",
+ field.ErrorList{
+ field.Required(
+ field.NewPath("metadata.name"),
+ "name is required",
+ ),
+ },
+)
- serviceCase1 := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- }
- serviceCase2 := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
- serviceCase3 := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
- }
- serviceCase4 := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{},
+func TestCreateOrUpdateService(t *testing.T) {
+ t.Parallel()
+
+ initObj := &corev1.Service{
+ ObjectMeta: getInitObjectMeta(),
+ }
+
+ type secriveCase struct {
+ name string
+ obj *corev1.Service
+ err error
+ }
+
+ secriveCases := []secriveCase{
+ {
+ name: "Create Simple case",
+ obj: &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create Alredy exist case",
+ obj: &corev1.Service{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: nil,
+ },
+ {
+ name: "Create with Another Namespace case",
+ obj: &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create without Name case",
+ obj: &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{},
+ },
+ err: nameRequeriedError,
+ },
+ }
+
+ for _, tc := range secriveCases {
+ t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
-
- t.Run("Create Simple case", reconcileObjectCase(serviceInit, serviceCase1, nil))
- t.Run("Create Alredy exist case", reconcileObjectCase(serviceInit, serviceCase2, nil))
- t.Run("Create with Another Namespace case", reconcileObjectCase(serviceInit, serviceCase3, nil))
- t.Run("Create without Name case", reconcileObjectCase(serviceInit, serviceCase4, errorCase4))
}
func TestCreateOrUpdateSecret(t *testing.T) {
- secretInit := &corev1.Secret{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
-
- secretCase1 := &corev1.Secret{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- }
- secretCase2 := &corev1.Secret{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
+ t.Parallel()
+
+ initObj := &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ }
+
+ type secretCase struct {
+ name string
+ obj *corev1.Secret
+ err error
+ }
+
+ secretCases := []secretCase{
+ {
+ name: "Create Simple case",
+ obj: &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create Alredy exist case",
+ obj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: nil,
+ },
+ {
+ name: "Create with Another Namespace case",
+ obj: &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create without Name case",
+ obj: &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{},
+ },
+ err: nameRequeriedError,
+ },
+ }
+
+ for _, tc := range secretCases {
+ t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
- secretCase3 := &corev1.Secret{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
- }
- secretCase4 := &corev1.Secret{
- ObjectMeta: metav1.ObjectMeta{},
- }
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
-
- t.Run("Create Simple case", reconcileObjectCase(secretInit, secretCase1, nil))
- t.Run("Create Alredy exist case", reconcileObjectCase(secretInit, secretCase2, nil))
- t.Run("Create with Another Namespace case", reconcileObjectCase(secretInit, secretCase3, nil))
- t.Run("Create without Name case", reconcileObjectCase(secretInit, secretCase4, errorCase4))
}
func TestCreateOrUpdateDaemonSet(t *testing.T) {
- daemonSetInit := &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
-
- daemonSetCase1 := &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- }
- daemonSetCase2 := &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
- daemonSetCase3 := &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
- }
- daemonSetCase4 := &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{},
+ t.Parallel()
+
+ initObj := &appsv1.DaemonSet{
+ ObjectMeta: getInitObjectMeta(),
+ }
+
+ type daemonSetCase struct {
+ name string
+ obj *appsv1.DaemonSet
+ err error
+ }
+
+ daemonSetCases := []daemonSetCase{
+ {
+ name: "Create Simple case",
+ obj: &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create Alredy exist case",
+ obj: &appsv1.DaemonSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: nil,
+ },
+ {
+ name: "Create with Another Namespace case",
+ obj: &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create without Name case",
+ obj: &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{},
+ },
+ err: nameRequeriedError,
+ },
+ }
+
+ for _, tc := range daemonSetCases {
+ t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
-
- t.Run("Create Simple case", reconcileObjectCase(daemonSetInit, daemonSetCase1, nil))
- t.Run("Create Alredy exist case", reconcileObjectCase(daemonSetInit, daemonSetCase2, nil))
- t.Run("Create with Another Namespace case", reconcileObjectCase(daemonSetInit, daemonSetCase3, nil))
- t.Run("Create without Name case", reconcileObjectCase(daemonSetInit, daemonSetCase4, errorCase4))
}
func TestCreateOrUpdateStatefulSet(t *testing.T) {
- statefulSetInit := &appsv1.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
-
- statefulSetCase1 := &appsv1.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- }
- statefulSetCase2 := &appsv1.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
- statefulSetCase3 := &appsv1.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
+ t.Parallel()
+
+ initObj := &appsv1.StatefulSet{
+ ObjectMeta: getInitObjectMeta(),
+ }
+
+ type statefulSetCase struct {
+ name string
+ obj *appsv1.StatefulSet
+ err error
+ }
+
+ statefulSetCases := []statefulSetCase{
+ {
+ name: "Create Simple case",
+ obj: &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create Alredy exist case",
+ obj: &appsv1.StatefulSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: nil,
+ },
+ {
+ name: "Create with Another Namespace case",
+ obj: &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create without Name case",
+ obj: &appsv1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{},
+ },
+ err: nameRequeriedError,
+ },
+ }
+
+ for _, tc := range statefulSetCases {
+ t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
- statefulSetCase4 := &appsv1.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{},
- }
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
-
- t.Run("Create Simple case", reconcileObjectCase(statefulSetInit, statefulSetCase1, nil))
- t.Run("Create Alredy exist case", reconcileObjectCase(statefulSetInit, statefulSetCase2, nil))
- t.Run("Create with Another Namespace case", reconcileObjectCase(statefulSetInit, statefulSetCase3, nil))
- t.Run("Create without Name case", reconcileObjectCase(statefulSetInit, statefulSetCase4, errorCase4))
}
func TestCreateOrUpdateServiceAccount(t *testing.T) {
- serviceAccountInit := &corev1.ServiceAccount{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
-
- serviceAccountCase1 := &corev1.ServiceAccount{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- }
- serviceAccountCase2 := &corev1.ServiceAccount{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
- serviceAccountCase3 := &corev1.ServiceAccount{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
- }
- serviceAccountCase4 := &corev1.ServiceAccount{
- ObjectMeta: metav1.ObjectMeta{},
+ t.Parallel()
+
+ initObj := &corev1.ServiceAccount{
+ ObjectMeta: getInitObjectMeta(),
+ }
+
+ type serviceAccountCase struct {
+ name string
+ obj *corev1.ServiceAccount
+ err error
+ }
+
+ serviceAccountCases := []serviceAccountCase{
+ {
+ name: "Create Simple case",
+ obj: &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create Alredy exist case",
+ obj: &corev1.ServiceAccount{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: nil,
+ },
+ {
+ name: "Create with Another Namespace case",
+ obj: &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create without Name case",
+ obj: &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{},
+ },
+ err: nameRequeriedError,
+ },
+ }
+
+ for _, tc := range serviceAccountCases {
+ t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
-
- t.Run("Create Simple case", reconcileObjectCase(serviceAccountInit, serviceAccountCase1, nil))
- t.Run("Create Alredy exist case", reconcileObjectCase(serviceAccountInit, serviceAccountCase2, nil))
- t.Run("Create with Another Namespace case", reconcileObjectCase(serviceAccountInit, serviceAccountCase3, nil))
- t.Run("Create without Name case", reconcileObjectCase(serviceAccountInit, serviceAccountCase4, errorCase4))
}
func TestCreateOrUpdateClusterRole(t *testing.T) {
- clusterRoleInit := &rbacv1.ClusterRole{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
-
- clusterRoleCase1 := &rbacv1.ClusterRole{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- }
- clusterRoleCase2 := &rbacv1.ClusterRole{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
+ t.Parallel()
+
+ initObj := &rbacv1.ClusterRole{
+ ObjectMeta: getInitObjectMeta(),
+ }
+
+ type clusterRoleCase struct {
+ name string
+ obj *rbacv1.ClusterRole
+ err error
+ }
+
+ clusterRoleCases := []clusterRoleCase{
+ {
+ name: "Create Simple case",
+ obj: &rbacv1.ClusterRole{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create Alredy exist case",
+ obj: &rbacv1.ClusterRole{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: nil,
+ },
+ {
+ name: "Create with Another Namespace case",
+ obj: &rbacv1.ClusterRole{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create without Name case",
+ obj: &rbacv1.ClusterRole{
+ ObjectMeta: metav1.ObjectMeta{},
+ },
+ err: nameRequeriedError,
+ },
+ }
+
+ for _, tc := range clusterRoleCases {
+ t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
- clusterRoleCase3 := &rbacv1.ClusterRole{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
- }
- clusterRoleCase4 := &rbacv1.ClusterRole{
- ObjectMeta: metav1.ObjectMeta{},
- }
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
-
- t.Run("Create Simple case", reconcileObjectCase(clusterRoleInit, clusterRoleCase1, nil))
- t.Run("Create Alredy exist case", reconcileObjectCase(clusterRoleInit, clusterRoleCase2, nil))
- t.Run("Create with Another Namespace case", reconcileObjectCase(clusterRoleInit, clusterRoleCase3, nil))
- t.Run("Create without Name case", reconcileObjectCase(clusterRoleInit, clusterRoleCase4, errorCase4))
}
func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
- clusterRoleBindingInit := &rbacv1.ClusterRoleBinding{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
-
- clusterRoleBindingCase1 := &rbacv1.ClusterRoleBinding{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
+ t.Parallel()
+
+ initObj := &rbacv1.ClusterRoleBinding{
+ ObjectMeta: getInitObjectMeta(),
+ }
+
+ type clusterRoleBindingCase struct {
+ name string
+ obj *rbacv1.ClusterRoleBinding
+ err error
+ }
+
+ clusterRoleBindingCases := []clusterRoleBindingCase{
+ {
+ name: "Create Simple case",
+ obj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create Alredy exist case",
+ obj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: nil,
+ },
+ {
+ name: "Create with Another Namespace case",
+ obj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create without Name case",
+ obj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: metav1.ObjectMeta{},
+ },
+ err: nameRequeriedError,
+ },
+ }
+
+ for _, tc := range clusterRoleBindingCases {
+ t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
- clusterRoleBindingCase2 := &rbacv1.ClusterRoleBinding{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
- clusterRoleBindingCase3 := &rbacv1.ClusterRoleBinding{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
- }
- clusterRoleBindingCase4 := &rbacv1.ClusterRoleBinding{
- ObjectMeta: metav1.ObjectMeta{},
- }
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
-
- t.Run("Create Simple case", reconcileObjectCase(clusterRoleBindingInit, clusterRoleBindingCase1, nil))
- t.Run("Create Alredy exist case", reconcileObjectCase(clusterRoleBindingInit, clusterRoleBindingCase2, nil))
- t.Run("Create with Another Namespace case", reconcileObjectCase(clusterRoleBindingInit, clusterRoleBindingCase3, nil))
- t.Run("Create without Name case", reconcileObjectCase(clusterRoleBindingInit, clusterRoleBindingCase4, errorCase4))
}
func TestCreatePod(t *testing.T) {
+ t.Parallel()
+
createPodCase := func(objInit, obj *corev1.Pod, want error) func(t *testing.T) {
return func(t *testing.T) {
+ t.Parallel()
t.Helper()
req := require.New(t)
@@ -371,46 +517,53 @@ func TestCreatePod(t *testing.T) {
}
}
- objInit := &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- ResourceVersion: "",
- },
+ initObj := &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
}
- objCase1 := &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
+
+ type podCase struct {
+ name string
+ obj *corev1.Pod
+ err error
}
- objCase2 := &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
+
+ podCases := []podCase{
+ {
+ name: "Create not exist pod case",
+ obj: &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ },
+ err: nil,
+ },
+ {
+ name: "Create alredy exist pod case",
+ obj: &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: apierrors.NewAlreadyExists(
+ schema.GroupResource{
+ Group: "",
+ Resource: "pods",
+ },
+ "init",
+ ),
},
}
- grCase2 := schema.GroupResource{
- Group: "",
- Resource: "pods",
- }
- errorCase2 := apierrors.NewAlreadyExists(grCase2, objCase2.ObjectMeta.Name)
- t.Run("Create not exist pod case", createPodCase(objInit, objCase1, nil))
- t.Run("Create alredy exist pod case", createPodCase(objInit, objCase2, errorCase2))
+ for _, tc := range podCases {
+ t.Run(tc.name, createPodCase(initObj, tc.obj, tc.err))
+ }
}
-// func CreatePod(pod *corev1.Pod, c client.Client) error {
-// err := c.Create(context.TODO(), pod)
-// if err != nil {
-// return err
-// }
-// return nil
-// }
-
func TestGetPod(t *testing.T) {
+ t.Parallel()
+
getPodCase := func(objInit, obj, wantPod *corev1.Pod, want error) func(t *testing.T) {
return func(t *testing.T) {
+ t.Parallel()
t.Helper()
req := require.New(t)
@@ -424,39 +577,62 @@ func TestGetPod(t *testing.T) {
}
}
- objInit := &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- ResourceVersion: "",
- },
+ initObj := &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ }
+
+ type podCase struct {
+ name string
+ obj *corev1.Pod
+ wantObj *corev1.Pod
+ err error
+ }
+
+ podCases := []podCase{
+ {
+ name: "Get not exist pod case",
+ obj: &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ },
+ wantObj: nil,
+ err: apierrors.NewNotFound(
+ schema.GroupResource{
+ Group: "",
+ Resource: "pods",
+ },
+ "test",
+ ),
+ },
+ {
+ name: "Get exist pod case",
+ obj: &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ wantObj: &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ ResourceVersion: "999",
+ },
+ },
+ err: nil,
+ },
+ }
+
+ for _, tc := range podCases {
+ t.Run(tc.name, getPodCase(initObj, tc.obj, tc.wantObj, tc.err))
}
- objCase1 := &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- }
- gvrCase1 := schema.GroupVersionResource{
- Group: "",
- Version: "v1",
- Resource: "pods",
- }
- errorCase1 := apierrors.NewNotFound(gvrCase1.GroupResource(), objCase1.ObjectMeta.Name)
- objCase2 := &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
-
- t.Run("Get not exist pod case", getPodCase(objInit, objCase1, nil, errorCase1))
- t.Run("Get exist pod case", getPodCase(objInit, objCase2, objInit, nil))
}
func TestUpdateStatus(t *testing.T) {
+ t.Parallel()
+
updateStatusCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
return func(t *testing.T) {
+ t.Parallel()
t.Helper()
req := require.New(t)
@@ -468,76 +644,76 @@ func TestUpdateStatus(t *testing.T) {
}
}
- objInit := &corev1.Secret{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- ResourceVersion: "",
- },
- }
- objCase1 := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- }
- objCase2 := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- },
- }
- objCase3 := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace2",
- },
- }
- objCase4 := &corev1.Service{
- ObjectMeta: metav1.ObjectMeta{},
+ type testCase struct {
+ name string
+ initObj *appsv1.Deployment
+ updateObj *appsv1.Deployment
+ err error
+ }
+
+ testCases := []testCase{
+ {
+ name: "Update Simple case",
+ initObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ updateObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: nil,
+ },
+ {
+ name: "Update Alredy exist case",
+ initObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ updateObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ err: nil,
+ },
+ {
+ name: "Update without Name case",
+ initObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ updateObj: &appsv1.Deployment{
+ ObjectMeta: metav1.ObjectMeta{},
+ },
+ err: nameRequeriedError,
+ },
+ {
+ name: "Update status case",
+ initObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ updateObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ Status: appsv1.DeploymentStatus{
+ Replicas: 10,
+ },
+ },
+ err: nil,
+ },
+ }
+
+ // objCase5 := &appsv1.Deployment{
+ // ObjectMeta: metav1.ObjectMeta{
+ // Name: "test",
+ // Namespace: "test-namespace",
+ // },
+ // Status: appsv1.DeploymentStatus{
+ // Replicas: 10,
+ // },
+ // }
+ // gvrCase5 := schema.GroupVersionResource{
+ // Group: "apps",
+ // Version: "v1",
+ // Resource: "deployments",
+ // }
+ // errorCase5 := apierrors.NewNotFound(gvrCase5.GroupResource(), objCase5.ObjectMeta.Name)
+
+ for _, tc := range testCases {
+ t.Run(tc.name, updateStatusCase(tc.initObj, tc.updateObj, tc.err))
}
- errorCase4 := apierrors.NewInvalid(schema.GroupKind{}, "", field.ErrorList{field.Required(field.NewPath("metadata.name"), "name is required")})
-
- objCase5 := &appsv1.Deployment{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- Status: appsv1.DeploymentStatus{
- Replicas: 10,
- },
- }
- gvrCase5 := schema.GroupVersionResource{
- Group: "apps",
- Version: "v1",
- Resource: "deployments",
- }
- errorCase5 := apierrors.NewNotFound(gvrCase5.GroupResource(), objCase5.ObjectMeta.Name)
-
- init_objCase6 := &appsv1.Deployment{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- Status: appsv1.DeploymentStatus{
- Replicas: 5,
- },
- }
- objCase6 := &appsv1.Deployment{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test",
- Namespace: "test-namespace",
- },
- Status: appsv1.DeploymentStatus{
- Replicas: 10,
- },
- }
-
- t.Run("Update Simple case", updateStatusCase(objInit, objCase1, nil))
- t.Run("Update Alredy exist case", updateStatusCase(objInit, objCase2, nil))
- t.Run("Update with Another Namespace case", updateStatusCase(objInit, objCase3, nil))
- t.Run("Update without Name case", updateStatusCase(objInit, objCase4, errorCase4))
- t.Run("Update not exist Deployment with wrong init case", updateStatusCase(objInit, objCase5, errorCase5))
- t.Run("Update Deployment case", updateStatusCase(init_objCase6, objCase6, nil))
-
}
From 88c53d1ff742c41bce8d747f304e1ce4b9e67229 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 12:27:22 +0300
Subject: [PATCH 050/316] fix some errors
Signed-off-by: Zemtsov Vladimir
---
.../factory/config/configcheck/configcheck.go | 3 +-
.../config/configcheck/configcheck_error.go | 4 +-
controllers/factory/utils/hash/hash.go | 1 +
controllers/factory/utils/hash/hash_test.go | 26 ++++++++-
controllers/factory/utils/k8s/k8s_test.go | 58 ++++++-------------
.../vector/vectoragent/vectoragent_config.go | 2 +-
controllers/vectorpipeline_controller.go | 2 +-
7 files changed, 49 insertions(+), 47 deletions(-)
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index b99c75d2..7698656a 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -142,6 +142,7 @@ func labelsForVectorConfigCheck() map[string]string {
func (cc *ConfigCheck) getNameVectorConfigCheck() string {
n := "configcheck-" + "-" + cc.Name + "-" + cc.Hash
+
return n
}
@@ -173,7 +174,7 @@ func (cc *ConfigCheck) getCheckResult(pod *corev1.Pod) error {
if err != nil {
return err
}
- return &ErrConfigCheck{
+ return &ConfigCheckError{
Reason: reason,
}
case "Succeeded":
diff --git a/controllers/factory/config/configcheck/configcheck_error.go b/controllers/factory/config/configcheck/configcheck_error.go
index 2fd40672..4ecf5e85 100644
--- a/controllers/factory/config/configcheck/configcheck_error.go
+++ b/controllers/factory/config/configcheck/configcheck_error.go
@@ -20,11 +20,11 @@ type error interface {
Error() string
}
-type ErrConfigCheck struct {
+type ConfigCheckError struct {
Reason string
Err error
}
-func (e *ErrConfigCheck) Error() string {
+func (e *ConfigCheckError) Error() string {
return e.Reason
}
diff --git a/controllers/factory/utils/hash/hash.go b/controllers/factory/utils/hash/hash.go
index cde0db8d..0681fe6c 100644
--- a/controllers/factory/utils/hash/hash.go
+++ b/controllers/factory/utils/hash/hash.go
@@ -20,5 +20,6 @@ import "hash/crc32"
func Get(input []byte) uint32 {
crc32q := crc32.MakeTable(crc32.IEEE)
+
return crc32.Checksum(input, crc32q)
}
diff --git a/controllers/factory/utils/hash/hash_test.go b/controllers/factory/utils/hash/hash_test.go
index 950a06f9..35ac2f68 100644
--- a/controllers/factory/utils/hash/hash_test.go
+++ b/controllers/factory/utils/hash/hash_test.go
@@ -27,6 +27,7 @@ func TestGet(t *testing.T) {
hashCase := func(bytes []byte, want uint32) func(t *testing.T) {
return func(t *testing.T) {
t.Helper()
+ t.Parallel()
req := require.New(t)
result := hash.Get(bytes)
@@ -34,6 +35,27 @@ func TestGet(t *testing.T) {
}
}
- t.Run("Simple case", hashCase([]byte("test"), uint32(3632233996)))
- t.Run("Zero case", hashCase([]byte(""), uint32(0)))
+ type testCase struct {
+ name string
+ bytes []byte
+ want uint32
+ }
+
+ testCases := []testCase{
+ {
+ name: "Simple case",
+ bytes: []byte("test"),
+ want: uint32(3632233996),
+ },
+ {
+ name: "Zero case",
+ bytes: []byte(""),
+ want: uint32(0),
+ },
+ }
+
+ t.Parallel()
+ for _, tc := range testCases {
+ t.Run(tc.name, hashCase(tc.bytes, tc.want))
+ }
}
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index 4f08a501..33beb0a2 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -47,8 +47,9 @@ func getInitObjectMeta() metav1.ObjectMeta {
var reconcileObjectCase = func(objInit, obj interface{}, want error) func(t *testing.T) {
return func(t *testing.T) {
- t.Parallel()
t.Helper()
+ t.Parallel()
+
req := require.New(t)
switch obj.(type) {
@@ -117,8 +118,6 @@ var nameRequeriedError = apierrors.NewInvalid(
)
func TestCreateOrUpdateService(t *testing.T) {
- t.Parallel()
-
initObj := &corev1.Service{
ObjectMeta: getInitObjectMeta(),
}
@@ -166,14 +165,13 @@ func TestCreateOrUpdateService(t *testing.T) {
},
}
+ t.Parallel()
for _, tc := range secriveCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
}
func TestCreateOrUpdateSecret(t *testing.T) {
- t.Parallel()
-
initObj := &corev1.Secret{
ObjectMeta: getInitObjectMeta(),
}
@@ -221,14 +219,13 @@ func TestCreateOrUpdateSecret(t *testing.T) {
},
}
+ t.Parallel()
for _, tc := range secretCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
}
func TestCreateOrUpdateDaemonSet(t *testing.T) {
- t.Parallel()
-
initObj := &appsv1.DaemonSet{
ObjectMeta: getInitObjectMeta(),
}
@@ -276,14 +273,13 @@ func TestCreateOrUpdateDaemonSet(t *testing.T) {
},
}
+ t.Parallel()
for _, tc := range daemonSetCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
}
func TestCreateOrUpdateStatefulSet(t *testing.T) {
- t.Parallel()
-
initObj := &appsv1.StatefulSet{
ObjectMeta: getInitObjectMeta(),
}
@@ -331,14 +327,13 @@ func TestCreateOrUpdateStatefulSet(t *testing.T) {
},
}
+ t.Parallel()
for _, tc := range statefulSetCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
}
func TestCreateOrUpdateServiceAccount(t *testing.T) {
- t.Parallel()
-
initObj := &corev1.ServiceAccount{
ObjectMeta: getInitObjectMeta(),
}
@@ -386,14 +381,13 @@ func TestCreateOrUpdateServiceAccount(t *testing.T) {
},
}
+ t.Parallel()
for _, tc := range serviceAccountCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
}
func TestCreateOrUpdateClusterRole(t *testing.T) {
- t.Parallel()
-
initObj := &rbacv1.ClusterRole{
ObjectMeta: getInitObjectMeta(),
}
@@ -441,14 +435,13 @@ func TestCreateOrUpdateClusterRole(t *testing.T) {
},
}
+ t.Parallel()
for _, tc := range clusterRoleCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
}
func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
- t.Parallel()
-
initObj := &rbacv1.ClusterRoleBinding{
ObjectMeta: getInitObjectMeta(),
}
@@ -496,18 +489,18 @@ func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
},
}
+ t.Parallel()
for _, tc := range clusterRoleBindingCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
}
func TestCreatePod(t *testing.T) {
- t.Parallel()
-
createPodCase := func(objInit, obj *corev1.Pod, want error) func(t *testing.T) {
+ t.Parallel()
return func(t *testing.T) {
- t.Parallel()
t.Helper()
+
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
@@ -553,18 +546,18 @@ func TestCreatePod(t *testing.T) {
},
}
+ t.Parallel()
for _, tc := range podCases {
t.Run(tc.name, createPodCase(initObj, tc.obj, tc.err))
}
}
func TestGetPod(t *testing.T) {
- t.Parallel()
-
getPodCase := func(objInit, obj, wantPod *corev1.Pod, want error) func(t *testing.T) {
+ t.Parallel()
return func(t *testing.T) {
- t.Parallel()
t.Helper()
+
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
@@ -622,18 +615,18 @@ func TestGetPod(t *testing.T) {
},
}
+ t.Parallel()
for _, tc := range podCases {
t.Run(tc.name, getPodCase(initObj, tc.obj, tc.wantObj, tc.err))
}
}
func TestUpdateStatus(t *testing.T) {
- t.Parallel()
-
updateStatusCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
+ t.Parallel()
return func(t *testing.T) {
- t.Parallel()
t.Helper()
+
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
@@ -697,22 +690,7 @@ func TestUpdateStatus(t *testing.T) {
},
}
- // objCase5 := &appsv1.Deployment{
- // ObjectMeta: metav1.ObjectMeta{
- // Name: "test",
- // Namespace: "test-namespace",
- // },
- // Status: appsv1.DeploymentStatus{
- // Replicas: 10,
- // },
- // }
- // gvrCase5 := schema.GroupVersionResource{
- // Group: "apps",
- // Version: "v1",
- // Resource: "deployments",
- // }
- // errorCase5 := apierrors.NewNotFound(gvrCase5.GroupResource(), objCase5.ObjectMeta.Name)
-
+ t.Parallel()
for _, tc := range testCases {
t.Run(tc.name, updateStatusCase(tc.initObj, tc.updateObj, tc.err))
}
diff --git a/controllers/factory/vector/vectoragent/vectoragent_config.go b/controllers/factory/vector/vectoragent/vectoragent_config.go
index cc47bcf9..b17bfdd8 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_config.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_config.go
@@ -32,7 +32,7 @@ func (ctrl *Controller) createVectorAgentConfig(ctx context.Context) (*corev1.Se
if ctrl.Vector.Status.LastAppliedConfigHash == nil || *ctrl.Vector.Status.LastAppliedConfigHash != cfgHash {
err := configCheck.Run()
- if _, ok := err.(*configcheck.ErrConfigCheck); ok {
+ if _, ok := err.(*configcheck.ConfigCheckError); ok {
if err := ctrl.SetFailedStatus(ctx, err); err != nil {
return nil, err
}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index c4db42bb..b542c2d0 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -127,7 +127,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// Start ConfigCheck
err = configCheck.Run()
- if _, ok := err.(*configcheck.ErrConfigCheck); ok {
+ if _, ok := err.(*configcheck.ConfigCheckError); ok {
if err := pCtrl.SetFailedStatus(err); err != nil {
return ctrl.Result{}, err
}
From 192aba9efbfb6511568447d193e7a43406778521 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 12:43:16 +0300
Subject: [PATCH 051/316] disable parallel for k8s utils
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/utils/k8s/k8s_test.go | 26 +++++++++++------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index 33beb0a2..58ffa2e1 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -165,7 +165,7 @@ func TestCreateOrUpdateService(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range secriveCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
@@ -219,7 +219,7 @@ func TestCreateOrUpdateSecret(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range secretCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
@@ -273,7 +273,7 @@ func TestCreateOrUpdateDaemonSet(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range daemonSetCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
@@ -327,7 +327,7 @@ func TestCreateOrUpdateStatefulSet(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range statefulSetCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
@@ -381,7 +381,7 @@ func TestCreateOrUpdateServiceAccount(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range serviceAccountCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
@@ -435,7 +435,7 @@ func TestCreateOrUpdateClusterRole(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range clusterRoleCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
@@ -489,7 +489,7 @@ func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range clusterRoleBindingCases {
t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
}
@@ -497,7 +497,7 @@ func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
func TestCreatePod(t *testing.T) {
createPodCase := func(objInit, obj *corev1.Pod, want error) func(t *testing.T) {
- t.Parallel()
+ // t.Parallel()
return func(t *testing.T) {
t.Helper()
@@ -546,7 +546,7 @@ func TestCreatePod(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range podCases {
t.Run(tc.name, createPodCase(initObj, tc.obj, tc.err))
}
@@ -554,7 +554,7 @@ func TestCreatePod(t *testing.T) {
func TestGetPod(t *testing.T) {
getPodCase := func(objInit, obj, wantPod *corev1.Pod, want error) func(t *testing.T) {
- t.Parallel()
+ // t.Parallel()
return func(t *testing.T) {
t.Helper()
@@ -615,7 +615,7 @@ func TestGetPod(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range podCases {
t.Run(tc.name, getPodCase(initObj, tc.obj, tc.wantObj, tc.err))
}
@@ -623,7 +623,7 @@ func TestGetPod(t *testing.T) {
func TestUpdateStatus(t *testing.T) {
updateStatusCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
- t.Parallel()
+ // t.Parallel()
return func(t *testing.T) {
t.Helper()
@@ -690,7 +690,7 @@ func TestUpdateStatus(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range testCases {
t.Run(tc.name, updateStatusCase(tc.initObj, tc.updateObj, tc.err))
}
From 6c192b47c59f6b95931b02409299dec471ce1580 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 13:25:34 +0300
Subject: [PATCH 052/316] Cleanup
Signed-off-by: Zemtsov Vladimir
---
.../factory/config/configcheck/configcheck.go | 21 -------------------
controllers/factory/utils/hash/hash_test.go | 2 +-
2 files changed, 1 insertion(+), 22 deletions(-)
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index 7698656a..62e6f9e1 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -54,27 +54,6 @@ func New(ctx context.Context, config []byte, c client.Client, cs *kubernetes.Cli
}
}
-// func (cfg *Config) StartCheck() error {
-
-// log := log.FromContext(context.TODO()).WithValues("ConfigCheck Vector Pipeline", cfg.vaCtrl.Vector.Name)
-
-// configCheck := configcheck.New(cfg.Ctx, cfg.ByteConfig, cfg.vaCtrl.Client, cfg.vaCtrl.ClientSet, cfg.Name, cfg.vaCtrl.Vector.Namespace, cfg.vaCtrl.Vector.Spec.Agent.Image)
-
-// err := configCheck.Run()
-// if _, ok := err.(*configcheck.ErrConfigCheck); ok {
-// if err := cfg.vaCtrl.SetFailedStatus(cfg.Ctx, err); err != nil {
-// return err
-// }
-// log.Error(err, "Vector Config has error")
-// return nil
-// }
-// if err != nil {
-// return err
-// }
-
-// return cfg.vaCtrl.SetSucceesStatus(cfg.Ctx)
-// }
-
func (cc *ConfigCheck) Run() error {
log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", cc.Name)
diff --git a/controllers/factory/utils/hash/hash_test.go b/controllers/factory/utils/hash/hash_test.go
index 35ac2f68..d3c8196d 100644
--- a/controllers/factory/utils/hash/hash_test.go
+++ b/controllers/factory/utils/hash/hash_test.go
@@ -54,7 +54,7 @@ func TestGet(t *testing.T) {
},
}
- t.Parallel()
+ // t.Parallel()
for _, tc := range testCases {
t.Run(tc.name, hashCase(tc.bytes, tc.want))
}
From f01b3792f78691538c3c3d048dc6a20e65be2885 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 31 Oct 2022 13:43:29 +0300
Subject: [PATCH 053/316] gc for checkconfig (#26)
---
.../factory/config/configcheck/configcheck.go | 54 +++++++++++++++++++
controllers/vectorpipeline_controller.go | 3 ++
2 files changed, 57 insertions(+)
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index 62e6f9e1..633dba4c 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -23,6 +23,7 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
@@ -107,6 +108,10 @@ func (cc *ConfigCheck) checkVectorConfigCheckPod() error {
return err
}
+ err = cc.cleanup()
+ if err != nil {
+ return err
+ }
return nil
}
@@ -162,3 +167,52 @@ func (cc *ConfigCheck) getCheckResult(pod *corev1.Pod) error {
}
}
}
+
+func (cc *ConfigCheck) cleanup() error {
+ listOpts, err := cc.gcRListOptions()
+ if err != nil {
+ return err
+ }
+
+ podlist := corev1.PodList{}
+ secretList := corev1.SecretList{}
+ err = cc.Client.List(cc.Ctx, &podlist, &listOpts)
+ if err != nil {
+ return err
+ }
+ err = cc.Client.List(cc.Ctx, &secretList, &listOpts)
+ if err != nil {
+ return err
+ }
+ for _, pod := range podlist.Items {
+ if pod.Status.Phase == "Succeeded" {
+ if err := cc.Client.Delete(cc.Ctx, &pod); err != nil {
+ return err
+ }
+ }
+ }
+ for _, secret := range secretList.Items {
+ if err := cc.Client.Delete(cc.Ctx, &secret); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (cc *ConfigCheck) gcRListOptions() (client.ListOptions, error) {
+ configCheckLabels := labelsForVectorConfigCheck()
+ var requirements []labels.Requirement
+ for k, v := range configCheckLabels {
+ r, err := labels.NewRequirement(k, "==", []string{v})
+ if err != nil {
+ return client.ListOptions{}, err
+ }
+ requirements = append(requirements, *r)
+ }
+ labelsSelector := labels.NewSelector().Add(requirements...)
+
+ return client.ListOptions{
+ LabelSelector: labelsSelector,
+ Namespace: cc.Namespace,
+ }, nil
+}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index b542c2d0..9338c1a0 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -106,6 +106,9 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// Init Controller for Vector Agent
vaCtrl := vectoragent.NewController(&vector, r.Client, r.Clientset)
+ if vaCtrl.Vector.Spec.Agent.DataDir == "" {
+ vaCtrl.Vector.Spec.Agent.DataDir = "/vector-data-dir"
+ }
// Get Vector Config file
config, err := config.New(ctx, vaCtrl)
From d2e255961dd826a7123dd87a7394df0674fdd8b9 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 16:30:02 +0300
Subject: [PATCH 054/316] restruct vector api field && Change name
printedColumn to Valid
Signed-off-by: Zemtsov Vladimir
---
api/v1alpha1/clustervectorpipeline_types.go | 2 +-
api/v1alpha1/vector_types.go | 11 ++++++--
api/v1alpha1/vectorpipeline_types.go | 2 +-
api/v1alpha1/zz_generated.deepcopy.go | 20 +++++++++++++
...ity.kaasops.io_clustervectorpipelines.yaml | 2 +-
...ervability.kaasops.io_vectorpipelines.yaml | 2 +-
.../observability.kaasops.io_vectors.yaml | 15 ++++++++--
controllers/factory/config/config_build.go | 2 +-
controllers/factory/vector/types.go | 20 ++++++-------
controllers/factory/vector/vector.go | 9 +++---
.../vector/vectoragent/vectoragent_default.go | 28 +++++++++++++++++++
controllers/vector_controller.go | 6 ++--
12 files changed, 89 insertions(+), 30 deletions(-)
create mode 100644 controllers/factory/vector/vectoragent/vectoragent_default.go
diff --git a/api/v1alpha1/clustervectorpipeline_types.go b/api/v1alpha1/clustervectorpipeline_types.go
index 2a3c088e..41fe3883 100644
--- a/api/v1alpha1/clustervectorpipeline_types.go
+++ b/api/v1alpha1/clustervectorpipeline_types.go
@@ -27,7 +27,7 @@ import (
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName=cvp
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
-//+kubebuilder:printcolumn:name="Status",type="boolean",JSONPath=".status.configCheckResult"
+//+kubebuilder:printcolumn:name="Valid",type="boolean",JSONPath=".status.configCheckResult"
// ClusterVectorPipeline is the Schema for the clustervectorpipelines API
type ClusterVectorPipeline struct {
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index a2cc0249..60b7b464 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -46,11 +46,18 @@ type VectorAgent struct {
// +kubebuilder:default:="timberio/vector:0.24.0-distroless-libc"
Image string `json:"image,omitempty"`
DataDir string `json:"dataDir,omitempty"`
- ApiEnabled bool `json:"ApiEnabled,omitempty"`
+ Api *ApiSpec `json:"api,omitempty"`
Service bool `json:"service,omitempty"`
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
}
+// ApiSpec is the Schema for the Vector Agent GraphQL API - https://vector.dev/docs/reference/api/
+type ApiSpec struct {
+ Address string `json:"address,omitempty"`
+ Enabled bool `json:"enabled,omitempty"`
+ Playground bool `json:"playground,omitempty"`
+}
+
// VectorAggregator is the Schema for the Vector Aggregator
type VectorAggregator struct {
Enable bool `json:"enable,omitempty"`
@@ -62,7 +69,7 @@ type VectorAggregator struct {
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
-//+kubebuilder:printcolumn:name="Status",type="boolean",JSONPath=".status.configCheckResult"
+//+kubebuilder:printcolumn:name="Valid",type="boolean",JSONPath=".status.configCheckResult"
// Vector is the Schema for the vectors API
type Vector struct {
diff --git a/api/v1alpha1/vectorpipeline_types.go b/api/v1alpha1/vectorpipeline_types.go
index b65340f3..8365e525 100644
--- a/api/v1alpha1/vectorpipeline_types.go
+++ b/api/v1alpha1/vectorpipeline_types.go
@@ -45,7 +45,7 @@ type VectorPipelineStatus struct {
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName=vp
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
-//+kubebuilder:printcolumn:name="Status",type="boolean",JSONPath=".status.configCheckResult"
+//+kubebuilder:printcolumn:name="Valid",type="boolean",JSONPath=".status.configCheckResult"
// VectorPipeline is the Schema for the vectorpipelines API
type VectorPipeline struct {
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 746cbf3f..cb8f5176 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -26,6 +26,21 @@ import (
"k8s.io/apimachinery/pkg/runtime"
)
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ApiSpec) DeepCopyInto(out *ApiSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApiSpec.
+func (in *ApiSpec) DeepCopy() *ApiSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(ApiSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterVectorPipeline) DeepCopyInto(out *ClusterVectorPipeline) {
*out = *in
@@ -115,6 +130,11 @@ func (in *Vector) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VectorAgent) DeepCopyInto(out *VectorAgent) {
*out = *in
+ if in.Api != nil {
+ in, out := &in.Api, &out.Api
+ *out = new(ApiSpec)
+ **out = **in
+ }
if in.Tolerations != nil {
in, out := &in.Tolerations, &out.Tolerations
*out = make([]v1.Toleration, len(*in))
diff --git a/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
index f22f7cbe..715b8145 100644
--- a/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
@@ -22,7 +22,7 @@ spec:
name: Age
type: date
- jsonPath: .status.configCheckResult
- name: Status
+ name: Valid
type: boolean
name: v1alpha1
schema:
diff --git a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
index 0577b656..e40dd908 100644
--- a/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
@@ -22,7 +22,7 @@ spec:
name: Age
type: date
- jsonPath: .status.configCheckResult
- name: Status
+ name: Valid
type: boolean
name: v1alpha1
schema:
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index e4f237ff..9783f7d7 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -20,7 +20,7 @@ spec:
name: Age
type: date
- jsonPath: .status.configCheckResult
- name: Status
+ name: Valid
type: boolean
name: v1alpha1
schema:
@@ -46,8 +46,17 @@ spec:
description: DisableAggregation DisableAggregation bool `json:"disableAggregation,omitempty"`
Vector Agent
properties:
- ApiEnabled:
- type: boolean
+ api:
+ description: ApiSpec is the Schema for the Vector Agent GraphQL
+ API - https://vector.dev/docs/reference/api/
+ properties:
+ address:
+ type: string
+ enabled:
+ type: boolean
+ playground:
+ type: boolean
+ type: object
dataDir:
type: string
image:
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index e5a8ce80..8a7bf82d 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -37,7 +37,7 @@ var (
)
func (cfg *Config) GenerateVectorConfig() error {
- vectorConfig := vector.New(cfg.vaCtrl.Vector.Spec.Agent.DataDir, cfg.vaCtrl.Vector.Spec.Agent.ApiEnabled)
+ vectorConfig := vector.New(cfg.vaCtrl.Vector)
sources, transforms, sinks, err := cfg.getComponents()
if err != nil {
diff --git a/controllers/factory/vector/types.go b/controllers/factory/vector/types.go
index 3349dd19..52a58681 100644
--- a/controllers/factory/vector/types.go
+++ b/controllers/factory/vector/types.go
@@ -16,18 +16,16 @@ limitations under the License.
package vector
-type VectorConfig struct {
- DataDir string `mapstructure:"data_dir"`
- Api *ApiSpec `mapstructure:"api"`
- Sources []Source `mapstructure:"sources"`
- Transforms []Transform `mapstructure:"transforms"`
- Sinks []Sink `mapstructure:"sinks"`
-}
+import (
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+)
-type ApiSpec struct {
- Enabled *bool `json:"enabled,omitempty"`
- Address *string `json:"address,omitempty"`
- Playground *bool `json:"playground,omitempty"`
+type VectorConfig struct {
+ DataDir string `mapstructure:"data_dir"`
+ Api *vectorv1alpha1.ApiSpec `mapstructure:"api"`
+ Sources []Source `mapstructure:"sources"`
+ Transforms []Transform `mapstructure:"transforms"`
+ Sinks []Sink `mapstructure:"sinks"`
}
type Source struct {
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
index fbff5dbb..7002c8a5 100644
--- a/controllers/factory/vector/vector.go
+++ b/controllers/factory/vector/vector.go
@@ -17,18 +17,17 @@ limitations under the License.
package vector
import (
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/mitchellh/mapstructure"
)
-func New(dataDir string, apiEnabled bool) *VectorConfig {
+func New(vector *vectorv1alpha1.Vector) *VectorConfig {
sources := []Source{}
sinks := []Sink{}
return &VectorConfig{
- DataDir: dataDir,
- Api: &ApiSpec{
- Enabled: &apiEnabled,
- },
+ DataDir: vector.Spec.Agent.DataDir,
+ Api: vector.Spec.Agent.Api,
Sources: sources,
Sinks: sinks,
}
diff --git a/controllers/factory/vector/vectoragent/vectoragent_default.go b/controllers/factory/vector/vectoragent/vectoragent_default.go
new file mode 100644
index 00000000..5f760472
--- /dev/null
+++ b/controllers/factory/vector/vectoragent/vectoragent_default.go
@@ -0,0 +1,28 @@
+/*
+Copyright 2022.
+
+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 vectoragent
+
+func (ctrl *Controller) SetDefault() {
+ if ctrl.Vector.Spec.Agent.Api.Address == "" {
+ ctrl.Vector.Spec.Agent.Api.Address = "0.0.0.0:8686"
+ }
+
+ if ctrl.Vector.Spec.Agent.DataDir == "" {
+ ctrl.Vector.Spec.Agent.DataDir = "/vector-data-dir"
+ }
+
+}
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 18699f0a..f635b34f 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -70,10 +70,6 @@ func (r *VectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, nil
}
- if vectorCR.Spec.Agent.DataDir == "" {
- vectorCR.Spec.Agent.DataDir = "/vector-data-dir"
- }
-
return r.CreateOrUpdateVector(ctx, vectorCR)
}
@@ -102,6 +98,8 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
// Init Controller for Vector Agent
vaCtrl := vectoragent.NewController(v, r.Client, r.Clientset)
+ vaCtrl.SetDefault()
+
// Get Vector Config file
config, err := config.New(ctx, vaCtrl)
if err != nil {
From d82838b8ec73b5ad8f55d6b55e8eb4ce1de71cb2 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 16:30:13 +0300
Subject: [PATCH 055/316] Add docs
Signed-off-by: Zemtsov Vladimir
---
docs/design.md | 48 ++++++++++++++++++++++++++++++++++
docs/specification.md | 60 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+)
create mode 100644 docs/design.md
create mode 100644 docs/specification.md
diff --git a/docs/design.md b/docs/design.md
new file mode 100644
index 00000000..10dc27e1
--- /dev/null
+++ b/docs/design.md
@@ -0,0 +1,48 @@
+# Design
+This document describes the design and interaction between the custom resource definitions (CRD) that the Vector Operator introduces.
+
+Operator introduces the following custom resources:
+- [Vector](#Vector)
+- [VectorPipeline](#vectorpipeline)
+- [ClusterVectorPipeline](#clustervectorpipeline)
+
+# Vector
+The `Vector` CRD declaratively defines a Vector installation to run in a Kubernetes cluster.
+For each Vector resource, the Operator deploys a properly configured DaemonSet in the same namespace.
+For each Vector resource, the Operator adds:
+- DaemonSet with Vector
+- Secret with Vector Configurtion file
+- Service. (For connect to Vector API, or scrape Vector metrics, if enabled)
+- ServiceAccount/ClusterRole/RoleBinding for get access to Kubernetes API
+
+
+## Restrictions
+- Currently tested only ONE installation Vector on Kubernetes cluster
+
+## Planned
+- Add aggregator role in StatefullSet
+- Add features for compress Vector configuration file. (Delete dublicates sources/Transforms/Sinks. Compress to gzip)
+
+## Specification
+Specification access to [this]() page
+
+
+# VectorPipeline
+The `VectorPipeline` CRD defines Sources, Transforms and Sinks rules for Vector.
+All `VectorPipelines`, with validated configuration file, added to Vector configuration file.
+
+## Restrictions
+- For source available only [kubernetes_logs](https://vector.dev/docs/reference/configuration/sources/kubernetes_logs/) type
+- For source field `extra_namespace_label_selector` cannot be installed. The operator control this field and sets the namespace there, where VectorPipeline is defined.
+
+## Specification
+Specification access to [this]() page
+
+# ClusterVectorPipeline
+The `ClusterVectorPipeline` CRD defines Sources, Transforms and Sinks rules for Vector.
+All `ClusterVectorPipelines`, with validated configuration file, added to Vector configuration file.
+
+ClusterVectorPipelines works like VectorPipeline, but without restrictions.
+
+## Specification
+Specification access to [this]() page
\ No newline at end of file
diff --git a/docs/specification.md b/docs/specification.md
new file mode 100644
index 00000000..f4b717fb
--- /dev/null
+++ b/docs/specification.md
@@ -0,0 +1,60 @@
+# Specification
+
+- [Vector](#vector-spec)
+- VectorPipeline
+- ClusterVectorPipeline
+
+
+
+# Vector Spec
+
+
+ agent
+ image
+ Image for Vector agent. timberio/vector:0.24.0-distroless-libc by default
+
+
+ dataDir
+ DataDir for Vector Agent. `/vector-data-dir` by default
+
+
+ api
+
+
+ address
+ The network address to which the API should bind. If you’re running Vector in a Docker container, make sure to bind to 0.0.0.0. Otherwise the API will not be exposed outside the container. By default - 0.0.0.0:8686
+
+
+ enabled
+ Whether the GraphQL API is enabled for this Vector instance. By default - false
+
+
+ playground
+ Whether the GraphQL Playground is enabled for the API. The Playground is accessible via the /playground endpoint of the address set using the bind parameter. By default - false
+
+
+ service
+ Temporary field for enabling service for Vector DaemonSet. By default - false
+
+
+ tolerations
+ Tolerations for Vector DaemonSet. By default - nil
+
+
+
+
+# VectorPipelineSpec (ClusterVectorPipelineSpec)
+
+
+ sources
+ List of Sources
+
+
+ transforms
+ List of Transforms
+
+
+ sinks
+ List of Sinks
+
+
\ No newline at end of file
From c39945a6a37db4a00e6c53f09ad0cbd6cebcacdf Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 17:23:44 +0300
Subject: [PATCH 056/316] Add controllet components for Vector Agent DaemonSet
Signed-off-by: Zemtsov Vladimir
---
api/v1alpha1/vector_types.go | 54 +-
api/v1alpha1/zz_generated.deepcopy.go | 32 +-
.../observability.kaasops.io_vectors.yaml | 1124 +++++++++++++++++
controllers/factory/vector/vector.go | 2 +-
.../vectoragent/vectoragent_daemonset.go | 10 +-
.../vector/vectoragent/vectoragent_default.go | 19 +
docs/design.md | 6 +-
docs/specification.md | 46 +-
8 files changed, 1277 insertions(+), 16 deletions(-)
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index 60b7b464..c7d6cdc1 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -44,11 +44,57 @@ type VectorStatus struct {
// VectorAgent is the Schema for the Vector Agent
type VectorAgent struct {
// +kubebuilder:default:="timberio/vector:0.24.0-distroless-libc"
- Image string `json:"image,omitempty"`
- DataDir string `json:"dataDir,omitempty"`
- Api *ApiSpec `json:"api,omitempty"`
- Service bool `json:"service,omitempty"`
+ // Image - docker image settings for Vector Agent
+ // if no specified operator uses default config version
+ // +optional
+ Image string `json:"image,omitempty"`
+ // ImagePullSecrets An optional list of references to secrets in the same namespace
+ // to use for pulling images from registries
+ // see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod
+ // +optional
+ ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
+ // Resources container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+ // if not specified - default setting will be used
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resources",xDescriptors="urn:alm:descriptor:com.tectonic.ui:resourceRequirements"
+ // +optional
+ Resources v1.ResourceRequirements `json:"resources,omitempty"`
+ // Affinity If specified, the pod's scheduling constraints.
+ // +optional
+ Affinity *v1.Affinity `json:"affinity,omitempty"`
+ // Tolerations If specified, the pod's tolerations.
+ // +optional
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
+ // SecurityContext holds pod-level security attributes and common container settings.
+ // This defaults to the default PodSecurityContext.
+ // +optional
+ // Tolerations If specified, the pod's tolerations.
+ // +optional
+ SecurityContext *v1.PodSecurityContext `json:"securityContext,omitempty"`
+ // SchedulerName - defines kubernetes scheduler name
+ // +optional
+ SchedulerName string `json:"schedulerName,omitempty"`
+ // RuntimeClassName - defines runtime class for kubernetes pod.
+ // https://kubernetes.io/docs/concepts/containers/runtime-class/
+ RuntimeClassName *string `json:"runtimeClassName,omitempty"`
+ // HostAliases provides mapping between ip and hostnames,
+ // that would be propagated to pod,
+ // cannot be used with HostNetwork.
+ // +optional
+ HostAliases []v1.HostAlias `json:"host_aliases,omitempty"`
+ // PodSecurityPolicyName - defines name for podSecurityPolicy
+ // in case of empty value, prefixedName will be used.
+ // +optional
+ PodSecurityPolicyName string `json:"podSecurityPolicyName,omitempty"`
+ // PriorityClassName assigned to the Pods
+ // +optional
+ PriorityClassName string `json:"priorityClassName,omitempty"`
+ // HostNetwork controls whether the pod may use the node network namespace
+ // +optional
+ HostNetwork bool `json:"hostNetwork,omitempty"`
+
+ DataDir string `json:"dataDir,omitempty"`
+ Api ApiSpec `json:"api,omitempty"`
+ Service bool `json:"service,omitempty"`
}
// ApiSpec is the Schema for the Vector Agent GraphQL API - https://vector.dev/docs/reference/api/
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index cb8f5176..c0fa7efc 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -130,10 +130,16 @@ func (in *Vector) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VectorAgent) DeepCopyInto(out *VectorAgent) {
*out = *in
- if in.Api != nil {
- in, out := &in.Api, &out.Api
- *out = new(ApiSpec)
- **out = **in
+ if in.ImagePullSecrets != nil {
+ in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
+ *out = make([]v1.LocalObjectReference, len(*in))
+ copy(*out, *in)
+ }
+ in.Resources.DeepCopyInto(&out.Resources)
+ if in.Affinity != nil {
+ in, out := &in.Affinity, &out.Affinity
+ *out = new(v1.Affinity)
+ (*in).DeepCopyInto(*out)
}
if in.Tolerations != nil {
in, out := &in.Tolerations, &out.Tolerations
@@ -142,6 +148,24 @@ func (in *VectorAgent) DeepCopyInto(out *VectorAgent) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
+ if in.SecurityContext != nil {
+ in, out := &in.SecurityContext, &out.SecurityContext
+ *out = new(v1.PodSecurityContext)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.RuntimeClassName != nil {
+ in, out := &in.RuntimeClassName, &out.RuntimeClassName
+ *out = new(string)
+ **out = **in
+ }
+ if in.HostAliases != nil {
+ in, out := &in.HostAliases, &out.HostAliases
+ *out = make([]v1.HostAlias, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ out.Api = in.Api
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VectorAgent.
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index 9783f7d7..807da448 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -46,6 +46,874 @@ spec:
description: DisableAggregation DisableAggregation bool `json:"disableAggregation,omitempty"`
Vector Agent
properties:
+ affinity:
+ description: Affinity If specified, the pod's scheduling constraints.
+ properties:
+ nodeAffinity:
+ description: Describes node affinity scheduling rules for
+ the pod.
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule pods
+ to nodes that satisfy the affinity expressions specified
+ by this field, but it may choose a node that violates
+ one or more of the expressions. The node that is most
+ preferred is the one with the greatest sum of weights,
+ i.e. for each node that meets all of the scheduling
+ requirements (resource request, requiredDuringScheduling
+ affinity expressions, etc.), compute a sum by iterating
+ through the elements of this field and adding "weight"
+ to the sum if the node matches the corresponding matchExpressions;
+ the node(s) with the highest sum are the most preferred.
+ items:
+ description: An empty preferred scheduling term matches
+ all objects with implicit weight 0 (i.e. it's a no-op).
+ A null preferred scheduling term matches no objects
+ (i.e. is also a no-op).
+ properties:
+ preference:
+ description: A node selector term, associated with
+ the corresponding weight.
+ properties:
+ matchExpressions:
+ description: A list of node selector requirements
+ by node's labels.
+ items:
+ description: A node selector requirement is
+ a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators
+ are In, NotIn, Exists, DoesNotExist.
+ Gt, and Lt.
+ type: string
+ values:
+ description: 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. If the
+ operator is Gt or Lt, the values array
+ must have a single element, which will
+ be interpreted as an integer. This array
+ is replaced during a strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchFields:
+ description: A list of node selector requirements
+ by node's fields.
+ items:
+ description: A node selector requirement is
+ a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators
+ are In, NotIn, Exists, DoesNotExist.
+ Gt, and Lt.
+ type: string
+ values:
+ description: 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. If the
+ operator is Gt or Lt, the values array
+ must have a single element, which will
+ be interpreted as an integer. This array
+ is replaced during a strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ type: object
+ x-kubernetes-map-type: atomic
+ weight:
+ description: Weight associated with matching the
+ corresponding nodeSelectorTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - preference
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the affinity requirements specified by
+ this field are not met at scheduling time, the pod will
+ not be scheduled onto the node. If the affinity requirements
+ specified by this field cease to be met at some point
+ during pod execution (e.g. due to an update), the system
+ may or may not try to eventually evict the pod from
+ its node.
+ properties:
+ nodeSelectorTerms:
+ description: Required. A list of node selector terms.
+ The terms are ORed.
+ items:
+ description: A null or empty node selector term
+ matches no objects. The requirements of them are
+ ANDed. The TopologySelectorTerm type implements
+ a subset of the NodeSelectorTerm.
+ properties:
+ matchExpressions:
+ description: A list of node selector requirements
+ by node's labels.
+ items:
+ description: A node selector requirement is
+ a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators
+ are In, NotIn, Exists, DoesNotExist.
+ Gt, and Lt.
+ type: string
+ values:
+ description: 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. If the
+ operator is Gt or Lt, the values array
+ must have a single element, which will
+ be interpreted as an integer. This array
+ is replaced during a strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchFields:
+ description: A list of node selector requirements
+ by node's fields.
+ items:
+ description: A node selector requirement is
+ a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators
+ are In, NotIn, Exists, DoesNotExist.
+ Gt, and Lt.
+ type: string
+ values:
+ description: 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. If the
+ operator is Gt or Lt, the values array
+ must have a single element, which will
+ be interpreted as an integer. This array
+ is replaced during a strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ type: object
+ x-kubernetes-map-type: atomic
+ type: array
+ required:
+ - nodeSelectorTerms
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ podAffinity:
+ description: Describes pod affinity scheduling rules (e.g.
+ co-locate this pod in the same node, zone, etc. as some
+ other pod(s)).
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule pods
+ to nodes that satisfy the affinity expressions specified
+ by this field, but it may choose a node that violates
+ one or more of the expressions. The node that is most
+ preferred is the one with the greatest sum of weights,
+ i.e. for each node that meets all of the scheduling
+ requirements (resource request, requiredDuringScheduling
+ affinity expressions, etc.), compute a sum by iterating
+ through the elements of this field and adding "weight"
+ to the sum if the node has pods which matches the corresponding
+ podAffinityTerm; the node(s) with the highest sum are
+ the most preferred.
+ items:
+ description: The weights of all of the matched WeightedPodAffinityTerm
+ fields are added per-node to find the most preferred
+ node(s)
+ properties:
+ podAffinityTerm:
+ description: Required. A pod affinity term, associated
+ with the corresponding weight.
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by
+ this field and the ones listed in the namespaces
+ field. null selector and null or empty namespaces
+ list means "this pod's namespace". An empty
+ selector ({}) matches all namespaces.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to.
+ The term is applied to the union of the namespaces
+ listed in this field and the ones selected
+ by namespaceSelector. null or empty namespaces
+ list and null namespaceSelector means "this
+ pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the
+ pods matching the labelSelector in the specified
+ namespaces, where co-located is defined as
+ running on a node whose value of the label
+ with key topologyKey matches that of any node
+ on which any of the selected pods is running.
+ Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ weight:
+ description: weight associated with matching the
+ corresponding podAffinityTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - podAffinityTerm
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the affinity requirements specified by
+ this field are not met at scheduling time, the pod will
+ not be scheduled onto the node. If the affinity requirements
+ specified by this field cease to be met at some point
+ during pod execution (e.g. due to a pod label update),
+ the system may or may not try to eventually evict the
+ pod from its node. When there are multiple elements,
+ the lists of nodes corresponding to each podAffinityTerm
+ are intersected, i.e. all terms must be satisfied.
+ items:
+ description: Defines a set of pods (namely those matching
+ the labelSelector relative to the given namespace(s))
+ that this pod should be co-located (affinity) or not
+ co-located (anti-affinity) with, where co-located
+ is defined as running on a node whose value of the
+ label with key matches that of any node
+ on which a pod of the set of pods is running
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by this
+ field and the ones listed in the namespaces field.
+ null selector and null or empty namespaces list
+ means "this pod's namespace". An empty selector
+ ({}) matches all namespaces.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to. The
+ term is applied to the union of the namespaces
+ listed in this field and the ones selected by
+ namespaceSelector. null or empty namespaces list
+ and null namespaceSelector means "this pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the pods
+ matching the labelSelector in the specified namespaces,
+ where co-located is defined as running on a node
+ whose value of the label with key topologyKey
+ matches that of any node on which any of the selected
+ pods is running. Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ type: array
+ type: object
+ podAntiAffinity:
+ description: Describes pod anti-affinity scheduling rules
+ (e.g. avoid putting this pod in the same node, zone, etc.
+ as some other pod(s)).
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule pods
+ to nodes that satisfy the anti-affinity expressions
+ specified by this field, but it may choose a node that
+ violates one or more of the expressions. The node that
+ is most preferred is the one with the greatest sum of
+ weights, i.e. for each node that meets all of the scheduling
+ requirements (resource request, requiredDuringScheduling
+ anti-affinity expressions, etc.), compute a sum by iterating
+ through the elements of this field and adding "weight"
+ to the sum if the node has pods which matches the corresponding
+ podAffinityTerm; the node(s) with the highest sum are
+ the most preferred.
+ items:
+ description: The weights of all of the matched WeightedPodAffinityTerm
+ fields are added per-node to find the most preferred
+ node(s)
+ properties:
+ podAffinityTerm:
+ description: Required. A pod affinity term, associated
+ with the corresponding weight.
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by
+ this field and the ones listed in the namespaces
+ field. null selector and null or empty namespaces
+ list means "this pod's namespace". An empty
+ selector ({}) matches all namespaces.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to.
+ The term is applied to the union of the namespaces
+ listed in this field and the ones selected
+ by namespaceSelector. null or empty namespaces
+ list and null namespaceSelector means "this
+ pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the
+ pods matching the labelSelector in the specified
+ namespaces, where co-located is defined as
+ running on a node whose value of the label
+ with key topologyKey matches that of any node
+ on which any of the selected pods is running.
+ Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ weight:
+ description: weight associated with matching the
+ corresponding podAffinityTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - podAffinityTerm
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the anti-affinity requirements specified
+ by this field are not met at scheduling time, the pod
+ will not be scheduled onto the node. If the anti-affinity
+ requirements specified by this field cease to be met
+ at some point during pod execution (e.g. due to a pod
+ label update), the system may or may not try to eventually
+ evict the pod from its node. When there are multiple
+ elements, the lists of nodes corresponding to each podAffinityTerm
+ are intersected, i.e. all terms must be satisfied.
+ items:
+ description: Defines a set of pods (namely those matching
+ the labelSelector relative to the given namespace(s))
+ that this pod should be co-located (affinity) or not
+ co-located (anti-affinity) with, where co-located
+ is defined as running on a node whose value of the
+ label with key matches that of any node
+ on which a pod of the set of pods is running
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by this
+ field and the ones listed in the namespaces field.
+ null selector and null or empty namespaces list
+ means "this pod's namespace". An empty selector
+ ({}) matches all namespaces.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to. The
+ term is applied to the union of the namespaces
+ listed in this field and the ones selected by
+ namespaceSelector. null or empty namespaces list
+ and null namespaceSelector means "this pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the pods
+ matching the labelSelector in the specified namespaces,
+ where co-located is defined as running on a node
+ whose value of the label with key topologyKey
+ matches that of any node on which any of the selected
+ pods is running. Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ type: array
+ type: object
+ type: object
api:
description: ApiSpec is the Schema for the Vector Agent GraphQL
API - https://vector.dev/docs/reference/api/
@@ -59,12 +927,268 @@ spec:
type: object
dataDir:
type: string
+ host_aliases:
+ description: HostAliases provides mapping between ip and hostnames,
+ that would be propagated to pod, cannot be used with HostNetwork.
+ items:
+ description: HostAlias holds the mapping between IP and hostnames
+ that will be injected as an entry in the pod's hosts file.
+ properties:
+ hostnames:
+ description: Hostnames for the above IP address.
+ items:
+ type: string
+ type: array
+ ip:
+ description: IP address of the host file entry.
+ type: string
+ type: object
+ type: array
+ hostNetwork:
+ description: HostNetwork controls whether the pod may use the
+ node network namespace
+ type: boolean
image:
default: timberio/vector:0.24.0-distroless-libc
+ description: Image - docker image settings for Vector Agent if
+ no specified operator uses default config version
type: string
+ imagePullSecrets:
+ description: ImagePullSecrets An optional list of references to
+ secrets in the same namespace to use for pulling images from
+ registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod
+ items:
+ description: LocalObjectReference contains enough information
+ to let you locate the referenced object inside the same namespace.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ type: array
+ podSecurityPolicyName:
+ description: PodSecurityPolicyName - defines name for podSecurityPolicy
+ in case of empty value, prefixedName will be used.
+ type: string
+ priorityClassName:
+ description: PriorityClassName assigned to the Pods
+ type: string
+ resources:
+ description: Resources container resource request and limits,
+ https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+ if not specified - default setting will be used
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ runtimeClassName:
+ description: RuntimeClassName - defines runtime class for kubernetes
+ pod. https://kubernetes.io/docs/concepts/containers/runtime-class/
+ type: string
+ schedulerName:
+ description: SchedulerName - defines kubernetes scheduler name
+ type: string
+ securityContext:
+ description: PodSecurityContext holds pod-level security attributes
+ and common container settings. Some fields are also present
+ in container.securityContext. Field values of container.securityContext
+ take precedence over field values of PodSecurityContext.
+ properties:
+ fsGroup:
+ description: "A special supplemental group that applies to
+ all containers in a pod. Some volume types allow the Kubelet
+ to change the ownership of that volume to be owned by the
+ pod: \n 1. The owning GID will be the FSGroup 2. The setgid
+ bit is set (new files created in the volume will be owned
+ by FSGroup) 3. The permission bits are OR'd with rw-rw----
+ \n If unset, the Kubelet will not modify the ownership and
+ permissions of any volume. Note that this field cannot be
+ set when spec.os.name is windows."
+ format: int64
+ type: integer
+ fsGroupChangePolicy:
+ description: 'fsGroupChangePolicy defines behavior of changing
+ ownership and permission of the volume before being exposed
+ inside Pod. This field will only apply to volume types which
+ support fsGroup based ownership(and permissions). It will
+ have no effect on ephemeral volume types such as: secret,
+ configmaps and emptydir. Valid values are "OnRootMismatch"
+ and "Always". If not specified, "Always" is used. Note that
+ this field cannot be set when spec.os.name is windows.'
+ type: string
+ runAsGroup:
+ description: The GID to run the entrypoint of the container
+ process. Uses runtime default if unset. May also be set
+ in SecurityContext. If set in both SecurityContext and
+ PodSecurityContext, the value specified in SecurityContext
+ takes precedence for that container. Note that this field
+ cannot be set when spec.os.name is windows.
+ format: int64
+ type: integer
+ runAsNonRoot:
+ description: Indicates that the container must run as a non-root
+ user. If true, the Kubelet will validate the image at runtime
+ to ensure that it does not run as UID 0 (root) and fail
+ to start the container if it does. If unset or false, no
+ such validation will be performed. May also be set in SecurityContext. If
+ set in both SecurityContext and PodSecurityContext, the
+ value specified in SecurityContext takes precedence.
+ type: boolean
+ runAsUser:
+ description: The UID to run the entrypoint of the container
+ process. Defaults to user specified in image metadata if
+ unspecified. May also be set in SecurityContext. If set
+ in both SecurityContext and PodSecurityContext, the value
+ specified in SecurityContext takes precedence for that container.
+ Note that this field cannot be set when spec.os.name is
+ windows.
+ format: int64
+ type: integer
+ seLinuxOptions:
+ description: The SELinux context to be applied to all containers.
+ If unspecified, the container runtime will allocate a random
+ SELinux context for each container. May also be set in
+ SecurityContext. If set in both SecurityContext and PodSecurityContext,
+ the value specified in SecurityContext takes precedence
+ for that container. Note that this field cannot be set when
+ spec.os.name is windows.
+ properties:
+ level:
+ description: Level is SELinux level label that applies
+ to the container.
+ type: string
+ role:
+ description: Role is a SELinux role label that applies
+ to the container.
+ type: string
+ type:
+ description: Type is a SELinux type label that applies
+ to the container.
+ type: string
+ user:
+ description: User is a SELinux user label that applies
+ to the container.
+ type: string
+ type: object
+ seccompProfile:
+ description: The seccomp options to use by the containers
+ in this pod. Note that this field cannot be set when spec.os.name
+ is windows.
+ properties:
+ localhostProfile:
+ description: localhostProfile indicates a profile defined
+ in a file on the node should be used. The profile must
+ be preconfigured on the node to work. Must be a descending
+ path, relative to the kubelet's configured seccomp profile
+ location. Must only be set if type is "Localhost".
+ type: string
+ type:
+ description: "type indicates which kind of seccomp profile
+ will be applied. Valid options are: \n Localhost - a
+ profile defined in a file on the node should be used.
+ RuntimeDefault - the container runtime default profile
+ should be used. Unconfined - no profile should be applied."
+ type: string
+ required:
+ - type
+ type: object
+ supplementalGroups:
+ description: A list of groups applied to the first process
+ run in each container, in addition to the container's primary
+ GID. If unspecified, no groups will be added to any container.
+ Note that this field cannot be set when spec.os.name is
+ windows.
+ items:
+ format: int64
+ type: integer
+ type: array
+ sysctls:
+ description: Sysctls hold a list of namespaced sysctls used
+ for the pod. Pods with unsupported sysctls (by the container
+ runtime) might fail to launch. Note that this field cannot
+ be set when spec.os.name is windows.
+ items:
+ description: Sysctl defines a kernel parameter to be set
+ properties:
+ name:
+ description: Name of a property to set
+ type: string
+ value:
+ description: Value of a property to set
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ windowsOptions:
+ description: The Windows specific settings applied to all
+ containers. If unspecified, the options within a container's
+ SecurityContext will be used. If set in both SecurityContext
+ and PodSecurityContext, the value specified in SecurityContext
+ takes precedence. Note that this field cannot be set when
+ spec.os.name is linux.
+ properties:
+ gmsaCredentialSpec:
+ description: GMSACredentialSpec is where the GMSA admission
+ webhook (https://github.com/kubernetes-sigs/windows-gmsa)
+ inlines the contents of the GMSA credential spec named
+ by the GMSACredentialSpecName field.
+ type: string
+ gmsaCredentialSpecName:
+ description: GMSACredentialSpecName is the name of the
+ GMSA credential spec to use.
+ type: string
+ hostProcess:
+ description: HostProcess determines if a container should
+ be run as a 'Host Process' container. This field is
+ alpha-level and will only be honored by components that
+ enable the WindowsHostProcessContainers feature flag.
+ Setting this field without the feature flag will result
+ in errors when validating the Pod. All of a Pod's containers
+ must have the same effective HostProcess value (it is
+ not allowed to have a mix of HostProcess containers
+ and non-HostProcess containers). In addition, if HostProcess
+ is true then HostNetwork must also be set to true.
+ type: boolean
+ runAsUserName:
+ description: The UserName in Windows to run the entrypoint
+ of the container process. Defaults to the user specified
+ in image metadata if unspecified. May also be set in
+ PodSecurityContext. If set in both SecurityContext and
+ PodSecurityContext, the value specified in SecurityContext
+ takes precedence.
+ type: string
+ type: object
+ type: object
service:
type: boolean
tolerations:
+ description: SecurityContext holds pod-level security attributes
+ and common container settings. This defaults to the default
+ PodSecurityContext. Tolerations If specified, the pod's tolerations.
items:
description: The pod this Toleration is attached to tolerates
any taint that matches the triple using
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
index 7002c8a5..139d458c 100644
--- a/controllers/factory/vector/vector.go
+++ b/controllers/factory/vector/vector.go
@@ -27,7 +27,7 @@ func New(vector *vectorv1alpha1.Vector) *VectorConfig {
return &VectorConfig{
DataDir: vector.Spec.Agent.DataDir,
- Api: vector.Spec.Agent.Api,
+ Api: &vector.Spec.Agent.Api,
Sources: sources,
Sinks: sinks,
}
diff --git a/controllers/factory/vector/vectoragent/vectoragent_daemonset.go b/controllers/factory/vector/vectoragent/vectoragent_daemonset.go
index e551b8df..6351b703 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_daemonset.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_daemonset.go
@@ -34,8 +34,15 @@ func (ctrl *Controller) createVectorAgentDaemonSet() *appsv1.DaemonSet {
Spec: corev1.PodSpec{
ServiceAccountName: ctrl.getNameVectorAgent(),
Volumes: ctrl.generateVectorAgentVolume(),
- SecurityContext: &corev1.PodSecurityContext{},
+ SecurityContext: ctrl.Vector.Spec.Agent.SecurityContext,
+ ImagePullSecrets: ctrl.Vector.Spec.Agent.ImagePullSecrets,
+ Affinity: ctrl.Vector.Spec.Agent.Affinity,
+ RuntimeClassName: ctrl.Vector.Spec.Agent.RuntimeClassName,
+ SchedulerName: ctrl.Vector.Spec.Agent.SchedulerName,
Tolerations: ctrl.Vector.Spec.Agent.Tolerations,
+ PriorityClassName: ctrl.Vector.Spec.Agent.PodSecurityPolicyName,
+ HostNetwork: ctrl.Vector.Spec.Agent.HostNetwork,
+ HostAliases: ctrl.Vector.Spec.Agent.HostAliases,
Containers: []corev1.Container{
{
Name: ctrl.getNameVectorAgent(),
@@ -50,6 +57,7 @@ func (ctrl *Controller) createVectorAgentDaemonSet() *appsv1.DaemonSet {
},
},
VolumeMounts: ctrl.generateVectorAgentVolumeMounts(),
+ Resources: ctrl.Vector.Spec.Agent.Resources,
SecurityContext: &corev1.SecurityContext{},
},
},
diff --git a/controllers/factory/vector/vectoragent/vectoragent_default.go b/controllers/factory/vector/vectoragent/vectoragent_default.go
index 5f760472..fefeddaa 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_default.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_default.go
@@ -16,7 +16,26 @@ limitations under the License.
package vectoragent
+import (
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/resource"
+)
+
func (ctrl *Controller) SetDefault() {
+ if ctrl.Vector.Spec.Agent.Image == "" {
+ ctrl.Vector.Spec.Agent.Image = "timberio/vector:0.24.0-distroless-libc"
+ }
+
+ if ctrl.Vector.Spec.Agent.Resources.Requests == nil {
+ ctrl.Vector.Spec.Agent.Resources.Requests[corev1.ResourceMemory] = resource.MustParse("200Mi")
+ ctrl.Vector.Spec.Agent.Resources.Requests[corev1.ResourceCPU] = resource.MustParse("100m")
+ }
+
+ if ctrl.Vector.Spec.Agent.Resources.Limits == nil {
+ ctrl.Vector.Spec.Agent.Resources.Limits[corev1.ResourceMemory] = resource.MustParse("1000Mi")
+ ctrl.Vector.Spec.Agent.Resources.Limits[corev1.ResourceCPU] = resource.MustParse("1000m")
+ }
+
if ctrl.Vector.Spec.Agent.Api.Address == "" {
ctrl.Vector.Spec.Agent.Api.Address = "0.0.0.0:8686"
}
diff --git a/docs/design.md b/docs/design.md
index 10dc27e1..1c75b8e5 100644
--- a/docs/design.md
+++ b/docs/design.md
@@ -24,7 +24,7 @@ For each Vector resource, the Operator adds:
- Add features for compress Vector configuration file. (Delete dublicates sources/Transforms/Sinks. Compress to gzip)
## Specification
-Specification access to [this]() page
+Specification access to [this](https://github.com/kaasops/vector-operator/blob/main/docs/specification.md#vector-spec) page
# VectorPipeline
@@ -36,7 +36,7 @@ All `VectorPipelines`, with validated configuration file, added to Vector config
- For source field `extra_namespace_label_selector` cannot be installed. The operator control this field and sets the namespace there, where VectorPipeline is defined.
## Specification
-Specification access to [this]() page
+Specification access to [this](https://github.com/kaasops/vector-operator/blob/main/docs/specification.md#vectorpipelinespec-clustervectorpipelinespec) page
# ClusterVectorPipeline
The `ClusterVectorPipeline` CRD defines Sources, Transforms and Sinks rules for Vector.
@@ -45,4 +45,4 @@ All `ClusterVectorPipelines`, with validated configuration file, added to Vector
ClusterVectorPipelines works like VectorPipeline, but without restrictions.
## Specification
-Specification access to [this]() page
\ No newline at end of file
+Specification access to [this](https://github.com/kaasops/vector-operator/blob/main/docs/specification.md#vectorpipelinespec-clustervectorpipelinespec) page
\ No newline at end of file
diff --git a/docs/specification.md b/docs/specification.md
index f4b717fb..49776e5f 100644
--- a/docs/specification.md
+++ b/docs/specification.md
@@ -1,15 +1,15 @@
# Specification
- [Vector](#vector-spec)
-- VectorPipeline
-- ClusterVectorPipeline
+- [VectorPipeline](#vectorpipelinespec-clustervectorpipelinespec)
+- [ClusterVectorPipeline](#vectorpipelinespec-clustervectorpipelinespec)
# Vector Spec
- agent
+ agent
image
Image for Vector agent. timberio/vector:0.24.0-distroless-libc by default
@@ -36,10 +36,50 @@
service
Temporary field for enabling service for Vector DaemonSet. By default - false
+
+ imagePullSecrets
+ ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries. By default not set
+
+
+ resources
+ Resources container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. If not specified - default setting will be used
+
+
+ affinity
+ Affinity If specified, the pod's scheduling constraints. By default not set
+
tolerations
Tolerations for Vector DaemonSet. By default - nil
+
+ securityContext
+ SecurityContext holds pod-level security attributes and common container settings. By default - not set
+
+
+ schedulerName
+ SchedulerName - defines kubernetes scheduler name. By default - not set
+
+
+ runtimeClassName
+ RuntimeClassName - defines runtime class for kubernetes pod.. By default - not set
+
+
+ hostAliases
+ HostAliases provides mapping between ip and hostnames, that would be propagated to pod.
+
+
+ podSecurityPolicyName
+ PodSecurityPolicyName - defines name for podSecurityPolicy in case of empty value, prefixedName will be used.
+
+
+ priorityClassName
+ PriorityClassName assigned to the Pods.
+
+
+ hostNetwork
+ HostNetwork controls whether the pod may use the node network namespace.
+
From c4a673355f3b08187842750d03cbc541709989bd Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 17:40:47 +0300
Subject: [PATCH 057/316] Add field env to Vector spec
Signed-off-by: Zemtsov Vladimir
---
api/v1alpha1/vector_types.go | 2 +
api/v1alpha1/zz_generated.deepcopy.go | 7 +
.../observability.kaasops.io_vectors.yaml | 125 +++++++++++++++++-
docs/specification.md | 42 +++---
4 files changed, 154 insertions(+), 22 deletions(-)
diff --git a/api/v1alpha1/vector_types.go b/api/v1alpha1/vector_types.go
index c7d6cdc1..9992dab2 100644
--- a/api/v1alpha1/vector_types.go
+++ b/api/v1alpha1/vector_types.go
@@ -91,6 +91,8 @@ type VectorAgent struct {
// HostNetwork controls whether the pod may use the node network namespace
// +optional
HostNetwork bool `json:"hostNetwork,omitempty"`
+ // Env that will be added to Vector pod
+ Env []v1.EnvVar `json:"env,omitempty"`
DataDir string `json:"dataDir,omitempty"`
Api ApiSpec `json:"api,omitempty"`
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index c0fa7efc..52a62c40 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -165,6 +165,13 @@ func (in *VectorAgent) DeepCopyInto(out *VectorAgent) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
+ if in.Env != nil {
+ in, out := &in.Env, &out.Env
+ *out = make([]v1.EnvVar, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
out.Api = in.Api
}
diff --git a/config/crd/bases/observability.kaasops.io_vectors.yaml b/config/crd/bases/observability.kaasops.io_vectors.yaml
index 807da448..1bc130b3 100644
--- a/config/crd/bases/observability.kaasops.io_vectors.yaml
+++ b/config/crd/bases/observability.kaasops.io_vectors.yaml
@@ -927,6 +927,120 @@ spec:
type: object
dataDir:
type: string
+ env:
+ description: Env that will be added to Vector pod
+ items:
+ description: EnvVar represents an environment variable present
+ in a Container.
+ properties:
+ name:
+ description: Name of the environment variable. Must be a
+ C_IDENTIFIER.
+ type: string
+ value:
+ description: 'Variable references $(VAR_NAME) are expanded
+ using the previously defined environment variables in
+ the container and any service environment variables. If
+ a variable cannot be resolved, the reference in the input
+ string will be unchanged. Double $$ are reduced to a single
+ $, which allows for escaping the $(VAR_NAME) syntax: i.e.
+ "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+ Escaped references will never be expanded, regardless
+ of whether the variable exists or not. Defaults to "".'
+ type: string
+ valueFrom:
+ description: Source for the environment variable's value.
+ Cannot be used if value is not empty.
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ fieldRef:
+ description: 'Selects a field of the pod: supports metadata.name,
+ metadata.namespace, `metadata.labels['''']`,
+ `metadata.annotations['''']`, spec.nodeName,
+ spec.serviceAccountName, status.hostIP, status.podIP,
+ status.podIPs.'
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ x-kubernetes-map-type: atomic
+ resourceFieldRef:
+ description: 'Selects a resource of the container: only
+ resources limits and requests (limits.cpu, limits.memory,
+ limits.ephemeral-storage, requests.cpu, requests.memory
+ and requests.ephemeral-storage) are currently supported.'
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ x-kubernetes-map-type: atomic
+ secretKeyRef:
+ description: Selects a key of a secret in the pod's
+ namespace
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ required:
+ - name
+ type: object
+ type: array
host_aliases:
description: HostAliases provides mapping between ip and hostnames,
that would be propagated to pod, cannot be used with HostNetwork.
@@ -1011,10 +1125,9 @@ spec:
description: SchedulerName - defines kubernetes scheduler name
type: string
securityContext:
- description: PodSecurityContext holds pod-level security attributes
- and common container settings. Some fields are also present
- in container.securityContext. Field values of container.securityContext
- take precedence over field values of PodSecurityContext.
+ description: SecurityContext holds pod-level security attributes
+ and common container settings. This defaults to the default
+ PodSecurityContext. Tolerations If specified, the pod's tolerations.
properties:
fsGroup:
description: "A special supplemental group that applies to
@@ -1186,9 +1299,7 @@ spec:
service:
type: boolean
tolerations:
- description: SecurityContext holds pod-level security attributes
- and common container settings. This defaults to the default
- PodSecurityContext. Tolerations If specified, the pod's tolerations.
+ description: Tolerations If specified, the pod's tolerations.
items:
description: The pod this Toleration is attached to tolerates
any taint that matches the triple using
diff --git a/docs/specification.md b/docs/specification.md
index 49776e5f..aa67c9b5 100644
--- a/docs/specification.md
+++ b/docs/specification.md
@@ -9,7 +9,7 @@
# Vector Spec
- agent
+ agent
image
Image for Vector agent. timberio/vector:0.24.0-distroless-libc by default
@@ -18,19 +18,8 @@
DataDir for Vector Agent. `/vector-data-dir` by default
- api
-
-
- address
- The network address to which the API should bind. If you’re running Vector in a Docker container, make sure to bind to 0.0.0.0. Otherwise the API will not be exposed outside the container. By default - 0.0.0.0:8686
-
-
- enabled
- Whether the GraphQL API is enabled for this Vector instance. By default - false
-
-
- playground
- Whether the GraphQL Playground is enabled for the API. The Playground is accessible via the /playground endpoint of the address set using the bind parameter. By default - false
+ api
+ ApiSpec
service
@@ -62,7 +51,7 @@
runtimeClassName
- RuntimeClassName - defines runtime class for kubernetes pod.. By default - not set
+ RuntimeClassName - defines runtime class for kubernetes pod. By default - not set
hostAliases
@@ -80,6 +69,29 @@
hostNetwork
HostNetwork controls whether the pod may use the node network namespace.
+
+ env
+ Env that will be added to Vector pod. By default - not set
+
+
+
+## ApiSpec
+
+
+ api
+
+
+ address
+ The network address to which the API should bind. If you’re running Vector in a Docker container, make sure to bind to 0.0.0.0. Otherwise the API will not be exposed outside the container. By default - 0.0.0.0:8686
+
+
+ enabled
+ Whether the GraphQL API is enabled for this Vector instance. By default - false
+
+
+ playground
+ Whether the GraphQL Playground is enabled for the API. The Playground is accessible via the /playground endpoint of the address set using the bind parameter. By default - false
+
From 1786d69fa87adc47cd3a66689e65df890bf08202 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 17:41:32 +0300
Subject: [PATCH 058/316] docs: Cleanup specification
Signed-off-by: Zemtsov Vladimir
---
docs/specification.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/specification.md b/docs/specification.md
index aa67c9b5..0556d071 100644
--- a/docs/specification.md
+++ b/docs/specification.md
@@ -75,7 +75,7 @@
-## ApiSpec
+## Api Spec
api
From ab5b24c2848fb1e23bc4809f834b0240a4915a04 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 31 Oct 2022 17:51:19 +0300
Subject: [PATCH 059/316] fix configcheck to delete pod-secret pairs (#27)
---
.../factory/config/configcheck/configcheck.go | 23 +++++++++++--------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index 633dba4c..98565ae3 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -24,6 +24,7 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
+ "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
@@ -175,27 +176,29 @@ func (cc *ConfigCheck) cleanup() error {
}
podlist := corev1.PodList{}
- secretList := corev1.SecretList{}
err = cc.Client.List(cc.Ctx, &podlist, &listOpts)
if err != nil {
return err
}
- err = cc.Client.List(cc.Ctx, &secretList, &listOpts)
- if err != nil {
- return err
- }
for _, pod := range podlist.Items {
if pod.Status.Phase == "Succeeded" {
+ for _, v := range pod.Spec.Volumes {
+ if v.Name == "config" {
+ secret := &corev1.Secret{}
+ secretName := v.Secret.SecretName
+ if err := cc.Client.Get(cc.Ctx, types.NamespacedName{Name: secretName, Namespace: pod.Namespace}, secret); err != nil {
+ return err
+ }
+ if err := cc.Client.Delete(cc.Ctx, secret); err != nil {
+ return err
+ }
+ }
+ }
if err := cc.Client.Delete(cc.Ctx, &pod); err != nil {
return err
}
}
}
- for _, secret := range secretList.Items {
- if err := cc.Client.Delete(cc.Ctx, &secret); err != nil {
- return err
- }
- }
return nil
}
From d6f32dd64dde1729146cfce1e930438c0a9eccfa Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Mon, 31 Oct 2022 17:58:19 +0300
Subject: [PATCH 060/316] Vector: Fix error if field resource not set
Signed-off-by: Zemtsov Vladimir
---
.../vector/vectoragent/vectoragent_default.go | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/controllers/factory/vector/vectoragent/vectoragent_default.go b/controllers/factory/vector/vectoragent/vectoragent_default.go
index fefeddaa..4d0c80e5 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_default.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_default.go
@@ -18,7 +18,7 @@ package vectoragent
import (
corev1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/resource"
+ resourcev1 "k8s.io/apimachinery/pkg/api/resource"
)
func (ctrl *Controller) SetDefault() {
@@ -27,13 +27,16 @@ func (ctrl *Controller) SetDefault() {
}
if ctrl.Vector.Spec.Agent.Resources.Requests == nil {
- ctrl.Vector.Spec.Agent.Resources.Requests[corev1.ResourceMemory] = resource.MustParse("200Mi")
- ctrl.Vector.Spec.Agent.Resources.Requests[corev1.ResourceCPU] = resource.MustParse("100m")
+ ctrl.Vector.Spec.Agent.Resources.Requests = corev1.ResourceList{
+ corev1.ResourceMemory: resourcev1.MustParse("200Mi"),
+ corev1.ResourceCPU: resourcev1.MustParse("100m"),
+ }
}
-
if ctrl.Vector.Spec.Agent.Resources.Limits == nil {
- ctrl.Vector.Spec.Agent.Resources.Limits[corev1.ResourceMemory] = resource.MustParse("1000Mi")
- ctrl.Vector.Spec.Agent.Resources.Limits[corev1.ResourceCPU] = resource.MustParse("1000m")
+ ctrl.Vector.Spec.Agent.Resources.Limits = corev1.ResourceList{
+ corev1.ResourceMemory: resourcev1.MustParse("1024Mi"),
+ corev1.ResourceCPU: resourcev1.MustParse("1000m"),
+ }
}
if ctrl.Vector.Spec.Agent.Api.Address == "" {
From 45fa2e2e689313fe10bf10ba3e1cec072d5386ab Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 31 Oct 2022 22:35:22 +0200
Subject: [PATCH 061/316] refactor gc
---
.../factory/config/configcheck/configcheck.go | 13 ++++++----
controllers/factory/utils/k8s/k8s.go | 24 +++++++++++++++++++
2 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index 98565ae3..c7343771 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -184,17 +184,20 @@ func (cc *ConfigCheck) cleanup() error {
if pod.Status.Phase == "Succeeded" {
for _, v := range pod.Spec.Volumes {
if v.Name == "config" {
- secret := &corev1.Secret{}
- secretName := v.Secret.SecretName
- if err := cc.Client.Get(cc.Ctx, types.NamespacedName{Name: secretName, Namespace: pod.Namespace}, secret); err != nil {
+ nn := types.NamespacedName{
+ Name: v.Secret.SecretName,
+ Namespace: pod.Namespace,
+ }
+ secret, err := k8s.GetSecret(nn, cc.Client)
+ if err != nil {
return err
}
- if err := cc.Client.Delete(cc.Ctx, secret); err != nil {
+ if err := k8s.DeleteSecret(secret, cc.Client); err != nil {
return err
}
}
}
- if err := cc.Client.Delete(cc.Ctx, &pod); err != nil {
+ if err := k8s.DeletePod(&pod, cc.Client); err != nil {
return err
}
}
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index 5ee3c494..8f3863da 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -27,6 +27,7 @@ import (
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
)
@@ -76,6 +77,29 @@ func GetPod(pod *corev1.Pod, c client.Client) (*corev1.Pod, error) {
return result, nil
}
+func DeletePod(pod *corev1.Pod, c client.Client) error {
+ if err := c.Delete(context.TODO(), pod); err != nil {
+ return err
+ }
+ return nil
+}
+
+func GetSecret(namespacedName types.NamespacedName, c client.Client) (*corev1.Secret, error) {
+ result := &corev1.Secret{}
+ err := c.Get(context.TODO(), namespacedName, result)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func DeleteSecret(secret *corev1.Secret, c client.Client) error {
+ if err := c.Delete(context.TODO(), secret); err != nil {
+ return err
+ }
+ return nil
+}
+
func GetPodLogs(pod *corev1.Pod, cs *kubernetes.Clientset) (string, error) {
count := int64(100)
podLogOptions := corev1.PodLogOptions{
From e76ff4d713c95fdd865aebee74eecefa8bb3bbcb Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Tue, 1 Nov 2022 13:17:42 +0300
Subject: [PATCH 062/316] Clusterpipeline (#28)
* added clusterpipeline feature
---
.../clustervectorpipeline_controller.go | 174 ++++++++++++------
controllers/factory/config/config.go | 36 +++-
controllers/factory/config/config_build.go | 15 +-
controllers/factory/pipeline/pipeline.go | 18 +-
controllers/factory/utils/k8s/k8s.go | 4 +
controllers/factory/vector/types.go | 8 +-
controllers/factory/vector/vector.go | 4 +-
7 files changed, 177 insertions(+), 82 deletions(-)
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
index f785e859..8cc8c017 100644
--- a/controllers/clustervectorpipeline_controller.go
+++ b/controllers/clustervectorpipeline_controller.go
@@ -19,6 +19,7 @@ package controllers
import (
"context"
+ "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
@@ -26,6 +27,11 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/config"
+ "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline/clustervectorpipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
)
// ClusterVectorPipelineReconciler reconciles a ClusterVectorPipeline object
@@ -51,68 +57,118 @@ type ClusterVectorPipelineReconciler struct {
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.2/pkg/reconcile
func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
- log := log.FromContext(ctx).WithValues("VectorPipeline", req.Name)
-
- log.Info("start Reconcile ClusterVectorPipeline")
-
- // cvp, err := r.findClusterVectorPipelineCustomResourceInstance(ctx, req)
- // if err != nil {
- // log.Error(err, "Failed to get Cluster Vector Pipeline")
- // return ctrl.Result{}, err
- // }
- // if cvp == nil {
- // log.Info("Cluster Vector Pipeline CR not found. Ignoring since object must be deleted")
- // return ctrl.Result{}, nil
- // }
- // hash, err := vectorpipeline.GetSpecHash(cvp.Spec)
- // if err != nil {
- // return ctrl.Result{}, err
- // }
- // if cvp.Status.LastAppliedPipelineHash != nil && *hash == *cvp.Status.LastAppliedPipelineHash {
- // log.Info("ClusterVectorPipeline has no changes. Finish Reconcile ClusterVectorPipeline")
- // return ctrl.Result{}, nil
- // }
-
- // vectorInstances := &vectorv1alpha1.VectorList{}
- // err = r.List(ctx, vectorInstances)
- // if err != nil {
- // return ctrl.Result{}, err
- // }
-
- // if len(vectorInstances.Items) == 0 {
- // log.Info("Vertors not found")
- // return ctrl.Result{}, nil
- // }
-
- // for _, v := range vectorInstances.Items {
- // if v.DeletionTimestamp != nil {
- // continue
- // }
- // if err = checkConfig(ctx, &v, vp, r.Client, r.Clientset); err != nil {
- // return ctrl.Result{}, err
- // }
- // if err = vectorpipeline.SetLastAppliedPipelineStatus(ctx, vp, r.Client); err != nil {
- // return ctrl.Result{}, err
- // }
-
- // }
-
- log.Info("finish Reconcile ClusterVectorPipeline")
+ log := log.FromContext(ctx).WithValues("ClusterVectorPipeline", req.Name)
+
+ log.Info("start Reconcile VectorPipeline")
+
+ // Get CR VectorPipeline
+ vectorPipelineCR, err := r.findClusterVectorPipelineCustomResourceInstance(ctx, req)
+ if err != nil {
+ log.Error(err, "Failed to get Vector Pipeline")
+ return ctrl.Result{}, err
+ }
+ if vectorPipelineCR == nil {
+ log.Info("VectorPIpeline CR not found. Ignoring since object must be deleted")
+ return ctrl.Result{}, nil
+ }
+
+ // Generate VectorPipeline Controller
+ vpCtrl := clustervectorpipeline.NewController(vectorPipelineCR)
+ // Generate Pipeline Controller
+ pCtrl := pipeline.NewController(ctx, r.Client, vpCtrl)
+
+ // Check Pipeline hash
+ checkResult, err := pCtrl.CheckHash()
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+ if checkResult {
+ log.Info("VectorPipeline has no changes. Finish Reconcile VectorPipeline")
+ return ctrl.Result{}, nil
+ }
+
+ // Generate Pipeline ConfigCheck for all Vectors
+ vectorInstances := &vectorv1alpha1.VectorList{}
+ err = r.List(ctx, vectorInstances)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
+ if len(vectorInstances.Items) == 0 {
+ log.Info("Vertors not found")
+ return ctrl.Result{}, nil
+ }
+
+ for _, vector := range vectorInstances.Items {
+ if vector.DeletionTimestamp != nil {
+ continue
+ }
+
+ // Init Controller for Vector Agent
+ vaCtrl := vectoragent.NewController(&vector, r.Client, r.Clientset)
+ if vaCtrl.Vector.Spec.Agent.DataDir == "" {
+ vaCtrl.Vector.Spec.Agent.DataDir = "/vector-data-dir"
+ }
+
+ // Get Vector Config file
+ config, err := config.New(ctx, vaCtrl)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+ if err := config.FillForVectorPipeline(pCtrl); err != nil {
+ return ctrl.Result{}, err
+ }
+
+ // Get Config in Json ([]byte)
+ byteConfig, err := config.GetByteConfig()
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
+ // Init CheckConfig
+ configCheck := configcheck.New(ctx, byteConfig, vaCtrl.Client, vaCtrl.ClientSet, vaCtrl.Vector.Name, vaCtrl.Vector.Namespace, vaCtrl.Vector.Spec.Agent.Image)
+
+ // Start ConfigCheck
+ err = configCheck.Run()
+ if _, ok := err.(*configcheck.ConfigCheckError); ok {
+ if err := pCtrl.SetFailedStatus(err); err != nil {
+ return ctrl.Result{}, err
+ }
+ if err = pCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ return ctrl.Result{}, err
+ }
+ return ctrl.Result{}, nil
+ }
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
+ if err = pCtrl.SetSucceesStatus(); err != nil {
+ return ctrl.Result{}, err
+ }
+
+ if err = pCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ return ctrl.Result{}, err
+ }
+
+ }
+
+ log.Info("finish Reconcile VectorPipeline")
return ctrl.Result{}, nil
}
-// func (r *ClusterVectorPipelineReconciler) findClusterVectorPipelineCustomResourceInstance(ctx context.Context, req ctrl.Request) (*vectorv1alpha1.ClusterVectorPipeline, error) {
-// // fetch the master instance
-// cvp := &vectorv1alpha1.ClusterVectorPipeline{}
-// err := r.Get(ctx, req.NamespacedName, cvp)
-// if err != nil {
-// if errors.IsNotFound(err) {
-// return nil, nil
-// }
-// return nil, err
-// }
-// return cvp, nil
-// }
+func (r *ClusterVectorPipelineReconciler) findClusterVectorPipelineCustomResourceInstance(ctx context.Context, req ctrl.Request) (*vectorv1alpha1.ClusterVectorPipeline, error) {
+ // fetch the master instance
+ cvp := &vectorv1alpha1.ClusterVectorPipeline{}
+ err := r.Get(ctx, req.NamespacedName, cvp)
+ if err != nil {
+ if errors.IsNotFound(err) {
+ return nil, nil
+ }
+ return nil, err
+ }
+ return cvp, nil
+}
// SetupWithManager sets up the controller with the Manager.
func (r *ClusterVectorPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
diff --git a/controllers/factory/config/config.go b/controllers/factory/config/config.go
index da4f8159..6c713a57 100644
--- a/controllers/factory/config/config.go
+++ b/controllers/factory/config/config.go
@@ -19,8 +19,11 @@ package config
import (
"context"
"encoding/json"
+ "errors"
"github.com/kaasops/vector-operator/controllers/factory/pipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline/clustervectorpipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
"github.com/kaasops/vector-operator/controllers/factory/vector"
"github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
"github.com/mitchellh/mapstructure"
@@ -62,11 +65,11 @@ func (cfg *Config) FillForVectorAgent() error {
return nil
}
-func (cfg *Config) FillForVectorPipeline(vCtrl *pipeline.Controller) error {
- cfg.Name = vCtrl.Pipeline.Name()
+func (cfg *Config) FillForVectorPipeline(pCtrl *pipeline.Controller) error {
+ cfg.Name = pCtrl.Pipeline.Name()
pCtrls := make([]pipeline.Controller, 1)
- pCtrls[0] = *vCtrl
+ pCtrls[0] = *pCtrl
cfg.pCtrls = pCtrls
@@ -74,6 +77,17 @@ func (cfg *Config) FillForVectorPipeline(vCtrl *pipeline.Controller) error {
return err
}
+ err := cfg.Validate()
+ if err != nil {
+ if err := pCtrl.SetFailedStatus(err); err != nil {
+ return err
+ }
+ if err := pCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ return err
+ }
+ return err
+ }
+
return nil
}
@@ -127,3 +141,19 @@ func CfgToMap(cfg vector.VectorConfig) (cfgMap map[string]interface{}, err error
return cfgMap, nil
}
+
+func (cfg *Config) Validate() error {
+ err := errors.New("type kubernetes_logs only allowed")
+ vp := cfg.pCtrls[0]
+ for _, source := range cfg.VectorConfig.Sources {
+ if vp.Pipeline.Type() != clustervectorpipeline.Type {
+ if source.Type != "kubernetes_logs" {
+ return err
+ }
+ if source.ExtraNamespaceLabelSelector != "" && source.ExtraNamespaceLabelSelector != k8s.NamespaceNameToLabel(vp.Pipeline.Namespace()) {
+ return err
+ }
+ }
+ }
+ return nil
+}
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index 8a7bf82d..cabc7fd8 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -17,15 +17,17 @@ limitations under the License.
package config
import (
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline/clustervectorpipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
"github.com/kaasops/vector-operator/controllers/factory/vector"
)
var (
- sourceDefault = vector.Source{
+ sourceDefault = &vector.Source{
Name: "defaultSource",
Type: "kubernetes_logs",
}
- sinkDefault = vector.Sink{
+ sinkDefault = &vector.Sink{
Name: "defaultSink",
Type: "blackhole",
Inputs: []string{"defaultSource"},
@@ -45,10 +47,10 @@ func (cfg *Config) GenerateVectorConfig() error {
}
if len(sources) == 0 {
- sources = []vector.Source{sourceDefault}
+ sources = []*vector.Source{sourceDefault}
}
if len(sinks) == 0 {
- sinks = []vector.Sink{sinkDefault}
+ sinks = []*vector.Sink{sinkDefault}
}
vectorConfig.Sinks = sinks
@@ -60,7 +62,7 @@ func (cfg *Config) GenerateVectorConfig() error {
return nil
}
-func (cfg *Config) getComponents() (sources []vector.Source, transforms []vector.Transform, sinks []vector.Sink, err error) {
+func (cfg *Config) getComponents() (sources []*vector.Source, transforms []*vector.Transform, sinks []*vector.Sink, err error) {
for _, vCtrl := range cfg.pCtrls {
pipelineSources, err := vCtrl.GetSources(nil)
@@ -71,6 +73,9 @@ func (cfg *Config) getComponents() (sources []vector.Source, transforms []vector
if err != nil {
return nil, nil, nil, err
}
+ if vCtrl.Pipeline.Type() != clustervectorpipeline.Type && source.Type == "kubernetes_logs" {
+ source.ExtraNamespaceLabelSelector = k8s.NamespaceNameToLabel(vCtrl.Pipeline.Namespace())
+ }
sources = append(sources, source)
}
pipelineTransforms, err := vCtrl.GetTransforms()
diff --git a/controllers/factory/pipeline/pipeline.go b/controllers/factory/pipeline/pipeline.go
index f6108ddf..da21ce8c 100644
--- a/controllers/factory/pipeline/pipeline.go
+++ b/controllers/factory/pipeline/pipeline.go
@@ -132,8 +132,8 @@ func (ctrl *Controller) SelectClusterVectorPipelineSucceesed() ([]*clustervector
return cvpCombined, nil
}
-func (ctrl *Controller) GetSources(filter []string) ([]vector.Source, error) {
- var sources []vector.Source
+func (ctrl *Controller) GetSources(filter []string) ([]*vector.Source, error) {
+ var sources []*vector.Source
sourcesMap, err := decodeRaw(ctrl.Pipeline.Spec().Sources.Raw)
if err != nil {
return nil, err
@@ -144,7 +144,7 @@ func (ctrl *Controller) GetSources(filter []string) ([]vector.Source, error) {
continue
}
}
- var source vector.Source
+ var source *vector.Source
if err := mapstructure.Decode(v, &source); err != nil {
return nil, err
}
@@ -154,7 +154,7 @@ func (ctrl *Controller) GetSources(filter []string) ([]vector.Source, error) {
return sources, nil
}
-func (ctrl *Controller) GetTransforms() ([]vector.Transform, error) {
+func (ctrl *Controller) GetTransforms() ([]*vector.Transform, error) {
if ctrl.Pipeline.Spec().Transforms == nil {
return nil, nil
}
@@ -162,12 +162,12 @@ func (ctrl *Controller) GetTransforms() ([]vector.Transform, error) {
if err != nil {
return nil, err
}
- var transforms []vector.Transform
+ var transforms []*vector.Transform
if err := json.Unmarshal(ctrl.Pipeline.Spec().Transforms.Raw, &transformsMap); err != nil {
return nil, err
}
for k, v := range transformsMap {
- var transform vector.Transform
+ var transform *vector.Transform
if err := mapstructure.Decode(v, &transform); err != nil {
return nil, err
}
@@ -180,14 +180,14 @@ func (ctrl *Controller) GetTransforms() ([]vector.Transform, error) {
return transforms, nil
}
-func (ctrl *Controller) GetSinks() ([]vector.Sink, error) {
+func (ctrl *Controller) GetSinks() ([]*vector.Sink, error) {
sinksMap, err := decodeRaw(ctrl.Pipeline.Spec().Sinks.Raw)
if err != nil {
return nil, err
}
- var sinks []vector.Sink
+ var sinks []*vector.Sink
for k, v := range sinksMap {
- var sink vector.Sink
+ var sink *vector.Sink
if err := mapstructure.Decode(v, &sink); err != nil {
return nil, err
}
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index 8f3863da..8247a4b1 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -289,3 +289,7 @@ func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
return nil
}
+
+func NamespaceNameToLabel(namespace string) string {
+ return "kubernetes.io/metadata.name=" + namespace
+}
diff --git a/controllers/factory/vector/types.go b/controllers/factory/vector/types.go
index 52a58681..929e69ab 100644
--- a/controllers/factory/vector/types.go
+++ b/controllers/factory/vector/types.go
@@ -23,15 +23,15 @@ import (
type VectorConfig struct {
DataDir string `mapstructure:"data_dir"`
Api *vectorv1alpha1.ApiSpec `mapstructure:"api"`
- Sources []Source `mapstructure:"sources"`
- Transforms []Transform `mapstructure:"transforms"`
- Sinks []Sink `mapstructure:"sinks"`
+ Sources []*Source `mapstructure:"sources"`
+ Transforms []*Transform `mapstructure:"transforms"`
+ Sinks []*Sink `mapstructure:"sinks"`
}
type Source struct {
Name string
Type string `mapper:"type"`
- ExtraNamespaceLabelSelector string `mapper:"extra_namespace_label_selector"`
+ ExtraNamespaceLabelSelector string `mapper:"extra_namespace_label_selector,omitempty"`
Options map[string]interface{} `mapstructure:",remain"`
}
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
index 139d458c..d96bd773 100644
--- a/controllers/factory/vector/vector.go
+++ b/controllers/factory/vector/vector.go
@@ -22,8 +22,8 @@ import (
)
func New(vector *vectorv1alpha1.Vector) *VectorConfig {
- sources := []Source{}
- sinks := []Sink{}
+ sources := []*Source{}
+ sinks := []*Sink{}
return &VectorConfig{
DataDir: vector.Spec.Agent.DataDir,
From eada0c7afd13d86d9aa3bea811a16cbdb16ac466 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Tue, 1 Nov 2022 15:13:52 +0300
Subject: [PATCH 063/316] Add quick-start doc
Signed-off-by: Zemtsov Vladimir
---
docs/quick-start.md | 300 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 300 insertions(+)
create mode 100644 docs/quick-start.md
diff --git a/docs/quick-start.md b/docs/quick-start.md
new file mode 100644
index 00000000..fd0dfc6a
--- /dev/null
+++ b/docs/quick-start.md
@@ -0,0 +1,300 @@
+# Quick start
+Operator serves to make running Vector applications on top of Kubernetes as easy as possible while preserving Kubernetes-native configuration options.
+
+# Installing by Manifest
+## Install CRDs
+```bash
+k apply -f config/crd/bases/observability.kaasops.io_vectors.yaml
+k apply -f config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+k apply -f config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
+```
+
+## Start Vector Operator
+### Create namespace for Vector Operator
+```bash
+kubectl create namespace vector-operator-system
+```
+
+### Create RBAC
+```bash
+# Create ServiceAccount for Vector Operator
+kubectl create serviceaccount -n vector-operator-system vector-operator
+
+# Create Secret for Vector Operator Service Account (if Kubernetes version > 1.23)
+cat <
Date: Tue, 1 Nov 2022 15:39:24 +0300
Subject: [PATCH 064/316] Cleanup doc quick-start
Signed-off-by: Zemtsov Vladimir
---
docs/quick-start.md | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/docs/quick-start.md b/docs/quick-start.md
index fd0dfc6a..399fd33a 100644
--- a/docs/quick-start.md
+++ b/docs/quick-start.md
@@ -4,9 +4,11 @@ Operator serves to make running Vector applications on top of Kubernetes as easy
# Installing by Manifest
## Install CRDs
```bash
-k apply -f config/crd/bases/observability.kaasops.io_vectors.yaml
-k apply -f config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
-k apply -f config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
+git clone https://github.com/kaasops/vector-operator.git
+cd vector-operator
+kubectl apply -f config/crd/bases/observability.kaasops.io_vectors.yaml
+kubectl apply -f config/crd/bases/observability.kaasops.io_vectorpipelines.yaml
+kubectl apply -f config/crd/bases/observability.kaasops.io_clustervectorpipelines.yaml
```
## Start Vector Operator
@@ -17,9 +19,6 @@ kubectl create namespace vector-operator-system
### Create RBAC
```bash
-# Create ServiceAccount for Vector Operator
-kubectl create serviceaccount -n vector-operator-system vector-operator
-
# Create Secret for Vector Operator Service Account (if Kubernetes version > 1.23)
cat <
Date: Tue, 1 Nov 2022 15:43:03 +0300
Subject: [PATCH 065/316] build docker only on master tag (#29)
---
.github/workflows/main.yaml | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
index c6cec786..bdeb0ff4 100644
--- a/.github/workflows/main.yaml
+++ b/.github/workflows/main.yaml
@@ -4,10 +4,7 @@ name: Build and Test
on:
push:
tags:
- - '*'
- branches:
- - main
- pull_request:
+ - 'v*'
branches:
- main
jobs:
@@ -20,7 +17,7 @@ jobs:
- name: Get tag
id: tag
- run: echo "TAG=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
+ run: echo "TAG=$(git describe --tags HEAD)" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
@@ -40,4 +37,4 @@ jobs:
context: .
platforms: linux/amd64,linux/arm64
push: true
- tags: ${{ github.repository }}:${{ steps.tag.outputs.TAG }}
\ No newline at end of file
+ tags: ${{ github.repository }}:${{ steps.tag.outputs.TAG }},${{ github.repository }}:latest
\ No newline at end of file
From 1d575f84e5b10787af03769d97117fe472d6da8f Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Tue, 1 Nov 2022 15:21:52 +0200
Subject: [PATCH 066/316] disable build image after push to main
---
.github/workflows/{main.yaml => build-image.yaml} | 2 --
1 file changed, 2 deletions(-)
rename .github/workflows/{main.yaml => build-image.yaml} (97%)
diff --git a/.github/workflows/main.yaml b/.github/workflows/build-image.yaml
similarity index 97%
rename from .github/workflows/main.yaml
rename to .github/workflows/build-image.yaml
index bdeb0ff4..13a9cca8 100644
--- a/.github/workflows/main.yaml
+++ b/.github/workflows/build-image.yaml
@@ -5,8 +5,6 @@ on:
push:
tags:
- 'v*'
- branches:
- - main
jobs:
build-and-push-docker-image:
name: Build and push Docker image
From cd91ca897283b30a7c363386ceebf55e3ddb6af5 Mon Sep 17 00:00:00 2001
From: Vladimir <31961982+zvlb@users.noreply.github.com>
Date: Tue, 1 Nov 2022 15:41:00 +0200
Subject: [PATCH 067/316] Update ReadMe (#30)
Signed-off-by: Zemtsov Vladimir
---
README.md | 46 +++++-----------------------------------------
1 file changed, 5 insertions(+), 41 deletions(-)
diff --git a/README.md b/README.md
index a80a0a6f..9f5e01ca 100644
--- a/README.md
+++ b/README.md
@@ -15,48 +15,14 @@ The operator deploys and configures a vector agent daemonset on every node to co
- [x] Building vector config from namespaced custom resources (kind: VectorPipeline)
- [x] Configuration validation
- [x] Full support of vector config options
-- [ ] Namespace isolation
-- [ ] Garbage collection
+- [x] Namespace isolation
- [ ] Vector config optimization
- [ ] Vector aggregator support
-
-## Getting Started
-You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster.
-**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows).
-
-### Running on the cluster
-1. Install Instances of Custom Resources:
-
-```sh
-kubectl apply -f config/samples/
-```
-
-2. Build and push your image to the location specified by `IMG`:
-
-```sh
-make docker-build docker-push IMG=docker pull kaasops/vector-operator:latest
-```
-
-3. Deploy the controller to the cluster with the image specified by `IMG`:
-
-```sh
-make deploy IMG=docker pull kaasops/vector-operator:latest
-```
-
-### Uninstall CRDs
-To delete the CRDs from the cluster:
-
-```sh
-make uninstall
-```
-
-### Undeploy controller
-UnDeploy the controller to the cluster:
-
-```sh
-make undeploy
-```
+## Documentation
+- Quick start [doc](https://github.com/kaasops/vector-operator/blob/main/docs/quick-start.md)
+- Design [doc](https://github.com/kaasops/vector-operator/blob/main/docs/design.md)
+- Specification [doc](https://github.com/kaasops/vector-operator/blob/main/docs/specification.md)
## Configuration Examples
Configuration for CR Vector:
@@ -113,8 +79,6 @@ spec:
```
-
-
## Contributing
### How it works
From de212eff71474a7c6244ffc62a8baede1908f187 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Fri, 4 Nov 2022 14:14:38 +0200
Subject: [PATCH 068/316] config build refactoring
---
api/v1alpha1/clustervectorpipeline.go | 59 +++++
api/v1alpha1/vectorpipeline.go | 59 +++++
.../clustervectorpipeline_controller.go | 32 ++-
controllers/factory/config/config.go | 146 ++----------
controllers/factory/config/config_build.go | 221 +++++++++++++++--
.../factory/{vector => config}/types.go | 2 +-
controllers/factory/config/utils.go | 28 +++
.../clustervectorpipeline.go | 76 ------
controllers/factory/pipeline/hash.go | 10 +-
controllers/factory/pipeline/pipeline.go | 223 +++---------------
.../pipeline/vectorpipeline/vectorpipeline.go | 76 ------
controllers/factory/vector/vector.go | 65 -----
controllers/vector_controller.go | 8 +-
controllers/vectorpipeline_controller.go | 32 ++-
14 files changed, 450 insertions(+), 587 deletions(-)
create mode 100644 api/v1alpha1/clustervectorpipeline.go
create mode 100644 api/v1alpha1/vectorpipeline.go
rename controllers/factory/{vector => config}/types.go (99%)
create mode 100644 controllers/factory/config/utils.go
delete mode 100644 controllers/factory/pipeline/clustervectorpipeline/clustervectorpipeline.go
delete mode 100644 controllers/factory/pipeline/vectorpipeline/vectorpipeline.go
delete mode 100644 controllers/factory/vector/vector.go
diff --git a/api/v1alpha1/clustervectorpipeline.go b/api/v1alpha1/clustervectorpipeline.go
new file mode 100644
index 00000000..b27b437a
--- /dev/null
+++ b/api/v1alpha1/clustervectorpipeline.go
@@ -0,0 +1,59 @@
+package v1alpha1
+
+import (
+ "context"
+
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+var (
+ ClusterPipelineKind = "ClusterVectorPipeline"
+)
+
+func (vp *ClusterVectorPipeline) GetSpec() VectorPipelineSpec {
+ return vp.Spec
+}
+
+func (vp *ClusterVectorPipeline) GetName() string {
+ return vp.Name
+}
+
+func (vp *ClusterVectorPipeline) GetNamespace() string {
+ return vp.Namespace
+}
+
+func (vp *ClusterVectorPipeline) Type() string {
+ return vp.Kind
+}
+
+func (vp *ClusterVectorPipeline) IsValid() bool {
+ if vp.Status.ConfigCheckResult != nil {
+ return *vp.Status.ConfigCheckResult
+ }
+ return false
+}
+
+func (vp *ClusterVectorPipeline) IsDeleted() bool {
+ return !vp.DeletionTimestamp.IsZero()
+}
+
+func (vp *ClusterVectorPipeline) SetConfigCheck(value bool) {
+ vp.Status.ConfigCheckResult = &value
+}
+
+func (vp *ClusterVectorPipeline) SetReason(reason *string) {
+ vp.Status.Reason = reason
+}
+
+func (vp *ClusterVectorPipeline) GetLastAppliedPipeline() *uint32 {
+ return vp.Status.LastAppliedPipelineHash
+}
+
+func (vp *ClusterVectorPipeline) SetLastAppliedPipeline(hash *uint32) {
+ vp.Status.LastAppliedPipelineHash = hash
+}
+
+func (vp *ClusterVectorPipeline) UpdateStatus(ctx context.Context, c client.Client) error {
+ return k8s.UpdateStatus(ctx, vp, c)
+}
diff --git a/api/v1alpha1/vectorpipeline.go b/api/v1alpha1/vectorpipeline.go
new file mode 100644
index 00000000..c99d3a5c
--- /dev/null
+++ b/api/v1alpha1/vectorpipeline.go
@@ -0,0 +1,59 @@
+package v1alpha1
+
+import (
+ "context"
+
+ "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+var (
+ LocalPipelineKind = "VectorPipeline"
+)
+
+func (vp *VectorPipeline) GetSpec() VectorPipelineSpec {
+ return vp.Spec
+}
+
+func (vp *VectorPipeline) GetName() string {
+ return vp.Name
+}
+
+func (vp *VectorPipeline) GetNamespace() string {
+ return vp.Namespace
+}
+
+func (vp *VectorPipeline) Type() string {
+ return vp.Kind
+}
+
+func (vp *VectorPipeline) IsValid() bool {
+ if vp.Status.ConfigCheckResult != nil {
+ return *vp.Status.ConfigCheckResult
+ }
+ return false
+}
+
+func (vp *VectorPipeline) IsDeleted() bool {
+ return !vp.DeletionTimestamp.IsZero()
+}
+
+func (vp *VectorPipeline) SetConfigCheck(value bool) {
+ vp.Status.ConfigCheckResult = &value
+}
+
+func (vp *VectorPipeline) SetReason(reason *string) {
+ vp.Status.Reason = reason
+}
+
+func (vp *VectorPipeline) GetLastAppliedPipeline() *uint32 {
+ return vp.Status.LastAppliedPipelineHash
+}
+
+func (vp *VectorPipeline) SetLastAppliedPipeline(hash *uint32) {
+ vp.Status.LastAppliedPipelineHash = hash
+}
+
+func (vp *VectorPipeline) UpdateStatus(ctx context.Context, c client.Client) error {
+ return k8s.UpdateStatus(ctx, vp, c)
+}
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
index 8cc8c017..7bbdabcd 100644
--- a/controllers/clustervectorpipeline_controller.go
+++ b/controllers/clustervectorpipeline_controller.go
@@ -30,7 +30,6 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/config"
"github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
"github.com/kaasops/vector-operator/controllers/factory/pipeline"
- "github.com/kaasops/vector-operator/controllers/factory/pipeline/clustervectorpipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
)
@@ -72,13 +71,8 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, nil
}
- // Generate VectorPipeline Controller
- vpCtrl := clustervectorpipeline.NewController(vectorPipelineCR)
- // Generate Pipeline Controller
- pCtrl := pipeline.NewController(ctx, r.Client, vpCtrl)
-
// Check Pipeline hash
- checkResult, err := pCtrl.CheckHash()
+ checkResult, err := pipeline.CheckHash(vectorPipelineCR)
if err != nil {
return ctrl.Result{}, err
}
@@ -111,18 +105,20 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
}
// Get Vector Config file
- config, err := config.New(ctx, vaCtrl)
+ configBuilder, err := config.NewConfigBuilder(ctx, vaCtrl, vectorPipelineCR)
if err != nil {
return ctrl.Result{}, err
}
- if err := config.FillForVectorPipeline(pCtrl); err != nil {
- return ctrl.Result{}, err
- }
- // Get Config in Json ([]byte)
- byteConfig, err := config.GetByteConfig()
+ byteConfig, err := configBuilder.GetByteConfigWithValidate()
if err != nil {
- return ctrl.Result{}, err
+ if err := pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
+ return ctrl.Result{}, err
+ }
+ if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
+ return ctrl.Result{}, err
+ }
+ return ctrl.Result{}, nil
}
// Init CheckConfig
@@ -131,10 +127,10 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
// Start ConfigCheck
err = configCheck.Run()
if _, ok := err.(*configcheck.ConfigCheckError); ok {
- if err := pCtrl.SetFailedStatus(err); err != nil {
+ if err = pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
return ctrl.Result{}, err
}
- if err = pCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
@@ -143,11 +139,11 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, err
}
- if err = pCtrl.SetSucceesStatus(); err != nil {
+ if err = pipeline.SetSucceesStatus(ctx, r.Client, vectorPipelineCR); err != nil {
return ctrl.Result{}, err
}
- if err = pCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
return ctrl.Result{}, err
}
diff --git a/controllers/factory/config/config.go b/controllers/factory/config/config.go
index 6c713a57..fe12b1a4 100644
--- a/controllers/factory/config/config.go
+++ b/controllers/factory/config/config.go
@@ -17,143 +17,49 @@ limitations under the License.
package config
import (
- "context"
- "encoding/json"
- "errors"
-
- "github.com/kaasops/vector-operator/controllers/factory/pipeline"
- "github.com/kaasops/vector-operator/controllers/factory/pipeline/clustervectorpipeline"
- "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
- "github.com/kaasops/vector-operator/controllers/factory/vector"
- "github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/mitchellh/mapstructure"
)
-type Config struct {
- Name string
-
- Ctx context.Context
- vaCtrl *vectoragent.Controller
- pCtrls []pipeline.Controller
-
- VectorConfig *vector.VectorConfig
-}
-
-func New(ctx context.Context, vaCtrl *vectoragent.Controller) (*Config, error) {
- cfg := &Config{
- Ctx: ctx,
- vaCtrl: vaCtrl,
- }
-
- return cfg, nil
-}
-
-func (cfg *Config) FillForVectorAgent() error {
- cfg.Name = cfg.vaCtrl.Vector.Name
-
- pCtrl := pipeline.NewController(cfg.Ctx, cfg.vaCtrl.Client, nil)
- pCtrls, err := pCtrl.SelectSucceesed()
- if err != nil {
- return err
- }
- cfg.pCtrls = pCtrls
+func New(vector *vectorv1alpha1.Vector) *VectorConfig {
+ sources := []*Source{}
+ sinks := []*Sink{}
- if err := cfg.GenerateVectorConfig(); err != nil {
- return err
+ return &VectorConfig{
+ DataDir: vector.Spec.Agent.DataDir,
+ Api: &vector.Spec.Agent.Api,
+ Sources: sources,
+ Sinks: sinks,
}
-
- return nil
}
-func (cfg *Config) FillForVectorPipeline(pCtrl *pipeline.Controller) error {
- cfg.Name = pCtrl.Pipeline.Name()
-
- pCtrls := make([]pipeline.Controller, 1)
- pCtrls[0] = *pCtrl
-
- cfg.pCtrls = pCtrls
-
- if err := cfg.GenerateVectorConfig(); err != nil {
- return err
+func Mapper(c ConfigComponent) (map[string]interface{}, error) {
+ spec := c.GetOptions()
+ config := &mapstructure.DecoderConfig{
+ Result: &spec,
+ ZeroFields: false,
+ TagName: "mapper",
+ IgnoreUntaggedFields: true,
}
-
- err := cfg.Validate()
- if err != nil {
- if err := pCtrl.SetFailedStatus(err); err != nil {
- return err
- }
- if err := pCtrl.SetLastAppliedPipelineStatus(); err != nil {
- return err
- }
- return err
- }
-
- return nil
-}
-
-func (cfg *Config) GetByteConfig() ([]byte, error) {
- cfgMap, err := CfgToMap(*cfg.VectorConfig)
+ decoder, err := mapstructure.NewDecoder(config)
if err != nil {
return nil, err
}
- data, err := json.Marshal(cfgMap)
+ err = decoder.Decode(c)
if err != nil {
return nil, err
}
-
- return data, nil
+ return spec, nil
}
-func CfgToMap(cfg vector.VectorConfig) (cfgMap map[string]interface{}, err error) {
- sources := make(map[string]interface{})
- transforms := make(map[string]interface{})
- sinks := make(map[string]interface{})
- for _, source := range cfg.Sources {
- spec, err := vector.Mapper(source)
- if err != nil {
- return nil, err
- }
- sources[source.Name] = spec
- }
- for _, transform := range cfg.Transforms {
- spec, err := vector.Mapper(transform)
- if err != nil {
- return nil, err
- }
- transforms[transform.Name] = spec
- }
- for _, sink := range cfg.Sinks {
- spec, err := vector.Mapper(sink)
- if err != nil {
- return nil, err
- }
- sinks[sink.Name] = spec
- }
-
- err = mapstructure.Decode(cfg, &cfgMap)
- if err != nil {
- return nil, err
- }
- // TODO: remove hardcoded map keys
- cfgMap["sources"] = sources
- cfgMap["transforms"] = transforms
- cfgMap["sinks"] = sinks
+func (t Source) GetOptions() map[string]interface{} {
+ return t.Options
+}
- return cfgMap, nil
+func (t Transform) GetOptions() map[string]interface{} {
+ return t.Options
}
-func (cfg *Config) Validate() error {
- err := errors.New("type kubernetes_logs only allowed")
- vp := cfg.pCtrls[0]
- for _, source := range cfg.VectorConfig.Sources {
- if vp.Pipeline.Type() != clustervectorpipeline.Type {
- if source.Type != "kubernetes_logs" {
- return err
- }
- if source.ExtraNamespaceLabelSelector != "" && source.ExtraNamespaceLabelSelector != k8s.NamespaceNameToLabel(vp.Pipeline.Namespace()) {
- return err
- }
- }
- }
- return nil
+func (t Sink) GetOptions() map[string]interface{} {
+ return t.Options
}
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index cabc7fd8..077127d6 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -17,17 +17,24 @@ limitations under the License.
package config
import (
- "github.com/kaasops/vector-operator/controllers/factory/pipeline/clustervectorpipeline"
+ "context"
+ "encoding/json"
+ "errors"
+
+ vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
- "github.com/kaasops/vector-operator/controllers/factory/vector"
+ "github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
+ "github.com/mitchellh/mapstructure"
)
var (
- sourceDefault = &vector.Source{
+ KubernetesSourceType = "kubernetes_logs"
+ sourceDefault = &Source{
Name: "defaultSource",
- Type: "kubernetes_logs",
+ Type: KubernetesSourceType,
}
- sinkDefault = &vector.Sink{
+ sinkDefault = &Sink{
Name: "defaultSink",
Type: "blackhole",
Inputs: []string{"defaultSource"},
@@ -38,34 +45,88 @@ var (
}
)
-func (cfg *Config) GenerateVectorConfig() error {
- vectorConfig := vector.New(cfg.vaCtrl.Vector)
+type ConfigBuilder struct {
+ Name string
+ Ctx context.Context
+ vaCtrl *vectoragent.Controller
+ Pipelines []pipeline.Pipeline
+}
+
+func NewConfigBuilder(ctx context.Context, vaCtrl *vectoragent.Controller, pipelines ...pipeline.Pipeline) (*ConfigBuilder, error) {
+ return &ConfigBuilder{
+ Ctx: ctx,
+ vaCtrl: vaCtrl,
+ Pipelines: pipelines,
+ }, nil
+}
+
+func (b *ConfigBuilder) GetByteConfig() ([]byte, error) {
+ config, err := b.generateVectorConfig()
+ if err != nil {
+ return nil, err
+ }
+
+ data, err := vectorConfigToByte(config)
+ if err != nil {
+ return nil, err
+ }
+
+ return data, nil
+}
+
+func (b *ConfigBuilder) GetByteConfigWithValidate() ([]byte, error) {
+ validateError := errors.New("type kubernetes_logs only allowed")
+ config, err := b.generateVectorConfig()
+ if err != nil {
+ return nil, err
+ }
+ if len(b.Pipelines) != 0 {
+ for _, pipeline := range b.Pipelines {
+ for _, source := range config.Sources {
+ if pipeline.Type() != vectorv1alpha1.ClusterPipelineKind {
+ if source.Type != KubernetesSourceType {
+ return nil, validateError
+ }
+ if source.ExtraNamespaceLabelSelector != "" && source.ExtraNamespaceLabelSelector != k8s.NamespaceNameToLabel(pipeline.GetNamespace()) {
+ return nil, validateError
+ }
+ }
+ }
+ }
+ }
+ data, err := vectorConfigToByte(config)
+ if err != nil {
+ return nil, err
+ }
+ return data, nil
+}
+
+func (b *ConfigBuilder) generateVectorConfig() (*VectorConfig, error) {
+ vectorConfig := New(b.vaCtrl.Vector)
- sources, transforms, sinks, err := cfg.getComponents()
+ sources, transforms, sinks, err := b.getComponents()
if err != nil {
- return err
+ return nil, err
}
if len(sources) == 0 {
- sources = []*vector.Source{sourceDefault}
+ sources = []*Source{sourceDefault}
}
if len(sinks) == 0 {
- sinks = []*vector.Sink{sinkDefault}
+ sinks = []*Sink{sinkDefault}
}
vectorConfig.Sinks = sinks
vectorConfig.Sources = sources
vectorConfig.Transforms = transforms
- cfg.VectorConfig = vectorConfig
-
- return nil
+ return vectorConfig, nil
}
-func (cfg *Config) getComponents() (sources []*vector.Source, transforms []*vector.Transform, sinks []*vector.Sink, err error) {
+func (b *ConfigBuilder) getComponents() (sources []*Source, transforms []*Transform, sinks []*Sink, err error) {
- for _, vCtrl := range cfg.pCtrls {
- pipelineSources, err := vCtrl.GetSources(nil)
+ for _, pipeline := range b.Pipelines {
+ pipelineSources, err := getSources(pipeline, nil)
if err != nil {
return nil, nil, nil, err
}
@@ -73,12 +134,12 @@ func (cfg *Config) getComponents() (sources []*vector.Source, transforms []*vect
if err != nil {
return nil, nil, nil, err
}
- if vCtrl.Pipeline.Type() != clustervectorpipeline.Type && source.Type == "kubernetes_logs" {
- source.ExtraNamespaceLabelSelector = k8s.NamespaceNameToLabel(vCtrl.Pipeline.Namespace())
+ if pipeline.Type() != vectorv1alpha1.ClusterPipelineKind && source.Type == KubernetesSourceType {
+ source.ExtraNamespaceLabelSelector = k8s.NamespaceNameToLabel(pipeline.GetNamespace())
}
sources = append(sources, source)
}
- pipelineTransforms, err := vCtrl.GetTransforms()
+ pipelineTransforms, err := getTransforms(pipeline)
if err != nil {
return nil, nil, nil, err
}
@@ -88,7 +149,7 @@ func (cfg *Config) getComponents() (sources []*vector.Source, transforms []*vect
}
transforms = append(transforms, transform)
}
- pipelineSinks, err := vCtrl.GetSinks()
+ pipelineSinks, err := getSinks(pipeline)
if err != nil {
return nil, nil, nil, err
}
@@ -101,3 +162,121 @@ func (cfg *Config) getComponents() (sources []*vector.Source, transforms []*vect
}
return sources, transforms, sinks, nil
}
+
+func vectorConfigToByte(config *VectorConfig) ([]byte, error) {
+ cfgMap, err := cfgToMap(config)
+ if err != nil {
+ return nil, err
+ }
+ data, err := json.Marshal(cfgMap)
+ if err != nil {
+ return nil, err
+ }
+ return data, nil
+}
+
+func getSources(pipeline pipeline.Pipeline, filter []string) ([]*Source, error) {
+ var sources []*Source
+ sourcesMap, err := decodeRaw(pipeline.GetSpec().Sources.Raw)
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range sourcesMap {
+ if len(filter) != 0 {
+ if !contains(filter, k) {
+ continue
+ }
+ }
+ var source *Source
+ if err := mapstructure.Decode(v, &source); err != nil {
+ return nil, err
+ }
+ source.Name = addPrefix(pipeline.GetNamespace(), pipeline.GetName(), k)
+ sources = append(sources, source)
+ }
+ return sources, nil
+}
+
+func getTransforms(pipeline pipeline.Pipeline) ([]*Transform, error) {
+ if pipeline.GetSpec().Transforms == nil {
+ return nil, nil
+ }
+ transformsMap, err := decodeRaw(pipeline.GetSpec().Transforms.Raw)
+ if err != nil {
+ return nil, err
+ }
+ var transforms []*Transform
+ if err := json.Unmarshal(pipeline.GetSpec().Transforms.Raw, &transformsMap); err != nil {
+ return nil, err
+ }
+ for k, v := range transformsMap {
+ var transform *Transform
+ if err := mapstructure.Decode(v, &transform); err != nil {
+ return nil, err
+ }
+ transform.Name = addPrefix(pipeline.GetNamespace(), pipeline.GetName(), k)
+ for i, inputName := range transform.Inputs {
+ transform.Inputs[i] = addPrefix(pipeline.GetNamespace(), pipeline.GetName(), inputName)
+ }
+ transforms = append(transforms, transform)
+ }
+ return transforms, nil
+}
+
+func getSinks(pipeline pipeline.Pipeline) ([]*Sink, error) {
+ sinksMap, err := decodeRaw(pipeline.GetSpec().Sinks.Raw)
+ if err != nil {
+ return nil, err
+ }
+ var sinks []*Sink
+ for k, v := range sinksMap {
+ var sink *Sink
+ if err := mapstructure.Decode(v, &sink); err != nil {
+ return nil, err
+ }
+ sink.Name = addPrefix(pipeline.GetNamespace(), pipeline.GetName(), k)
+ for i, inputName := range sink.Inputs {
+ sink.Inputs[i] = addPrefix(pipeline.GetNamespace(), pipeline.GetName(), inputName)
+ }
+ sinks = append(sinks, sink)
+ }
+ return sinks, nil
+}
+
+func cfgToMap(config *VectorConfig) (cfgMap map[string]interface{}, err error) {
+ sources := make(map[string]interface{})
+ transforms := make(map[string]interface{})
+ sinks := make(map[string]interface{})
+ for _, source := range config.Sources {
+ spec, err := Mapper(source)
+ if err != nil {
+ return nil, err
+ }
+ sources[source.Name] = spec
+ }
+ for _, transform := range config.Transforms {
+ spec, err := Mapper(transform)
+ if err != nil {
+ return nil, err
+ }
+ transforms[transform.Name] = spec
+ }
+ for _, sink := range config.Sinks {
+ spec, err := Mapper(sink)
+ if err != nil {
+ return nil, err
+ }
+ sinks[sink.Name] = spec
+ }
+
+ err = mapstructure.Decode(config, &cfgMap)
+ if err != nil {
+ return nil, err
+ }
+ // TODO: remove hardcoded map keys
+ cfgMap["sources"] = sources
+ cfgMap["transforms"] = transforms
+ cfgMap["sinks"] = sinks
+
+ return cfgMap, nil
+}
diff --git a/controllers/factory/vector/types.go b/controllers/factory/config/types.go
similarity index 99%
rename from controllers/factory/vector/types.go
rename to controllers/factory/config/types.go
index 929e69ab..d62ca2a5 100644
--- a/controllers/factory/vector/types.go
+++ b/controllers/factory/config/types.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package vector
+package config
import (
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
diff --git a/controllers/factory/config/utils.go b/controllers/factory/config/utils.go
new file mode 100644
index 00000000..fc37bf91
--- /dev/null
+++ b/controllers/factory/config/utils.go
@@ -0,0 +1,28 @@
+package config
+
+import "encoding/json"
+
+func decodeRaw(raw []byte) (map[string]interface{}, error) {
+ result := make(map[string]interface{})
+ if err := json.Unmarshal(raw, &result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func contains(elems []string, v string) bool {
+ for _, s := range elems {
+ if v == s {
+ return true
+ }
+ }
+ return false
+}
+
+func addPrefix(Namespace, Name, componentName string) string {
+ return generateName(Namespace, Name) + "-" + componentName
+}
+
+func generateName(Namespace, Name string) string {
+ return Namespace + "-" + Name
+}
diff --git a/controllers/factory/pipeline/clustervectorpipeline/clustervectorpipeline.go b/controllers/factory/pipeline/clustervectorpipeline/clustervectorpipeline.go
deleted file mode 100644
index 40b5e97c..00000000
--- a/controllers/factory/pipeline/clustervectorpipeline/clustervectorpipeline.go
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-Copyright 2022.
-
-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 clustervectorpipeline
-
-import (
- "context"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
- "sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-var (
- Type = "cluster"
-)
-
-type Controller struct {
- ClusterVectorPipeline *vectorv1alpha1.ClusterVectorPipeline
- Config []byte
-}
-
-func (ctrl *Controller) Spec() vectorv1alpha1.VectorPipelineSpec {
- return ctrl.ClusterVectorPipeline.Spec
-}
-
-func (ctrl *Controller) Name() string {
- return ctrl.ClusterVectorPipeline.Name
-}
-
-func (ctrl *Controller) Namespace() string {
- return ctrl.ClusterVectorPipeline.Namespace
-}
-
-func (ctrl *Controller) Type() string {
- return Type
-}
-
-func (ctrl *Controller) SetConfigCheck(value bool) {
- ctrl.ClusterVectorPipeline.Status.ConfigCheckResult = &value
-}
-
-func (ctrl *Controller) SetReason(reason *string) {
- ctrl.ClusterVectorPipeline.Status.Reason = reason
-}
-
-func (ctrl *Controller) GetLastAppliedPipeline() *uint32 {
- return ctrl.ClusterVectorPipeline.Status.LastAppliedPipelineHash
-}
-
-func (ctrl *Controller) SetLastAppliedPipeline(hash *uint32) {
- ctrl.ClusterVectorPipeline.Status.LastAppliedPipelineHash = hash
-}
-
-func (ctrl *Controller) UpdateStatus(ctx context.Context, c client.Client) error {
- return k8s.UpdateStatus(ctx, ctrl.ClusterVectorPipeline, c)
-}
-
-func NewController(cvp *vectorv1alpha1.ClusterVectorPipeline) *Controller {
- return &Controller{
- ClusterVectorPipeline: cvp,
- }
-}
diff --git a/controllers/factory/pipeline/hash.go b/controllers/factory/pipeline/hash.go
index 56ae2669..2be62ee8 100644
--- a/controllers/factory/pipeline/hash.go
+++ b/controllers/factory/pipeline/hash.go
@@ -22,8 +22,8 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/utils/hash"
)
-func (ctrl *Controller) GetSpecHash() (*uint32, error) {
- a, err := json.Marshal(ctrl.Pipeline.Spec())
+func GetSpecHash(pipeline Pipeline) (*uint32, error) {
+ a, err := json.Marshal(pipeline.GetSpec())
if err != nil {
return nil, err
}
@@ -32,13 +32,13 @@ func (ctrl *Controller) GetSpecHash() (*uint32, error) {
}
// CheckHash returns true, if hash in .status.lastAppliedPipelineHash matches with spec Hash
-func (ctrl *Controller) CheckHash() (bool, error) {
- hash, err := ctrl.GetSpecHash()
+func CheckHash(pipeline Pipeline) (bool, error) {
+ hash, err := GetSpecHash(pipeline)
if err != nil {
return false, err
}
- if ctrl.Pipeline.GetLastAppliedPipeline() != nil && *hash == *ctrl.Pipeline.GetLastAppliedPipeline() {
+ if pipeline.GetLastAppliedPipeline() != nil && *hash == *pipeline.GetLastAppliedPipeline() {
return true, nil
}
diff --git a/controllers/factory/pipeline/pipeline.go b/controllers/factory/pipeline/pipeline.go
index da21ce8c..8edb9edf 100644
--- a/controllers/factory/pipeline/pipeline.go
+++ b/controllers/factory/pipeline/pipeline.go
@@ -18,238 +18,93 @@ package pipeline
import (
"context"
- "encoding/json"
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/pipeline/clustervectorpipeline"
- "github.com/kaasops/vector-operator/controllers/factory/pipeline/vectorpipeline"
- "github.com/kaasops/vector-operator/controllers/factory/vector"
- "github.com/mitchellh/mapstructure"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type Pipeline interface {
- Spec() vectorv1alpha1.VectorPipelineSpec
- Name() string
- Namespace() string
+ GetSpec() vectorv1alpha1.VectorPipelineSpec
+ GetName() string
+ GetNamespace() string
Type() string
SetConfigCheck(bool)
SetReason(*string)
GetLastAppliedPipeline() *uint32
SetLastAppliedPipeline(*uint32)
+ IsValid() bool
+ IsDeleted() bool
UpdateStatus(context.Context, client.Client) error
}
-type Controller struct {
- Pipeline Pipeline
- Ctx context.Context
- Client client.Client
-}
-
-func NewController(ctx context.Context, c client.Client, p Pipeline) *Controller {
- return &Controller{
- Pipeline: p,
- Ctx: ctx,
- Client: c,
- }
-}
-
-func (ctrl *Controller) SelectSucceesed() ([]Controller, error) {
- var combined []Controller
-
- vpCombined, err := ctrl.SelectVectorPipelineSucceesed()
- if err != nil {
- return nil, err
- }
-
- cvpCombined, err := ctrl.SelectClusterVectorPipelineSucceesed()
- if err != nil {
- return nil, err
- }
-
- for _, vp := range vpCombined {
- combined = append(combined, Controller{
- Pipeline: vp,
- })
- }
- for _, cvp := range cvpCombined {
- combined = append(combined, Controller{
- Pipeline: cvp,
- })
- }
-
- return combined, nil
-
-}
-
-func (ctrl *Controller) SelectVectorPipelineSucceesed() ([]*vectorpipeline.Controller, error) {
- var vpCombined []*vectorpipeline.Controller
-
- vps := vectorv1alpha1.VectorPipelineList{}
- err := ctrl.Client.List(ctrl.Ctx, &vps)
+func GetValidPipelines(ctx context.Context, client client.Client) ([]Pipeline, error) {
+ var validPipelines []Pipeline
+ vps, err := GetVectorPipelines(ctx, client)
if err != nil {
return nil, err
}
-
- for _, vp := range vps.Items {
- if !vp.DeletionTimestamp.IsZero() {
- continue
- }
- if vp.Status.ConfigCheckResult != nil {
- if *vp.Status.ConfigCheckResult {
- vpCombined = append(vpCombined, &vectorpipeline.Controller{
- VectorPipeline: vp.DeepCopy(),
- })
- }
- }
-
- }
- return vpCombined, nil
-}
-
-func (ctrl *Controller) SelectClusterVectorPipelineSucceesed() ([]*clustervectorpipeline.Controller, error) {
- var cvpCombined []*clustervectorpipeline.Controller
-
- cvps := vectorv1alpha1.ClusterVectorPipelineList{}
- err := ctrl.Client.List(ctrl.Ctx, &cvps)
+ cvps, err := GetClusterVectorPipelines(ctx, client)
if err != nil {
return nil, err
}
-
- for _, cvp := range cvps.Items {
- if !cvp.DeletionTimestamp.IsZero() {
- continue
- }
- if cvp.Status.ConfigCheckResult != nil {
- if *cvp.Status.ConfigCheckResult {
- cvpCombined = append(cvpCombined, &clustervectorpipeline.Controller{
- ClusterVectorPipeline: cvp.DeepCopy(),
- })
+ if len(vps) != 0 {
+ for _, vp := range vps {
+ if !vp.IsDeleted() && vp.IsValid() {
+ validPipelines = append(validPipelines, vp.DeepCopy())
}
}
-
}
- return cvpCombined, nil
-}
-
-func (ctrl *Controller) GetSources(filter []string) ([]*vector.Source, error) {
- var sources []*vector.Source
- sourcesMap, err := decodeRaw(ctrl.Pipeline.Spec().Sources.Raw)
- if err != nil {
- return nil, err
- }
- for k, v := range sourcesMap {
- if len(filter) != 0 {
- if !contains(filter, k) {
- continue
+ if len(cvps) != 0 {
+ for _, cvp := range cvps {
+ if !cvp.IsDeleted() && cvp.IsValid() {
+ validPipelines = append(validPipelines, cvp.DeepCopy())
}
}
- var source *vector.Source
- if err := mapstructure.Decode(v, &source); err != nil {
- return nil, err
- }
- source.Name = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), k)
- sources = append(sources, source)
- }
- return sources, nil
-}
-
-func (ctrl *Controller) GetTransforms() ([]*vector.Transform, error) {
- if ctrl.Pipeline.Spec().Transforms == nil {
- return nil, nil
- }
- transformsMap, err := decodeRaw(ctrl.Pipeline.Spec().Transforms.Raw)
- if err != nil {
- return nil, err
- }
- var transforms []*vector.Transform
- if err := json.Unmarshal(ctrl.Pipeline.Spec().Transforms.Raw, &transformsMap); err != nil {
- return nil, err
- }
- for k, v := range transformsMap {
- var transform *vector.Transform
- if err := mapstructure.Decode(v, &transform); err != nil {
- return nil, err
- }
- transform.Name = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), k)
- for i, inputName := range transform.Inputs {
- transform.Inputs[i] = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), inputName)
- }
- transforms = append(transforms, transform)
- }
- return transforms, nil
-}
-
-func (ctrl *Controller) GetSinks() ([]*vector.Sink, error) {
- sinksMap, err := decodeRaw(ctrl.Pipeline.Spec().Sinks.Raw)
- if err != nil {
- return nil, err
- }
- var sinks []*vector.Sink
- for k, v := range sinksMap {
- var sink *vector.Sink
- if err := mapstructure.Decode(v, &sink); err != nil {
- return nil, err
- }
- sink.Name = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), k)
- for i, inputName := range sink.Inputs {
- sink.Inputs[i] = addPrefix(ctrl.Pipeline.Namespace(), ctrl.Pipeline.Name(), inputName)
- }
- sinks = append(sinks, sink)
}
- return sinks, nil
+ return validPipelines, nil
}
-func (ctrl *Controller) SetSucceesStatus() error {
+func SetSucceesStatus(ctx context.Context, client client.Client, p Pipeline) error {
var status = true
- ctrl.Pipeline.SetConfigCheck(status)
- ctrl.Pipeline.SetReason(nil)
+ p.SetConfigCheck(status)
+ p.SetReason(nil)
- return ctrl.Pipeline.UpdateStatus(ctrl.Ctx, ctrl.Client)
+ return p.UpdateStatus(ctx, client)
}
-func (ctrl *Controller) SetFailedStatus(err error) error {
+func SetFailedStatus(ctx context.Context, client client.Client, p Pipeline, err error) error {
var status = false
var reason = err.Error()
- ctrl.Pipeline.SetConfigCheck(status)
- ctrl.Pipeline.SetReason(&reason)
+ p.SetConfigCheck(status)
+ p.SetReason(&reason)
- return ctrl.Pipeline.UpdateStatus(ctrl.Ctx, ctrl.Client)
+ return p.UpdateStatus(ctx, client)
}
-func (ctrl *Controller) SetLastAppliedPipelineStatus() error {
- hash, err := ctrl.GetSpecHash()
+func SetLastAppliedPipelineStatus(ctx context.Context, client client.Client, p Pipeline) error {
+ hash, err := GetSpecHash(p)
if err != nil {
return err
}
- ctrl.Pipeline.SetLastAppliedPipeline(hash)
+ p.SetLastAppliedPipeline(hash)
- return ctrl.Pipeline.UpdateStatus(ctrl.Ctx, ctrl.Client)
+ return p.UpdateStatus(ctx, client)
}
-func decodeRaw(raw []byte) (map[string]interface{}, error) {
- result := make(map[string]interface{})
- if err := json.Unmarshal(raw, &result); err != nil {
+func GetVectorPipelines(ctx context.Context, client client.Client) ([]vectorv1alpha1.VectorPipeline, error) {
+ vps := vectorv1alpha1.VectorPipelineList{}
+ if err := client.List(ctx, &vps); err != nil {
return nil, err
}
- return result, nil
+ return vps.Items, nil
}
-func contains(elems []string, v string) bool {
- for _, s := range elems {
- if v == s {
- return true
- }
+func GetClusterVectorPipelines(ctx context.Context, client client.Client) ([]vectorv1alpha1.ClusterVectorPipeline, error) {
+ cvps := vectorv1alpha1.ClusterVectorPipelineList{}
+ if err := client.List(ctx, &cvps); err != nil {
+ return nil, err
}
- return false
-}
-
-func addPrefix(Namespace, Name, componentName string) string {
- return generateName(Namespace, Name) + "-" + componentName
-}
-
-func generateName(Namespace, Name string) string {
- return Namespace + "-" + Name
+ return cvps.Items, nil
}
diff --git a/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go b/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go
deleted file mode 100644
index 8c9d9922..00000000
--- a/controllers/factory/pipeline/vectorpipeline/vectorpipeline.go
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-Copyright 2022.
-
-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 vectorpipeline
-
-import (
- "context"
-
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/kaasops/vector-operator/controllers/factory/utils/k8s"
- "sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-var (
- Type = "noCluster"
-)
-
-type Controller struct {
- VectorPipeline *vectorv1alpha1.VectorPipeline
- Config []byte
-}
-
-func (ctrl *Controller) Spec() vectorv1alpha1.VectorPipelineSpec {
- return ctrl.VectorPipeline.Spec
-}
-
-func (ctrl *Controller) Name() string {
- return ctrl.VectorPipeline.Name
-}
-
-func (ctrl *Controller) Namespace() string {
- return ctrl.VectorPipeline.Namespace
-}
-
-func (ctrl *Controller) Type() string {
- return Type
-}
-
-func (ctrl *Controller) SetConfigCheck(value bool) {
- ctrl.VectorPipeline.Status.ConfigCheckResult = &value
-}
-
-func (ctrl *Controller) SetReason(reason *string) {
- ctrl.VectorPipeline.Status.Reason = reason
-}
-
-func (ctrl *Controller) GetLastAppliedPipeline() *uint32 {
- return ctrl.VectorPipeline.Status.LastAppliedPipelineHash
-}
-
-func (ctrl *Controller) SetLastAppliedPipeline(hash *uint32) {
- ctrl.VectorPipeline.Status.LastAppliedPipelineHash = hash
-}
-
-func (ctrl *Controller) UpdateStatus(ctx context.Context, c client.Client) error {
- return k8s.UpdateStatus(ctx, ctrl.VectorPipeline, c)
-}
-
-func NewController(vp *vectorv1alpha1.VectorPipeline) *Controller {
- return &Controller{
- VectorPipeline: vp,
- }
-}
diff --git a/controllers/factory/vector/vector.go b/controllers/factory/vector/vector.go
deleted file mode 100644
index d96bd773..00000000
--- a/controllers/factory/vector/vector.go
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-Copyright 2022.
-
-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 vector
-
-import (
- vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
- "github.com/mitchellh/mapstructure"
-)
-
-func New(vector *vectorv1alpha1.Vector) *VectorConfig {
- sources := []*Source{}
- sinks := []*Sink{}
-
- return &VectorConfig{
- DataDir: vector.Spec.Agent.DataDir,
- Api: &vector.Spec.Agent.Api,
- Sources: sources,
- Sinks: sinks,
- }
-}
-
-func Mapper(c ConfigComponent) (map[string]interface{}, error) {
- spec := c.GetOptions()
- config := &mapstructure.DecoderConfig{
- Result: &spec,
- ZeroFields: false,
- TagName: "mapper",
- IgnoreUntaggedFields: true,
- }
- decoder, err := mapstructure.NewDecoder(config)
- if err != nil {
- return nil, err
- }
- err = decoder.Decode(c)
- if err != nil {
- return nil, err
- }
- return spec, nil
-}
-
-func (t Source) GetOptions() map[string]interface{} {
- return t.Options
-}
-
-func (t Transform) GetOptions() map[string]interface{} {
- return t.Options
-}
-
-func (t Sink) GetOptions() map[string]interface{} {
- return t.Options
-}
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index f635b34f..35d4bd6e 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -21,6 +21,7 @@ import (
"time"
"github.com/kaasops/vector-operator/controllers/factory/config"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
@@ -101,16 +102,17 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
vaCtrl.SetDefault()
// Get Vector Config file
- config, err := config.New(ctx, vaCtrl)
+ pipelines, err := pipeline.GetValidPipelines(ctx, vaCtrl.Client)
if err != nil {
return ctrl.Result{}, err
}
- if err := config.FillForVectorAgent(); err != nil {
+ configBuilder, err := config.NewConfigBuilder(ctx, vaCtrl, pipelines...)
+ if err != nil {
return ctrl.Result{}, err
}
// Get Config in Json ([]byte)
- byteConfig, err := config.GetByteConfig()
+ byteConfig, err := configBuilder.GetByteConfig()
if err != nil {
return ctrl.Result{}, err
}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 9338c1a0..fbe22007 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -30,7 +30,6 @@ import (
"github.com/kaasops/vector-operator/controllers/factory/config"
"github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
"github.com/kaasops/vector-operator/controllers/factory/pipeline"
- "github.com/kaasops/vector-operator/controllers/factory/pipeline/vectorpipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
)
@@ -72,13 +71,8 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, nil
}
- // Generate VectorPipeline Controller
- vpCtrl := vectorpipeline.NewController(vectorPipelineCR)
- // Generate Pipeline Controller
- pCtrl := pipeline.NewController(ctx, r.Client, vpCtrl)
-
// Check Pipeline hash
- checkResult, err := pCtrl.CheckHash()
+ checkResult, err := pipeline.CheckHash(vectorPipelineCR)
if err != nil {
return ctrl.Result{}, err
}
@@ -111,18 +105,20 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
}
// Get Vector Config file
- config, err := config.New(ctx, vaCtrl)
+ configBuilder, err := config.NewConfigBuilder(ctx, vaCtrl, vectorPipelineCR)
if err != nil {
return ctrl.Result{}, err
}
- if err := config.FillForVectorPipeline(pCtrl); err != nil {
- return ctrl.Result{}, err
- }
- // Get Config in Json ([]byte)
- byteConfig, err := config.GetByteConfig()
+ byteConfig, err := configBuilder.GetByteConfigWithValidate()
if err != nil {
- return ctrl.Result{}, err
+ if err := pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
+ return ctrl.Result{}, err
+ }
+ if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
+ return ctrl.Result{}, err
+ }
+ return ctrl.Result{}, nil
}
// Init CheckConfig
@@ -131,10 +127,10 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// Start ConfigCheck
err = configCheck.Run()
if _, ok := err.(*configcheck.ConfigCheckError); ok {
- if err := pCtrl.SetFailedStatus(err); err != nil {
+ if err := pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
return ctrl.Result{}, err
}
- if err = pCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ if err := pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
@@ -143,11 +139,11 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, err
}
- if err = pCtrl.SetSucceesStatus(); err != nil {
+ if err = pipeline.SetSucceesStatus(ctx, r.Client, vectorPipelineCR); err != nil {
return ctrl.Result{}, err
}
- if err = pCtrl.SetLastAppliedPipelineStatus(); err != nil {
+ if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
return ctrl.Result{}, err
}
From e8c2ebf4805fa1b6dcfdfb7b8645ea30bc949a8c Mon Sep 17 00:00:00 2001
From: Nikita Strelkov
Date: Sat, 5 Nov 2022 23:54:01 +0400
Subject: [PATCH 069/316] Rename builder - simplify name
---
controllers/clustervectorpipeline_controller.go | 2 +-
controllers/factory/config/config_build.go | 14 +++++++-------
controllers/vector_controller.go | 2 +-
controllers/vectorpipeline_controller.go | 2 +-
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
index 7bbdabcd..57adeb16 100644
--- a/controllers/clustervectorpipeline_controller.go
+++ b/controllers/clustervectorpipeline_controller.go
@@ -105,7 +105,7 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
}
// Get Vector Config file
- configBuilder, err := config.NewConfigBuilder(ctx, vaCtrl, vectorPipelineCR)
+ configBuilder, err := config.NewBuilder(ctx, vaCtrl, vectorPipelineCR)
if err != nil {
return ctrl.Result{}, err
}
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index 077127d6..222ba51d 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -45,22 +45,22 @@ var (
}
)
-type ConfigBuilder struct {
+type Builder struct {
Name string
Ctx context.Context
vaCtrl *vectoragent.Controller
Pipelines []pipeline.Pipeline
}
-func NewConfigBuilder(ctx context.Context, vaCtrl *vectoragent.Controller, pipelines ...pipeline.Pipeline) (*ConfigBuilder, error) {
- return &ConfigBuilder{
+func NewBuilder(ctx context.Context, vaCtrl *vectoragent.Controller, pipelines ...pipeline.Pipeline) (*Builder, error) {
+ return &Builder{
Ctx: ctx,
vaCtrl: vaCtrl,
Pipelines: pipelines,
}, nil
}
-func (b *ConfigBuilder) GetByteConfig() ([]byte, error) {
+func (b *Builder) GetByteConfig() ([]byte, error) {
config, err := b.generateVectorConfig()
if err != nil {
return nil, err
@@ -74,7 +74,7 @@ func (b *ConfigBuilder) GetByteConfig() ([]byte, error) {
return data, nil
}
-func (b *ConfigBuilder) GetByteConfigWithValidate() ([]byte, error) {
+func (b *Builder) GetByteConfigWithValidate() ([]byte, error) {
validateError := errors.New("type kubernetes_logs only allowed")
config, err := b.generateVectorConfig()
if err != nil {
@@ -101,7 +101,7 @@ func (b *ConfigBuilder) GetByteConfigWithValidate() ([]byte, error) {
return data, nil
}
-func (b *ConfigBuilder) generateVectorConfig() (*VectorConfig, error) {
+func (b *Builder) generateVectorConfig() (*VectorConfig, error) {
vectorConfig := New(b.vaCtrl.Vector)
sources, transforms, sinks, err := b.getComponents()
@@ -123,7 +123,7 @@ func (b *ConfigBuilder) generateVectorConfig() (*VectorConfig, error) {
return vectorConfig, nil
}
-func (b *ConfigBuilder) getComponents() (sources []*Source, transforms []*Transform, sinks []*Sink, err error) {
+func (b *Builder) getComponents() (sources []*Source, transforms []*Transform, sinks []*Sink, err error) {
for _, pipeline := range b.Pipelines {
pipelineSources, err := getSources(pipeline, nil)
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 35d4bd6e..46d688f1 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -106,7 +106,7 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
if err != nil {
return ctrl.Result{}, err
}
- configBuilder, err := config.NewConfigBuilder(ctx, vaCtrl, pipelines...)
+ configBuilder, err := config.NewBuilder(ctx, vaCtrl, pipelines...)
if err != nil {
return ctrl.Result{}, err
}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index fbe22007..2fdecd09 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -105,7 +105,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
}
// Get Vector Config file
- configBuilder, err := config.NewConfigBuilder(ctx, vaCtrl, vectorPipelineCR)
+ configBuilder, err := config.NewBuilder(ctx, vaCtrl, vectorPipelineCR)
if err != nil {
return ctrl.Result{}, err
}
From 63b191558e93cad9ce0b8814d37f127b44b8a80d Mon Sep 17 00:00:00 2001
From: Nikita Strelkov
Date: Sun, 6 Nov 2022 00:07:59 +0400
Subject: [PATCH 070/316] Make config error more ideomatic
---
api/v1alpha1/groupversion_info.go | 4 ++--
controllers/clustervectorpipeline_controller.go | 7 ++++---
.../factory/config/configcheck/configcheck.go | 4 +---
.../config/configcheck/configcheck_error.go | 16 +++++++---------
.../vector/vectoragent/vectoragent_config.go | 3 ++-
controllers/vectorpipeline_controller.go | 7 ++++---
6 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/api/v1alpha1/groupversion_info.go b/api/v1alpha1/groupversion_info.go
index ee33ae74..11f08d85 100644
--- a/api/v1alpha1/groupversion_info.go
+++ b/api/v1alpha1/groupversion_info.go
@@ -15,8 +15,8 @@ limitations under the License.
*/
// Package v1alpha1 contains API Schema definitions for the observability v1alpha1 API group
-//+kubebuilder:object:generate=true
-//+groupName=observability.kaasops.io
+// +kubebuilder:object:generate=true
+// +groupName=observability.kaasops.io
package v1alpha1
import (
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
index 57adeb16..a2dc5bb9 100644
--- a/controllers/clustervectorpipeline_controller.go
+++ b/controllers/clustervectorpipeline_controller.go
@@ -18,8 +18,9 @@ package controllers
import (
"context"
+ "errors"
- "k8s.io/apimachinery/pkg/api/errors"
+ api_errors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
@@ -126,7 +127,7 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
// Start ConfigCheck
err = configCheck.Run()
- if _, ok := err.(*configcheck.ConfigCheckError); ok {
+ if errors.Is(err, configcheck.ValidationError) {
if err = pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
return ctrl.Result{}, err
}
@@ -158,7 +159,7 @@ func (r *ClusterVectorPipelineReconciler) findClusterVectorPipelineCustomResourc
cvp := &vectorv1alpha1.ClusterVectorPipeline{}
err := r.Get(ctx, req.NamespacedName, cvp)
if err != nil {
- if errors.IsNotFound(err) {
+ if api_errors.IsNotFound(err) {
return nil, nil
}
return nil, err
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index c7343771..85b2dffc 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -159,9 +159,7 @@ func (cc *ConfigCheck) getCheckResult(pod *corev1.Pod) error {
if err != nil {
return err
}
- return &ConfigCheckError{
- Reason: reason,
- }
+ return newValidationError(reason)
case "Succeeded":
log.Info("Config Check completed successfully")
return nil
diff --git a/controllers/factory/config/configcheck/configcheck_error.go b/controllers/factory/config/configcheck/configcheck_error.go
index 4ecf5e85..3a457466 100644
--- a/controllers/factory/config/configcheck/configcheck_error.go
+++ b/controllers/factory/config/configcheck/configcheck_error.go
@@ -16,15 +16,13 @@ limitations under the License.
package configcheck
-type error interface {
- Error() string
-}
+import (
+ "errors"
+ "fmt"
+)
-type ConfigCheckError struct {
- Reason string
- Err error
-}
+var ValidationError = errors.New("config validation error")
-func (e *ConfigCheckError) Error() string {
- return e.Reason
+func newValidationError(reason string) error {
+ return fmt.Errorf("%w: %s", ValidationError, reason)
}
diff --git a/controllers/factory/vector/vectoragent/vectoragent_config.go b/controllers/factory/vector/vectoragent/vectoragent_config.go
index b17bfdd8..a59e2ac3 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_config.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_config.go
@@ -18,6 +18,7 @@ package vectoragent
import (
"context"
+ "errors"
corev1 "k8s.io/api/core/v1"
@@ -32,7 +33,7 @@ func (ctrl *Controller) createVectorAgentConfig(ctx context.Context) (*corev1.Se
if ctrl.Vector.Status.LastAppliedConfigHash == nil || *ctrl.Vector.Status.LastAppliedConfigHash != cfgHash {
err := configCheck.Run()
- if _, ok := err.(*configcheck.ConfigCheckError); ok {
+ if errors.Is(err, configcheck.ValidationError) {
if err := ctrl.SetFailedStatus(ctx, err); err != nil {
return nil, err
}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 2fdecd09..3b0481a4 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -18,8 +18,9 @@ package controllers
import (
"context"
+ "errors"
- "k8s.io/apimachinery/pkg/api/errors"
+ api_errors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
@@ -126,7 +127,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// Start ConfigCheck
err = configCheck.Run()
- if _, ok := err.(*configcheck.ConfigCheckError); ok {
+ if errors.Is(err, configcheck.ValidationError) {
if err := pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
return ctrl.Result{}, err
}
@@ -158,7 +159,7 @@ func (r *VectorPipelineReconciler) findVectorPipelineCustomResourceInstance(ctx
vectorPipelineCR := &vectorv1alpha1.VectorPipeline{}
err := r.Get(ctx, req.NamespacedName, vectorPipelineCR)
if err != nil {
- if errors.IsNotFound(err) {
+ if api_errors.IsNotFound(err) {
return nil, nil
}
return nil, err
From 96e62c40fcb75daaa7bfae79f3e4e560ff30bfb2 Mon Sep 17 00:00:00 2001
From: Nikita Strelkov
Date: Sun, 6 Nov 2022 00:42:12 +0400
Subject: [PATCH 071/316] Fix typo
---
controllers/clustervectorpipeline_controller.go | 2 +-
controllers/factory/pipeline/pipeline.go | 2 +-
controllers/vectorpipeline_controller.go | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
index a2dc5bb9..680c6830 100644
--- a/controllers/clustervectorpipeline_controller.go
+++ b/controllers/clustervectorpipeline_controller.go
@@ -140,7 +140,7 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, err
}
- if err = pipeline.SetSucceesStatus(ctx, r.Client, vectorPipelineCR); err != nil {
+ if err = pipeline.SetSuccessStatus(ctx, r.Client, vectorPipelineCR); err != nil {
return ctrl.Result{}, err
}
diff --git a/controllers/factory/pipeline/pipeline.go b/controllers/factory/pipeline/pipeline.go
index 8edb9edf..13af5bec 100644
--- a/controllers/factory/pipeline/pipeline.go
+++ b/controllers/factory/pipeline/pipeline.go
@@ -64,7 +64,7 @@ func GetValidPipelines(ctx context.Context, client client.Client) ([]Pipeline, e
return validPipelines, nil
}
-func SetSucceesStatus(ctx context.Context, client client.Client, p Pipeline) error {
+func SetSuccessStatus(ctx context.Context, client client.Client, p Pipeline) error {
var status = true
p.SetConfigCheck(status)
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index 3b0481a4..c6d89918 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -140,7 +140,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
return ctrl.Result{}, err
}
- if err = pipeline.SetSucceesStatus(ctx, r.Client, vectorPipelineCR); err != nil {
+ if err = pipeline.SetSuccessStatus(ctx, r.Client, vectorPipelineCR); err != nil {
return ctrl.Result{}, err
}
From 7ba643b36ee9543d96e16129987c382744e5a8f1 Mon Sep 17 00:00:00 2001
From: Nikita Strelkov
Date: Sun, 6 Nov 2022 00:43:48 +0400
Subject: [PATCH 072/316] Simplify code
---
controllers/factory/pipeline/pipeline.go | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/controllers/factory/pipeline/pipeline.go b/controllers/factory/pipeline/pipeline.go
index 13af5bec..f6d59e6d 100644
--- a/controllers/factory/pipeline/pipeline.go
+++ b/controllers/factory/pipeline/pipeline.go
@@ -65,19 +65,16 @@ func GetValidPipelines(ctx context.Context, client client.Client) ([]Pipeline, e
}
func SetSuccessStatus(ctx context.Context, client client.Client, p Pipeline) error {
- var status = true
-
- p.SetConfigCheck(status)
+ p.SetConfigCheck(true)
p.SetReason(nil)
return p.UpdateStatus(ctx, client)
}
func SetFailedStatus(ctx context.Context, client client.Client, p Pipeline, err error) error {
- var status = false
var reason = err.Error()
- p.SetConfigCheck(status)
+ p.SetConfigCheck(true)
p.SetReason(&reason)
return p.UpdateStatus(ctx, client)
From 6544220b0d340237c1a2673a632f6736af2f42a5 Mon Sep 17 00:00:00 2001
From: Nikita Strelkov
Date: Sun, 6 Nov 2022 00:49:11 +0400
Subject: [PATCH 073/316] Simplify errors checking
No need in comparing err != nil two times, because
errors.IsAlreadyExists works fine with nil error, and after checking
`errors.IsAlreadyExists(err)` we just need to return `err` whether it is
nil or not
---
controllers/factory/utils/k8s/k8s.go | 56 +++++++---------------------
1 file changed, 14 insertions(+), 42 deletions(-)
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index 8247a4b1..1c09eed0 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -133,7 +133,7 @@ func reconcileService(obj runtime.Object, c client.Client) error {
desired := obj.(*corev1.Service)
err := c.Create(context.TODO(), desired)
- if err != nil && errors.IsAlreadyExists(err) {
+ if errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
@@ -145,11 +145,7 @@ func reconcileService(obj runtime.Object, c client.Client) error {
return err
}
}
- if err != nil && !errors.IsAlreadyExists(err) {
- return err
- }
-
- return nil
+ return err
}
func reconcileSecret(obj runtime.Object, c client.Client) error {
@@ -158,7 +154,7 @@ func reconcileSecret(obj runtime.Object, c client.Client) error {
desired := obj.(*corev1.Secret)
err := c.Create(context.TODO(), desired)
- if err != nil && errors.IsAlreadyExists(err) {
+ if errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
@@ -169,11 +165,7 @@ func reconcileSecret(obj runtime.Object, c client.Client) error {
return c.Update(context.TODO(), existing)
}
}
- if err != nil && !errors.IsAlreadyExists(err) {
- return err
- }
-
- return nil
+ return err
}
func reconcileDaemonSet(obj runtime.Object, c client.Client) error {
@@ -182,7 +174,7 @@ func reconcileDaemonSet(obj runtime.Object, c client.Client) error {
desired := obj.(*appsv1.DaemonSet)
err := c.Create(context.TODO(), desired)
- if err != nil && errors.IsAlreadyExists(err) {
+ if errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
@@ -193,11 +185,7 @@ func reconcileDaemonSet(obj runtime.Object, c client.Client) error {
return c.Update(context.TODO(), existing)
}
}
- if err != nil && !errors.IsAlreadyExists(err) {
- return err
- }
-
- return nil
+ return err
}
func reconcileStatefulSet(obj runtime.Object, c client.Client) error {
@@ -206,7 +194,7 @@ func reconcileStatefulSet(obj runtime.Object, c client.Client) error {
desired := obj.(*appsv1.StatefulSet)
err := c.Create(context.TODO(), desired)
- if err != nil && errors.IsAlreadyExists(err) {
+ if errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
@@ -217,11 +205,7 @@ func reconcileStatefulSet(obj runtime.Object, c client.Client) error {
return c.Update(context.TODO(), existing)
}
}
- if err != nil && !errors.IsAlreadyExists(err) {
- return err
- }
-
- return nil
+ return err
}
func reconcileServiceAccount(obj runtime.Object, c client.Client) error {
@@ -230,17 +214,13 @@ func reconcileServiceAccount(obj runtime.Object, c client.Client) error {
desired := obj.(*corev1.ServiceAccount)
err := c.Create(context.TODO(), desired)
- if err != nil && errors.IsAlreadyExists(err) {
+ if errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
}
- if err != nil && !errors.IsAlreadyExists(err) {
- return err
- }
-
- return nil
+ return err
}
func reconcileClusterRole(obj runtime.Object, c client.Client) error {
@@ -249,7 +229,7 @@ func reconcileClusterRole(obj runtime.Object, c client.Client) error {
desired := obj.(*rbacv1.ClusterRole)
err := c.Create(context.TODO(), desired)
- if err != nil && errors.IsAlreadyExists(err) {
+ if errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
@@ -259,11 +239,7 @@ func reconcileClusterRole(obj runtime.Object, c client.Client) error {
return c.Update(context.TODO(), existing)
}
}
- if err != nil && !errors.IsAlreadyExists(err) {
- return err
- }
-
- return nil
+ return err
}
func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
@@ -272,7 +248,7 @@ func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
desired := obj.(*rbacv1.ClusterRoleBinding)
err := c.Create(context.TODO(), desired)
- if err != nil && errors.IsAlreadyExists(err) {
+ if errors.IsAlreadyExists(err) {
err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
@@ -283,11 +259,7 @@ func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
return c.Update(context.TODO(), existing)
}
}
- if err != nil && !errors.IsAlreadyExists(err) {
- return err
- }
-
- return nil
+ return err
}
func NamespaceNameToLabel(namespace string) string {
From 06da0da039a169c1d4ed6caa6dded522d91838a4 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 7 Nov 2022 10:10:43 +0200
Subject: [PATCH 074/316] return nil on succesfull reconcle
---
controllers/factory/utils/k8s/k8s.go | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index 1c09eed0..05d8b1ae 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -141,9 +141,9 @@ func reconcileService(obj runtime.Object, c client.Client) error {
if !equality.Semantic.DeepEqual(existing, desired) {
existing.Spec = desired.Spec
existing.Labels = desired.Labels
- err := c.Update(context.TODO(), existing)
- return err
+ return c.Update(context.TODO(), existing)
}
+ return nil
}
return err
}
@@ -164,6 +164,7 @@ func reconcileSecret(obj runtime.Object, c client.Client) error {
existing.Labels = desired.Labels
return c.Update(context.TODO(), existing)
}
+ return nil
}
return err
}
@@ -184,6 +185,7 @@ func reconcileDaemonSet(obj runtime.Object, c client.Client) error {
existing.Labels = desired.Labels
return c.Update(context.TODO(), existing)
}
+ return nil
}
return err
}
@@ -204,6 +206,7 @@ func reconcileStatefulSet(obj runtime.Object, c client.Client) error {
existing.Labels = desired.Labels
return c.Update(context.TODO(), existing)
}
+ return nil
}
return err
}
@@ -219,6 +222,7 @@ func reconcileServiceAccount(obj runtime.Object, c client.Client) error {
if err != nil {
return err
}
+ return nil
}
return err
}
@@ -238,6 +242,7 @@ func reconcileClusterRole(obj runtime.Object, c client.Client) error {
existing.Rules = desired.Rules
return c.Update(context.TODO(), existing)
}
+ return nil
}
return err
}
@@ -258,6 +263,7 @@ func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
existing.Subjects = desired.Subjects
return c.Update(context.TODO(), existing)
}
+ return nil
}
return err
}
From 67b81e5d56d053b42a0aa65c49ca75a330a7b7ec Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 7 Nov 2022 17:21:17 +0200
Subject: [PATCH 075/316] added reconcile config func
---
.../clustervectorpipeline_controller.go | 45 +---------------
controllers/factory/config/config.go | 53 +++++++++++++++++++
controllers/vectorpipeline_controller.go | 43 +--------------
3 files changed, 55 insertions(+), 86 deletions(-)
diff --git a/controllers/clustervectorpipeline_controller.go b/controllers/clustervectorpipeline_controller.go
index 680c6830..77965e1d 100644
--- a/controllers/clustervectorpipeline_controller.go
+++ b/controllers/clustervectorpipeline_controller.go
@@ -18,7 +18,6 @@ package controllers
import (
"context"
- "errors"
api_errors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
@@ -29,7 +28,6 @@ import (
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/config"
- "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
"github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
)
@@ -104,50 +102,9 @@ func (r *ClusterVectorPipelineReconciler) Reconcile(ctx context.Context, req ctr
if vaCtrl.Vector.Spec.Agent.DataDir == "" {
vaCtrl.Vector.Spec.Agent.DataDir = "/vector-data-dir"
}
-
- // Get Vector Config file
- configBuilder, err := config.NewBuilder(ctx, vaCtrl, vectorPipelineCR)
- if err != nil {
- return ctrl.Result{}, err
- }
-
- byteConfig, err := configBuilder.GetByteConfigWithValidate()
- if err != nil {
- if err := pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
- return ctrl.Result{}, err
- }
- if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
- return ctrl.Result{}, err
- }
- return ctrl.Result{}, nil
- }
-
- // Init CheckConfig
- configCheck := configcheck.New(ctx, byteConfig, vaCtrl.Client, vaCtrl.ClientSet, vaCtrl.Vector.Name, vaCtrl.Vector.Namespace, vaCtrl.Vector.Spec.Agent.Image)
-
- // Start ConfigCheck
- err = configCheck.Run()
- if errors.Is(err, configcheck.ValidationError) {
- if err = pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
- return ctrl.Result{}, err
- }
- if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
- return ctrl.Result{}, err
- }
- return ctrl.Result{}, nil
- }
- if err != nil {
+ if err := config.ReconcileConfig(ctx, r.Client, vectorPipelineCR, vaCtrl); err != nil {
return ctrl.Result{}, err
}
-
- if err = pipeline.SetSuccessStatus(ctx, r.Client, vectorPipelineCR); err != nil {
- return ctrl.Result{}, err
- }
-
- if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
- return ctrl.Result{}, err
- }
-
}
log.Info("finish Reconcile VectorPipeline")
diff --git a/controllers/factory/config/config.go b/controllers/factory/config/config.go
index fe12b1a4..f4967007 100644
--- a/controllers/factory/config/config.go
+++ b/controllers/factory/config/config.go
@@ -17,10 +17,63 @@ limitations under the License.
package config
import (
+ "context"
+ "errors"
+
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
+ "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
+ "github.com/kaasops/vector-operator/controllers/factory/pipeline"
+ "github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
"github.com/mitchellh/mapstructure"
+ "sigs.k8s.io/controller-runtime/pkg/client"
)
+func ReconcileConfig(ctx context.Context, client client.Client, p pipeline.Pipeline, vaCtrl *vectoragent.Controller) error {
+ // Get Vector Config file
+ configBuilder, err := NewBuilder(ctx, vaCtrl, p)
+ if err != nil {
+ return err
+ }
+
+ byteConfig, err := configBuilder.GetByteConfigWithValidate()
+ if err != nil {
+ if err := pipeline.SetFailedStatus(ctx, client, p, err); err != nil {
+ return err
+ }
+ if err = pipeline.SetLastAppliedPipelineStatus(ctx, client, p); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ // Init CheckConfig
+ configCheck := configcheck.New(ctx, byteConfig, vaCtrl.Client, vaCtrl.ClientSet, vaCtrl.Vector.Name, vaCtrl.Vector.Namespace, vaCtrl.Vector.Spec.Agent.Image)
+
+ // Start ConfigCheck
+ err = configCheck.Run()
+ if errors.Is(err, configcheck.ValidationError) {
+ if err = pipeline.SetFailedStatus(ctx, client, p, err); err != nil {
+ return err
+ }
+ if err = pipeline.SetLastAppliedPipelineStatus(ctx, client, p); err != nil {
+ return err
+ }
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+
+ if err = pipeline.SetSuccessStatus(ctx, client, p); err != nil {
+ return err
+ }
+
+ if err = pipeline.SetLastAppliedPipelineStatus(ctx, client, p); err != nil {
+ return err
+ }
+ return nil
+}
+
func New(vector *vectorv1alpha1.Vector) *VectorConfig {
sources := []*Source{}
sinks := []*Sink{}
diff --git a/controllers/vectorpipeline_controller.go b/controllers/vectorpipeline_controller.go
index c6d89918..a2f3e0f5 100644
--- a/controllers/vectorpipeline_controller.go
+++ b/controllers/vectorpipeline_controller.go
@@ -18,7 +18,6 @@ package controllers
import (
"context"
- "errors"
api_errors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
@@ -29,7 +28,6 @@ import (
vectorv1alpha1 "github.com/kaasops/vector-operator/api/v1alpha1"
"github.com/kaasops/vector-operator/controllers/factory/config"
- "github.com/kaasops/vector-operator/controllers/factory/config/configcheck"
"github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
)
@@ -105,46 +103,7 @@ func (r *VectorPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Reque
vaCtrl.Vector.Spec.Agent.DataDir = "/vector-data-dir"
}
- // Get Vector Config file
- configBuilder, err := config.NewBuilder(ctx, vaCtrl, vectorPipelineCR)
- if err != nil {
- return ctrl.Result{}, err
- }
-
- byteConfig, err := configBuilder.GetByteConfigWithValidate()
- if err != nil {
- if err := pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
- return ctrl.Result{}, err
- }
- if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
- return ctrl.Result{}, err
- }
- return ctrl.Result{}, nil
- }
-
- // Init CheckConfig
- configCheck := configcheck.New(ctx, byteConfig, vaCtrl.Client, vaCtrl.ClientSet, vaCtrl.Vector.Name, vaCtrl.Vector.Namespace, vaCtrl.Vector.Spec.Agent.Image)
-
- // Start ConfigCheck
- err = configCheck.Run()
- if errors.Is(err, configcheck.ValidationError) {
- if err := pipeline.SetFailedStatus(ctx, r.Client, vectorPipelineCR, err); err != nil {
- return ctrl.Result{}, err
- }
- if err := pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
- return ctrl.Result{}, err
- }
- return ctrl.Result{}, nil
- }
- if err != nil {
- return ctrl.Result{}, err
- }
-
- if err = pipeline.SetSuccessStatus(ctx, r.Client, vectorPipelineCR); err != nil {
- return ctrl.Result{}, err
- }
-
- if err = pipeline.SetLastAppliedPipelineStatus(ctx, r.Client, vectorPipelineCR); err != nil {
+ if err := config.ReconcileConfig(ctx, r.Client, vectorPipelineCR, vaCtrl); err != nil {
return ctrl.Result{}, err
}
From 821a5414ed307ab01546929ffbce1369ab218c01 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Mon, 7 Nov 2022 17:33:05 +0200
Subject: [PATCH 076/316] fix set failed status
---
controllers/factory/pipeline/pipeline.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/controllers/factory/pipeline/pipeline.go b/controllers/factory/pipeline/pipeline.go
index f6d59e6d..699dc894 100644
--- a/controllers/factory/pipeline/pipeline.go
+++ b/controllers/factory/pipeline/pipeline.go
@@ -74,7 +74,7 @@ func SetSuccessStatus(ctx context.Context, client client.Client, p Pipeline) err
func SetFailedStatus(ctx context.Context, client client.Client, p Pipeline, err error) error {
var reason = err.Error()
- p.SetConfigCheck(true)
+ p.SetConfigCheck(false)
p.SetReason(&reason)
return p.UpdateStatus(ctx, client)
From fc9f72dac5f83f244fb9e458460a6992ec26de5a Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Wed, 9 Nov 2022 14:41:02 +0200
Subject: [PATCH 077/316] Cleadup quick start doc
Signed-off-by: Zemtsov Vladimir
---
docs/quick-start.md | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/docs/quick-start.md b/docs/quick-start.md
index 399fd33a..15d3ecf7 100644
--- a/docs/quick-start.md
+++ b/docs/quick-start.md
@@ -14,7 +14,7 @@ kubectl apply -f config/crd/bases/observability.kaasops.io_clustervectorpipeline
## Start Vector Operator
### Create namespace for Vector Operator
```bash
-kubectl create namespace vector-operator-system
+kubectl create namespace vector
```
### Create RBAC
@@ -25,7 +25,7 @@ apiVersion: v1
kind: Secret
metadata:
name: vector-operator-sa-token
- namespace: vector-operator-system
+ namespace: vector
annotations:
kubernetes.io/service-account.name: vector-operator
type: kubernetes.io/service-account-token
@@ -34,7 +34,7 @@ EOF
```bash
# Create ServiceAccount for Vector Operator
-kubectl create serviceaccount -n vector-operator-system vector-operator
+kubectl create serviceaccount -n vector vector-operator
# Create ClusterRole for Vector Operator
cat <
Date: Wed, 9 Nov 2022 14:41:22 +0200
Subject: [PATCH 078/316] Add RoadMap to Readme
Signed-off-by: Zemtsov Vladimir
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index 9f5e01ca..ac393f96 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,8 @@ The operator deploys and configures a vector agent daemonset on every node to co
- [ ] Vector config optimization
- [ ] Vector aggregator support
+[RoadMap](https://github.com/orgs/kaasops/projects/1)
+
## Documentation
- Quick start [doc](https://github.com/kaasops/vector-operator/blob/main/docs/quick-start.md)
- Design [doc](https://github.com/kaasops/vector-operator/blob/main/docs/design.md)
From 01c18e9ce318051213a0ae4fa6e77de0fd40cbeb Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Wed, 9 Nov 2022 16:07:28 +0200
Subject: [PATCH 079/316] Fix context-in-struct warning
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/config/config.go | 9 +++------
controllers/factory/config/config_build.go | 7 ++-----
.../factory/config/configcheck/configcheck.go | 17 +++++++----------
.../vector/vectoragent/vectoragent_config.go | 4 ++--
controllers/vector_controller.go | 5 +----
5 files changed, 15 insertions(+), 27 deletions(-)
diff --git a/controllers/factory/config/config.go b/controllers/factory/config/config.go
index f4967007..70fc3595 100644
--- a/controllers/factory/config/config.go
+++ b/controllers/factory/config/config.go
@@ -30,10 +30,7 @@ import (
func ReconcileConfig(ctx context.Context, client client.Client, p pipeline.Pipeline, vaCtrl *vectoragent.Controller) error {
// Get Vector Config file
- configBuilder, err := NewBuilder(ctx, vaCtrl, p)
- if err != nil {
- return err
- }
+ configBuilder := NewBuilder(vaCtrl, p)
byteConfig, err := configBuilder.GetByteConfigWithValidate()
if err != nil {
@@ -47,10 +44,10 @@ func ReconcileConfig(ctx context.Context, client client.Client, p pipeline.Pipel
}
// Init CheckConfig
- configCheck := configcheck.New(ctx, byteConfig, vaCtrl.Client, vaCtrl.ClientSet, vaCtrl.Vector.Name, vaCtrl.Vector.Namespace, vaCtrl.Vector.Spec.Agent.Image)
+ configCheck := configcheck.New(byteConfig, vaCtrl.Client, vaCtrl.ClientSet, vaCtrl.Vector.Name, vaCtrl.Vector.Namespace, vaCtrl.Vector.Spec.Agent.Image)
// Start ConfigCheck
- err = configCheck.Run()
+ err = configCheck.Run(ctx)
if errors.Is(err, configcheck.ValidationError) {
if err = pipeline.SetFailedStatus(ctx, client, p, err); err != nil {
return err
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index 222ba51d..8512d3ea 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -17,7 +17,6 @@ limitations under the License.
package config
import (
- "context"
"encoding/json"
"errors"
@@ -47,17 +46,15 @@ var (
type Builder struct {
Name string
- Ctx context.Context
vaCtrl *vectoragent.Controller
Pipelines []pipeline.Pipeline
}
-func NewBuilder(ctx context.Context, vaCtrl *vectoragent.Controller, pipelines ...pipeline.Pipeline) (*Builder, error) {
+func NewBuilder(vaCtrl *vectoragent.Controller, pipelines ...pipeline.Pipeline) *Builder {
return &Builder{
- Ctx: ctx,
vaCtrl: vaCtrl,
Pipelines: pipelines,
- }, nil
+ }
}
func (b *Builder) GetByteConfig() ([]byte, error) {
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index 85b2dffc..c2d7f666 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -31,8 +31,6 @@ import (
)
type ConfigCheck struct {
- Ctx context.Context
-
Config []byte
Client client.Client
@@ -44,9 +42,8 @@ type ConfigCheck struct {
Hash string
}
-func New(ctx context.Context, config []byte, c client.Client, cs *kubernetes.Clientset, name, namespace, image string) *ConfigCheck {
+func New(config []byte, c client.Client, cs *kubernetes.Clientset, name, namespace, image string) *ConfigCheck {
return &ConfigCheck{
- Ctx: ctx,
Config: config,
Client: c,
ClientSet: cs,
@@ -56,7 +53,7 @@ func New(ctx context.Context, config []byte, c client.Client, cs *kubernetes.Cli
}
}
-func (cc *ConfigCheck) Run() error {
+func (cc *ConfigCheck) Run(ctx context.Context) error {
log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", cc.Name)
log.Info("start ConfigCheck")
@@ -71,7 +68,7 @@ func (cc *ConfigCheck) Run() error {
return err
}
- if err := cc.checkVectorConfigCheckPod(); err != nil {
+ if err := cc.checkVectorConfigCheckPod(ctx); err != nil {
return err
}
@@ -96,7 +93,7 @@ func (cc *ConfigCheck) ensureVectorConfigCheckConfig() error {
return k8s.CreateOrUpdateSecret(vectorConfigCheckSecret, cc.Client)
}
-func (cc *ConfigCheck) checkVectorConfigCheckPod() error {
+func (cc *ConfigCheck) checkVectorConfigCheckPod(ctx context.Context) error {
vectorConfigCheckPod := cc.createVectorConfigCheckPod()
err := k8s.CreatePod(vectorConfigCheckPod, cc.Client)
@@ -109,7 +106,7 @@ func (cc *ConfigCheck) checkVectorConfigCheckPod() error {
return err
}
- err = cc.cleanup()
+ err = cc.cleanup(ctx)
if err != nil {
return err
}
@@ -167,14 +164,14 @@ func (cc *ConfigCheck) getCheckResult(pod *corev1.Pod) error {
}
}
-func (cc *ConfigCheck) cleanup() error {
+func (cc *ConfigCheck) cleanup(ctx context.Context) error {
listOpts, err := cc.gcRListOptions()
if err != nil {
return err
}
podlist := corev1.PodList{}
- err = cc.Client.List(cc.Ctx, &podlist, &listOpts)
+ err = cc.Client.List(ctx, &podlist, &listOpts)
if err != nil {
return err
}
diff --git a/controllers/factory/vector/vectoragent/vectoragent_config.go b/controllers/factory/vector/vectoragent/vectoragent_config.go
index a59e2ac3..a32d418d 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_config.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_config.go
@@ -29,10 +29,10 @@ import (
func (ctrl *Controller) createVectorAgentConfig(ctx context.Context) (*corev1.Secret, error) {
cfgHash := hash.Get(ctrl.Config)
- configCheck := configcheck.New(ctx, ctrl.Config, ctrl.Client, ctrl.ClientSet, ctrl.Vector.Name, ctrl.Vector.Namespace, ctrl.Vector.Spec.Agent.Image)
+ configCheck := configcheck.New(ctrl.Config, ctrl.Client, ctrl.ClientSet, ctrl.Vector.Name, ctrl.Vector.Namespace, ctrl.Vector.Spec.Agent.Image)
if ctrl.Vector.Status.LastAppliedConfigHash == nil || *ctrl.Vector.Status.LastAppliedConfigHash != cfgHash {
- err := configCheck.Run()
+ err := configCheck.Run(ctx)
if errors.Is(err, configcheck.ValidationError) {
if err := ctrl.SetFailedStatus(ctx, err); err != nil {
return nil, err
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 46d688f1..ce86e071 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -106,10 +106,7 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
if err != nil {
return ctrl.Result{}, err
}
- configBuilder, err := config.NewBuilder(ctx, vaCtrl, pipelines...)
- if err != nil {
- return ctrl.Result{}, err
- }
+ configBuilder := config.NewBuilder(vaCtrl, pipelines...)
// Get Config in Json ([]byte)
byteConfig, err := configBuilder.GetByteConfig()
From d6b6898a02d0d48e002794fa9364486266502a20 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Thu, 10 Nov 2022 09:06:20 +0200
Subject: [PATCH 080/316] Disable reconcile by time (#38)
* improve reconcile kubernetes objects
---
controllers/factory/utils/k8s/k8s.go | 47 ++++++++++++++++++++++------
controllers/vector_controller.go | 11 +++++--
2 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index 05d8b1ae..a19fdbc4 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -138,9 +138,12 @@ func reconcileService(obj runtime.Object, c client.Client) error {
if err != nil {
return err
}
- if !equality.Semantic.DeepEqual(existing, desired) {
- existing.Spec = desired.Spec
+ if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
+ !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
+ !equality.Semantic.DeepDerivative(desired.Spec, existing.Spec) {
existing.Labels = desired.Labels
+ existing.Annotations = desired.Annotations
+ existing.Spec = desired.Spec
return c.Update(context.TODO(), existing)
}
return nil
@@ -159,9 +162,12 @@ func reconcileSecret(obj runtime.Object, c client.Client) error {
if err != nil {
return err
}
- if !equality.Semantic.DeepEqual(existing, desired) {
- existing.Data = desired.Data
+ if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
+ !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
+ !equality.Semantic.DeepDerivative(desired.Data, existing.Data) {
existing.Labels = desired.Labels
+ existing.Annotations = desired.Annotations
+ existing.Data = desired.Data
return c.Update(context.TODO(), existing)
}
return nil
@@ -180,9 +186,12 @@ func reconcileDaemonSet(obj runtime.Object, c client.Client) error {
if err != nil {
return err
}
- if !equality.Semantic.DeepEqual(existing, desired) {
- existing.Spec = desired.Spec
+ if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
+ !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
+ !equality.Semantic.DeepDerivative(desired.Spec, existing.Spec) {
existing.Labels = desired.Labels
+ existing.Annotations = desired.Annotations
+ existing.Spec = desired.Spec
return c.Update(context.TODO(), existing)
}
return nil
@@ -201,9 +210,12 @@ func reconcileStatefulSet(obj runtime.Object, c client.Client) error {
if err != nil {
return err
}
- if !equality.Semantic.DeepEqual(existing, desired) {
- existing.Spec = desired.Spec
+ if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
+ !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
+ !equality.Semantic.DeepDerivative(desired.Spec, existing.Spec) {
existing.Labels = desired.Labels
+ existing.Annotations = desired.Annotations
+ existing.Spec = desired.Spec
return c.Update(context.TODO(), existing)
}
return nil
@@ -222,6 +234,12 @@ func reconcileServiceAccount(obj runtime.Object, c client.Client) error {
if err != nil {
return err
}
+ if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
+ !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) {
+ existing.Labels = desired.Labels
+ existing.Annotations = desired.Annotations
+ return c.Update(context.TODO(), existing)
+ }
return nil
}
return err
@@ -238,7 +256,11 @@ func reconcileClusterRole(obj runtime.Object, c client.Client) error {
if err != nil {
return err
}
- if !equality.Semantic.DeepEqual(existing, desired) {
+ if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
+ !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
+ !equality.Semantic.DeepDerivative(desired.Rules, existing.Rules) {
+ existing.Labels = desired.Labels
+ existing.Annotations = desired.Annotations
existing.Rules = desired.Rules
return c.Update(context.TODO(), existing)
}
@@ -258,7 +280,12 @@ func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
if err != nil {
return err
}
- if !equality.Semantic.DeepEqual(existing, desired) {
+ if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
+ !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
+ !equality.Semantic.DeepDerivative(desired.RoleRef, existing.RoleRef) ||
+ !equality.Semantic.DeepDerivative(desired.Subjects, existing.Subjects) {
+ existing.Labels = desired.Labels
+ existing.Annotations = desired.Annotations
existing.RoleRef = desired.RoleRef
existing.Subjects = desired.Subjects
return c.Update(context.TODO(), existing)
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index ce86e071..16508455 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -18,11 +18,13 @@ package controllers
import (
"context"
- "time"
"github.com/kaasops/vector-operator/controllers/factory/config"
"github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
@@ -92,6 +94,10 @@ func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context,
func (r *VectorReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&vectorv1alpha1.Vector{}).
+ Owns(&appsv1.DaemonSet{}).
+ Owns(&corev1.Service{}).
+ Owns(&corev1.Secret{}).
+ Owns(&corev1.ServiceAccount{}).
Complete(r)
}
@@ -119,6 +125,5 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
if err := vaCtrl.EnsureVectorAgent(); err != nil {
return ctrl.Result{}, err
}
-
- return ctrl.Result{RequeueAfter: 15 * time.Second}, nil
+ return ctrl.Result{}, nil
}
From ba1ce1dcf3447e54d606683c918c96f3c141f961 Mon Sep 17 00:00:00 2001
From: Ilya Batyukov
Date: Thu, 10 Nov 2022 10:17:04 +0300
Subject: [PATCH 081/316] add helm chart
---
helm/.helmignore | 23 +
helm/Chart.yaml | 28 +
helm/templates/_helpers.tpl | 62 ++
helm/templates/crds.yaml | 1506 ++++++++++++++++++++++++++++
helm/templates/deployment.yaml | 40 +
helm/templates/monitor.yaml | 18 +
helm/templates/rbac.yaml | 125 +++
helm/templates/serviceaccount.yaml | 13 +
helm/values.yaml | 31 +
9 files changed, 1846 insertions(+)
create mode 100644 helm/.helmignore
create mode 100644 helm/Chart.yaml
create mode 100644 helm/templates/_helpers.tpl
create mode 100644 helm/templates/crds.yaml
create mode 100644 helm/templates/deployment.yaml
create mode 100644 helm/templates/monitor.yaml
create mode 100644 helm/templates/rbac.yaml
create mode 100644 helm/templates/serviceaccount.yaml
create mode 100644 helm/values.yaml
diff --git a/helm/.helmignore b/helm/.helmignore
new file mode 100644
index 00000000..0e8a0eb3
--- /dev/null
+++ b/helm/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/helm/Chart.yaml b/helm/Chart.yaml
new file mode 100644
index 00000000..39087628
--- /dev/null
+++ b/helm/Chart.yaml
@@ -0,0 +1,28 @@
+apiVersion: v2
+name: vector-operator
+description: A Helm chart A Helm chart to install vector-operator
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.0.1
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "0.0.1"
+
+home: https://github.com/kaasops/vector-operator
+sources:
+ - https://github.com/kaasops/vector-operator
\ No newline at end of file
diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl
new file mode 100644
index 00000000..dc13106d
--- /dev/null
+++ b/helm/templates/_helpers.tpl
@@ -0,0 +1,62 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "vector-operator.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "vector-operator.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "vector-operator.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "vector-operator.labels" -}}
+helm.sh/chart: {{ include "vector-operator.chart" . }}
+{{ include "vector-operator.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "vector-operator.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "vector-operator.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "vector-operator.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "vector-operator.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/helm/templates/crds.yaml b/helm/templates/crds.yaml
new file mode 100644
index 00000000..2f16cfeb
--- /dev/null
+++ b/helm/templates/crds.yaml
@@ -0,0 +1,1506 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.9.2
+ creationTimestamp: null
+ name: clustervectorpipelines.observability.kaasops.io
+spec:
+ group: observability.kaasops.io
+ names:
+ kind: ClusterVectorPipeline
+ listKind: ClusterVectorPipelineList
+ plural: clustervectorpipelines
+ shortNames:
+ - cvp
+ singular: clustervectorpipeline
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ - jsonPath: .status.configCheckResult
+ name: Valid
+ type: boolean
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: ClusterVectorPipeline is the Schema for the clustervectorpipelines
+ API
+ 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: VectorPipelineSpec defines the desired state of VectorPipeline
+ properties:
+ sinks:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ sources:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ transforms:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ status:
+ description: VectorPipelineStatus defines the observed state of VectorPipeline
+ properties:
+ LastAppliedPipelineHash:
+ format: int32
+ type: integer
+ configCheckResult:
+ type: boolean
+ reason:
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+---
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.9.2
+ creationTimestamp: null
+ name: vectorpipelines.observability.kaasops.io
+spec:
+ group: observability.kaasops.io
+ names:
+ kind: VectorPipeline
+ listKind: VectorPipelineList
+ plural: vectorpipelines
+ shortNames:
+ - vp
+ singular: vectorpipeline
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ - jsonPath: .status.configCheckResult
+ name: Valid
+ type: boolean
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: VectorPipeline is the Schema for the vectorpipelines API
+ 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: VectorPipelineSpec defines the desired state of VectorPipeline
+ properties:
+ sinks:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ sources:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ transforms:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ status:
+ description: VectorPipelineStatus defines the observed state of VectorPipeline
+ properties:
+ LastAppliedPipelineHash:
+ format: int32
+ type: integer
+ configCheckResult:
+ type: boolean
+ reason:
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+---
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.9.2
+ creationTimestamp: null
+ name: vectors.observability.kaasops.io
+spec:
+ group: observability.kaasops.io
+ names:
+ kind: Vector
+ listKind: VectorList
+ plural: vectors
+ singular: vector
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ - jsonPath: .status.configCheckResult
+ name: Valid
+ type: boolean
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: Vector is the Schema for the vectors API
+ 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: VectorSpec defines the desired state of Vector
+ properties:
+ agent:
+ description: DisableAggregation DisableAggregation bool `json:"disableAggregation,omitempty"`
+ Vector Agent
+ properties:
+ affinity:
+ description: Affinity If specified, the pod's scheduling constraints.
+ properties:
+ nodeAffinity:
+ description: Describes node affinity scheduling rules for
+ the pod.
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule pods
+ to nodes that satisfy the affinity expressions specified
+ by this field, but it may choose a node that violates
+ one or more of the expressions. The node that is most
+ preferred is the one with the greatest sum of weights,
+ i.e. for each node that meets all of the scheduling
+ requirements (resource request, requiredDuringScheduling
+ affinity expressions, etc.), compute a sum by iterating
+ through the elements of this field and adding "weight"
+ to the sum if the node matches the corresponding matchExpressions;
+ the node(s) with the highest sum are the most preferred.
+ items:
+ description: An empty preferred scheduling term matches
+ all objects with implicit weight 0 (i.e. it's a no-op).
+ A null preferred scheduling term matches no objects
+ (i.e. is also a no-op).
+ properties:
+ preference:
+ description: A node selector term, associated with
+ the corresponding weight.
+ properties:
+ matchExpressions:
+ description: A list of node selector requirements
+ by node's labels.
+ items:
+ description: A node selector requirement is
+ a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators
+ are In, NotIn, Exists, DoesNotExist.
+ Gt, and Lt.
+ type: string
+ values:
+ description: 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. If the
+ operator is Gt or Lt, the values array
+ must have a single element, which will
+ be interpreted as an integer. This array
+ is replaced during a strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchFields:
+ description: A list of node selector requirements
+ by node's fields.
+ items:
+ description: A node selector requirement is
+ a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators
+ are In, NotIn, Exists, DoesNotExist.
+ Gt, and Lt.
+ type: string
+ values:
+ description: 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. If the
+ operator is Gt or Lt, the values array
+ must have a single element, which will
+ be interpreted as an integer. This array
+ is replaced during a strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ type: object
+ x-kubernetes-map-type: atomic
+ weight:
+ description: Weight associated with matching the
+ corresponding nodeSelectorTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - preference
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the affinity requirements specified by
+ this field are not met at scheduling time, the pod will
+ not be scheduled onto the node. If the affinity requirements
+ specified by this field cease to be met at some point
+ during pod execution (e.g. due to an update), the system
+ may or may not try to eventually evict the pod from
+ its node.
+ properties:
+ nodeSelectorTerms:
+ description: Required. A list of node selector terms.
+ The terms are ORed.
+ items:
+ description: A null or empty node selector term
+ matches no objects. The requirements of them are
+ ANDed. The TopologySelectorTerm type implements
+ a subset of the NodeSelectorTerm.
+ properties:
+ matchExpressions:
+ description: A list of node selector requirements
+ by node's labels.
+ items:
+ description: A node selector requirement is
+ a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators
+ are In, NotIn, Exists, DoesNotExist.
+ Gt, and Lt.
+ type: string
+ values:
+ description: 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. If the
+ operator is Gt or Lt, the values array
+ must have a single element, which will
+ be interpreted as an integer. This array
+ is replaced during a strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchFields:
+ description: A list of node selector requirements
+ by node's fields.
+ items:
+ description: A node selector requirement is
+ a selector that contains values, a key,
+ and an operator that relates the key and
+ values.
+ properties:
+ key:
+ description: The label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's relationship
+ to a set of values. Valid operators
+ are In, NotIn, Exists, DoesNotExist.
+ Gt, and Lt.
+ type: string
+ values:
+ description: 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. If the
+ operator is Gt or Lt, the values array
+ must have a single element, which will
+ be interpreted as an integer. This array
+ is replaced during a strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ type: object
+ x-kubernetes-map-type: atomic
+ type: array
+ required:
+ - nodeSelectorTerms
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ podAffinity:
+ description: Describes pod affinity scheduling rules (e.g.
+ co-locate this pod in the same node, zone, etc. as some
+ other pod(s)).
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule pods
+ to nodes that satisfy the affinity expressions specified
+ by this field, but it may choose a node that violates
+ one or more of the expressions. The node that is most
+ preferred is the one with the greatest sum of weights,
+ i.e. for each node that meets all of the scheduling
+ requirements (resource request, requiredDuringScheduling
+ affinity expressions, etc.), compute a sum by iterating
+ through the elements of this field and adding "weight"
+ to the sum if the node has pods which matches the corresponding
+ podAffinityTerm; the node(s) with the highest sum are
+ the most preferred.
+ items:
+ description: The weights of all of the matched WeightedPodAffinityTerm
+ fields are added per-node to find the most preferred
+ node(s)
+ properties:
+ podAffinityTerm:
+ description: Required. A pod affinity term, associated
+ with the corresponding weight.
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by
+ this field and the ones listed in the namespaces
+ field. null selector and null or empty namespaces
+ list means "this pod's namespace". An empty
+ selector ({}) matches all namespaces.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to.
+ The term is applied to the union of the namespaces
+ listed in this field and the ones selected
+ by namespaceSelector. null or empty namespaces
+ list and null namespaceSelector means "this
+ pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the
+ pods matching the labelSelector in the specified
+ namespaces, where co-located is defined as
+ running on a node whose value of the label
+ with key topologyKey matches that of any node
+ on which any of the selected pods is running.
+ Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ weight:
+ description: weight associated with matching the
+ corresponding podAffinityTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - podAffinityTerm
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the affinity requirements specified by
+ this field are not met at scheduling time, the pod will
+ not be scheduled onto the node. If the affinity requirements
+ specified by this field cease to be met at some point
+ during pod execution (e.g. due to a pod label update),
+ the system may or may not try to eventually evict the
+ pod from its node. When there are multiple elements,
+ the lists of nodes corresponding to each podAffinityTerm
+ are intersected, i.e. all terms must be satisfied.
+ items:
+ description: Defines a set of pods (namely those matching
+ the labelSelector relative to the given namespace(s))
+ that this pod should be co-located (affinity) or not
+ co-located (anti-affinity) with, where co-located
+ is defined as running on a node whose value of the
+ label with key matches that of any node
+ on which a pod of the set of pods is running
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by this
+ field and the ones listed in the namespaces field.
+ null selector and null or empty namespaces list
+ means "this pod's namespace". An empty selector
+ ({}) matches all namespaces.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to. The
+ term is applied to the union of the namespaces
+ listed in this field and the ones selected by
+ namespaceSelector. null or empty namespaces list
+ and null namespaceSelector means "this pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the pods
+ matching the labelSelector in the specified namespaces,
+ where co-located is defined as running on a node
+ whose value of the label with key topologyKey
+ matches that of any node on which any of the selected
+ pods is running. Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ type: array
+ type: object
+ podAntiAffinity:
+ description: Describes pod anti-affinity scheduling rules
+ (e.g. avoid putting this pod in the same node, zone, etc.
+ as some other pod(s)).
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule pods
+ to nodes that satisfy the anti-affinity expressions
+ specified by this field, but it may choose a node that
+ violates one or more of the expressions. The node that
+ is most preferred is the one with the greatest sum of
+ weights, i.e. for each node that meets all of the scheduling
+ requirements (resource request, requiredDuringScheduling
+ anti-affinity expressions, etc.), compute a sum by iterating
+ through the elements of this field and adding "weight"
+ to the sum if the node has pods which matches the corresponding
+ podAffinityTerm; the node(s) with the highest sum are
+ the most preferred.
+ items:
+ description: The weights of all of the matched WeightedPodAffinityTerm
+ fields are added per-node to find the most preferred
+ node(s)
+ properties:
+ podAffinityTerm:
+ description: Required. A pod affinity term, associated
+ with the corresponding weight.
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by
+ this field and the ones listed in the namespaces
+ field. null selector and null or empty namespaces
+ list means "this pod's namespace". An empty
+ selector ({}) matches all namespaces.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to.
+ The term is applied to the union of the namespaces
+ listed in this field and the ones selected
+ by namespaceSelector. null or empty namespaces
+ list and null namespaceSelector means "this
+ pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the
+ pods matching the labelSelector in the specified
+ namespaces, where co-located is defined as
+ running on a node whose value of the label
+ with key topologyKey matches that of any node
+ on which any of the selected pods is running.
+ Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ weight:
+ description: weight associated with matching the
+ corresponding podAffinityTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - podAffinityTerm
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the anti-affinity requirements specified
+ by this field are not met at scheduling time, the pod
+ will not be scheduled onto the node. If the anti-affinity
+ requirements specified by this field cease to be met
+ at some point during pod execution (e.g. due to a pod
+ label update), the system may or may not try to eventually
+ evict the pod from its node. When there are multiple
+ elements, the lists of nodes corresponding to each podAffinityTerm
+ are intersected, i.e. all terms must be satisfied.
+ items:
+ description: Defines a set of pods (namely those matching
+ the labelSelector relative to the given namespace(s))
+ that this pod should be co-located (affinity) or not
+ co-located (anti-affinity) with, where co-located
+ is defined as running on a node whose value of the
+ label with key matches that of any node
+ on which a pod of the set of pods is running
+ properties:
+ labelSelector:
+ description: A label query over a set of resources,
+ in this case pods.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaceSelector:
+ description: A label query over the set of namespaces
+ that the term applies to. The term is applied
+ to the union of the namespaces selected by this
+ field and the ones listed in the namespaces field.
+ null selector and null or empty namespaces list
+ means "this pod's namespace". An empty selector
+ ({}) matches all namespaces.
+ 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: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ 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
+ type: object
+ x-kubernetes-map-type: atomic
+ namespaces:
+ description: namespaces specifies a static list
+ of namespace names that the term applies to. The
+ term is applied to the union of the namespaces
+ listed in this field and the ones selected by
+ namespaceSelector. null or empty namespaces list
+ and null namespaceSelector means "this pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located (affinity)
+ or not co-located (anti-affinity) with the pods
+ matching the labelSelector in the specified namespaces,
+ where co-located is defined as running on a node
+ whose value of the label with key topologyKey
+ matches that of any node on which any of the selected
+ pods is running. Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ type: array
+ type: object
+ type: object
+ api:
+ description: ApiSpec is the Schema for the Vector Agent GraphQL
+ API - https://vector.dev/docs/reference/api/
+ properties:
+ address:
+ type: string
+ enabled:
+ type: boolean
+ playground:
+ type: boolean
+ type: object
+ dataDir:
+ type: string
+ env:
+ description: Env that will be added to Vector pod
+ items:
+ description: EnvVar represents an environment variable present
+ in a Container.
+ properties:
+ name:
+ description: Name of the environment variable. Must be a
+ C_IDENTIFIER.
+ type: string
+ value:
+ description: 'Variable references $(VAR_NAME) are expanded
+ using the previously defined environment variables in
+ the container and any service environment variables. If
+ a variable cannot be resolved, the reference in the input
+ string will be unchanged. Double $$ are reduced to a single
+ $, which allows for escaping the $(VAR_NAME) syntax: i.e.
+ "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
+ Escaped references will never be expanded, regardless
+ of whether the variable exists or not. Defaults to "".'
+ type: string
+ valueFrom:
+ description: Source for the environment variable's value.
+ Cannot be used if value is not empty.
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the ConfigMap or its
+ key must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ fieldRef:
+ description: 'Selects a field of the pod: supports metadata.name,
+ metadata.namespace, `metadata.labels['''']`,
+ `metadata.annotations['''']`, spec.nodeName,
+ spec.serviceAccountName, status.hostIP, status.podIP,
+ status.podIPs.'
+ properties:
+ apiVersion:
+ description: Version of the schema the FieldPath
+ is written in terms of, defaults to "v1".
+ type: string
+ fieldPath:
+ description: Path of the field to select in the
+ specified API version.
+ type: string
+ required:
+ - fieldPath
+ type: object
+ x-kubernetes-map-type: atomic
+ resourceFieldRef:
+ description: 'Selects a resource of the container: only
+ resources limits and requests (limits.cpu, limits.memory,
+ limits.ephemeral-storage, requests.cpu, requests.memory
+ and requests.ephemeral-storage) are currently supported.'
+ properties:
+ containerName:
+ description: 'Container name: required for volumes,
+ optional for env vars'
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Specifies the output format of the
+ exposed resources, defaults to "1"
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ description: 'Required: resource to select'
+ type: string
+ required:
+ - resource
+ type: object
+ x-kubernetes-map-type: atomic
+ secretKeyRef:
+ description: Selects a key of a secret in the pod's
+ namespace
+ 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
+ TODO: Add other useful fields. apiVersion, kind,
+ uid?'
+ type: string
+ optional:
+ description: Specify whether the Secret or its key
+ must be defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ host_aliases:
+ description: HostAliases provides mapping between ip and hostnames,
+ that would be propagated to pod, cannot be used with HostNetwork.
+ items:
+ description: HostAlias holds the mapping between IP and hostnames
+ that will be injected as an entry in the pod's hosts file.
+ properties:
+ hostnames:
+ description: Hostnames for the above IP address.
+ items:
+ type: string
+ type: array
+ ip:
+ description: IP address of the host file entry.
+ type: string
+ type: object
+ type: array
+ hostNetwork:
+ description: HostNetwork controls whether the pod may use the
+ node network namespace
+ type: boolean
+ image:
+ default: timberio/vector:0.24.0-distroless-libc
+ description: Image - docker image settings for Vector Agent if
+ no specified operator uses default config version
+ type: string
+ imagePullSecrets:
+ description: ImagePullSecrets An optional list of references to
+ secrets in the same namespace to use for pulling images from
+ registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod
+ items:
+ description: LocalObjectReference contains enough information
+ to let you locate the referenced object inside the same namespace.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ type: array
+ podSecurityPolicyName:
+ description: PodSecurityPolicyName - defines name for podSecurityPolicy
+ in case of empty value, prefixedName will be used.
+ type: string
+ priorityClassName:
+ description: PriorityClassName assigned to the Pods
+ type: string
+ resources:
+ description: Resources container resource request and limits,
+ https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
+ if not specified - default setting will be used
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ runtimeClassName:
+ description: RuntimeClassName - defines runtime class for kubernetes
+ pod. https://kubernetes.io/docs/concepts/containers/runtime-class/
+ type: string
+ schedulerName:
+ description: SchedulerName - defines kubernetes scheduler name
+ type: string
+ securityContext:
+ description: SecurityContext holds pod-level security attributes
+ and common container settings. This defaults to the default
+ PodSecurityContext. Tolerations If specified, the pod's tolerations.
+ properties:
+ fsGroup:
+ description: "A special supplemental group that applies to
+ all containers in a pod. Some volume types allow the Kubelet
+ to change the ownership of that volume to be owned by the
+ pod: \n 1. The owning GID will be the FSGroup 2. The setgid
+ bit is set (new files created in the volume will be owned
+ by FSGroup) 3. The permission bits are OR'd with rw-rw----
+ \n If unset, the Kubelet will not modify the ownership and
+ permissions of any volume. Note that this field cannot be
+ set when spec.os.name is windows."
+ format: int64
+ type: integer
+ fsGroupChangePolicy:
+ description: 'fsGroupChangePolicy defines behavior of changing
+ ownership and permission of the volume before being exposed
+ inside Pod. This field will only apply to volume types which
+ support fsGroup based ownership(and permissions). It will
+ have no effect on ephemeral volume types such as: secret,
+ configmaps and emptydir. Valid values are "OnRootMismatch"
+ and "Always". If not specified, "Always" is used. Note that
+ this field cannot be set when spec.os.name is windows.'
+ type: string
+ runAsGroup:
+ description: The GID to run the entrypoint of the container
+ process. Uses runtime default if unset. May also be set
+ in SecurityContext. If set in both SecurityContext and
+ PodSecurityContext, the value specified in SecurityContext
+ takes precedence for that container. Note that this field
+ cannot be set when spec.os.name is windows.
+ format: int64
+ type: integer
+ runAsNonRoot:
+ description: Indicates that the container must run as a non-root
+ user. If true, the Kubelet will validate the image at runtime
+ to ensure that it does not run as UID 0 (root) and fail
+ to start the container if it does. If unset or false, no
+ such validation will be performed. May also be set in SecurityContext. If
+ set in both SecurityContext and PodSecurityContext, the
+ value specified in SecurityContext takes precedence.
+ type: boolean
+ runAsUser:
+ description: The UID to run the entrypoint of the container
+ process. Defaults to user specified in image metadata if
+ unspecified. May also be set in SecurityContext. If set
+ in both SecurityContext and PodSecurityContext, the value
+ specified in SecurityContext takes precedence for that container.
+ Note that this field cannot be set when spec.os.name is
+ windows.
+ format: int64
+ type: integer
+ seLinuxOptions:
+ description: The SELinux context to be applied to all containers.
+ If unspecified, the container runtime will allocate a random
+ SELinux context for each container. May also be set in
+ SecurityContext. If set in both SecurityContext and PodSecurityContext,
+ the value specified in SecurityContext takes precedence
+ for that container. Note that this field cannot be set when
+ spec.os.name is windows.
+ properties:
+ level:
+ description: Level is SELinux level label that applies
+ to the container.
+ type: string
+ role:
+ description: Role is a SELinux role label that applies
+ to the container.
+ type: string
+ type:
+ description: Type is a SELinux type label that applies
+ to the container.
+ type: string
+ user:
+ description: User is a SELinux user label that applies
+ to the container.
+ type: string
+ type: object
+ seccompProfile:
+ description: The seccomp options to use by the containers
+ in this pod. Note that this field cannot be set when spec.os.name
+ is windows.
+ properties:
+ localhostProfile:
+ description: localhostProfile indicates a profile defined
+ in a file on the node should be used. The profile must
+ be preconfigured on the node to work. Must be a descending
+ path, relative to the kubelet's configured seccomp profile
+ location. Must only be set if type is "Localhost".
+ type: string
+ type:
+ description: "type indicates which kind of seccomp profile
+ will be applied. Valid options are: \n Localhost - a
+ profile defined in a file on the node should be used.
+ RuntimeDefault - the container runtime default profile
+ should be used. Unconfined - no profile should be applied."
+ type: string
+ required:
+ - type
+ type: object
+ supplementalGroups:
+ description: A list of groups applied to the first process
+ run in each container, in addition to the container's primary
+ GID. If unspecified, no groups will be added to any container.
+ Note that this field cannot be set when spec.os.name is
+ windows.
+ items:
+ format: int64
+ type: integer
+ type: array
+ sysctls:
+ description: Sysctls hold a list of namespaced sysctls used
+ for the pod. Pods with unsupported sysctls (by the container
+ runtime) might fail to launch. Note that this field cannot
+ be set when spec.os.name is windows.
+ items:
+ description: Sysctl defines a kernel parameter to be set
+ properties:
+ name:
+ description: Name of a property to set
+ type: string
+ value:
+ description: Value of a property to set
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ type: array
+ windowsOptions:
+ description: The Windows specific settings applied to all
+ containers. If unspecified, the options within a container's
+ SecurityContext will be used. If set in both SecurityContext
+ and PodSecurityContext, the value specified in SecurityContext
+ takes precedence. Note that this field cannot be set when
+ spec.os.name is linux.
+ properties:
+ gmsaCredentialSpec:
+ description: GMSACredentialSpec is where the GMSA admission
+ webhook (https://github.com/kubernetes-sigs/windows-gmsa)
+ inlines the contents of the GMSA credential spec named
+ by the GMSACredentialSpecName field.
+ type: string
+ gmsaCredentialSpecName:
+ description: GMSACredentialSpecName is the name of the
+ GMSA credential spec to use.
+ type: string
+ hostProcess:
+ description: HostProcess determines if a container should
+ be run as a 'Host Process' container. This field is
+ alpha-level and will only be honored by components that
+ enable the WindowsHostProcessContainers feature flag.
+ Setting this field without the feature flag will result
+ in errors when validating the Pod. All of a Pod's containers
+ must have the same effective HostProcess value (it is
+ not allowed to have a mix of HostProcess containers
+ and non-HostProcess containers). In addition, if HostProcess
+ is true then HostNetwork must also be set to true.
+ type: boolean
+ runAsUserName:
+ description: The UserName in Windows to run the entrypoint
+ of the container process. Defaults to the user specified
+ in image metadata if unspecified. May also be set in
+ PodSecurityContext. If set in both SecurityContext and
+ PodSecurityContext, the value specified in SecurityContext
+ takes precedence.
+ type: string
+ type: object
+ type: object
+ service:
+ type: boolean
+ tolerations:
+ description: Tolerations If specified, the pod's tolerations.
+ items:
+ description: The pod this Toleration is attached to tolerates
+ any taint that matches the triple using
+ the matching operator .
+ properties:
+ effect:
+ description: Effect indicates the taint effect to match.
+ Empty means match all taint effects. When specified, allowed
+ values are NoSchedule, PreferNoSchedule and NoExecute.
+ type: string
+ key:
+ description: Key is the taint key that the toleration applies
+ to. Empty means match all taint keys. If the key is empty,
+ operator must be Exists; this combination means to match
+ all values and all keys.
+ type: string
+ operator:
+ description: Operator represents a key's relationship to
+ the value. Valid operators are Exists and Equal. Defaults
+ to Equal. Exists is equivalent to wildcard for value,
+ so that a pod can tolerate all taints of a particular
+ category.
+ type: string
+ tolerationSeconds:
+ description: TolerationSeconds represents the period of
+ time the toleration (which must be of effect NoExecute,
+ otherwise this field is ignored) tolerates the taint.
+ By default, it is not set, which means tolerate the taint
+ forever (do not evict). Zero and negative values will
+ be treated as 0 (evict immediately) by the system.
+ format: int64
+ type: integer
+ value:
+ description: Value is the taint value the toleration matches
+ to. If the operator is Exists, the value should be empty,
+ otherwise just a regular string.
+ type: string
+ type: object
+ type: array
+ type: object
+ type: object
+ status:
+ description: VectorStatus defines the observed state of Vector
+ properties:
+ LastAppliedConfigHash:
+ format: int32
+ type: integer
+ configCheckResult:
+ type: boolean
+ reason:
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml
new file mode 100644
index 00000000..413f679f
--- /dev/null
+++ b/helm/templates/deployment.yaml
@@ -0,0 +1,40 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: vector-operator
+ namespace: vector-operator-system
+ labels:
+ app.kubernetes.io/name: vector-operator
+spec:
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: vector-operator
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: vector-operator
+ app.kubernetes.io/managed-by: "helm"
+ meta.helm.sh/release-name: vector-operator
+ spec:
+ volumes:
+ - name: kube-api-access
+ secret:
+ secretName: vector-operator-sa-token
+ defaultMode: 420
+ automountServiceAccountToken: false
+ serviceAccount: vector-operator
+ serviceAccountName: vector-operator
+ containers:
+ - image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ name: vector-operator
+ volumeMounts:
+ - name: kube-api-access
+ readOnly: true
+ mountPath: /var/run/secrets/kubernetes.io/serviceaccount
+ resources:
+{{ toYaml .Values.resources | indent 12 }}
+ securityContext:
+{{- toYaml .Values.image.securityContext | nindent 10 }}
+
+
\ No newline at end of file
diff --git a/helm/templates/monitor.yaml b/helm/templates/monitor.yaml
new file mode 100644
index 00000000..0b3952c3
--- /dev/null
+++ b/helm/templates/monitor.yaml
@@ -0,0 +1,18 @@
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ labels:
+ control-plane: controller-manager
+ name: controller-manager-metrics-monitor
+ namespace: vector-operator-system
+spec:
+ endpoints:
+ - path: /metrics
+ port: https
+ scheme: https
+ bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+ tlsConfig:
+ insecureSkipVerify: true
+ selector:
+ matchLabels:
+ control-plane: controller-manager
\ No newline at end of file
diff --git a/helm/templates/rbac.yaml b/helm/templates/rbac.yaml
new file mode 100644
index 00000000..80e0dd23
--- /dev/null
+++ b/helm/templates/rbac.yaml
@@ -0,0 +1,125 @@
+{{- if .Values.rbac.create -}}
+
+---
+{{- if semverCompare ">= 1.24" .Capabilities.KubeVersion.Version }}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: vector-operator-sa-token
+ namespace: vector-operator-system
+ annotations:
+ kubernetes.io/service-account.name: vector-operator
+type: kubernetes.io/service-account-token
+{{- end }}
+
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: vector-operator
+ namespace: vector-operator-system
+secrets:
+ - name: vector-operator-sa-token
+
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: vector-operator
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: vector-operator
+subjects:
+- kind: ServiceAccount
+ name: vector-operator
+ namespace: vector-operator-system
+
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: vector-operator
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - secrets
+ - pods
+ - serviceaccounts
+ - services
+ - namespaces
+ - nodes
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ - clusterrolebindings
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - apps
+ resources:
+ - daemonsets
+ - replicasets
+ - statefulsets
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - apps
+ - extensions
+ resources:
+ - deployments
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - clustervectorpipelines
+ - vectorpipelines
+ - vectors
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - observability.kaasops.io
+ resources:
+ - clustervectorpipelines/status
+ - vectorpipelines/status
+ - vectors/status
+ verbs:
+ - get
+ - patch
+ - update
+{{- end }}
\ No newline at end of file
diff --git a/helm/templates/serviceaccount.yaml b/helm/templates/serviceaccount.yaml
new file mode 100644
index 00000000..20822842
--- /dev/null
+++ b/helm/templates/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ toYaml .Values.serviceAccount.name | nindent 4 }}
+ namespace: vector-operator-system
+{{- if .Values.serviceAccount.annotations }}
+ annotations:
+{{ toYaml .Values.serviceAccount.annotations | nindent 4 }}
+{{- end }}
+secrets:
+ - name: vector-operator-sa-token
+{{- end }}
\ No newline at end of file
diff --git a/helm/values.yaml b/helm/values.yaml
new file mode 100644
index 00000000..27e12d31
--- /dev/null
+++ b/helm/values.yaml
@@ -0,0 +1,31 @@
+image:
+ repository: kaasops/vector-operator
+ tag: "latest"
+ pullPolicy: IfNotPresent
+
+ securityContext:
+ allowPrivilegeEscalation: false
+ runAsGroup: 1000
+ runAsNonRoot: true
+ readOnlyRootFilesystem: true
+ seccompProfile:
+ type: RuntimeDefault
+ capabilities:
+ drop:
+ - ALL
+
+resources:
+ limits:
+ cpu: "2"
+ memory: 1Gi
+ requests:
+ cpu: 100m
+ memory: 50Mi
+
+rbac:
+ create: true
+
+serviceAccount:
+ create: false
+ name: "vector-operator"
+ annotations: {}
From fe2e4c81a1d3e47ede266bcd671f03192f86adfc Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 10 Nov 2022 09:19:31 +0200
Subject: [PATCH 082/316] Fix context forward
Signed-off-by: Zemtsov Vladimir
---
.../factory/config/configcheck/configcheck.go | 36 +++---
controllers/factory/utils/k8s/k8s.go | 108 +++++++++---------
controllers/factory/utils/k8s/k8s_test.go | 34 +++---
.../vectoragent/vectoragent_controller.go | 47 ++++----
controllers/vector_controller.go | 2 +-
5 files changed, 111 insertions(+), 116 deletions(-)
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index c2d7f666..c7511668 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -54,17 +54,17 @@ func New(config []byte, c client.Client, cs *kubernetes.Clientset, name, namespa
}
func (cc *ConfigCheck) Run(ctx context.Context) error {
- log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", cc.Name)
+ log := log.FromContext(ctx).WithValues("Vector ConfigCheck", cc.Name)
log.Info("start ConfigCheck")
- if err := cc.ensureVectorConfigCheckRBAC(); err != nil {
+ if err := cc.ensureVectorConfigCheckRBAC(ctx); err != nil {
return err
}
cc.Hash = randStringRunes()
- if err := cc.ensureVectorConfigCheckConfig(); err != nil {
+ if err := cc.ensureVectorConfigCheckConfig(ctx); err != nil {
return err
}
@@ -75,33 +75,33 @@ func (cc *ConfigCheck) Run(ctx context.Context) error {
return nil
}
-func (cc *ConfigCheck) ensureVectorConfigCheckRBAC() error {
- return cc.ensureVectorConfigCheckServiceAccount()
+func (cc *ConfigCheck) ensureVectorConfigCheckRBAC(ctx context.Context) error {
+ return cc.ensureVectorConfigCheckServiceAccount(ctx)
}
-func (cc *ConfigCheck) ensureVectorConfigCheckServiceAccount() error {
+func (cc *ConfigCheck) ensureVectorConfigCheckServiceAccount(ctx context.Context) error {
vectorAgentServiceAccount := cc.createVectorConfigCheckServiceAccount()
- return k8s.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, cc.Client)
+ return k8s.CreateOrUpdateServiceAccount(ctx, vectorAgentServiceAccount, cc.Client)
}
-func (cc *ConfigCheck) ensureVectorConfigCheckConfig() error {
+func (cc *ConfigCheck) ensureVectorConfigCheckConfig(ctx context.Context) error {
vectorConfigCheckSecret, err := cc.createVectorConfigCheckConfig()
if err != nil {
return err
}
- return k8s.CreateOrUpdateSecret(vectorConfigCheckSecret, cc.Client)
+ return k8s.CreateOrUpdateSecret(ctx, vectorConfigCheckSecret, cc.Client)
}
func (cc *ConfigCheck) checkVectorConfigCheckPod(ctx context.Context) error {
vectorConfigCheckPod := cc.createVectorConfigCheckPod()
- err := k8s.CreatePod(vectorConfigCheckPod, cc.Client)
+ err := k8s.CreatePod(ctx, vectorConfigCheckPod, cc.Client)
if err != nil {
return err
}
- err = cc.getCheckResult(vectorConfigCheckPod)
+ err = cc.getCheckResult(ctx, vectorConfigCheckPod)
if err != nil {
return err
}
@@ -138,11 +138,11 @@ func randStringRunes() string {
return string(b)
}
-func (cc *ConfigCheck) getCheckResult(pod *corev1.Pod) error {
- log := log.FromContext(context.TODO()).WithValues("Vector ConfigCheck", pod.Name)
+func (cc *ConfigCheck) getCheckResult(ctx context.Context, pod *corev1.Pod) error {
+ log := log.FromContext(ctx).WithValues("Vector ConfigCheck", pod.Name)
for {
- existing, err := k8s.GetPod(pod, cc.Client)
+ existing, err := k8s.GetPod(ctx, pod, cc.Client)
if err != nil {
return err
}
@@ -152,7 +152,7 @@ func (cc *ConfigCheck) getCheckResult(pod *corev1.Pod) error {
log.Info("wait Validate Vector Config Result")
time.Sleep(5 * time.Second)
case "Failed":
- reason, err := k8s.GetPodLogs(pod, cc.ClientSet)
+ reason, err := k8s.GetPodLogs(ctx, pod, cc.ClientSet)
if err != nil {
return err
}
@@ -183,16 +183,16 @@ func (cc *ConfigCheck) cleanup(ctx context.Context) error {
Name: v.Secret.SecretName,
Namespace: pod.Namespace,
}
- secret, err := k8s.GetSecret(nn, cc.Client)
+ secret, err := k8s.GetSecret(ctx, nn, cc.Client)
if err != nil {
return err
}
- if err := k8s.DeleteSecret(secret, cc.Client); err != nil {
+ if err := k8s.DeleteSecret(ctx, secret, cc.Client); err != nil {
return err
}
}
}
- if err := k8s.DeletePod(&pod, cc.Client); err != nil {
+ if err := k8s.DeletePod(ctx, &pod, cc.Client); err != nil {
return err
}
}
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index a19fdbc4..aa435e8b 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -32,82 +32,82 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)
-func CreateOrUpdateService(svc *corev1.Service, c client.Client) error {
- return reconcileService(svc, c)
+func CreateOrUpdateService(ctx context.Context, svc *corev1.Service, c client.Client) error {
+ return reconcileService(ctx, svc, c)
}
-func CreateOrUpdateSecret(secret *corev1.Secret, c client.Client) error {
- return reconcileSecret(secret, c)
+func CreateOrUpdateSecret(ctx context.Context, secret *corev1.Secret, c client.Client) error {
+ return reconcileSecret(ctx, secret, c)
}
-func CreateOrUpdateDaemonSet(daemonSet *appsv1.DaemonSet, c client.Client) error {
- return reconcileDaemonSet(daemonSet, c)
+func CreateOrUpdateDaemonSet(ctx context.Context, daemonSet *appsv1.DaemonSet, c client.Client) error {
+ return reconcileDaemonSet(ctx, daemonSet, c)
}
-func CreateOrUpdateStatefulSet(statefulSet *appsv1.StatefulSet, c client.Client) error {
- return reconcileStatefulSet(statefulSet, c)
+func CreateOrUpdateStatefulSet(ctx context.Context, statefulSet *appsv1.StatefulSet, c client.Client) error {
+ return reconcileStatefulSet(ctx, statefulSet, c)
}
-func CreateOrUpdateServiceAccount(secret *corev1.ServiceAccount, c client.Client) error {
- return reconcileServiceAccount(secret, c)
+func CreateOrUpdateServiceAccount(ctx context.Context, secret *corev1.ServiceAccount, c client.Client) error {
+ return reconcileServiceAccount(ctx, secret, c)
}
-func CreateOrUpdateClusterRole(secret *rbacv1.ClusterRole, c client.Client) error {
- return reconcileClusterRole(secret, c)
+func CreateOrUpdateClusterRole(ctx context.Context, secret *rbacv1.ClusterRole, c client.Client) error {
+ return reconcileClusterRole(ctx, secret, c)
}
-func CreateOrUpdateClusterRoleBinding(secret *rbacv1.ClusterRoleBinding, c client.Client) error {
- return reconcileClusterRoleBinding(secret, c)
+func CreateOrUpdateClusterRoleBinding(ctx context.Context, secret *rbacv1.ClusterRoleBinding, c client.Client) error {
+ return reconcileClusterRoleBinding(ctx, secret, c)
}
-func CreatePod(pod *corev1.Pod, c client.Client) error {
- err := c.Create(context.TODO(), pod)
+func CreatePod(ctx context.Context, pod *corev1.Pod, c client.Client) error {
+ err := c.Create(ctx, pod)
if err != nil {
return err
}
return nil
}
-func GetPod(pod *corev1.Pod, c client.Client) (*corev1.Pod, error) {
+func GetPod(ctx context.Context, pod *corev1.Pod, c client.Client) (*corev1.Pod, error) {
result := &corev1.Pod{}
- err := c.Get(context.TODO(), client.ObjectKeyFromObject(pod), result)
+ err := c.Get(ctx, client.ObjectKeyFromObject(pod), result)
if err != nil {
return nil, err
}
return result, nil
}
-func DeletePod(pod *corev1.Pod, c client.Client) error {
- if err := c.Delete(context.TODO(), pod); err != nil {
+func DeletePod(ctx context.Context, pod *corev1.Pod, c client.Client) error {
+ if err := c.Delete(ctx, pod); err != nil {
return err
}
return nil
}
-func GetSecret(namespacedName types.NamespacedName, c client.Client) (*corev1.Secret, error) {
+func GetSecret(ctx context.Context, namespacedName types.NamespacedName, c client.Client) (*corev1.Secret, error) {
result := &corev1.Secret{}
- err := c.Get(context.TODO(), namespacedName, result)
+ err := c.Get(ctx, namespacedName, result)
if err != nil {
return nil, err
}
return result, nil
}
-func DeleteSecret(secret *corev1.Secret, c client.Client) error {
- if err := c.Delete(context.TODO(), secret); err != nil {
+func DeleteSecret(ctx context.Context, secret *corev1.Secret, c client.Client) error {
+ if err := c.Delete(ctx, secret); err != nil {
return err
}
return nil
}
-func GetPodLogs(pod *corev1.Pod, cs *kubernetes.Clientset) (string, error) {
+func GetPodLogs(ctx context.Context, pod *corev1.Pod, cs *kubernetes.Clientset) (string, error) {
count := int64(100)
podLogOptions := corev1.PodLogOptions{
TailLines: &count,
}
req := cs.CoreV1().Pods(pod.Namespace).GetLogs(pod.Name, &podLogOptions)
- podLogs, err := req.Stream(context.TODO())
+ podLogs, err := req.Stream(ctx)
if err != nil {
return "", err
}
@@ -127,14 +127,14 @@ func UpdateStatus(ctx context.Context, obj client.Object, c client.Client) error
return c.Status().Update(ctx, obj)
}
-func reconcileService(obj runtime.Object, c client.Client) error {
+func reconcileService(ctx context.Context, obj runtime.Object, c client.Client) error {
existing := &corev1.Service{}
desired := obj.(*corev1.Service)
- err := c.Create(context.TODO(), desired)
+ err := c.Create(ctx, desired)
if errors.IsAlreadyExists(err) {
- err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
@@ -144,21 +144,21 @@ func reconcileService(obj runtime.Object, c client.Client) error {
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
existing.Spec = desired.Spec
- return c.Update(context.TODO(), existing)
+ return c.Update(ctx, existing)
}
return nil
}
return err
}
-func reconcileSecret(obj runtime.Object, c client.Client) error {
+func reconcileSecret(ctx context.Context, obj runtime.Object, c client.Client) error {
existing := &corev1.Secret{}
desired := obj.(*corev1.Secret)
- err := c.Create(context.TODO(), desired)
+ err := c.Create(ctx, desired)
if errors.IsAlreadyExists(err) {
- err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
@@ -168,21 +168,21 @@ func reconcileSecret(obj runtime.Object, c client.Client) error {
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
existing.Data = desired.Data
- return c.Update(context.TODO(), existing)
+ return c.Update(ctx, existing)
}
return nil
}
return err
}
-func reconcileDaemonSet(obj runtime.Object, c client.Client) error {
+func reconcileDaemonSet(ctx context.Context, obj runtime.Object, c client.Client) error {
existing := &appsv1.DaemonSet{}
desired := obj.(*appsv1.DaemonSet)
- err := c.Create(context.TODO(), desired)
+ err := c.Create(ctx, desired)
if errors.IsAlreadyExists(err) {
- err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
@@ -192,21 +192,21 @@ func reconcileDaemonSet(obj runtime.Object, c client.Client) error {
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
existing.Spec = desired.Spec
- return c.Update(context.TODO(), existing)
+ return c.Update(ctx, existing)
}
return nil
}
return err
}
-func reconcileStatefulSet(obj runtime.Object, c client.Client) error {
+func reconcileStatefulSet(ctx context.Context, obj runtime.Object, c client.Client) error {
existing := &appsv1.StatefulSet{}
desired := obj.(*appsv1.StatefulSet)
- err := c.Create(context.TODO(), desired)
+ err := c.Create(ctx, desired)
if errors.IsAlreadyExists(err) {
- err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
@@ -216,21 +216,21 @@ func reconcileStatefulSet(obj runtime.Object, c client.Client) error {
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
existing.Spec = desired.Spec
- return c.Update(context.TODO(), existing)
+ return c.Update(ctx, existing)
}
return nil
}
return err
}
-func reconcileServiceAccount(obj runtime.Object, c client.Client) error {
+func reconcileServiceAccount(ctx context.Context, obj runtime.Object, c client.Client) error {
existing := &corev1.ServiceAccount{}
desired := obj.(*corev1.ServiceAccount)
- err := c.Create(context.TODO(), desired)
+ err := c.Create(ctx, desired)
if errors.IsAlreadyExists(err) {
- err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
@@ -238,21 +238,21 @@ func reconcileServiceAccount(obj runtime.Object, c client.Client) error {
!equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) {
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
- return c.Update(context.TODO(), existing)
+ return c.Update(ctx, existing)
}
return nil
}
return err
}
-func reconcileClusterRole(obj runtime.Object, c client.Client) error {
+func reconcileClusterRole(ctx context.Context, obj runtime.Object, c client.Client) error {
existing := &rbacv1.ClusterRole{}
desired := obj.(*rbacv1.ClusterRole)
- err := c.Create(context.TODO(), desired)
+ err := c.Create(ctx, desired)
if errors.IsAlreadyExists(err) {
- err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
@@ -262,21 +262,21 @@ func reconcileClusterRole(obj runtime.Object, c client.Client) error {
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
existing.Rules = desired.Rules
- return c.Update(context.TODO(), existing)
+ return c.Update(ctx, existing)
}
return nil
}
return err
}
-func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
+func reconcileClusterRoleBinding(ctx context.Context, obj runtime.Object, c client.Client) error {
existing := &rbacv1.ClusterRoleBinding{}
desired := obj.(*rbacv1.ClusterRoleBinding)
- err := c.Create(context.TODO(), desired)
+ err := c.Create(ctx, desired)
if errors.IsAlreadyExists(err) {
- err := c.Get(context.TODO(), client.ObjectKeyFromObject(desired), existing)
+ err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
@@ -288,7 +288,7 @@ func reconcileClusterRoleBinding(obj runtime.Object, c client.Client) error {
existing.Annotations = desired.Annotations
existing.RoleRef = desired.RoleRef
existing.Subjects = desired.Subjects
- return c.Update(context.TODO(), existing)
+ return c.Update(ctx, existing)
}
return nil
}
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index 58ffa2e1..07f548b1 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -45,7 +45,7 @@ func getInitObjectMeta() metav1.ObjectMeta {
return ObjectMeta
}
-var reconcileObjectCase = func(objInit, obj interface{}, want error) func(t *testing.T) {
+var reconcileObjectCase = func(ctx context.Context, objInit, obj interface{}, want error) func(t *testing.T) {
return func(t *testing.T) {
t.Helper()
t.Parallel()
@@ -58,49 +58,49 @@ var reconcileObjectCase = func(objInit, obj interface{}, want error) func(t *tes
service := obj.(*corev1.Service)
cl := fake.NewClientBuilder().WithObjects(serviceInit).Build()
- err := k8s.CreateOrUpdateService(service, cl)
+ err := k8s.CreateOrUpdateService(ctx, service, cl)
req.Equal(err, want)
case *corev1.Secret:
secretInit := objInit.(*corev1.Secret)
secret := obj.(*corev1.Secret)
cl := fake.NewClientBuilder().WithObjects(secretInit).Build()
- err := k8s.CreateOrUpdateSecret(secret, cl)
+ err := k8s.CreateOrUpdateSecret(ctx, secret, cl)
req.Equal(err, want)
case *appsv1.DaemonSet:
daemonSetInit := objInit.(*appsv1.DaemonSet)
daemonSet := obj.(*appsv1.DaemonSet)
cl := fake.NewClientBuilder().WithObjects(daemonSetInit).Build()
- err := k8s.CreateOrUpdateDaemonSet(daemonSet, cl)
+ err := k8s.CreateOrUpdateDaemonSet(ctx, daemonSet, cl)
req.Equal(err, want)
case *appsv1.StatefulSet:
statefulSetInit := objInit.(*appsv1.StatefulSet)
statefulSet := obj.(*appsv1.StatefulSet)
cl := fake.NewClientBuilder().WithObjects(statefulSetInit).Build()
- err := k8s.CreateOrUpdateStatefulSet(statefulSet, cl)
+ err := k8s.CreateOrUpdateStatefulSet(ctx, statefulSet, cl)
req.Equal(err, want)
case *corev1.ServiceAccount:
serviceAccountInit := objInit.(*corev1.ServiceAccount)
serviceAccount := obj.(*corev1.ServiceAccount)
cl := fake.NewClientBuilder().WithObjects(serviceAccountInit).Build()
- err := k8s.CreateOrUpdateServiceAccount(serviceAccount, cl)
+ err := k8s.CreateOrUpdateServiceAccount(ctx, serviceAccount, cl)
req.Equal(err, want)
case *rbacv1.ClusterRole:
clusterRoleInit := objInit.(*rbacv1.ClusterRole)
clusterRole := obj.(*rbacv1.ClusterRole)
cl := fake.NewClientBuilder().WithObjects(clusterRoleInit).Build()
- err := k8s.CreateOrUpdateClusterRole(clusterRole, cl)
+ err := k8s.CreateOrUpdateClusterRole(ctx, clusterRole, cl)
req.Equal(err, want)
case *rbacv1.ClusterRoleBinding:
clusterRoleBindingInit := objInit.(*rbacv1.ClusterRoleBinding)
clusterRoleBinding := obj.(*rbacv1.ClusterRoleBinding)
cl := fake.NewClientBuilder().WithObjects(clusterRoleBindingInit).Build()
- err := k8s.CreateOrUpdateClusterRoleBinding(clusterRoleBinding, cl)
+ err := k8s.CreateOrUpdateClusterRoleBinding(ctx, clusterRoleBinding, cl)
req.Equal(err, want)
}
}
@@ -167,7 +167,7 @@ func TestCreateOrUpdateService(t *testing.T) {
// t.Parallel()
for _, tc := range secriveCases {
- t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
+ t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
}
}
@@ -221,7 +221,7 @@ func TestCreateOrUpdateSecret(t *testing.T) {
// t.Parallel()
for _, tc := range secretCases {
- t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
+ t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
}
}
@@ -275,7 +275,7 @@ func TestCreateOrUpdateDaemonSet(t *testing.T) {
// t.Parallel()
for _, tc := range daemonSetCases {
- t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
+ t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
}
}
@@ -329,7 +329,7 @@ func TestCreateOrUpdateStatefulSet(t *testing.T) {
// t.Parallel()
for _, tc := range statefulSetCases {
- t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
+ t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
}
}
@@ -383,7 +383,7 @@ func TestCreateOrUpdateServiceAccount(t *testing.T) {
// t.Parallel()
for _, tc := range serviceAccountCases {
- t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
+ t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
}
}
@@ -437,7 +437,7 @@ func TestCreateOrUpdateClusterRole(t *testing.T) {
// t.Parallel()
for _, tc := range clusterRoleCases {
- t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
+ t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
}
}
@@ -491,7 +491,7 @@ func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
// t.Parallel()
for _, tc := range clusterRoleBindingCases {
- t.Run(tc.name, reconcileObjectCase(initObj, tc.obj, tc.err))
+ t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
}
}
@@ -505,7 +505,7 @@ func TestCreatePod(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- err := k8s.CreatePod(obj, cl)
+ err := k8s.CreatePod(context.Background(), obj, cl)
req.Equal(err, want)
}
}
@@ -562,7 +562,7 @@ func TestGetPod(t *testing.T) {
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
- result, err := k8s.GetPod(obj, cl)
+ result, err := k8s.GetPod(context.Background(), obj, cl)
if result != nil {
req.Equal(result.ObjectMeta, wantPod.ObjectMeta)
}
diff --git a/controllers/factory/vector/vectoragent/vectoragent_controller.go b/controllers/factory/vector/vectoragent/vectoragent_controller.go
index 84e75d3b..914600b1 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_controller.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_controller.go
@@ -25,83 +25,79 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
)
-func (ctrl *Controller) EnsureVectorAgent() error {
- ctx := context.Background()
+func (ctrl *Controller) EnsureVectorAgent(ctx context.Context) error {
log := log.FromContext(ctx).WithValues("vector-agent", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent")
- if err := ctrl.ensureVectorAgentRBAC(); err != nil {
+ if err := ctrl.ensureVectorAgentRBAC(ctx); err != nil {
return err
}
if ctrl.Vector.Spec.Agent.Service {
- if err := ctrl.ensureVectorAgentService(); err != nil {
+ if err := ctrl.ensureVectorAgentService(ctx); err != nil {
return err
}
}
- if err := ctrl.ensureVectorAgentConfig(); err != nil {
+ if err := ctrl.ensureVectorAgentConfig(ctx); err != nil {
return err
}
- if err := ctrl.ensureVectorAgentDaemonSet(); err != nil {
+ if err := ctrl.ensureVectorAgentDaemonSet(ctx); err != nil {
return err
}
return nil
}
-func (ctrl *Controller) ensureVectorAgentRBAC() error {
- ctx := context.Background()
+func (ctrl *Controller) ensureVectorAgentRBAC(ctx context.Context) error {
log := log.FromContext(ctx).WithValues("vector-agent-rbac", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent RBAC")
- if err := ctrl.ensureVectorAgentServiceAccount(); err != nil {
+ if err := ctrl.ensureVectorAgentServiceAccount(ctx); err != nil {
return err
}
- if err := ctrl.ensureVectorAgentClusterRole(); err != nil {
+ if err := ctrl.ensureVectorAgentClusterRole(ctx); err != nil {
return err
}
- if err := ctrl.ensureVectorAgentClusterRoleBinding(); err != nil {
+ if err := ctrl.ensureVectorAgentClusterRoleBinding(ctx); err != nil {
return err
}
return nil
}
-func (ctrl *Controller) ensureVectorAgentServiceAccount() error {
+func (ctrl *Controller) ensureVectorAgentServiceAccount(ctx context.Context) error {
vectorAgentServiceAccount := ctrl.createVectorAgentServiceAccount()
- return k8s.CreateOrUpdateServiceAccount(vectorAgentServiceAccount, ctrl.Client)
+ return k8s.CreateOrUpdateServiceAccount(ctx, vectorAgentServiceAccount, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentClusterRole() error {
+func (ctrl *Controller) ensureVectorAgentClusterRole(ctx context.Context) error {
vectorAgentClusterRole := ctrl.createVectorAgentClusterRole()
- return k8s.CreateOrUpdateClusterRole(vectorAgentClusterRole, ctrl.Client)
+ return k8s.CreateOrUpdateClusterRole(ctx, vectorAgentClusterRole, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentClusterRoleBinding() error {
+func (ctrl *Controller) ensureVectorAgentClusterRoleBinding(ctx context.Context) error {
vectorAgentClusterRoleBinding := ctrl.createVectorAgentClusterRoleBinding()
- return k8s.CreateOrUpdateClusterRoleBinding(vectorAgentClusterRoleBinding, ctrl.Client)
+ return k8s.CreateOrUpdateClusterRoleBinding(ctx, vectorAgentClusterRoleBinding, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentService() error {
- ctx := context.Background()
+func (ctrl *Controller) ensureVectorAgentService(ctx context.Context) error {
log := log.FromContext(ctx).WithValues("vector-agent-service", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent Service")
vectorAgentService := ctrl.createVectorAgentService()
- return k8s.CreateOrUpdateService(vectorAgentService, ctrl.Client)
+ return k8s.CreateOrUpdateService(ctx, vectorAgentService, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentConfig() error {
- ctx := context.Background()
+func (ctrl *Controller) ensureVectorAgentConfig(ctx context.Context) error {
log := log.FromContext(ctx).WithValues("vector-agent-secret", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent Secret")
@@ -111,18 +107,17 @@ func (ctrl *Controller) ensureVectorAgentConfig() error {
return err
}
- return k8s.CreateOrUpdateSecret(vectorAgentSecret, ctrl.Client)
+ return k8s.CreateOrUpdateSecret(ctx, vectorAgentSecret, ctrl.Client)
}
-func (ctrl *Controller) ensureVectorAgentDaemonSet() error {
- ctx := context.Background()
+func (ctrl *Controller) ensureVectorAgentDaemonSet(ctx context.Context) error {
log := log.FromContext(ctx).WithValues("vector-agent-daemon-set", ctrl.Vector.Name)
log.Info("start Reconcile Vector Agent DaemonSet")
vectorAgentDaemonSet := ctrl.createVectorAgentDaemonSet()
- return k8s.CreateOrUpdateDaemonSet(vectorAgentDaemonSet, ctrl.Client)
+ return k8s.CreateOrUpdateDaemonSet(ctx, vectorAgentDaemonSet, ctrl.Client)
}
func (ctrl *Controller) labelsForVectorAgent() map[string]string {
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 16508455..3bda6319 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -122,7 +122,7 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
vaCtrl.Config = byteConfig
// Start Reconcile Vector Agent
- if err := vaCtrl.EnsureVectorAgent(); err != nil {
+ if err := vaCtrl.EnsureVectorAgent(ctx); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
From 2534939e0b67cb4b9e1a40d1cc2426eed66b186a Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 10 Nov 2022 09:23:41 +0200
Subject: [PATCH 083/316] Update ChangeLog
Signed-off-by: Zemtsov Vladimir
---
CHANGELOG.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b943256..7c0205cb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,8 @@
### Added
+- [[40](https://github.com/kaasops/vector-operator/pull/40)] **Fix**: Sloved context forward errors
+
+
+### v0.0.1
- Refactor: Refactor Pipeline for add ClusterVectorPipeline and checks
- Feature: Add field reason to CR Vector and VectorPipeline
- Feature: Add ConfigCheck for Vector
From 6cdb77d099dd2d13adcfed33d73ee9efff38b5f2 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Thu, 10 Nov 2022 09:45:00 +0200
Subject: [PATCH 084/316] revert reconcile by time (#42)
---
controllers/vector_controller.go | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/controllers/vector_controller.go b/controllers/vector_controller.go
index 3bda6319..6dbedc18 100644
--- a/controllers/vector_controller.go
+++ b/controllers/vector_controller.go
@@ -18,12 +18,11 @@ package controllers
import (
"context"
+ "time"
"github.com/kaasops/vector-operator/controllers/factory/config"
"github.com/kaasops/vector-operator/controllers/factory/pipeline"
"github.com/kaasops/vector-operator/controllers/factory/vector/vectoragent"
- appsv1 "k8s.io/api/apps/v1"
- corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
@@ -94,10 +93,6 @@ func (r *VectorReconciler) findVectorCustomResourceInstance(ctx context.Context,
func (r *VectorReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&vectorv1alpha1.Vector{}).
- Owns(&appsv1.DaemonSet{}).
- Owns(&corev1.Service{}).
- Owns(&corev1.Secret{}).
- Owns(&corev1.ServiceAccount{}).
Complete(r)
}
@@ -125,5 +120,5 @@ func (r *VectorReconciler) CreateOrUpdateVector(ctx context.Context, v *vectorv1
if err := vaCtrl.EnsureVectorAgent(ctx); err != nil {
return ctrl.Result{}, err
}
- return ctrl.Result{}, nil
+ return ctrl.Result{RequeueAfter: 15 * time.Second}, nil
}
From 370a2d2c680a36d34fb303d7071c3a0f33a3f6ab Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 11 Nov 2022 11:28:50 +0200
Subject: [PATCH 085/316] Refactor k8s utils
Signed-off-by: Zemtsov Vladimir
---
.../factory/config/configcheck/configcheck.go | 6 +-
controllers/factory/utils/k8s/k8s.go | 423 ++++++---
controllers/factory/utils/k8s/k8s_test.go | 866 ++++++++++++------
.../vectoragent/vectoragent_controller.go | 12 +-
4 files changed, 900 insertions(+), 407 deletions(-)
diff --git a/controllers/factory/config/configcheck/configcheck.go b/controllers/factory/config/configcheck/configcheck.go
index c7511668..aef5bf8e 100644
--- a/controllers/factory/config/configcheck/configcheck.go
+++ b/controllers/factory/config/configcheck/configcheck.go
@@ -82,7 +82,7 @@ func (cc *ConfigCheck) ensureVectorConfigCheckRBAC(ctx context.Context) error {
func (cc *ConfigCheck) ensureVectorConfigCheckServiceAccount(ctx context.Context) error {
vectorAgentServiceAccount := cc.createVectorConfigCheckServiceAccount()
- return k8s.CreateOrUpdateServiceAccount(ctx, vectorAgentServiceAccount, cc.Client)
+ return k8s.CreateOrUpdateResource(ctx, vectorAgentServiceAccount, cc.Client)
}
func (cc *ConfigCheck) ensureVectorConfigCheckConfig(ctx context.Context) error {
vectorConfigCheckSecret, err := cc.createVectorConfigCheckConfig()
@@ -90,7 +90,7 @@ func (cc *ConfigCheck) ensureVectorConfigCheckConfig(ctx context.Context) error
return err
}
- return k8s.CreateOrUpdateSecret(ctx, vectorConfigCheckSecret, cc.Client)
+ return k8s.CreateOrUpdateResource(ctx, vectorConfigCheckSecret, cc.Client)
}
func (cc *ConfigCheck) checkVectorConfigCheckPod(ctx context.Context) error {
@@ -142,7 +142,7 @@ func (cc *ConfigCheck) getCheckResult(ctx context.Context, pod *corev1.Pod) erro
log := log.FromContext(ctx).WithValues("Vector ConfigCheck", pod.Name)
for {
- existing, err := k8s.GetPod(ctx, pod, cc.Client)
+ existing, err := k8s.GetPod(ctx, client.ObjectKeyFromObject(pod), cc.Client)
if err != nil {
return err
}
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index aa435e8b..be7242af 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -19,128 +19,120 @@ package k8s
import (
"bytes"
"context"
+ "errors"
+ "fmt"
"io"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/equality"
- "k8s.io/apimachinery/pkg/api/errors"
+ api_errors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
)
-func CreateOrUpdateService(ctx context.Context, svc *corev1.Service, c client.Client) error {
- return reconcileService(ctx, svc, c)
-}
-
-func CreateOrUpdateSecret(ctx context.Context, secret *corev1.Secret, c client.Client) error {
- return reconcileSecret(ctx, secret, c)
-}
-
-func CreateOrUpdateDaemonSet(ctx context.Context, daemonSet *appsv1.DaemonSet, c client.Client) error {
- return reconcileDaemonSet(ctx, daemonSet, c)
-}
-
-func CreateOrUpdateStatefulSet(ctx context.Context, statefulSet *appsv1.StatefulSet, c client.Client) error {
- return reconcileStatefulSet(ctx, statefulSet, c)
-}
-
-func CreateOrUpdateServiceAccount(ctx context.Context, secret *corev1.ServiceAccount, c client.Client) error {
- return reconcileServiceAccount(ctx, secret, c)
-}
-
-func CreateOrUpdateClusterRole(ctx context.Context, secret *rbacv1.ClusterRole, c client.Client) error {
- return reconcileClusterRole(ctx, secret, c)
-}
-
-func CreateOrUpdateClusterRoleBinding(ctx context.Context, secret *rbacv1.ClusterRoleBinding, c client.Client) error {
- return reconcileClusterRoleBinding(ctx, secret, c)
-}
-
-func CreatePod(ctx context.Context, pod *corev1.Pod, c client.Client) error {
- err := c.Create(ctx, pod)
- if err != nil {
- return err
- }
- return nil
-}
-
-func GetPod(ctx context.Context, pod *corev1.Pod, c client.Client) (*corev1.Pod, error) {
- result := &corev1.Pod{}
- err := c.Get(ctx, client.ObjectKeyFromObject(pod), result)
- if err != nil {
- return nil, err
- }
- return result, nil
-}
+var (
+ ErrNotSupported = errors.New("Not Supported type for create or update kubernetes resource")
+)
-func DeletePod(ctx context.Context, pod *corev1.Pod, c client.Client) error {
- if err := c.Delete(ctx, pod); err != nil {
- return err
- }
- return nil
+func NewNotSupportedError(obj client.Object) error {
+ return fmt.Errorf("%w.\n %+v", ErrNotSupported, obj)
}
-func GetSecret(ctx context.Context, namespacedName types.NamespacedName, c client.Client) (*corev1.Secret, error) {
- result := &corev1.Secret{}
- err := c.Get(ctx, namespacedName, result)
- if err != nil {
- return nil, err
+func CreateOrUpdateResource(ctx context.Context, obj client.Object, c client.Client) error {
+ switch obj.(type) {
+ case *appsv1.Deployment:
+ runtimeObj := obj.DeepCopyObject()
+ return createOrUpdateDeployment(ctx, runtimeObj, c)
+ case *appsv1.StatefulSet:
+ return createOrUpdateStatefulSet(ctx, obj, c)
+ case *appsv1.DaemonSet:
+ return createOrUpdateDaemonSet(ctx, obj, c)
+ case *corev1.Secret:
+ return createOrUpdateSecret(ctx, obj, c)
+ case *corev1.Service:
+ return createOrUpdateService(ctx, obj, c)
+ case *corev1.ServiceAccount:
+ runtimeObj := obj.DeepCopyObject()
+ return createOrUpdateServiceAccount(ctx, runtimeObj, c)
+ case *rbacv1.ClusterRole:
+ return createOrUpdateClusterRole(ctx, obj, c)
+ case *rbacv1.ClusterRoleBinding:
+ return createOrUpdateClusterRoleBinding(ctx, obj, c)
+ default:
+ return NewNotSupportedError(obj)
}
- return result, nil
}
-func DeleteSecret(ctx context.Context, secret *corev1.Secret, c client.Client) error {
- if err := c.Delete(ctx, secret); err != nil {
- return err
- }
- return nil
-}
+func createOrUpdateDeployment(ctx context.Context, obj runtime.Object, c client.Client) error {
+ desired := obj.(*appsv1.Deployment)
-func GetPodLogs(ctx context.Context, pod *corev1.Pod, cs *kubernetes.Clientset) (string, error) {
- count := int64(100)
- podLogOptions := corev1.PodLogOptions{
- TailLines: &count,
- }
+ // Create Deployment
+ err := c.Create(ctx, desired)
+ if api_errors.IsAlreadyExists(err) {
+ // If alredy exist - compare with existed
+ existing := &appsv1.Deployment{}
+ err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
+ if err != nil {
+ return err
+ }
- req := cs.CoreV1().Pods(pod.Namespace).GetLogs(pod.Name, &podLogOptions)
- podLogs, err := req.Stream(ctx)
- if err != nil {
- return "", err
- }
- defer podLogs.Close()
+ // init Interface for compare
+ desiredFields := []interface{}{
+ desired.GetAnnotations(),
+ desired.GetLabels(),
+ desired.Spec,
+ }
+ existingFields := []interface{}{
+ existing.GetAnnotations(),
+ existing.GetLabels(),
+ existing.Spec,
+ }
- buf := new(bytes.Buffer)
- _, err = io.Copy(buf, podLogs)
- if err != nil {
- return "", err
+ // Compare
+ if !equality.Semantic.DeepDerivative(desiredFields, existingFields) {
+ // Update if not equal
+ existing.Labels = desired.Labels
+ existing.Annotations = desired.Annotations
+ existing.Spec = desired.Spec
+ return c.Update(ctx, existing)
+ }
+ return nil
}
- str := buf.String()
-
- return str, nil
-}
-
-func UpdateStatus(ctx context.Context, obj client.Object, c client.Client) error {
- return c.Status().Update(ctx, obj)
+ return err
}
-func reconcileService(ctx context.Context, obj runtime.Object, c client.Client) error {
-
- existing := &corev1.Service{}
- desired := obj.(*corev1.Service)
+func createOrUpdateStatefulSet(ctx context.Context, obj runtime.Object, c client.Client) error {
+ desired := obj.(*appsv1.StatefulSet)
+ // Create StatefulSet
err := c.Create(ctx, desired)
- if errors.IsAlreadyExists(err) {
+ if api_errors.IsAlreadyExists(err) {
+ // If alredy exist - compare with existed
+ existing := &appsv1.StatefulSet{}
err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
- if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
- !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
- !equality.Semantic.DeepDerivative(desired.Spec, existing.Spec) {
+
+ // init Interface for compare
+ desiredFields := []interface{}{
+ desired.GetAnnotations(),
+ desired.GetLabels(),
+ desired.Spec,
+ }
+ existingFields := []interface{}{
+ existing.GetAnnotations(),
+ existing.GetLabels(),
+ existing.Spec,
+ }
+
+ // Compare
+ if !equality.Semantic.DeepDerivative(desiredFields, existingFields) {
+ // Update if not equal
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
existing.Spec = desired.Spec
@@ -151,23 +143,37 @@ func reconcileService(ctx context.Context, obj runtime.Object, c client.Client)
return err
}
-func reconcileSecret(ctx context.Context, obj runtime.Object, c client.Client) error {
-
- existing := &corev1.Secret{}
- desired := obj.(*corev1.Secret)
+func createOrUpdateDaemonSet(ctx context.Context, obj runtime.Object, c client.Client) error {
+ desired := obj.(*appsv1.DaemonSet)
+ // Create DaemonSet
err := c.Create(ctx, desired)
- if errors.IsAlreadyExists(err) {
+ if api_errors.IsAlreadyExists(err) {
+ // If alredy exist - compare with existed
+ existing := &appsv1.DaemonSet{}
err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
- if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
- !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
- !equality.Semantic.DeepDerivative(desired.Data, existing.Data) {
+
+ // init Interface for compare
+ desiredFields := []interface{}{
+ desired.GetAnnotations(),
+ desired.GetLabels(),
+ desired.Spec,
+ }
+ existingFields := []interface{}{
+ existing.GetAnnotations(),
+ existing.GetLabels(),
+ existing.Spec,
+ }
+
+ // Compare
+ if !equality.Semantic.DeepDerivative(desiredFields, existingFields) {
+ // Update if not equal
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
- existing.Data = desired.Data
+ existing.Spec = desired.Spec
return c.Update(ctx, existing)
}
return nil
@@ -175,23 +181,37 @@ func reconcileSecret(ctx context.Context, obj runtime.Object, c client.Client) e
return err
}
-func reconcileDaemonSet(ctx context.Context, obj runtime.Object, c client.Client) error {
-
- existing := &appsv1.DaemonSet{}
- desired := obj.(*appsv1.DaemonSet)
+func createOrUpdateSecret(ctx context.Context, obj runtime.Object, c client.Client) error {
+ desired := obj.(*corev1.Secret)
+ // Create Secret
err := c.Create(ctx, desired)
- if errors.IsAlreadyExists(err) {
+ if api_errors.IsAlreadyExists(err) {
+ // If alredy exist - compare with existed
+ existing := &corev1.Secret{}
err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
- if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
- !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
- !equality.Semantic.DeepDerivative(desired.Spec, existing.Spec) {
+
+ // init Interface for compare
+ desiredFields := []interface{}{
+ desired.GetAnnotations(),
+ desired.GetLabels(),
+ desired.Data,
+ }
+ existingFields := []interface{}{
+ existing.GetAnnotations(),
+ existing.GetLabels(),
+ existing.Data,
+ }
+
+ // Compare
+ if !equality.Semantic.DeepDerivative(desiredFields, existingFields) {
+ // Update if not equal
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
- existing.Spec = desired.Spec
+ existing.Data = desired.Data
return c.Update(ctx, existing)
}
return nil
@@ -199,20 +219,34 @@ func reconcileDaemonSet(ctx context.Context, obj runtime.Object, c client.Client
return err
}
-func reconcileStatefulSet(ctx context.Context, obj runtime.Object, c client.Client) error {
-
- existing := &appsv1.StatefulSet{}
- desired := obj.(*appsv1.StatefulSet)
+func createOrUpdateService(ctx context.Context, obj runtime.Object, c client.Client) error {
+ desired := obj.(*corev1.Service)
+ // Create Service
err := c.Create(ctx, desired)
- if errors.IsAlreadyExists(err) {
+ if api_errors.IsAlreadyExists(err) {
+ // If alredy exist - compare with existed
+ existing := &corev1.Service{}
err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
- if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
- !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
- !equality.Semantic.DeepDerivative(desired.Spec, existing.Spec) {
+
+ // init Interface for compare
+ desiredFields := []interface{}{
+ desired.GetAnnotations(),
+ desired.GetLabels(),
+ desired.Spec,
+ }
+ existingFields := []interface{}{
+ existing.GetAnnotations(),
+ existing.GetLabels(),
+ existing.Spec,
+ }
+
+ // Compare
+ if !equality.Semantic.DeepDerivative(desiredFields, existingFields) {
+ // Update if not equal
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
existing.Spec = desired.Spec
@@ -223,19 +257,32 @@ func reconcileStatefulSet(ctx context.Context, obj runtime.Object, c client.Clie
return err
}
-func reconcileServiceAccount(ctx context.Context, obj runtime.Object, c client.Client) error {
-
- existing := &corev1.ServiceAccount{}
+func createOrUpdateServiceAccount(ctx context.Context, obj runtime.Object, c client.Client) error {
desired := obj.(*corev1.ServiceAccount)
+ // Create ServiceAccount
err := c.Create(ctx, desired)
- if errors.IsAlreadyExists(err) {
+ if api_errors.IsAlreadyExists(err) {
+ // If alredy exist - compare with existed
+ existing := &corev1.ServiceAccount{}
err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
- if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
- !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) {
+
+ // init Interface for compare
+ desiredFields := []interface{}{
+ desired.GetAnnotations(),
+ desired.GetLabels(),
+ }
+ existingFields := []interface{}{
+ existing.GetAnnotations(),
+ existing.GetLabels(),
+ }
+
+ // Compare
+ if !equality.Semantic.DeepDerivative(desiredFields, existingFields) {
+ // Update if not equal
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
return c.Update(ctx, existing)
@@ -245,20 +292,34 @@ func reconcileServiceAccount(ctx context.Context, obj runtime.Object, c client.C
return err
}
-func reconcileClusterRole(ctx context.Context, obj runtime.Object, c client.Client) error {
-
- existing := &rbacv1.ClusterRole{}
+func createOrUpdateClusterRole(ctx context.Context, obj runtime.Object, c client.Client) error {
desired := obj.(*rbacv1.ClusterRole)
+ // Create ClusterRole
err := c.Create(ctx, desired)
- if errors.IsAlreadyExists(err) {
+ if api_errors.IsAlreadyExists(err) {
+ // If alredy exist - compare with existed
+ existing := &rbacv1.ClusterRole{}
err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
- if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
- !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
- !equality.Semantic.DeepDerivative(desired.Rules, existing.Rules) {
+
+ // init Interface for compare
+ desiredFields := []interface{}{
+ desired.GetAnnotations(),
+ desired.GetLabels(),
+ desired.Rules,
+ }
+ existingFields := []interface{}{
+ existing.GetAnnotations(),
+ existing.GetLabels(),
+ existing.Rules,
+ }
+
+ // Compare
+ if !equality.Semantic.DeepDerivative(desiredFields, existingFields) {
+ // Update if not equal
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
existing.Rules = desired.Rules
@@ -269,21 +330,36 @@ func reconcileClusterRole(ctx context.Context, obj runtime.Object, c client.Clie
return err
}
-func reconcileClusterRoleBinding(ctx context.Context, obj runtime.Object, c client.Client) error {
-
- existing := &rbacv1.ClusterRoleBinding{}
+func createOrUpdateClusterRoleBinding(ctx context.Context, obj runtime.Object, c client.Client) error {
desired := obj.(*rbacv1.ClusterRoleBinding)
+ // Create ClusterRoleBinding
err := c.Create(ctx, desired)
- if errors.IsAlreadyExists(err) {
+ if api_errors.IsAlreadyExists(err) {
+ // If alredy exist - compare with existed
+ existing := &rbacv1.ClusterRoleBinding{}
err := c.Get(ctx, client.ObjectKeyFromObject(desired), existing)
if err != nil {
return err
}
- if !equality.Semantic.DeepDerivative(desired.ObjectMeta.Labels, existing.ObjectMeta.Labels) ||
- !equality.Semantic.DeepDerivative(desired.Annotations, existing.Annotations) ||
- !equality.Semantic.DeepDerivative(desired.RoleRef, existing.RoleRef) ||
- !equality.Semantic.DeepDerivative(desired.Subjects, existing.Subjects) {
+
+ // Init Interface for compare
+ desiredFields := []interface{}{
+ desired.GetAnnotations(),
+ desired.GetLabels(),
+ desired.RoleRef,
+ desired.Subjects,
+ }
+ existingFields := []interface{}{
+ existing.GetAnnotations(),
+ existing.GetLabels(),
+ existing.RoleRef,
+ existing.Subjects,
+ }
+
+ // Compare
+ if !equality.Semantic.DeepDerivative(desiredFields, existingFields) {
+ // Update if not equal
existing.Labels = desired.Labels
existing.Annotations = desired.Annotations
existing.RoleRef = desired.RoleRef
@@ -295,6 +371,75 @@ func reconcileClusterRoleBinding(ctx context.Context, obj runtime.Object, c clie
return err
}
+// Something else:
+
+func CreatePod(ctx context.Context, pod *corev1.Pod, c client.Client) error {
+ err := c.Create(ctx, pod)
+ if api_errors.IsAlreadyExists(err) {
+ return nil
+ }
+ return err
+}
+
+func GetPod(ctx context.Context, namespacedName types.NamespacedName, c client.Client) (*corev1.Pod, error) {
+ result := &corev1.Pod{}
+ err := c.Get(ctx, namespacedName, result)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func DeletePod(ctx context.Context, pod *corev1.Pod, c client.Client) error {
+ if err := c.Delete(ctx, pod); err != nil {
+ return err
+ }
+ return nil
+}
+
+func GetSecret(ctx context.Context, namespacedName types.NamespacedName, c client.Client) (*corev1.Secret, error) {
+ result := &corev1.Secret{}
+ err := c.Get(ctx, namespacedName, result)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func DeleteSecret(ctx context.Context, secret *corev1.Secret, c client.Client) error {
+ if err := c.Delete(ctx, secret); err != nil {
+ return err
+ }
+ return nil
+}
+
+func GetPodLogs(ctx context.Context, pod *corev1.Pod, cs *kubernetes.Clientset) (string, error) {
+ count := int64(100)
+ podLogOptions := corev1.PodLogOptions{
+ TailLines: &count,
+ }
+
+ req := cs.CoreV1().Pods(pod.Namespace).GetLogs(pod.Name, &podLogOptions)
+ podLogs, err := req.Stream(ctx)
+ if err != nil {
+ return "", err
+ }
+ defer podLogs.Close()
+
+ buf := new(bytes.Buffer)
+ _, err = io.Copy(buf, podLogs)
+ if err != nil {
+ return "", err
+ }
+ str := buf.String()
+
+ return str, nil
+}
+
+func UpdateStatus(ctx context.Context, obj client.Object, c client.Client) error {
+ return c.Status().Update(ctx, obj)
+}
+
func NamespaceNameToLabel(namespace string) string {
return "kubernetes.io/metadata.name=" + namespace
}
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index 07f548b1..cb5fe3e6 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -28,7 +28,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
- apierrors "k8s.io/apimachinery/pkg/api/errors"
+ api_errors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
@@ -36,77 +36,14 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)
-func getInitObjectMeta() metav1.ObjectMeta {
- ObjectMeta := metav1.ObjectMeta{
- Name: "init",
- Namespace: "test-namespace",
- }
-
- return ObjectMeta
+type objCase struct {
+ name string
+ initObj client.Object
+ obj client.Object
+ want error
}
-var reconcileObjectCase = func(ctx context.Context, objInit, obj interface{}, want error) func(t *testing.T) {
- return func(t *testing.T) {
- t.Helper()
- t.Parallel()
-
- req := require.New(t)
-
- switch obj.(type) {
- case *corev1.Service:
- serviceInit := objInit.(*corev1.Service)
- service := obj.(*corev1.Service)
-
- cl := fake.NewClientBuilder().WithObjects(serviceInit).Build()
- err := k8s.CreateOrUpdateService(ctx, service, cl)
- req.Equal(err, want)
- case *corev1.Secret:
- secretInit := objInit.(*corev1.Secret)
- secret := obj.(*corev1.Secret)
-
- cl := fake.NewClientBuilder().WithObjects(secretInit).Build()
- err := k8s.CreateOrUpdateSecret(ctx, secret, cl)
- req.Equal(err, want)
- case *appsv1.DaemonSet:
- daemonSetInit := objInit.(*appsv1.DaemonSet)
- daemonSet := obj.(*appsv1.DaemonSet)
-
- cl := fake.NewClientBuilder().WithObjects(daemonSetInit).Build()
- err := k8s.CreateOrUpdateDaemonSet(ctx, daemonSet, cl)
- req.Equal(err, want)
- case *appsv1.StatefulSet:
- statefulSetInit := objInit.(*appsv1.StatefulSet)
- statefulSet := obj.(*appsv1.StatefulSet)
-
- cl := fake.NewClientBuilder().WithObjects(statefulSetInit).Build()
- err := k8s.CreateOrUpdateStatefulSet(ctx, statefulSet, cl)
- req.Equal(err, want)
- case *corev1.ServiceAccount:
- serviceAccountInit := objInit.(*corev1.ServiceAccount)
- serviceAccount := obj.(*corev1.ServiceAccount)
-
- cl := fake.NewClientBuilder().WithObjects(serviceAccountInit).Build()
- err := k8s.CreateOrUpdateServiceAccount(ctx, serviceAccount, cl)
- req.Equal(err, want)
- case *rbacv1.ClusterRole:
- clusterRoleInit := objInit.(*rbacv1.ClusterRole)
- clusterRole := obj.(*rbacv1.ClusterRole)
-
- cl := fake.NewClientBuilder().WithObjects(clusterRoleInit).Build()
- err := k8s.CreateOrUpdateClusterRole(ctx, clusterRole, cl)
- req.Equal(err, want)
- case *rbacv1.ClusterRoleBinding:
- clusterRoleBindingInit := objInit.(*rbacv1.ClusterRoleBinding)
- clusterRoleBinding := obj.(*rbacv1.ClusterRoleBinding)
-
- cl := fake.NewClientBuilder().WithObjects(clusterRoleBindingInit).Build()
- err := k8s.CreateOrUpdateClusterRoleBinding(ctx, clusterRoleBinding, cl)
- req.Equal(err, want)
- }
- }
-}
-
-var nameRequeriedError = apierrors.NewInvalid(
+var nameRequeriedError = api_errors.NewInvalid(
schema.GroupKind{},
"",
field.ErrorList{
@@ -117,394 +54,594 @@ var nameRequeriedError = apierrors.NewInvalid(
},
)
-func TestCreateOrUpdateService(t *testing.T) {
- initObj := &corev1.Service{
- ObjectMeta: getInitObjectMeta(),
+func getInitObjectMeta() metav1.ObjectMeta {
+ ObjectMeta := metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
}
- type secriveCase struct {
- name string
- obj *corev1.Service
- err error
+ return ObjectMeta
+}
+
+func TestCreateOrUpdateResource(t *testing.T) {
+ createOrUpdateResourceCase := func(initObj, obj client.Object, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ t.Helper()
+ t.Parallel()
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(initObj).Build()
+ result := k8s.CreateOrUpdateResource(context.Background(), obj, cl)
+ req.Equal(result, want)
+ }
}
- secriveCases := []secriveCase{
+ var cases []objCase
+
+ // Deployment cases
+ deploymentCases := []objCase{
{
name: "Create Simple case",
- obj: &corev1.Service{
+ initObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create Alredy exist case",
- obj: &corev1.Service{
+ initObj: &appsv1.Deployment{
ObjectMeta: getInitObjectMeta(),
},
- err: nil,
+ obj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ want: nil,
},
{
name: "Create with Another Namespace case",
- obj: &corev1.Service{
+ initObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create without Name case",
- obj: &corev1.Service{
+ initObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{},
},
- err: nameRequeriedError,
+ want: nameRequeriedError,
+ },
+ {
+ name: "Update exist case",
+ initObj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &appsv1.Deployment{
+ ObjectMeta: getInitObjectMeta(),
+ Spec: appsv1.DeploymentSpec{
+ MinReadySeconds: 2,
+ },
+ },
+ want: nil,
},
}
+ cases = append(cases, deploymentCases...)
- // t.Parallel()
- for _, tc := range secriveCases {
- t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
- }
-}
-
-func TestCreateOrUpdateSecret(t *testing.T) {
- initObj := &corev1.Secret{
- ObjectMeta: getInitObjectMeta(),
- }
-
- type secretCase struct {
- name string
- obj *corev1.Secret
- err error
- }
-
- secretCases := []secretCase{
+ // StatefulSet cases
+ statefulSetCases := []objCase{
{
name: "Create Simple case",
- obj: &corev1.Secret{
+ initObj: &appsv1.StatefulSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create Alredy exist case",
- obj: &corev1.Secret{
+ initObj: &appsv1.StatefulSet{
ObjectMeta: getInitObjectMeta(),
},
- err: nil,
+ obj: &appsv1.StatefulSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ want: nil,
},
{
name: "Create with Another Namespace case",
- obj: &corev1.Secret{
+ initObj: &appsv1.StatefulSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create without Name case",
- obj: &corev1.Secret{
+ initObj: &appsv1.StatefulSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{},
},
- err: nameRequeriedError,
+ want: nameRequeriedError,
+ },
+ {
+ name: "Update exist case",
+ initObj: &appsv1.StatefulSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &appsv1.StatefulSet{
+ ObjectMeta: getInitObjectMeta(),
+ Spec: appsv1.StatefulSetSpec{
+ MinReadySeconds: 2,
+ },
+ },
+ want: nil,
},
}
+ cases = append(cases, statefulSetCases...)
- // t.Parallel()
- for _, tc := range secretCases {
- t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
- }
-}
-
-func TestCreateOrUpdateDaemonSet(t *testing.T) {
- initObj := &appsv1.DaemonSet{
- ObjectMeta: getInitObjectMeta(),
- }
-
- type daemonSetCase struct {
- name string
- obj *appsv1.DaemonSet
- err error
- }
-
- daemonSetCases := []daemonSetCase{
+ // DaemonSet cases
+ daemonSetCases := []objCase{
{
name: "Create Simple case",
+ initObj: &appsv1.DaemonSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
+ Name: "test",
Namespace: "test-namespace",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create Alredy exist case",
+ initObj: &appsv1.DaemonSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &appsv1.DaemonSet{
ObjectMeta: getInitObjectMeta(),
},
- err: nil,
+ want: nil,
},
{
name: "Create with Another Namespace case",
+ initObj: &appsv1.DaemonSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create without Name case",
+ initObj: &appsv1.DaemonSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{},
},
- err: nameRequeriedError,
+ want: nameRequeriedError,
+ },
+ {
+ name: "Update exist case",
+ initObj: &appsv1.DaemonSet{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &appsv1.DaemonSet{
+ ObjectMeta: getInitObjectMeta(),
+ Spec: appsv1.DaemonSetSpec{
+ MinReadySeconds: 2,
+ },
+ },
+ want: nil,
},
}
+ cases = append(cases, daemonSetCases...)
- // t.Parallel()
- for _, tc := range daemonSetCases {
- t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
- }
-}
-
-func TestCreateOrUpdateStatefulSet(t *testing.T) {
- initObj := &appsv1.StatefulSet{
- ObjectMeta: getInitObjectMeta(),
- }
-
- type statefulSetCase struct {
- name string
- obj *appsv1.StatefulSet
- err error
- }
-
- statefulSetCases := []statefulSetCase{
+ // Secret cases
+ secretCases := []objCase{
{
name: "Create Simple case",
- obj: &appsv1.StatefulSet{
+ initObj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
+ Name: "test",
Namespace: "test-namespace",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create Alredy exist case",
- obj: &appsv1.StatefulSet{
+ initObj: &corev1.Secret{
ObjectMeta: getInitObjectMeta(),
},
- err: nil,
+ obj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ want: nil,
},
{
name: "Create with Another Namespace case",
- obj: &appsv1.StatefulSet{
+ initObj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create without Name case",
- obj: &appsv1.StatefulSet{
+ initObj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{},
},
- err: nameRequeriedError,
+ want: nameRequeriedError,
+ },
+ {
+ name: "Update exist case",
+ initObj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ Data: map[string][]byte{
+ "test": []byte("test"),
+ },
+ },
+ want: nil,
},
}
+ cases = append(cases, secretCases...)
- // t.Parallel()
- for _, tc := range statefulSetCases {
- t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
- }
-}
-
-func TestCreateOrUpdateServiceAccount(t *testing.T) {
- initObj := &corev1.ServiceAccount{
- ObjectMeta: getInitObjectMeta(),
- }
-
- type serviceAccountCase struct {
- name string
- obj *corev1.ServiceAccount
- err error
+ // Service cases
+ serviceCases := []objCase{
+ {
+ name: "Create Simple case",
+ initObj: &corev1.Service{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ },
+ want: nil,
+ },
+ {
+ name: "Create Alredy exist case",
+ initObj: &corev1.Service{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Service{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ want: nil,
+ },
+ {
+ name: "Create with Another Namespace case",
+ initObj: &corev1.Service{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ want: nil,
+ },
+ {
+ name: "Create without Name case",
+ initObj: &corev1.Service{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{},
+ },
+ want: nameRequeriedError,
+ },
+ {
+ name: "Update exist case",
+ initObj: &corev1.Service{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Service{
+ ObjectMeta: getInitObjectMeta(),
+ Spec: corev1.ServiceSpec{
+ ClusterIP: "1.1.1.1",
+ },
+ },
+ want: nil,
+ },
}
+ cases = append(cases, serviceCases...)
- serviceAccountCases := []serviceAccountCase{
+ // ServiceAccount cases
+ serviceAccountCases := []objCase{
{
name: "Create Simple case",
+ initObj: &corev1.ServiceAccount{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
+ Name: "test",
Namespace: "test-namespace",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create Alredy exist case",
+ initObj: &corev1.ServiceAccount{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &corev1.ServiceAccount{
ObjectMeta: getInitObjectMeta(),
},
- err: nil,
+ want: nil,
},
{
name: "Create with Another Namespace case",
+ initObj: &corev1.ServiceAccount{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create without Name case",
+ initObj: &corev1.ServiceAccount{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{},
},
- err: nameRequeriedError,
+ want: nameRequeriedError,
+ },
+ {
+ name: "Update exist case",
+ initObj: &corev1.ServiceAccount{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.ServiceAccount{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ Labels: map[string]string{
+ "test": "test",
+ },
+ },
+ },
+ want: nil,
},
}
+ cases = append(cases, serviceAccountCases...)
- // t.Parallel()
- for _, tc := range serviceAccountCases {
- t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
- }
-}
-
-func TestCreateOrUpdateClusterRole(t *testing.T) {
- initObj := &rbacv1.ClusterRole{
- ObjectMeta: getInitObjectMeta(),
- }
-
- type clusterRoleCase struct {
- name string
- obj *rbacv1.ClusterRole
- err error
- }
-
- clusterRoleCases := []clusterRoleCase{
+ // ClusterRole cases
+ clusterRoleCases := []objCase{
{
name: "Create Simple case",
+ initObj: &rbacv1.ClusterRole{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
+ Name: "test",
Namespace: "test-namespace",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create Alredy exist case",
+ initObj: &rbacv1.ClusterRole{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &rbacv1.ClusterRole{
ObjectMeta: getInitObjectMeta(),
},
- err: nil,
+ want: nil,
},
{
name: "Create with Another Namespace case",
+ initObj: &rbacv1.ClusterRole{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create without Name case",
+ initObj: &rbacv1.ClusterRole{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{},
},
- err: nameRequeriedError,
+ want: nameRequeriedError,
+ },
+ {
+ name: "Update exist case",
+ initObj: &rbacv1.ClusterRole{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &rbacv1.ClusterRole{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ Labels: map[string]string{
+ "test": "test",
+ },
+ },
+ },
+ want: nil,
},
}
+ cases = append(cases, clusterRoleCases...)
- // t.Parallel()
- for _, tc := range clusterRoleCases {
- t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
- }
-}
-
-func TestCreateOrUpdateClusterRoleBinding(t *testing.T) {
- initObj := &rbacv1.ClusterRoleBinding{
- ObjectMeta: getInitObjectMeta(),
- }
-
- type clusterRoleBindingCase struct {
- name string
- obj *rbacv1.ClusterRoleBinding
- err error
- }
-
- clusterRoleBindingCases := []clusterRoleBindingCase{
+ // ClusterRoleBinding cases
+ clusterRoleBindingCases := []objCase{
{
name: "Create Simple case",
+ initObj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
- Name: "init",
+ Name: "test",
Namespace: "test-namespace",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create Alredy exist case",
+ initObj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &rbacv1.ClusterRoleBinding{
ObjectMeta: getInitObjectMeta(),
},
- err: nil,
+ want: nil,
},
{
name: "Create with Another Namespace case",
+ initObj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test-namespace2",
},
},
- err: nil,
+ want: nil,
},
{
name: "Create without Name case",
+ initObj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{},
},
- err: nameRequeriedError,
+ want: nameRequeriedError,
+ },
+ {
+ name: "Update exist case",
+ initObj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &rbacv1.ClusterRoleBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ Labels: map[string]string{
+ "test": "test",
+ },
+ },
+ },
+ want: nil,
+ },
+ }
+ cases = append(cases, clusterRoleBindingCases...)
+
+ // Not supported type case
+ notSuppurtedcase := []objCase{
+ {
+ name: "Update exist case",
+ initObj: &rbacv1.RoleBinding{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &rbacv1.RoleBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ Labels: map[string]string{
+ "test": "test",
+ },
+ },
+ },
+ want: k8s.NewNotSupportedError(&rbacv1.RoleBinding{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ Labels: map[string]string{
+ "test": "test",
+ },
+ },
+ },
+ ),
},
}
+ cases = append(cases, notSuppurtedcase...)
- // t.Parallel()
- for _, tc := range clusterRoleBindingCases {
- t.Run(tc.name, reconcileObjectCase(context.Background(), initObj, tc.obj, tc.err))
+ for _, tc := range cases {
+ t.Run(tc.name, createOrUpdateResourceCase(tc.initObj, tc.obj, tc.want))
}
}
func TestCreatePod(t *testing.T) {
createPodCase := func(objInit, obj *corev1.Pod, want error) func(t *testing.T) {
- // t.Parallel()
return func(t *testing.T) {
t.Helper()
-
+ t.Parallel()
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
-
err := k8s.CreatePod(context.Background(), obj, cl)
req.Equal(err, want)
}
@@ -536,17 +673,17 @@ func TestCreatePod(t *testing.T) {
obj: &corev1.Pod{
ObjectMeta: getInitObjectMeta(),
},
- err: apierrors.NewAlreadyExists(
- schema.GroupResource{
- Group: "",
- Resource: "pods",
- },
- "init",
- ),
+ err: nil,
+ // err: api_errors.NewAlreadyExists(
+ // schema.GroupResource{
+ // Group: "",
+ // Resource: "pods",
+ // },
+ // "init",
+ // ),
},
}
- // t.Parallel()
for _, tc := range podCases {
t.Run(tc.name, createPodCase(initObj, tc.obj, tc.err))
}
@@ -554,15 +691,13 @@ func TestCreatePod(t *testing.T) {
func TestGetPod(t *testing.T) {
getPodCase := func(objInit, obj, wantPod *corev1.Pod, want error) func(t *testing.T) {
- // t.Parallel()
return func(t *testing.T) {
t.Helper()
-
+ t.Parallel()
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
-
- result, err := k8s.GetPod(context.Background(), obj, cl)
+ result, err := k8s.GetPod(context.Background(), client.ObjectKeyFromObject(obj), cl)
if result != nil {
req.Equal(result.ObjectMeta, wantPod.ObjectMeta)
}
@@ -570,12 +705,9 @@ func TestGetPod(t *testing.T) {
}
}
- initObj := &corev1.Pod{
- ObjectMeta: getInitObjectMeta(),
- }
-
type podCase struct {
name string
+ initObj *corev1.Pod
obj *corev1.Pod
wantObj *corev1.Pod
err error
@@ -584,6 +716,9 @@ func TestGetPod(t *testing.T) {
podCases := []podCase{
{
name: "Get not exist pod case",
+ initObj: &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
@@ -591,7 +726,7 @@ func TestGetPod(t *testing.T) {
},
},
wantObj: nil,
- err: apierrors.NewNotFound(
+ err: api_errors.NewNotFound(
schema.GroupResource{
Group: "",
Resource: "pods",
@@ -601,6 +736,9 @@ func TestGetPod(t *testing.T) {
},
{
name: "Get exist pod case",
+ initObj: &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ },
obj: &corev1.Pod{
ObjectMeta: getInitObjectMeta(),
},
@@ -615,24 +753,199 @@ func TestGetPod(t *testing.T) {
},
}
- // t.Parallel()
for _, tc := range podCases {
- t.Run(tc.name, getPodCase(initObj, tc.obj, tc.wantObj, tc.err))
+ t.Run(tc.name, getPodCase(tc.initObj, tc.obj, tc.wantObj, tc.err))
}
}
-func TestUpdateStatus(t *testing.T) {
- updateStatusCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
- // t.Parallel()
+func TestDeletePod(t *testing.T) {
+ deletePodCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ t.Helper()
+ t.Parallel()
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+ pod := obj.(*corev1.Pod)
+ err := k8s.DeletePod(context.Background(), pod, cl)
+ req.Equal(err, want)
+ }
+ }
+
+ var cases []objCase
+
+ // DeletePodcases
+ deletePodCases := []objCase{
+ {
+ name: "Delete Simple case",
+ initObj: &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ want: nil,
+ },
+ {
+ name: "Delete not exist case",
+ initObj: &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ want: api_errors.NewNotFound(
+ schema.GroupResource{
+ Group: "",
+ Resource: "pods",
+ },
+ "test",
+ ),
+ },
+ }
+ cases = append(cases, deletePodCases...)
+
+ for _, tc := range cases {
+ t.Run(tc.name, deletePodCase(tc.initObj, tc.obj, tc.want))
+ }
+}
+
+func TestGetSecret(t *testing.T) {
+ getSecretCase := func(objInit, obj, wantSecret *corev1.Secret, want error) func(t *testing.T) {
return func(t *testing.T) {
t.Helper()
+ t.Parallel()
+ req := require.New(t)
+
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+ result, err := k8s.GetSecret(context.Background(), client.ObjectKeyFromObject(obj), cl)
+ if result != nil {
+ req.Equal(result.ObjectMeta, wantSecret.ObjectMeta)
+ }
+ req.Equal(err, want)
+ }
+ }
+
+ type secretCase struct {
+ name string
+ initObj *corev1.Secret
+ obj *corev1.Secret
+ wantObj *corev1.Secret
+ err error
+ }
+
+ podCases := []secretCase{
+ {
+ name: "Get not exist secret case",
+ initObj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace",
+ },
+ },
+ wantObj: nil,
+ err: api_errors.NewNotFound(
+ schema.GroupResource{
+ Group: "",
+ Resource: "secrets",
+ },
+ "test",
+ ),
+ },
+ {
+ name: "Get exist secret case",
+ initObj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ wantObj: &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "init",
+ Namespace: "test-namespace",
+ ResourceVersion: "999",
+ },
+ },
+ err: nil,
+ },
+ }
+
+ for _, tc := range podCases {
+ t.Run(tc.name, getSecretCase(tc.initObj, tc.obj, tc.wantObj, tc.err))
+ }
+}
+func TestDeleteSecret(t *testing.T) {
+ deleteSecretCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ t.Helper()
+ t.Parallel()
req := require.New(t)
cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+ secret := obj.(*corev1.Secret)
+ err := k8s.DeleteSecret(context.Background(), secret, cl)
+ req.Equal(err, want)
+ }
+ }
- err := k8s.UpdateStatus(context.Background(), obj, cl)
+ var cases []objCase
+
+ // DeletePodcases
+ deleteSecretCases := []objCase{
+ {
+ name: "Delete Simple case",
+ initObj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ want: nil,
+ },
+ {
+ name: "Delete not exist case",
+ initObj: &corev1.Secret{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ obj: &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-namespace2",
+ },
+ },
+ want: api_errors.NewNotFound(
+ schema.GroupResource{
+ Group: "",
+ Resource: "secrets",
+ },
+ "test",
+ ),
+ },
+ }
+ cases = append(cases, deleteSecretCases...)
+
+ for _, tc := range cases {
+ t.Run(tc.name, deleteSecretCase(tc.initObj, tc.obj, tc.want))
+ }
+}
+
+func TestUpdateStatus(t *testing.T) {
+ updateStatusCase := func(objInit, obj client.Object, want error) func(t *testing.T) {
+ return func(t *testing.T) {
+ t.Helper()
+ t.Parallel()
+ req := require.New(t)
+ cl := fake.NewClientBuilder().WithObjects(objInit).Build()
+ err := k8s.UpdateStatus(context.Background(), obj, cl)
req.Equal(err, want)
}
}
@@ -690,8 +1003,43 @@ func TestUpdateStatus(t *testing.T) {
},
}
- // t.Parallel()
for _, tc := range testCases {
t.Run(tc.name, updateStatusCase(tc.initObj, tc.updateObj, tc.err))
}
}
+
+func TestNamespaceNameToLabel(t *testing.T) {
+ namespaceNameToLabelCase := func(in, want string) func(t *testing.T) {
+ return func(t *testing.T) {
+ t.Helper()
+ t.Parallel()
+ req := require.New(t)
+
+ result := k8s.NamespaceNameToLabel(in)
+ req.Equal(result, want)
+ }
+ }
+
+ type testCase struct {
+ name string
+ in string
+ want string
+ }
+
+ testCases := []testCase{
+ {
+ name: "Simple case",
+ in: "test",
+ want: "kubernetes.io/metadata.name=test",
+ },
+ {
+ name: "Zero case",
+ in: "",
+ want: "kubernetes.io/metadata.name=",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, namespaceNameToLabelCase(tc.in, tc.want))
+ }
+}
diff --git a/controllers/factory/vector/vectoragent/vectoragent_controller.go b/controllers/factory/vector/vectoragent/vectoragent_controller.go
index 914600b1..1c1dfa22 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_controller.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_controller.go
@@ -72,19 +72,19 @@ func (ctrl *Controller) ensureVectorAgentRBAC(ctx context.Context) error {
func (ctrl *Controller) ensureVectorAgentServiceAccount(ctx context.Context) error {
vectorAgentServiceAccount := ctrl.createVectorAgentServiceAccount()
- return k8s.CreateOrUpdateServiceAccount(ctx, vectorAgentServiceAccount, ctrl.Client)
+ return k8s.CreateOrUpdateResource(ctx, vectorAgentServiceAccount, ctrl.Client)
}
func (ctrl *Controller) ensureVectorAgentClusterRole(ctx context.Context) error {
vectorAgentClusterRole := ctrl.createVectorAgentClusterRole()
- return k8s.CreateOrUpdateClusterRole(ctx, vectorAgentClusterRole, ctrl.Client)
+ return k8s.CreateOrUpdateResource(ctx, vectorAgentClusterRole, ctrl.Client)
}
func (ctrl *Controller) ensureVectorAgentClusterRoleBinding(ctx context.Context) error {
vectorAgentClusterRoleBinding := ctrl.createVectorAgentClusterRoleBinding()
- return k8s.CreateOrUpdateClusterRoleBinding(ctx, vectorAgentClusterRoleBinding, ctrl.Client)
+ return k8s.CreateOrUpdateResource(ctx, vectorAgentClusterRoleBinding, ctrl.Client)
}
func (ctrl *Controller) ensureVectorAgentService(ctx context.Context) error {
@@ -94,7 +94,7 @@ func (ctrl *Controller) ensureVectorAgentService(ctx context.Context) error {
vectorAgentService := ctrl.createVectorAgentService()
- return k8s.CreateOrUpdateService(ctx, vectorAgentService, ctrl.Client)
+ return k8s.CreateOrUpdateResource(ctx, vectorAgentService, ctrl.Client)
}
func (ctrl *Controller) ensureVectorAgentConfig(ctx context.Context) error {
@@ -107,7 +107,7 @@ func (ctrl *Controller) ensureVectorAgentConfig(ctx context.Context) error {
return err
}
- return k8s.CreateOrUpdateSecret(ctx, vectorAgentSecret, ctrl.Client)
+ return k8s.CreateOrUpdateResource(ctx, vectorAgentSecret, ctrl.Client)
}
func (ctrl *Controller) ensureVectorAgentDaemonSet(ctx context.Context) error {
@@ -117,7 +117,7 @@ func (ctrl *Controller) ensureVectorAgentDaemonSet(ctx context.Context) error {
vectorAgentDaemonSet := ctrl.createVectorAgentDaemonSet()
- return k8s.CreateOrUpdateDaemonSet(ctx, vectorAgentDaemonSet, ctrl.Client)
+ return k8s.CreateOrUpdateResource(ctx, vectorAgentDaemonSet, ctrl.Client)
}
func (ctrl *Controller) labelsForVectorAgent() map[string]string {
From b8b499c7ed16a9de8abda50b2071918ed210e131 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 11 Nov 2022 11:36:03 +0200
Subject: [PATCH 086/316] Cleanup k8s utils
Signed-off-by: Zemtsov Vladimir
---
controllers/factory/utils/k8s/k8s.go | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index be7242af..6706c24a 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -45,8 +45,7 @@ func NewNotSupportedError(obj client.Object) error {
func CreateOrUpdateResource(ctx context.Context, obj client.Object, c client.Client) error {
switch obj.(type) {
case *appsv1.Deployment:
- runtimeObj := obj.DeepCopyObject()
- return createOrUpdateDeployment(ctx, runtimeObj, c)
+ return createOrUpdateDeployment(ctx, obj, c)
case *appsv1.StatefulSet:
return createOrUpdateStatefulSet(ctx, obj, c)
case *appsv1.DaemonSet:
@@ -56,8 +55,7 @@ func CreateOrUpdateResource(ctx context.Context, obj client.Object, c client.Cli
case *corev1.Service:
return createOrUpdateService(ctx, obj, c)
case *corev1.ServiceAccount:
- runtimeObj := obj.DeepCopyObject()
- return createOrUpdateServiceAccount(ctx, runtimeObj, c)
+ return createOrUpdateServiceAccount(ctx, obj, c)
case *rbacv1.ClusterRole:
return createOrUpdateClusterRole(ctx, obj, c)
case *rbacv1.ClusterRoleBinding:
From 7239cabfd6e1bcad5390322023682334bc36c70e Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Sat, 12 Nov 2022 09:49:46 +0200
Subject: [PATCH 087/316] first commit
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index ac393f96..7e3ff295 100644
--- a/README.md
+++ b/README.md
@@ -115,3 +115,4 @@ make manifests
More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html)
+# lighthouse-role
From 49fae632d446178f4e367c7c92798f3ae6a8f642 Mon Sep 17 00:00:00 2001
From: Vladimir <31961982+zvlb@users.noreply.github.com>
Date: Sat, 12 Nov 2022 09:53:45 +0200
Subject: [PATCH 088/316] Update README.md
Fix mistake
---
README.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/README.md b/README.md
index 7e3ff295..998e05c2 100644
--- a/README.md
+++ b/README.md
@@ -114,5 +114,3 @@ make manifests
**NOTE:** Run `make --help` for more information on all potential `make` targets
More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html)
-
-# lighthouse-role
From 01269f5b9a8d9bc20e60a1124eda2a33b4844d26 Mon Sep 17 00:00:00 2001
From: Ilya Batyukov
Date: Tue, 15 Nov 2022 11:09:10 +0300
Subject: [PATCH 089/316] try to add vectorpipeline & clustervectorpipeline
---
helm/templates/clustervectorpipeline.yaml | 8 ++++++++
helm/templates/vectorpipeline.yaml | 8 ++++++++
helm/values.yaml | 8 ++++++++
3 files changed, 24 insertions(+)
create mode 100644 helm/templates/clustervectorpipeline.yaml
create mode 100644 helm/templates/vectorpipeline.yaml
diff --git a/helm/templates/clustervectorpipeline.yaml b/helm/templates/clustervectorpipeline.yaml
new file mode 100644
index 00000000..f8fd5dfa
--- /dev/null
+++ b/helm/templates/clustervectorpipeline.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.ClusterVectorPipeline -}}
+apiVersion: observability.kaasops.io/v1alpha1
+kind: ClusterVectorPipeline
+metadata:
+ name: {{ .Values.ClusterVectorPipeline.name }}
+spec:
+{{- toYaml .Values.ClusterVectorPipeline.spec | nindent 2 }}
+ {{- end }}
\ No newline at end of file
diff --git a/helm/templates/vectorpipeline.yaml b/helm/templates/vectorpipeline.yaml
new file mode 100644
index 00000000..55142a87
--- /dev/null
+++ b/helm/templates/vectorpipeline.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.VectorPipeline -}}
+apiVersion: observability.kaasops.io/v1alpha1
+kind: VectorPipeline
+metadata:
+ name: {{ .Values.VectorPipeline.name }}
+spec:
+{{- toYaml .Values.VectorPipeline.spec | nindent 2 }}
+ {{- end }}
\ No newline at end of file
diff --git a/helm/values.yaml b/helm/values.yaml
index 27e12d31..f2127b2e 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -29,3 +29,11 @@ serviceAccount:
create: false
name: "vector-operator"
annotations: {}
+
+ClusterVectorPipeline:
+ name: test1
+ spec: {}
+
+VectorPipeline:
+ name: test12
+ spec: {}
From 06e616379588fed1a4b6be355c6dee818a0999ae Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Tue, 15 Nov 2022 10:48:25 +0200
Subject: [PATCH 090/316] fix namespace validate logic (#44)
---
controllers/factory/config/config_build.go | 20 ++++++++++++++------
controllers/factory/config/types.go | 2 +-
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/controllers/factory/config/config_build.go b/controllers/factory/config/config_build.go
index 8512d3ea..be158360 100644
--- a/controllers/factory/config/config_build.go
+++ b/controllers/factory/config/config_build.go
@@ -44,6 +44,11 @@ var (
}
)
+var (
+ PipelineTypeError error = errors.New("type kubernetes_logs only allowed")
+ PipelineScopeError error = errors.New("logs from external namespace not allowed")
+)
+
type Builder struct {
Name string
vaCtrl *vectoragent.Controller
@@ -72,7 +77,6 @@ func (b *Builder) GetByteConfig() ([]byte, error) {
}
func (b *Builder) GetByteConfigWithValidate() ([]byte, error) {
- validateError := errors.New("type kubernetes_logs only allowed")
config, err := b.generateVectorConfig()
if err != nil {
return nil, err
@@ -82,10 +86,12 @@ func (b *Builder) GetByteConfigWithValidate() ([]byte, error) {
for _, source := range config.Sources {
if pipeline.Type() != vectorv1alpha1.ClusterPipelineKind {
if source.Type != KubernetesSourceType {
- return nil, validateError
+ return nil, PipelineTypeError
}
- if source.ExtraNamespaceLabelSelector != "" && source.ExtraNamespaceLabelSelector != k8s.NamespaceNameToLabel(pipeline.GetNamespace()) {
- return nil, validateError
+ if source.ExtraNamespaceLabelSelector != "" {
+ if source.ExtraNamespaceLabelSelector != k8s.NamespaceNameToLabel(pipeline.GetNamespace()) {
+ return nil, PipelineScopeError
+ }
}
}
}
@@ -131,8 +137,10 @@ func (b *Builder) getComponents() (sources []*Source, transforms []*Transform, s
if err != nil {
return nil, nil, nil, err
}
- if pipeline.Type() != vectorv1alpha1.ClusterPipelineKind && source.Type == KubernetesSourceType {
- source.ExtraNamespaceLabelSelector = k8s.NamespaceNameToLabel(pipeline.GetNamespace())
+ if source.Type == KubernetesSourceType {
+ if pipeline.Type() != vectorv1alpha1.ClusterPipelineKind && source.ExtraNamespaceLabelSelector == "" {
+ source.ExtraNamespaceLabelSelector = k8s.NamespaceNameToLabel(pipeline.GetNamespace())
+ }
}
sources = append(sources, source)
}
diff --git a/controllers/factory/config/types.go b/controllers/factory/config/types.go
index d62ca2a5..834e4ede 100644
--- a/controllers/factory/config/types.go
+++ b/controllers/factory/config/types.go
@@ -31,7 +31,7 @@ type VectorConfig struct {
type Source struct {
Name string
Type string `mapper:"type"`
- ExtraNamespaceLabelSelector string `mapper:"extra_namespace_label_selector,omitempty"`
+ ExtraNamespaceLabelSelector string `mapstructure:"extra_namespace_label_selector" mapper:"extra_namespace_label_selector,omitempty"`
Options map[string]interface{} `mapstructure:",remain"`
}
From 800aff4c0f7ba5a6e7bf32e8d4960da6c598f4a7 Mon Sep 17 00:00:00 2001
From: Denis Khachyan
Date: Tue, 15 Nov 2022 10:51:02 +0200
Subject: [PATCH 091/316] GetPodLogs test (#45)
---
controllers/factory/utils/k8s/k8s.go | 2 +-
controllers/factory/utils/k8s/k8s_test.go | 40 +++++++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/controllers/factory/utils/k8s/k8s.go b/controllers/factory/utils/k8s/k8s.go
index 6706c24a..31e2666d 100644
--- a/controllers/factory/utils/k8s/k8s.go
+++ b/controllers/factory/utils/k8s/k8s.go
@@ -411,7 +411,7 @@ func DeleteSecret(ctx context.Context, secret *corev1.Secret, c client.Client) e
return nil
}
-func GetPodLogs(ctx context.Context, pod *corev1.Pod, cs *kubernetes.Clientset) (string, error) {
+func GetPodLogs(ctx context.Context, pod *corev1.Pod, cs kubernetes.Interface) (string, error) {
count := int64(100)
podLogOptions := corev1.PodLogOptions{
TailLines: &count,
diff --git a/controllers/factory/utils/k8s/k8s_test.go b/controllers/factory/utils/k8s/k8s_test.go
index cb5fe3e6..c2c71975 100644
--- a/controllers/factory/utils/k8s/k8s_test.go
+++ b/controllers/factory/utils/k8s/k8s_test.go
@@ -32,6 +32,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
+ fakeclientset "k8s.io/client-go/kubernetes/fake"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)
@@ -1043,3 +1044,42 @@ func TestNamespaceNameToLabel(t *testing.T) {
t.Run(tc.name, namespaceNameToLabelCase(tc.in, tc.want))
}
}
+
+func TestGetPodLogs(t *testing.T) {
+ getPodLogsCase := func(initPod, pod *corev1.Pod, want string, err error) func(t *testing.T) {
+ return func(t *testing.T) {
+ t.Helper()
+ t.Parallel()
+ req := require.New(t)
+ clientset := fakeclientset.NewSimpleClientset(initPod)
+ result, err1 := k8s.GetPodLogs(context.TODO(), pod, clientset)
+ if result != "" {
+ req.Equal(result, want)
+ }
+ req.Equal(err1, err)
+ }
+ }
+ type testCase struct {
+ name string
+ initPod *corev1.Pod
+ pod *corev1.Pod
+ want string
+ err error
+ }
+ testCases := []testCase{
+ {
+ name: "Simple case",
+ initPod: &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ pod: &corev1.Pod{
+ ObjectMeta: getInitObjectMeta(),
+ },
+ want: "fake logs",
+ err: nil,
+ },
+ }
+ for _, tc := range testCases {
+ t.Run(tc.name, getPodLogsCase(tc.initPod, tc.pod, tc.want, tc.err))
+ }
+}
From 91b4bf108880bb8f92ee67ec4f4775d7e0ef75f5 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Tue, 15 Nov 2022 11:04:15 +0200
Subject: [PATCH 092/316] Update changelog for release
Signed-off-by: Zemtsov Vladimir
---
CHANGELOG.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7c0205cb..873a06b3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,8 @@
### Added
+- [[45](https://github.com/kaasops/vector-operator/pull/45)] **Tests**: Add tests for k8s utils && refactor k8s utils
+- [[44](https://github.com/kaasops/vector-operator/pull/44)] **Features**: Add validations errors for VectorPipeline
+- [[37](https://github.com/kaasops/vector-operator/pull/37)] **Cleanup**: Fix context-in-struct warning
+- [[32](https://github.com/kaasops/vector-operator/pull/32)] **Refactor**: Config build refactoring
- [[40](https://github.com/kaasops/vector-operator/pull/40)] **Fix**: Sloved context forward errors
From b68f3c58dd5285b186ac90722a9b02db1bac9b57 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Tue, 15 Nov 2022 11:05:25 +0200
Subject: [PATCH 093/316] Release changelog
Signed-off-by: Zemtsov Vladimir
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 873a06b3..333c3b53 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,7 @@
### Added
+
+
+### v0.0.2
- [[45](https://github.com/kaasops/vector-operator/pull/45)] **Tests**: Add tests for k8s utils && refactor k8s utils
- [[44](https://github.com/kaasops/vector-operator/pull/44)] **Features**: Add validations errors for VectorPipeline
- [[37](https://github.com/kaasops/vector-operator/pull/37)] **Cleanup**: Fix context-in-struct warning
From 4803492d062311b3e3439662070dcad45ef12d00 Mon Sep 17 00:00:00 2001
From: Ilya Batyukov
Date: Wed, 16 Nov 2022 15:04:41 +0300
Subject: [PATCH 094/316] try to add vectorpipeline & clustervectorpipeline
---
helm/templates/clustervectorpipeline.yaml | 21 ++++++++++-----
helm/templates/vector.yaml | 15 +++++++++++
helm/templates/vectorpipeline.yaml | 17 ++++++++----
helm/values.yaml | 33 +++++++++++++++++++----
4 files changed, 70 insertions(+), 16 deletions(-)
create mode 100644 helm/templates/vector.yaml
diff --git a/helm/templates/clustervectorpipeline.yaml b/helm/templates/clustervectorpipeline.yaml
index f8fd5dfa..f4ef2b8d 100644
--- a/helm/templates/clustervectorpipeline.yaml
+++ b/helm/templates/clustervectorpipeline.yaml
@@ -1,8 +1,17 @@
-{{- if .Values.ClusterVectorPipeline -}}
+{{- range $pipeline := .Values.ClusterVectorPipeline }}
apiVersion: observability.kaasops.io/v1alpha1
kind: ClusterVectorPipeline
-metadata:
- name: {{ .Values.ClusterVectorPipeline.name }}
-spec:
-{{- toYaml .Values.ClusterVectorPipeline.spec | nindent 2 }}
- {{- end }}
\ No newline at end of file
+metadata:
+ name: {{ $pipeline.name }}
+spec:
+ sources:
+ {{ toYaml $pipeline.sources | nindent 6 }}
+ transforms:
+ {{ toYaml $pipeline.sources | nindent 6 }}
+ sinks:
+ {{ toYaml $pipeline.sources | nindent 6 }}
+---
+{{- end }}
+
+
+
diff --git a/helm/templates/vector.yaml b/helm/templates/vector.yaml
new file mode 100644
index 00000000..95288e21
--- /dev/null
+++ b/helm/templates/vector.yaml
@@ -0,0 +1,15 @@
+{{- if .Values.vector.create -}}
+apiVersion: observability.kaasops.io/v1alpha1
+kind: Vector
+metadata:
+ name: {{ .Values.vector.name }}
+ namespace: vector-operator-system
+spec:
+ agent:
+ service: true
+ image: "timberio/vector:0.24.0-distroless-libc"
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/helm/templates/vectorpipeline.yaml b/helm/templates/vectorpipeline.yaml
index 55142a87..c4bc1439 100644
--- a/helm/templates/vectorpipeline.yaml
+++ b/helm/templates/vectorpipeline.yaml
@@ -1,8 +1,15 @@
-{{- if .Values.VectorPipeline -}}
+{{- range $pipeline := .Values.VectorPipeline }}
apiVersion: observability.kaasops.io/v1alpha1
kind: VectorPipeline
metadata:
- name: {{ .Values.VectorPipeline.name }}
-spec:
-{{- toYaml .Values.VectorPipeline.spec | nindent 2 }}
- {{- end }}
\ No newline at end of file
+ name: {{ $pipeline.name }}
+ namespace: {{ $pipeline.nanamespace }}
+spec:
+ sources:
+ {{ toYaml $pipeline.sources | nindent 6 }}
+ transforms:
+ {{ toYaml $pipeline.sources | nindent 6 }}
+ sinks:
+ {{ toYaml $pipeline.sources | nindent 6 }}
+---
+{{- end }}
diff --git a/helm/values.yaml b/helm/values.yaml
index f2127b2e..dc307874 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -25,15 +25,38 @@ resources:
rbac:
create: true
+vector:
+ create: true
+ name: "vector-agent"
+ tolerations: []
+
+
serviceAccount:
create: false
name: "vector-operator"
annotations: {}
-ClusterVectorPipeline:
- name: test1
- spec: {}
+ClusterVectorPipeline:
+ - name: ""
+ sources: {}
+ transforms: {}
+ sinks: {}
+ - name: ""
+ sources: {}
+ transforms: {}
+ sinks: {}
VectorPipeline:
- name: test12
- spec: {}
+ - name: ""
+ namespace: ""
+ sources: {}
+ transforms: {}
+ sinks: {}
+ - name: ""
+ namespace: ""
+ sources: {}
+ transforms: {}
+ sinks: {}
+
+
+
From 4b7af593744016d1492391dec5c6f971f5f9c684 Mon Sep 17 00:00:00 2001
From: Ilya Batyukov
Date: Wed, 16 Nov 2022 15:18:34 +0300
Subject: [PATCH 095/316] fix ClusterVectorPipeline
---
helm/templates/clustervectorpipeline.yaml | 4 ++--
helm/templates/vectorpipeline.yaml | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/helm/templates/clustervectorpipeline.yaml b/helm/templates/clustervectorpipeline.yaml
index f4ef2b8d..9cb635b8 100644
--- a/helm/templates/clustervectorpipeline.yaml
+++ b/helm/templates/clustervectorpipeline.yaml
@@ -7,9 +7,9 @@ spec:
sources:
{{ toYaml $pipeline.sources | nindent 6 }}
transforms:
- {{ toYaml $pipeline.sources | nindent 6 }}
+ {{ toYaml $pipeline.transforms | nindent 6 }}
sinks:
- {{ toYaml $pipeline.sources | nindent 6 }}
+ {{ toYaml $pipeline.transforms | nindent 6 }}
---
{{- end }}
diff --git a/helm/templates/vectorpipeline.yaml b/helm/templates/vectorpipeline.yaml
index c4bc1439..4496441d 100644
--- a/helm/templates/vectorpipeline.yaml
+++ b/helm/templates/vectorpipeline.yaml
@@ -8,8 +8,8 @@ spec:
sources:
{{ toYaml $pipeline.sources | nindent 6 }}
transforms:
- {{ toYaml $pipeline.sources | nindent 6 }}
+ {{ toYaml $pipeline.transforms | nindent 6 }}
sinks:
- {{ toYaml $pipeline.sources | nindent 6 }}
+ {{ toYaml $pipeline.transforms | nindent 6 }}
---
{{- end }}
From 449623656148597e1938d3c8a76c6e94b03afc81 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Wed, 16 Nov 2022 16:36:31 +0200
Subject: [PATCH 096/316] Fix error with envs forfarding from CR Vector
Signed-off-by: Zemtsov Vladimir
---
.../factory/vector/vectoragent/vectoragent_daemonset.go | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/controllers/factory/vector/vectoragent/vectoragent_daemonset.go b/controllers/factory/vector/vectoragent/vectoragent_daemonset.go
index 6351b703..deccbcaa 100644
--- a/controllers/factory/vector/vectoragent/vectoragent_daemonset.go
+++ b/controllers/factory/vector/vectoragent/vectoragent_daemonset.go
@@ -156,7 +156,9 @@ func (ctrl *Controller) generateVectorAgentVolumeMounts() []corev1.VolumeMount {
}
func (ctrl *Controller) generateVectorAgentEnvs() []corev1.EnvVar {
- envs := []corev1.EnvVar{
+ envs := ctrl.Vector.Spec.Agent.Env
+
+ envs = append(envs, []corev1.EnvVar{
{
Name: "VECTOR_SELF_NODE_NAME",
ValueFrom: &corev1.EnvVarSource{
@@ -192,7 +194,7 @@ func (ctrl *Controller) generateVectorAgentEnvs() []corev1.EnvVar {
Name: "SYSFS_ROOT",
Value: "/host/sys",
},
- }
+ }...)
return envs
}
From c33aa749db03abf1b388923284b02ddf8dc8bc41 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Wed, 16 Nov 2022 16:37:55 +0200
Subject: [PATCH 097/316] Update changelog
Signed-off-by: Zemtsov Vladimir
---
CHANGELOG.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 333c3b53..7f256bb1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
### Added
+### v0.0.3
+- [[46](https://github.com/kaasops/vector-operator/pull/46)] **Fix**: Fix error with envs forwarding from CR Vector
### v0.0.2
- [[45](https://github.com/kaasops/vector-operator/pull/45)] **Tests**: Add tests for k8s utils && refactor k8s utils
From fbe2920a2e985112e9301cbdf0ebc83aa2682c0f Mon Sep 17 00:00:00 2001
From: Ilya Batyukov
Date: Thu, 17 Nov 2022 13:54:26 +0300
Subject: [PATCH 098/316] small fix
---
helm/Chart.yaml | 2 +-
helm/templates/_helpers.tpl | 33 ++++++++++--------------------
helm/templates/deployment.yaml | 15 +++++++-------
helm/templates/rbac.yaml | 19 ++++++++---------
helm/templates/serviceaccount.yaml | 3 +--
helm/templates/vector.yaml | 1 -
helm/templates/vectorpipeline.yaml | 1 -
helm/values.yaml | 12 ++++++-----
8 files changed, 36 insertions(+), 50 deletions(-)
diff --git a/helm/Chart.yaml b/helm/Chart.yaml
index 39087628..f6bba612 100644
--- a/helm/Chart.yaml
+++ b/helm/Chart.yaml
@@ -1,6 +1,6 @@
apiVersion: v2
name: vector-operator
-description: A Helm chart A Helm chart to install vector-operator
+description: A Helm chart to install vector-operator
# A chart can be either an 'application' or a 'library' chart.
#
diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl
index dc13106d..6e03383e 100644
--- a/helm/templates/_helpers.tpl
+++ b/helm/templates/_helpers.tpl
@@ -5,6 +5,15 @@ Expand the name of the chart.
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
+{{- define "vector-operator.namespace" -}}
+{{- if .Values.namespaceOverride -}}
+{{ .Values.namespaceOverride -}}
+{{- else -}}
+{{ .Release.Namespace }}
+{{- end -}}
+{{- end -}}
+
+
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
@@ -30,33 +39,13 @@ Create chart name and version as used by the chart label.
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
-{{/*
-Common labels
-*/}}
-{{- define "vector-operator.labels" -}}
-helm.sh/chart: {{ include "vector-operator.chart" . }}
-{{ include "vector-operator.selectorLabels" . }}
-{{- if .Chart.AppVersion }}
-app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
-{{- end }}
-app.kubernetes.io/managed-by: {{ .Release.Service }}
-{{- end }}
-
-{{/*
-Selector labels
-*/}}
-{{- define "vector-operator.selectorLabels" -}}
-app.kubernetes.io/name: {{ include "vector-operator.name" . }}
-app.kubernetes.io/instance: {{ .Release.Name }}
-{{- end }}
-
{{/*
Create the name of the service account to use
*/}}
{{- define "vector-operator.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
-{{- default (include "vector-operator.fullname" .) .Values.serviceAccount.name }}
+{{- default .Values.serviceAccount.name }}
{{- else }}
-{{- default "default" .Values.serviceAccount.name }}
+{{- default (include "vector-operator.fullname" .) }}
{{- end }}
{{- end }}
diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml
index 413f679f..4637d52f 100644
--- a/helm/templates/deployment.yaml
+++ b/helm/templates/deployment.yaml
@@ -1,20 +1,20 @@
apiVersion: apps/v1
kind: Deployment
metadata:
- name: vector-operator
- namespace: vector-operator-system
+ name: {{ include "vector-operator.name" . }}
+ namespace: {{ include "vector-operator.namespace" . }}
labels:
- app.kubernetes.io/name: vector-operator
+ app.kubernetes.io/name: {{ include "vector-operator.name" . }}
spec:
selector:
matchLabels:
- app.kubernetes.io/name: vector-operator
+ app.kubernetes.io/name: {{ include "vector-operator.name" . }}
template:
metadata:
labels:
- app.kubernetes.io/name: vector-operator
+ app.kubernetes.io/name: {{ include "vector-operator.name" . }}
app.kubernetes.io/managed-by: "helm"
- meta.helm.sh/release-name: vector-operator
+ meta.helm.sh/release-name: {{ include "vector-operator.name" . }}
spec:
volumes:
- name: kube-api-access
@@ -22,8 +22,7 @@ spec:
secretName: vector-operator-sa-token
defaultMode: 420
automountServiceAccountToken: false
- serviceAccount: vector-operator
- serviceAccountName: vector-operator
+ serviceAccountName: {{ include "vector-operator.serviceAccountName" . }}
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
diff --git a/helm/templates/rbac.yaml b/helm/templates/rbac.yaml
index 80e0dd23..220effe3 100644
--- a/helm/templates/rbac.yaml
+++ b/helm/templates/rbac.yaml
@@ -1,4 +1,4 @@
-{{- if .Values.rbac.create -}}
+{{- if .Values.rbac.create -}}
---
{{- if semverCompare ">= 1.24" .Capabilities.KubeVersion.Version }}
@@ -6,9 +6,8 @@ apiVersion: v1
kind: Secret
metadata:
name: vector-operator-sa-token
- namespace: vector-operator-system
annotations:
- kubernetes.io/service-account.name: vector-operator
+ kubernetes.io/service-account.name: {{ include "vector-operator.serviceAccountName" . }}
type: kubernetes.io/service-account-token
{{- end }}
@@ -16,8 +15,7 @@ type: kubernetes.io/service-account-token
apiVersion: v1
kind: ServiceAccount
metadata:
- name: vector-operator
- namespace: vector-operator-system
+ name: {{ include "vector-operator.serviceAccountName" . }}
secrets:
- name: vector-operator-sa-token
@@ -25,21 +23,22 @@ secrets:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
- name: vector-operator
+ name: {{ include "vector-operator.name" . }}
+
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
- name: vector-operator
+ name: {{ include "vector-operator.name" . }}
subjects:
- kind: ServiceAccount
- name: vector-operator
- namespace: vector-operator-system
+ name: {{ include "vector-operator.name" . }}
+ namespace: {{ include "vector-operator.namespace" . }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
- name: vector-operator
+ name: {{ include "vector-operator.name" . }}
rules:
- apiGroups:
- ""
diff --git a/helm/templates/serviceaccount.yaml b/helm/templates/serviceaccount.yaml
index 20822842..06a9ae6b 100644
--- a/helm/templates/serviceaccount.yaml
+++ b/helm/templates/serviceaccount.yaml
@@ -2,8 +2,7 @@
apiVersion: v1
kind: ServiceAccount
metadata:
- name: {{ toYaml .Values.serviceAccount.name | nindent 4 }}
- namespace: vector-operator-system
+ name: {{ include "vector-operator.serviceAccountName" . }}
{{- if .Values.serviceAccount.annotations }}
annotations:
{{ toYaml .Values.serviceAccount.annotations | nindent 4 }}
diff --git a/helm/templates/vector.yaml b/helm/templates/vector.yaml
index 95288e21..17f708b9 100644
--- a/helm/templates/vector.yaml
+++ b/helm/templates/vector.yaml
@@ -3,7 +3,6 @@ apiVersion: observability.kaasops.io/v1alpha1
kind: Vector
metadata:
name: {{ .Values.vector.name }}
- namespace: vector-operator-system
spec:
agent:
service: true
diff --git a/helm/templates/vectorpipeline.yaml b/helm/templates/vectorpipeline.yaml
index 4496441d..3faad7c1 100644
--- a/helm/templates/vectorpipeline.yaml
+++ b/helm/templates/vectorpipeline.yaml
@@ -3,7 +3,6 @@ apiVersion: observability.kaasops.io/v1alpha1
kind: VectorPipeline
metadata:
name: {{ $pipeline.name }}
- namespace: {{ $pipeline.nanamespace }}
spec:
sources:
{{ toYaml $pipeline.sources | nindent 6 }}
diff --git a/helm/values.yaml b/helm/values.yaml
index dc307874..46c44ab5 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -1,3 +1,7 @@
+fullnameOverride: ""
+nameOverride: ""
+namespaceOverride: ""
+
image:
repository: kaasops/vector-operator
tag: "latest"
@@ -17,7 +21,7 @@ image:
resources:
limits:
cpu: "2"
- memory: 1Gi
+ memory: 2Gi
requests:
cpu: 100m
memory: 50Mi
@@ -27,13 +31,13 @@ rbac:
vector:
create: true
- name: "vector-agent"
+ name: ""
tolerations: []
serviceAccount:
create: false
- name: "vector-operator"
+ name: ""
annotations: {}
ClusterVectorPipeline:
@@ -48,12 +52,10 @@ ClusterVectorPipeline:
VectorPipeline:
- name: ""
- namespace: ""
sources: {}
transforms: {}
sinks: {}
- name: ""
- namespace: ""
sources: {}
transforms: {}
sinks: {}
From 1b79827c1388f876b05a45def93110d5e59f375d Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 17 Nov 2022 16:37:59 +0200
Subject: [PATCH 099/316] Update helm
Signed-off-by: Zemtsov Vladimir
---
helm/Chart.yaml | 6 +-
...ity.kaasops.io_clustervectorpipelines.yaml | 73 +++++++++
...ervability.kaasops.io_vectorpipelines.yaml | 72 +++++++++
.../observability.kaasops.io_vectors.yaml} | 149 +-----------------
helm/templates/_helpers.tpl | 76 +++++----
.../templates/{rbac.yaml => clusterrole.yaml} | 52 ++----
helm/templates/clusterrolebinding.yaml | 25 +++
helm/templates/clustervectorpipeline.yaml | 3 +-
helm/templates/deployment.yaml | 41 +++--
helm/templates/monitor.yaml | 18 ---
helm/templates/serviceaccount.yaml | 27 +++-
helm/templates/vector.yaml | 14 +-
helm/values.yaml | 103 ++++++------
13 files changed, 348 insertions(+), 311 deletions(-)
create mode 100644 helm/crds/observability.kaasops.io_clustervectorpipelines.yaml
create mode 100644 helm/crds/observability.kaasops.io_vectorpipelines.yaml
rename helm/{templates/crds.yaml => crds/observability.kaasops.io_vectors.yaml} (94%)
rename helm/templates/{rbac.yaml => clusterrole.yaml} (56%)
create mode 100644 helm/templates/clusterrolebinding.yaml
delete mode 100644 helm/templates/monitor.yaml
diff --git a/helm/Chart.yaml b/helm/Chart.yaml
index f6bba612..e664fec8 100644
--- a/helm/Chart.yaml
+++ b/helm/Chart.yaml
@@ -1,6 +1,6 @@
apiVersion: v2
name: vector-operator
-description: A Helm chart to install vector-operator
+description: A Helm chart to install Vector Operator
# A chart can be either an 'application' or a 'library' chart.
#
@@ -21,8 +21,8 @@ version: 0.0.1
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
-appVersion: "0.0.1"
+appVersion: "v0.0.3"
home: https://github.com/kaasops/vector-operator
sources:
- - https://github.com/kaasops/vector-operator
\ No newline at end of file
+ - https://github.com/kaasops/vector-operator
diff --git a/helm/crds/observability.kaasops.io_clustervectorpipelines.yaml b/helm/crds/observability.kaasops.io_clustervectorpipelines.yaml
new file mode 100644
index 00000000..715b8145
--- /dev/null
+++ b/helm/crds/observability.kaasops.io_clustervectorpipelines.yaml
@@ -0,0 +1,73 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.9.2
+ creationTimestamp: null
+ name: clustervectorpipelines.observability.kaasops.io
+spec:
+ group: observability.kaasops.io
+ names:
+ kind: ClusterVectorPipeline
+ listKind: ClusterVectorPipelineList
+ plural: clustervectorpipelines
+ shortNames:
+ - cvp
+ singular: clustervectorpipeline
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ - jsonPath: .status.configCheckResult
+ name: Valid
+ type: boolean
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: ClusterVectorPipeline is the Schema for the clustervectorpipelines
+ API
+ 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: VectorPipelineSpec defines the desired state of VectorPipeline
+ properties:
+ sinks:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ sources:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ transforms:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ status:
+ description: VectorPipelineStatus defines the observed state of VectorPipeline
+ properties:
+ LastAppliedPipelineHash:
+ format: int32
+ type: integer
+ configCheckResult:
+ type: boolean
+ reason:
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/helm/crds/observability.kaasops.io_vectorpipelines.yaml b/helm/crds/observability.kaasops.io_vectorpipelines.yaml
new file mode 100644
index 00000000..e40dd908
--- /dev/null
+++ b/helm/crds/observability.kaasops.io_vectorpipelines.yaml
@@ -0,0 +1,72 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.9.2
+ creationTimestamp: null
+ name: vectorpipelines.observability.kaasops.io
+spec:
+ group: observability.kaasops.io
+ names:
+ kind: VectorPipeline
+ listKind: VectorPipelineList
+ plural: vectorpipelines
+ shortNames:
+ - vp
+ singular: vectorpipeline
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ - jsonPath: .status.configCheckResult
+ name: Valid
+ type: boolean
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: VectorPipeline is the Schema for the vectorpipelines API
+ 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: VectorPipelineSpec defines the desired state of VectorPipeline
+ properties:
+ sinks:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ sources:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ transforms:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ status:
+ description: VectorPipelineStatus defines the observed state of VectorPipeline
+ properties:
+ LastAppliedPipelineHash:
+ format: int32
+ type: integer
+ configCheckResult:
+ type: boolean
+ reason:
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/helm/templates/crds.yaml b/helm/crds/observability.kaasops.io_vectors.yaml
similarity index 94%
rename from helm/templates/crds.yaml
rename to helm/crds/observability.kaasops.io_vectors.yaml
index 2f16cfeb..1bc130b3 100644
--- a/helm/templates/crds.yaml
+++ b/helm/crds/observability.kaasops.io_vectors.yaml
@@ -1,153 +1,6 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.9.2
- creationTimestamp: null
- name: clustervectorpipelines.observability.kaasops.io
-spec:
- group: observability.kaasops.io
- names:
- kind: ClusterVectorPipeline
- listKind: ClusterVectorPipelineList
- plural: clustervectorpipelines
- shortNames:
- - cvp
- singular: clustervectorpipeline
- scope: Namespaced
- versions:
- - additionalPrinterColumns:
- - jsonPath: .metadata.creationTimestamp
- name: Age
- type: date
- - jsonPath: .status.configCheckResult
- name: Valid
- type: boolean
- name: v1alpha1
- schema:
- openAPIV3Schema:
- description: ClusterVectorPipeline is the Schema for the clustervectorpipelines
- API
- 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: VectorPipelineSpec defines the desired state of VectorPipeline
- properties:
- sinks:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- sources:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- transforms:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- type: object
- status:
- description: VectorPipelineStatus defines the observed state of VectorPipeline
- properties:
- LastAppliedPipelineHash:
- format: int32
- type: integer
- configCheckResult:
- type: boolean
- reason:
- type: string
- type: object
- type: object
- served: true
- storage: true
- subresources:
- status: {}
----
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.9.2
- creationTimestamp: null
- name: vectorpipelines.observability.kaasops.io
-spec:
- group: observability.kaasops.io
- names:
- kind: VectorPipeline
- listKind: VectorPipelineList
- plural: vectorpipelines
- shortNames:
- - vp
- singular: vectorpipeline
- scope: Namespaced
- versions:
- - additionalPrinterColumns:
- - jsonPath: .metadata.creationTimestamp
- name: Age
- type: date
- - jsonPath: .status.configCheckResult
- name: Valid
- type: boolean
- name: v1alpha1
- schema:
- openAPIV3Schema:
- description: VectorPipeline is the Schema for the vectorpipelines API
- 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: VectorPipelineSpec defines the desired state of VectorPipeline
- properties:
- sinks:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- sources:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- transforms:
- type: object
- x-kubernetes-preserve-unknown-fields: true
- type: object
- status:
- description: VectorPipelineStatus defines the observed state of VectorPipeline
- properties:
- LastAppliedPipelineHash:
- format: int32
- type: integer
- configCheckResult:
- type: boolean
- reason:
- type: string
- type: object
- type: object
- served: true
- storage: true
- subresources:
- status: {}
----
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.2
@@ -1503,4 +1356,4 @@ spec:
served: true
storage: true
subresources:
- status: {}
+ status: {}
diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl
index 6e03383e..c1589807 100644
--- a/helm/templates/_helpers.tpl
+++ b/helm/templates/_helpers.tpl
@@ -1,51 +1,63 @@
+{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
-{{- define "vector-operator.name" -}}
-{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
-{{- end }}
-
-{{- define "vector-operator.namespace" -}}
-{{- if .Values.namespaceOverride -}}
-{{ .Values.namespaceOverride -}}
-{{- else -}}
-{{ .Release.Namespace }}
-{{- end -}}
+{{- define "chart.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
-
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
-{{- define "vector-operator.fullname" -}}
-{{- if .Values.fullnameOverride }}
-{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
-{{- else }}
-{{- $name := default .Chart.Name .Values.nameOverride }}
-{{- if contains $name .Release.Name }}
-{{- .Release.Name | trunc 63 | trimSuffix "-" }}
-{{- else }}
-{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
-{{- end }}
-{{- end }}
-{{- end }}
+{{- define "chart.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
-{{- define "vector-operator.chart" -}}
-{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- define "chart.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "chart.labels" -}}
+helm.sh/chart: {{ include "chart.chart" . }}
+{{ include "chart.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "chart.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "chart.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
{{/*
Create the name of the service account to use
*/}}
-{{- define "vector-operator.serviceAccountName" -}}
-{{- if .Values.serviceAccount.create }}
-{{- default .Values.serviceAccount.name }}
-{{- else }}
-{{- default (include "vector-operator.fullname" .) }}
-{{- end }}
-{{- end }}
+{{- define "chart.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+ {{ default (include "chart.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+ {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/helm/templates/rbac.yaml b/helm/templates/clusterrole.yaml
similarity index 56%
rename from helm/templates/rbac.yaml
rename to helm/templates/clusterrole.yaml
index 220effe3..fdf9170f 100644
--- a/helm/templates/rbac.yaml
+++ b/helm/templates/clusterrole.yaml
@@ -1,44 +1,18 @@
{{- if .Values.rbac.create -}}
-
----
-{{- if semverCompare ">= 1.24" .Capabilities.KubeVersion.Version }}
-apiVersion: v1
-kind: Secret
-metadata:
- name: vector-operator-sa-token
- annotations:
- kubernetes.io/service-account.name: {{ include "vector-operator.serviceAccountName" . }}
-type: kubernetes.io/service-account-token
-{{- end }}
-
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: {{ include "vector-operator.serviceAccountName" . }}
-secrets:
- - name: vector-operator-sa-token
-
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: {{ include "vector-operator.name" . }}
-
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: {{ include "vector-operator.name" . }}
-subjects:
-- kind: ServiceAccount
- name: {{ include "vector-operator.name" . }}
- namespace: {{ include "vector-operator.namespace" . }}
-
----
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
- name: {{ include "vector-operator.name" . }}
+ name: {{ template "chart.fullname" . }}-clusterrole
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "chart.labels" . | nindent 4 }}
+{{- with .Values.rbac.extraLabels }}
+{{ toYaml . | indent 4}}
+{{- end }}
+ {{- with .Values.rbac.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
rules:
- apiGroups:
- ""
@@ -120,5 +94,5 @@ rules:
verbs:
- get
- patch
- - update
-{{- end }}
\ No newline at end of file
+ - update
+{{- end -}}
diff --git a/helm/templates/clusterrolebinding.yaml b/helm/templates/clusterrolebinding.yaml
new file mode 100644
index 00000000..25a9e074
--- /dev/null
+++ b/helm/templates/clusterrolebinding.yaml
@@ -0,0 +1,25 @@
+
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ template "chart.fullname" . }}-clusterrolebinding
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "chart.labels" . | nindent 4 }}
+{{- with .Values.rbac.extraLabels }}
+{{ toYaml . | indent 4}}
+{{- end }}
+ {{- with .Values.rbac.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ template "chart.fullname" . }}-clusterrole
+subjects:
+ - kind: ServiceAccount
+ name: {{ template "chart.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
+{{- end -}}
diff --git a/helm/templates/clustervectorpipeline.yaml b/helm/templates/clustervectorpipeline.yaml
index 9cb635b8..ceb9ff85 100644
--- a/helm/templates/clustervectorpipeline.yaml
+++ b/helm/templates/clustervectorpipeline.yaml
@@ -2,7 +2,8 @@
apiVersion: observability.kaasops.io/v1alpha1
kind: ClusterVectorPipeline
metadata:
- name: {{ $pipeline.name }}
+ name: {{ $pipeline.name }}
+ namespace: {{ .Release.Namespace }}
spec:
sources:
{{ toYaml $pipeline.sources | nindent 6 }}
diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml
index 4637d52f..c76c7587 100644
--- a/helm/templates/deployment.yaml
+++ b/helm/templates/deployment.yaml
@@ -1,30 +1,47 @@
apiVersion: apps/v1
kind: Deployment
metadata:
- name: {{ include "vector-operator.name" . }}
- namespace: {{ include "vector-operator.namespace" . }}
+ name: {{ include "chart.fullname" . }}
+ namespace: {{ .Release.Namespace }}
labels:
- app.kubernetes.io/name: {{ include "vector-operator.name" . }}
+ {{- include "chart.labels" . | nindent 4 }}
+{{- with .Values.extraLabels }}
+{{ toYaml . | indent 4 }}
+{{- end }}
+ {{- with .Values.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
spec:
+ replicas: {{ .Values.replicaCount }}
+ {{- with .Values.strategy }}
+ strategy:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
selector:
matchLabels:
- app.kubernetes.io/name: {{ include "vector-operator.name" . }}
+ {{- include "chart.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
- app.kubernetes.io/name: {{ include "vector-operator.name" . }}
- app.kubernetes.io/managed-by: "helm"
- meta.helm.sh/release-name: {{ include "vector-operator.name" . }}
+ {{- include "chart.selectorLabels" . | nindent 8 }}
spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
volumes:
- name: kube-api-access
secret:
- secretName: vector-operator-sa-token
+ secretName: {{ include "chart.serviceAccountName" . }}
defaultMode: 420
- automountServiceAccountToken: false
- serviceAccountName: {{ include "vector-operator.serviceAccountName" . }}
+ serviceAccountName: {{ include "chart.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- - image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ - image: {{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 10 }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
name: vector-operator
volumeMounts:
@@ -33,7 +50,5 @@ spec:
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
resources:
{{ toYaml .Values.resources | indent 12 }}
- securityContext:
-{{- toYaml .Values.image.securityContext | nindent 10 }}
\ No newline at end of file
diff --git a/helm/templates/monitor.yaml b/helm/templates/monitor.yaml
deleted file mode 100644
index 0b3952c3..00000000
--- a/helm/templates/monitor.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-apiVersion: monitoring.coreos.com/v1
-kind: ServiceMonitor
-metadata:
- labels:
- control-plane: controller-manager
- name: controller-manager-metrics-monitor
- namespace: vector-operator-system
-spec:
- endpoints:
- - path: /metrics
- port: https
- scheme: https
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
- tlsConfig:
- insecureSkipVerify: true
- selector:
- matchLabels:
- control-plane: controller-manager
\ No newline at end of file
diff --git a/helm/templates/serviceaccount.yaml b/helm/templates/serviceaccount.yaml
index 06a9ae6b..7bdd8504 100644
--- a/helm/templates/serviceaccount.yaml
+++ b/helm/templates/serviceaccount.yaml
@@ -1,12 +1,25 @@
+
{{- if .Values.serviceAccount.create -}}
+{{- if semverCompare ">= 1.24" .Capabilities.KubeVersion.Version }}
apiVersion: v1
-kind: ServiceAccount
+kind: Secret
metadata:
- name: {{ include "vector-operator.serviceAccountName" . }}
-{{- if .Values.serviceAccount.annotations }}
+ name: {{ include "chart.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
annotations:
-{{ toYaml .Values.serviceAccount.annotations | nindent 4 }}
+ kubernetes.io/service-account.name: {{ include "chart.serviceAccountName" . }}
+type: kubernetes.io/service-account-token
{{- end }}
-secrets:
- - name: vector-operator-sa-token
-{{- end }}
\ No newline at end of file
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "chart.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "chart.labels" . | nindent 4 }}
+ {{- with .Values.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end -}}
\ No newline at end of file
diff --git a/helm/templates/vector.yaml b/helm/templates/vector.yaml
index 17f708b9..10b5272b 100644
--- a/helm/templates/vector.yaml
+++ b/helm/templates/vector.yaml
@@ -3,12 +3,16 @@ apiVersion: observability.kaasops.io/v1alpha1
kind: Vector
metadata:
name: {{ .Values.vector.name }}
+ namespace: {{ .Release.Namespace }}
spec:
agent:
- service: true
- image: "timberio/vector:0.24.0-distroless-libc"
- {{- with .Values.tolerations }}
+ image: {{ .Values.vector.agent.image }}
+ {{- with .Values.tolerations }}
tolerations:
- {{- toYaml . | nindent 8 }}
- {{- end }}
+ {{- toYaml . | nindent 6 }}
+ {{- end }}
+ {{- with .Values.env }}
+ env:
+ {{- toYaml . | nindent 6 }}
+ {{- end }}
{{- end }}
\ No newline at end of file
diff --git a/helm/values.yaml b/helm/values.yaml
index 46c44ab5..369cedb7 100644
--- a/helm/values.yaml
+++ b/helm/values.yaml
@@ -2,63 +2,76 @@ fullnameOverride: ""
nameOverride: ""
namespaceOverride: ""
+replicaCount: 1
+
image:
repository: kaasops/vector-operator
- tag: "latest"
+ tag: "" # rewrites Chart.AppVersion
pullPolicy: IfNotPresent
-
- securityContext:
- allowPrivilegeEscalation: false
- runAsGroup: 1000
- runAsNonRoot: true
- readOnlyRootFilesystem: true
- seccompProfile:
- type: RuntimeDefault
- capabilities:
- drop:
- - ALL
-resources:
+# -- enables CRD creation and management.
+# -- with this option, if you remove this chart, all crd resources will be deleted with it.
+createCRD: true
+
+strategy: {}
+# rollingUpdate:
+# maxSurge: 25%
+# maxUnavailable: 25%
+# type: RollingUpdate
+
+imagePullSecrets: []
+
+securityContext:
+ allowPrivilegeEscalation: false
+ runAsGroup: 1000
+ runAsNonRoot: true
+ readOnlyRootFilesystem: true
+ seccompProfile:
+ type: RuntimeDefault
+ capabilities:
+ drop:
+ - ALL
+resources:
limits:
- cpu: "2"
- memory: 2Gi
+ cpu: "1"
+ memory: 1Gi
requests:
cpu: 100m
memory: 50Mi
-rbac:
- create: true
-
-vector:
- create: true
- name: ""
- tolerations: []
-
-
serviceAccount:
- create: false
- name: ""
+ # Specifies whether a service account should be created
+ create: true
+ # Annotations to add to the service account
+ annotations: {}
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname template
+ name:
+
+rbac:
+ create: true
annotations: {}
+ extraLabels: {}
+
+ClusterVectorPipeline: {}
+# - name: ""
+# sources: {}
+# transforms: {}
+# sinks: {}
+# - name: ""
+# sources: {}
+# transforms: {}
+# sinks: {}
-ClusterVectorPipeline:
- - name: ""
- sources: {}
- transforms: {}
- sinks: {}
- - name: ""
- sources: {}
- transforms: {}
- sinks: {}
+# extra Labels for Pods, Deployment
+extraLabels: {}
-VectorPipeline:
- - name: ""
- sources: {}
- transforms: {}
- sinks: {}
- - name: ""
- sources: {}
- transforms: {}
- sinks: {}
-
+# Annotations to be added to the deployment
+annotations: {}
+vector:
+ create: true
+ name: "vector"
+ agent:
+ image: timberio/vector:0.24.0-distroless-libc
From 7b685fade6cd538e6215e02b745850c9d88ad11c Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Thu, 17 Nov 2022 16:39:13 +0200
Subject: [PATCH 100/316] Update changelog
Signed-off-by: Zemtsov Vladimir
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7f256bb1..2e085a10 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
### Added
+- [[47](https://github.com/kaasops/vector-operator/pull/47)] **Features**: Init Helm chart
### v0.0.3
- [[46](https://github.com/kaasops/vector-operator/pull/46)] **Fix**: Fix error with envs forwarding from CR Vector
From a78f334c9f532d4287602b851632e680041b650a Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 18 Nov 2022 10:33:59 +0200
Subject: [PATCH 101/316] Update helm
Signed-off-by: Zemtsov Vladimir
---
Makefile | 1 +
helm/Makefile | 17 ++
helm/{ => charts/vector-operator}/.helmignore | 0
helm/{ => charts/vector-operator}/Chart.yaml | 0
...ity.kaasops.io_clustervectorpipelines.yaml | 0
...ervability.kaasops.io_vectorpipelines.yaml | 0
.../observability.kaasops.io_vectors.yaml | 0
.../vector-operator}/templates/_helpers.tpl | 0
.../templates/clusterrole.yaml | 0
.../templates/clusterrolebinding.yaml | 0
.../templates/clustervectorpipeline.yaml | 0
.../templates/deployment.yaml | 0
.../templates/serviceaccount.yaml | 0
helm/{ => charts/vector-operator}/values.yaml | 0
helm/index.yaml | 17 ++
helm/packages/vector-operator-0.0.1.tgz | Bin 0 -> 12171 bytes
helm/templates/vector.yaml | 18 --
helm/templates/vectorpipeline.yaml | 14 --
index.yaml | 3 +
vector.yaml | 26 +++
vectorpipelines.yaml | 194 ++++++++++++++++++
21 files changed, 258 insertions(+), 32 deletions(-)
create mode 100644 helm/Makefile
rename helm/{ => charts/vector-operator}/.helmignore (100%)
rename helm/{ => charts/vector-operator}/Chart.yaml (100%)
rename helm/{ => charts/vector-operator}/crds/observability.kaasops.io_clustervectorpipelines.yaml (100%)
rename helm/{ => charts/vector-operator}/crds/observability.kaasops.io_vectorpipelines.yaml (100%)
rename helm/{ => charts/vector-operator}/crds/observability.kaasops.io_vectors.yaml (100%)
rename helm/{ => charts/vector-operator}/templates/_helpers.tpl (100%)
rename helm/{ => charts/vector-operator}/templates/clusterrole.yaml (100%)
rename helm/{ => charts/vector-operator}/templates/clusterrolebinding.yaml (100%)
rename helm/{ => charts/vector-operator}/templates/clustervectorpipeline.yaml (100%)
rename helm/{ => charts/vector-operator}/templates/deployment.yaml (100%)
rename helm/{ => charts/vector-operator}/templates/serviceaccount.yaml (100%)
rename helm/{ => charts/vector-operator}/values.yaml (100%)
create mode 100644 helm/index.yaml
create mode 100644 helm/packages/vector-operator-0.0.1.tgz
delete mode 100644 helm/templates/vector.yaml
delete mode 100644 helm/templates/vectorpipeline.yaml
create mode 100644 index.yaml
create mode 100644 vector.yaml
create mode 100644 vectorpipelines.yaml
diff --git a/Makefile b/Makefile
index c8419f6d..92b3a5b7 100644
--- a/Makefile
+++ b/Makefile
@@ -233,3 +233,4 @@ catalog-build: opm ## Build a catalog image.
.PHONY: catalog-push
catalog-push: ## Push a catalog image.
$(MAKE) docker-push IMG=$(CATALOG_IMG)
+
\ No newline at end of file
diff --git a/helm/Makefile b/helm/Makefile
new file mode 100644
index 00000000..73087366
--- /dev/null
+++ b/helm/Makefile
@@ -0,0 +1,17 @@
+URL=https://kaasops.github.io/helm-charts/
+HELM_IMAGE = alpine/helm:3.9.1
+HELM_DOCS_IMAGE = jnorwood/helm-docs:v1.11.0
+KNOWN_TARGETS=helm
+
+# Run linter for helm chart
+lint:
+ helm lint charts/vector-operator
+
+# Package chart into zip file
+package:
+ helm package charts/* -d packages
+
+# Create index file (use only for initial setup)
+index:
+ helm repo index --url ${URL} /
+ mv index.yaml
\ No newline at end of file
diff --git a/helm/.helmignore b/helm/charts/vector-operator/.helmignore
similarity index 100%
rename from helm/.helmignore
rename to helm/charts/vector-operator/.helmignore
diff --git a/helm/Chart.yaml b/helm/charts/vector-operator/Chart.yaml
similarity index 100%
rename from helm/Chart.yaml
rename to helm/charts/vector-operator/Chart.yaml
diff --git a/helm/crds/observability.kaasops.io_clustervectorpipelines.yaml b/helm/charts/vector-operator/crds/observability.kaasops.io_clustervectorpipelines.yaml
similarity index 100%
rename from helm/crds/observability.kaasops.io_clustervectorpipelines.yaml
rename to helm/charts/vector-operator/crds/observability.kaasops.io_clustervectorpipelines.yaml
diff --git a/helm/crds/observability.kaasops.io_vectorpipelines.yaml b/helm/charts/vector-operator/crds/observability.kaasops.io_vectorpipelines.yaml
similarity index 100%
rename from helm/crds/observability.kaasops.io_vectorpipelines.yaml
rename to helm/charts/vector-operator/crds/observability.kaasops.io_vectorpipelines.yaml
diff --git a/helm/crds/observability.kaasops.io_vectors.yaml b/helm/charts/vector-operator/crds/observability.kaasops.io_vectors.yaml
similarity index 100%
rename from helm/crds/observability.kaasops.io_vectors.yaml
rename to helm/charts/vector-operator/crds/observability.kaasops.io_vectors.yaml
diff --git a/helm/templates/_helpers.tpl b/helm/charts/vector-operator/templates/_helpers.tpl
similarity index 100%
rename from helm/templates/_helpers.tpl
rename to helm/charts/vector-operator/templates/_helpers.tpl
diff --git a/helm/templates/clusterrole.yaml b/helm/charts/vector-operator/templates/clusterrole.yaml
similarity index 100%
rename from helm/templates/clusterrole.yaml
rename to helm/charts/vector-operator/templates/clusterrole.yaml
diff --git a/helm/templates/clusterrolebinding.yaml b/helm/charts/vector-operator/templates/clusterrolebinding.yaml
similarity index 100%
rename from helm/templates/clusterrolebinding.yaml
rename to helm/charts/vector-operator/templates/clusterrolebinding.yaml
diff --git a/helm/templates/clustervectorpipeline.yaml b/helm/charts/vector-operator/templates/clustervectorpipeline.yaml
similarity index 100%
rename from helm/templates/clustervectorpipeline.yaml
rename to helm/charts/vector-operator/templates/clustervectorpipeline.yaml
diff --git a/helm/templates/deployment.yaml b/helm/charts/vector-operator/templates/deployment.yaml
similarity index 100%
rename from helm/templates/deployment.yaml
rename to helm/charts/vector-operator/templates/deployment.yaml
diff --git a/helm/templates/serviceaccount.yaml b/helm/charts/vector-operator/templates/serviceaccount.yaml
similarity index 100%
rename from helm/templates/serviceaccount.yaml
rename to helm/charts/vector-operator/templates/serviceaccount.yaml
diff --git a/helm/values.yaml b/helm/charts/vector-operator/values.yaml
similarity index 100%
rename from helm/values.yaml
rename to helm/charts/vector-operator/values.yaml
diff --git a/helm/index.yaml b/helm/index.yaml
new file mode 100644
index 00000000..057356b9
--- /dev/null
+++ b/helm/index.yaml
@@ -0,0 +1,17 @@
+apiVersion: v1
+entries:
+ vector-operator:
+ - apiVersion: v2
+ appVersion: v0.0.3
+ created: "2022-11-18T09:59:54.491957+02:00"
+ description: A Helm chart to install Vector Operator
+ digest: 89ea474465728f855baea8d8e2fdfa2c70050ae7443eb84a555cf8cbd233fc67
+ home: https://github.com/kaasops/vector-operator
+ name: vector-operator
+ sources:
+ - https://github.com/kaasops/vector-operator
+ type: application
+ urls:
+ - https://kaasops.github.io/helm-charts/packages/vector-operator-0.0.1.tgz
+ version: 0.0.1
+generated: "2022-11-18T09:59:54.49135+02:00"
diff --git a/helm/packages/vector-operator-0.0.1.tgz b/helm/packages/vector-operator-0.0.1.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..04ca1c89c42c8a9f5ea6441e40ca65e6e5354f3b
GIT binary patch
literal 12171
zcmYLvWl)_lw>9qW?oiy_-Q5oE?(S|a?(R_B-MzRT+}))(6eygp?|bjuFF*FqPBKYm
z_VcV{vKDD992VGr3WyGj!BkeA)m&DIThW(~%Zx*t)k1^IR!@VETSZ%&TM6J`XX<3(
ztEuKJBx~v52zDK4>%Gn0Y$N>IFqq0Qt}d-4myzl3-(Jcf5Ut#MuA6YSotd2}mU`|a
zNi_&QnBkw-yZ42H0M>B|(QYx?B@xi5zhlv)T1megb(j+o6HBKOJs1;P`iPA~zrIiP
zbvQS6|F0~KCmw)~j*i|z;}t4}0j>{!o}MO`mcFTw6b88l{EO}{aL@nzR<$9`*3=1b
z4Y;yi`SwbP&s%mIos`ysuP2hT&&l*9h>{S#BqwP>Yg4`7!|}uvjfrK)EEYpK^>f%Y
zZWofUm?tBihM^z{Uym+*Y6A#Nsn+5~6)zw%G-vdsPqYi*G1b{q1!+GhMo7-lERi=Z
z(@=9nEOC~TullI0Iw||fe@ivaJud`SPJ;->@squ4!2FIuz?P$!O|wFFt9Y54>2$
zgtqHGT}*NtNh=#?=fyvfimp1JUKDUY*7@eMa*9(YBWQf&tS}>>l5wJ?VZ>DJs#RE_lSijXdh?y}j@u
zK!b8VBYR<=k;;@XUGP{|Ij{rU@4eS>COh7$t^Z{~^C
zUF;fn3MEBF6C(*jpfvQ~ClLg}}G7UO{VJAx&h`O!efr}eFen~YzXxRkA4{Mmf9(sy?g$F>{^3W7YYr5_n%_9NyR!sA9AVA7%6EO6|+{
zVcEOo0CAg`Iivo(W2`mfan9l?BZBe`q?`QfAyRm`kS^u^;*bLo4hja`0wU6H=?sNL
z10^}CW=axnI8lSGm=PpJHE9tZV$TE(KlIQ;S)13$9hfEEMq79nubeXk7F$A9_=ri0
zIL105C=~km4rv!bRoGSGOVb(#hyf+H!5tK`u>^;)g`a2%9qI$as>AM;x3;K?C9=9bM4`J-v154g~llz;uLf5T^qHkFQuLy(H0
zai^f|&~x`967(Y?QlX?z-)Bp9BUtj~?P{ab*aHzuOq7xWsFb6VLgk%p5uUC=6^W!G
z)i)rO!hB);*MA>5sR&76D{G1F{Qt&zT
zU{ww4h>|@$C0d*62uD|hwzLa<3Hnwskm}E6bJ``*S$pFi`5`}DEj8Mm?8apo~5*~?S}X$si<%7wz!Y<)hn60fGQ6k$&xVY6aZ-^bx4&|
zL;1%tN;pU|Ez%Wdr2>--Obeuyg4bT0iSx5>rqN@Ea$(?r6S>|U9N8qdmE>zY5xL`U
z+*h`%l&WoeylUJun$j5|>0sam<zg6rl2k&o)IdjOBOzi`a}ey(?2tv;9g@eExot$vVSfNRc_<1&RJ#@x@+F65ZgV1-C*U5lpALnGEaiU%?D@{@M>13|0%
z3-m+xSu2|J4tNLJPW#B&sI<+yk2r6
z2R@6as1&X|gIbo@K*1~$h-rfkatoPG@#s09bO6J6IU&t0yiJFnrO)sQOW5@{C|V|?
zFria=bTZ!(=l|HkWn)YjpI(Tm=1E
zIElAl7b`RxZ<`K2px$mLsAK_oyS=xPfPDWRZ_t8X*`~~D^T&tN7|KQol{#Ns>INEj
zi@Q!OtBQ>@ZcyqtE20fV2N#C2Bgz)5a5N3@lUL~LD{b&F;JSLlyV!uj$I}=a@SZ8e=nY7`)4y`bqG$JfY4L_!quaTTt3m%anMRF`CRm^9?Z!?+e)#dyxRuDCp!
z0rr$9_cx8aMLHA-3d=8n=KBua3&Pi(D;(fOYs^lgZX7_6g5&8A@cx%r{hq)vJni>p
zE#Y=0R)yCz8NkYPE^V|yLMEK8N)Aogi$>3S)`^l*i-zc-=Go=pd++QF5Ou#x4<
z+s_~oL|jNBLVPpuf%kRc=U+@Une)TF;HM5+>+6|Faq2$sNC+!0)6PHqAAU9w2vjaR
zrYYz0N-SM38cAD?D_>YUIqAB`SG&Y0l!0?-DDTHcR|Wir643ga)7VU2Ei{0$sTpSf
zDqd=+^gx5zKBeSsV*uL1vI#f@)`MnQyj?LWdA?q2gTBr#mX1=@KzrkrRlz;y+BeRY
zApwwqG{bAP^>&GyOx+!ZtOLmS^=zlU8v`}8w4>&;eNs2l}H^;4*Dun@K+y?)#E1E&0T~IRYmky9ij83~|@ij{-74}DR
z8DDWvAwqKz>9*J=$P=yT-(7}mZeKYbLq1xR%qDgJZ6y&9gUIe1a(xl;dIq2^5myeQ
z){?nv5DUhb0Z}LH8^4a)`ThjC22XJb(1Xpo`sA0nyvQl{BOEL7ztLwMT}=W)<)5sX
z&)ptYK)HgVw@pQYspp4phQP18-@Vd`aTS>lkdd^|Lx_f6T7pxix25|1aUJrP@HfOMTF!Oa
z+jD*8z=>=O!G!26X87m3iB`q_7}-LAMG^I_p~-@t?zT{1S|@N836!2g9rK
zO4ibhO2wKoQr|ksxLKFgnu>xGt2Fo8j2{=5b12frvIkuW7ilKj4j~}8UVs`{^%{?e
zmeY)5B`02vMG=D39BBe_$#lf&3GW&arEsfocw2EZL8)A1FW!*m}-5vq&?v
z(HczQfZ>Z`=`9%P*)IC<1VaIgjqIEjT}=ux^`)0#kJc(0|346>QM_1Z&}f`g;@t(%
z6KGBPKbPK)d!+vuINN6L**tofM&9)Wf;*xnliX2Of{8k39Rqxg();(
zgjXG2Stjjop&BcmA$W5IU4s@|$OGF1t{qD&It4jYJ;mhO94Z&jh(>kW4LvViB9R!)kVhBNm1!##gUh;dsjN??6kn+|%
zyWw{xu|CG4fTm(SKG%Y?cfz$A`hEZ%JVO{Jx?H4{VR6DU;pB)ppu%k%Cf@W;zY+0ao;n$+p(;J-%R{6Cf7dyC(<1q_oZ*bg8{dkTQcr}oNF@f
zp8(Faz*!HK)H==Xt@r&i%|l*(P>s^@j8P0Tj;Mo;Q~;c&qVJPxnBI?O9gd)hY)uG_+1dD{
zo~Fg{`yY9pW*tg)f6SGsw)5ue;_y5Qm-M=@Dcm^hq_l=`=DisXPbDKRIvq&Lxtc$QxMr>hVsd}`$ksKAV=&O;mNz&n3p|L`
zP_LiIYTbe(_Jy|fFV?S<=U5}CK~FInxH7{JTZQgd*-x25UW88Kiy0J2+S6_wwMFQe
z?D8Z*mSIo_*sD}021IU`*O8j-)ru`(prFV`T4bEd?4orW(D|-Irom8!I2P`^Xo=I2
zOUn7+ez#Z4<&Z>`tQ)Bc=?Io>Ep(>VZX@m9>-bX(>#&4DN>MVrzmFCvD93RwR&On`
zM^?R0CB~xJh9Rg=fRM6IaZ`(C0>=v7+BK13GmqxkP^c1WrW;mCPO^ZFz+Ojz+Jz=r
zPQ>q!ZES?~_%6Y+3Uk~qNQ-A8mC4ZYrIST6l2e1wZwo;8vq|5nB45aev4m?4h~`k}
zRzOeg8tdO+PXBh%JnI+L@$8
zEv1YnTAN_v+a5lHHndfIj$-tmN$KK=X4kyPd3_#8>@Q>SZD^}|7zU5kRW0a9hmcQ$DOf?=?
z*JV5Ok53xZed!f=z+M%cDST?NedI%UHMkmi`7j!)d9@E(AAPce=1TO#8LL9hSLpop
z*AV7^5D*B*vcko3?8UJkJ(k6N{Ai!Xl^b3_wL3ixyCXl#UryrFj`?1VG!XQ`OuLTC!o5u=u}emKLHZq#|HiSy1`s%Hqx-dWI6tAjaK8UtO79BE>GtxRmu0;a{4>iicW;-
z0dDpCn;<6JFWQBs6Td%vovh2X%dn349;|NRkM4+h!R&nmGhE0}6hm)7w
z{5hIKm+~NF@m`yts7|G}MpQ%K_$``wGiaev=?Xj8wr}Cy=?dGK^W7P6Fg7RD-#HU>A0Cw7i+
z4mA|d7N$yI4pq$luiJLp6w0(C9M2N8rA?K+#$h5gVwwQpTQ(7H8%OUA<^DzJcL*0w
z#17$<4I>>CeijxP^WO%L|4MIvCsquo8#}I{sPm6KG}$Z3S)qAx#DC2R)_vl3_Ef
zZJ!@b+LD^5$~yvE6cL|%3Kns;jC}5G(N?%@w|-3z2$)OI@AYxi01
zCSO;-9GY_bm#{Iq$*5Ef^hd0?zX-0NWqtA0=tD_eh#m<+N;XBuNNmCtmQRB9q^(Ui
z>!0VRsU9NLD{Y@+xunR|LPP>&Tq@?*A;&A=@IjpS3Tp^ena%ZTiy_*wLac_RKTEJN
z-mhXpkPsmdvn-lQY+bvn*M>rO#($aNw3`i7b8wdP8X#lwFkWvk!hehxR~e4GI&2Yj
zk;U`jiQe`{y>$gj07&2?i5-lc@0zTL`k)0IH*1F5nUFAD3^A<(SuS!KhXd9#VLxF~
zJYoONFxg8#L)@^nw9n=k{lIP+pU%60wuPeOG5^xp3rDT
zh#JjZsulPrdx(S`g*qdho_lOb2YG{jxwUwlk{gR;9NN!!Aiyz1ppFCARYxf8wXlcu=po$Ziwq?Ruj3
zbvcLE622Q~U8w@a@w$A8XUvJejO|}j&qdsh$G^awC%-9oZe8gtb%*`si1_0^;ok&s
zVdMW$AbjkF7R@6(-ZVx|38zM#(nxc
zUV&s@j_NeGxOq-)vR&Ki>Z~>XZB|w6_f}emAhgKo`fvViV0H(rMVWJhv-Q8OmHs{n
z{>K-vxsMl=^O-H!#pfGhfyab=U;nZ7>@{y8uFe`&grs@9P==>A7AZ-2F7}`8t9+xeG0Maa@v4
z1OV00!n7vnZP(>vL!A(R4=%6%>vb9@VxF000jn-e{^a`H#!=Hoa#aQ$^#r{&mWq)|
zhPO;6p6nfxk~gN+bE)5qWLgEUVBE0A$z+Bv5#EXkP{y{)2tB`ExBpaY9DyCAtba%>
z#6j(F)AYi!z6r;z88K(LrZT$I-GQy)^;_s!rgwZL1aWCyZ3thd-k!122;G9krtI5F
z&fT_7qGT%_WZ`*^_KKmparU5n9@gx4!aI}&hAS=aLR1mZ{oz~e+AVW`zt4TULaMJV
z>%!fxhR>f}AaAC4bpLj6@XO2instK_Q3$e<@XstMp>BaxCmuy;U5$cCpVV7DrRC%w
z?UPCQ%$&+?v34UZgjCTwOO4t4XuykzXvA^^wwB1bFjQ
z-;&hk2M8_H(GX90*6+H;LGTe+R8!)VQtN)9`7Q&39)wl9r$22enI!V~)iVL|PFcgG
zR;p!N@SeBRi;n*Fw!CYV*>#&UG*Q3j*ftrAcaYyA$KoX|jo6`2ER>)mGa0`TQ;22g
zNU|mGoZ=YU*u(iX5qbleNhV88;%dNzz9Hs~%J-1iIJ5Zpd=r0a+s{XiU9DeDEaD?5ltij?fZcWe<65@@{)$
zKlq$&CgDa@kR4x#vp$y7#(hS-74_*aNvVfAog0~sid_UCin+!O$jFtEN+K)T){!N*
zCYMVWJhZR-oR|e70Xe7w{OyI9E#gsWs{r-X!|NE=u_oX=_2de
zS?&F{;mFo~aO?R58wMLu?uDuVUWl|pjEZ<-O2MH`qfRoLG_#n7NUbK0wJPmYl-*T$
zOP?8D6ZqpRIT${u{_nxTh)B@u;Q;9G-N7CRh}zUi_|!Cct|b~0PHOZ0wGB7HrK`hq
z3@q8D7&~y)Sf(biLsgXhyvq*&hu162hOBim&lVROl!EU5$=R(t?|yV$|3&*#sXN(^
zIeUqDW2UL5JA*cVApdX4*|m;k;kQ_gYrB*BF{B67zScRFm!d41<>UPw1s$qQ9%C5O
z9O6yHum~yxpXHzH({kMu(cD87>aL-g$E>iBhGfQYXs&O~Y;^FeCo6M~wH#&HS;$yjl)*vmU-@UJ8L|A3dy(cmwE=d?ve(?JXhil?vE0SVaqZ&@wH}J5*vP{i+_+QIr1bjMcziMV|
zJ-R^o2EQ3b2*>tbm@NoCZ%h-OBo2hgoJD<=ym(4@{YtGX`~@
zyE)R5B~TS;n+2Gj60J*_VYAg@;Sp_e;c}W?;^1}S_ZS#wG4{^^Ix)`@s@Uqg1mSCv
zwoOi}fUoS@0Ct2AFY$J00z1w<$^++f=zl({Twk*cO*=+(;gmhp`QX}F?>`S4>slDAswfQ*o_dzkEs*0R}FBi
za}`}(b5N#QA7D(pvqzgY=mIs*rEYLM#t<4-iJ9rk4zZlGi&|d+M%j6QcRG~o;)`@E
zHjgw23+nZlIsu?M3vQ&D07R5_OMbc>Mfr4`^znpfpovW%upB3#l+=zb&y9O@X$wHo
zdrY3N7lPD3+tTOzOlNx6tmjB!N7~^imdv+@iy6r+C{eCmlOvW;TSPfU6)y|vd0VG_
z(83<|onWXB=C>j3t|4QKlV$$HdCY$m6qDuzPMhXND|l{8fqKasK{`2u(j-^7?TT^i
zOR7Iu9Qx>grlB4v^*upGg9RD&k!@XG_*Ld1OmWelv1KfJS3mosWu!3cs=)_rXeV!k
zE0I_|3?4d?Ofg+5UEZ$1T+K>aZOy2X!m|rV(TFw>QD+@cXPKm@Y}Ok_6-=EYJH5kl^@V2_TGqOp;hAdX4sg=JKAz<9W*$K*
zHA5XlSfB2H4>b3O6_&yoNnb?S!TihDZ5ZzV-Y%IS`1ba2te^Q&?MiLgu`i!Iko0L5
z`tVIP+DAOSIhxeq{H8txUn@N>Je|Com6<2~M}Vw3f%-%c->09ALmDA{4;r^jy-iAv
z1b_@t1Mq26-7l=rb=f6qp$LpX+5qmYI?-(~;SeA^J2$$F{@uDZA%X5+b~|oN%pNw+
z=>U@0dgeO|q@=C`eEA-Dd0CvD~okq_|ssYoLaTZfooI)_^`)hJ!(@QONFn7M@q8-lhVDPDGEU
zt5Qqyrt=o#F;AE^F?lfp`s*AL1#eVbXZkH36Bkk`UyQr6VUH3KZfk0}1##y`%(q|V
z^`X$$%1G{C%(m=+5GH<*WY6u-t2+O2vr8yN!R9$1>@?AVb?JtYC464Pl-=vg
zw7WZD#i9z`E$UYF;C{2@PWuG#TSn{5W;@^-sSj3CS#(TC7}a}4HZjdV_9lviN{#HG
zKu@moFF?mH9b0}_8cw6i3JW2JPA)*cd-JgU6!bdcdze#Cbu*GBNh3PyG{C)iA@?rN
zCaN78-Vi1ne#^j)Ef7$PdL;9-+M9UVh=4X7YPh43)V
zYJfaNXn;2(N*)c1KyZzEfGDJQV@CwQO=riydu}L_e=OyisB(sR_s+lE#f
zt1>z9Y1~pKSF{>tj`tenWs}ik^xHEQlo_`%KJo_BGYhrN9Md3@isg_q^Av0
z7|8rtTJNgx7#LiU(-5$)(Bk0v62)Q&9qezVk{EZ=;n(0az)jrUZH3&^X*F@leKCr%
zz5`=ZV{{$jlSrVEl9^^nx(in0`Rk({@8J@98;%NsVz@f
z1%e5ub`4s7x%+m=*}MNYvdGuJT{U=8Hq1wK$Sxc)5X2Bki6B>5R2af-jV12D>g@xr
z{^HdbiW-p5>GS{Qt(4X4sVvpvG1M=RKO#ZY(5czSxmlv|sV(X53~^O4;vIC-fd-7Y
z;+rL6z#$kZN?5guMO@m9fxh
z&62f1RR>dT0?H@Q(c-f-3fRTvoYcaV}odfbXtn)Gbt|27DE}M9K$j1R1L5yD0gsMN64UlKhrX&^J3A5Y>DR!9PwF){
zN{N+~qqdw1PJl#E^D?doOG+G3?@LU1Kn}AOp6EfA+`9#%$aIdxWIlgUvP7B
zaXYfmBH6(7(WyKeBm_=CXDRq3kX`v~J2F>Lq~G$<-iavXXRT;bbx~5QQ_Hn?+jZ*O
z@tuIVIfOLhD66bGY?tJcR~fLL;bbeNkw!iPujlH+(q~0=)8h)`aB)w9yYz&mJzsr=
zfj$=-Rt7ypj|s(O)_eWfR_{RGO~0mCi9N5_T#qz0BaXIVM1LCP1sSm~PEa~|a^b)r
zNxR6qgawTCgda6CVk0?5A&`KV3X&Yh`ltG=VvSTg{7{`*hHP0b(Ba?~9j7fO<&3h-
z+SL&scbO}n-4+T6hiG(-xVH$BV#6>0~^
z9`nLIi#NAuGsF6#*jEtjFvl(qc$Y74Dm3hPNDAB-BS}({O6{m#w1M%1eL=8m*8NRx
zu(vVLT<;cT;R_h}{^*DzMu607cz|0jn2=#-
z^&`K&E>B~7e{<;qCjprK$~kzF#Ka7l0{&j}cylwnwNtbQ;F9ue=&E55k<4_l_;=vE
zgsuG@g~hO{)@bfMuC7Q`jEvaBW{Kl?^!#Uxv1`v#HPr>rf1Yq{U^QGcH&lo7|N1>f
z%a_`PLUCHB8_ar${$Qb;Ew(7Q%H;P=)nTg8#8(F@7{afEx_^G_ik{)F{L|3$xntfF
zbIN&
z*S#@c71u!2{QmPt?(VuhL3KFTCn-fITgK$#&)3@Zmu1!PrSj`gC`KULCT!9V8u(~h
zZK_=&UVx#~PYSuU)?4m#;o1g}{~AZH>e5(2O;gOyuD_?pRV*AsyIH}>gBp-8^%IH&
z2E(H2WL186icj
literal 0
HcmV?d00001
diff --git a/helm/templates/vector.yaml b/helm/templates/vector.yaml
deleted file mode 100644
index 10b5272b..00000000
--- a/helm/templates/vector.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-{{- if .Values.vector.create -}}
-apiVersion: observability.kaasops.io/v1alpha1
-kind: Vector
-metadata:
- name: {{ .Values.vector.name }}
- namespace: {{ .Release.Namespace }}
-spec:
- agent:
- image: {{ .Values.vector.agent.image }}
- {{- with .Values.tolerations }}
- tolerations:
- {{- toYaml . | nindent 6 }}
- {{- end }}
- {{- with .Values.env }}
- env:
- {{- toYaml . | nindent 6 }}
- {{- end }}
-{{- end }}
\ No newline at end of file
diff --git a/helm/templates/vectorpipeline.yaml b/helm/templates/vectorpipeline.yaml
deleted file mode 100644
index 3faad7c1..00000000
--- a/helm/templates/vectorpipeline.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-{{- range $pipeline := .Values.VectorPipeline }}
-apiVersion: observability.kaasops.io/v1alpha1
-kind: VectorPipeline
-metadata:
- name: {{ $pipeline.name }}
-spec:
- sources:
- {{ toYaml $pipeline.sources | nindent 6 }}
- transforms:
- {{ toYaml $pipeline.transforms | nindent 6 }}
- sinks:
- {{ toYaml $pipeline.transforms | nindent 6 }}
----
-{{- end }}
diff --git a/index.yaml b/index.yaml
new file mode 100644
index 00000000..8e363c5c
--- /dev/null
+++ b/index.yaml
@@ -0,0 +1,3 @@
+apiVersion: v1
+entries: {}
+generated: "2022-11-18T10:05:12.719734+02:00"
diff --git a/vector.yaml b/vector.yaml
new file mode 100644
index 00000000..b6668829
--- /dev/null
+++ b/vector.yaml
@@ -0,0 +1,26 @@
+apiVersion: observability.kaasops.io/v1alpha1
+kind: Vector
+metadata:
+ name: vector-sample
+ namespace: vector
+spec:
+ agent:
+ image: timberio/vector:0.24.0-distroless-libc
+ service: true
+ env:
+ - name: "LUX-LOG-ELASTIC-HOST"
+ value: "lux-log.xbet.lan"
+ - name: "LUX-LOG-ELASTIC-USER"
+ value: "lux-write"
+ - name: "LUX-LOG-ELASTIC-PASSWORD"
+ value: "bieteuH3keileR}"
+ tolerations:
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/ingress
+ operator: Exists
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/master
+ operator: Exists
+ - effect: NoSchedule
+ key: node-role.kubernetes.io/control-plane
+ operator: Exists
diff --git a/vectorpipelines.yaml b/vectorpipelines.yaml
new file mode 100644
index 00000000..f1119374
--- /dev/null
+++ b/vectorpipelines.yaml
@@ -0,0 +1,194 @@
+# ### Fluentd
+# apiVersion: observability.kaasops.io/v1alpha1
+# kind: VectorPipeline
+# metadata:
+# name: fluentd
+# namespace: vector-operator-system
+# spec:
+# sources:
+# fluentd:
+# type: "kubernetes_logs"
+# extra_label_selector: "app.kubernetes.io/component=fluentd"
+# extra_namespace_label_selector: "kubernetes.io/metadata.name=logging"
+# transforms:
+# fluentd-transform:
+# type: "remap"
+# inputs:
+# - fluentd
+# source: |
+# .@timestamp = del(.timestamp)
+
+# .cluster = "lux"
+# sinks:
+# elastic:
+# type: "elasticsearch"
+# inputs:
+# - fluentd-transform
+# endpoint: "https://ams-kube-log.xbet.lan:9260"
+# bulk:
+# index: "vector-fluentd-%Y-%m-%d"
+# auth:
+# user: for_services
+# password: oodoo8EiL]o]sh9aQuie
+# strategy: basic
+# tls:
+# verify_certificate: false
+# ---
+### Ingress
+apiVersion: observability.kaasops.io/v1alpha1
+kind: VectorPipeline
+metadata:
+ name: ingress
+ namespace: ingress-nginx
+spec:
+ sources:
+ ingress:
+ type: "kubernetes_logs"
+ extra_label_selector: "app.kubernetes.io/name=ingress-nginx"
+ extra_namespace_label_selector: "kubernetes.io/metadata.name=ingress-nginx"
+ transforms:
+ ingress-transform:
+ type: "remap"
+ inputs:
+ - ingress
+ source: |
+ res, errjson = parse_json(.message)
+ if errjson != null {
+ res, errregex = parse_regex(.message, r'^(?P\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}) \[(?P[\w]+.)\] (?P\d+)\#(?P\d+): (?P.*), client: (?P.*), server: (?P.*), request: "(?P.*)", host: "(?P.*)"$')
+ if errregex != null {
+ abort
+ } else {
+ . = res
+ }
+ } else {
+ . = res
+ }
+
+ .ts, err = parse_timestamp(.time, "%d/%b/%Y:%H:%M:%S %z")
+ if err != null {
+ .ts = parse_timestamp!(.time, "%Y/%m/%d %H:%M:%S")
+ }
+ .@timestamp = del(.ts)
+
+ .pid = to_int!(.pid)
+ .worker_id = to_int!(.worker_id)
+
+ .cluster = "lux"
+ sinks:
+ elastic:
+ type: "elasticsearch"
+ inputs:
+ - ingress-transform
+ endpoint: "https://ams-kube-log.xbet.lan:9260"
+ bulk:
+ index: "ingress-lux-%Y-%m-%d"
+ auth:
+ user: for_services
+ password: oodoo8EiL]o]sh9aQuie
+ strategy: basic
+ tls:
+ verify_certificate: false
+---
+# #test
+apiVersion: observability.kaasops.io/v1alpha1
+kind: ClusterVectorPipeline
+metadata:
+ name: test
+ namespace: vector
+spec:
+ sources:
+ test:
+ type: "kubernetes_logs"
+ extra_namespace_label_selector: "kubernetes.io/metadata.name=webproject-njs-frontend-1177"
+ transforms:
+ test-transform:
+ type: "remap"
+ inputs:
+ - test
+ source: |
+ .@timestamp = del(.timestamp)
+
+ .cluster = "lux"
+ sinks:
+ elastic:
+ type: "elasticsearch"
+ inputs:
+ - test-transform
+ endpoint: "https://ams-kube-log.xbet.lan:9260"
+ bulk:
+ index: "vector-test-%Y-%m-%d"
+ auth:
+ user: for_services
+ password: oodoo8EiL]o]sh9aQuie
+ strategy: basic
+ tls:
+ verify_certificate: false
+# #Failed
+---
+apiVersion: observability.kaasops.io/v1alpha1
+kind: VectorPipeline
+metadata:
+ name: vectorpipeline-sample
+ namespace: vector
+spec:
+ sources:
+ test1:
+ type: "kubernetes_logs1"
+ extra_label_selector: "app!=testdeployment"
+ transforms:
+ test:
+ type: "filter"
+ inputs:
+ - test1
+ condition:
+ type: "vrl"
+ source: ".status != 200"
+ sinks:
+ test2:
+ type: "console"
+ encoding:
+ codec: "json"
+ inputs:
+ - test1
+# ---
+# apiVersion: observability.kaasops.io/v1alpha1
+# kind: VectorPipeline
+# metadata:
+# name: vectorpipeline-sample1
+# namespace: kube-system
+# spec:
+# source:
+# test1:
+# type: "kubernetes_logs"
+# extra_label_selector: "app!=testdeployment2"
+# sinks:
+# test2:
+# type: "console"
+# encoding:
+# codec: "json"
+# inputs:
+# - test1
+# ---
+# apiVersion: observability.kaasops.io/v1alpha1
+# kind: VectorPipeline
+# metadata:
+# name: vectorpipeline-sample2
+# namespace: default
+# spec:
+# source:
+# labelSelector:
+# app: "testdeployment2"
+# sinks:
+# type: "console"
+# ---
+# apiVersion: observability.kaasops.io/v1alpha1
+# kind: VectorPipeline
+# metadata:
+# name: vectorpipeline-sample3
+# namespace: default
+# spec:
+# source:
+# labelSelector:
+# app: "testdeployment2"
+# sinks:
+# type: "console"
\ No newline at end of file
From 738793e22c899915df925ad294f1a4a8bc3634fc Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 18 Nov 2022 10:34:21 +0200
Subject: [PATCH 102/316] Update helm [2]
Signed-off-by: Zemtsov Vladimir
---
helm/Makefile | 1 -
1 file changed, 1 deletion(-)
diff --git a/helm/Makefile b/helm/Makefile
index 73087366..d46629ed 100644
--- a/helm/Makefile
+++ b/helm/Makefile
@@ -14,4 +14,3 @@ package:
# Create index file (use only for initial setup)
index:
helm repo index --url ${URL} /
- mv index.yaml
\ No newline at end of file
From 6c4769f82173aab342cd554b34dd8bd1983a4303 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 18 Nov 2022 10:37:08 +0200
Subject: [PATCH 103/316] try
Signed-off-by: Zemtsov Vladimir
---
index.yaml | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/index.yaml b/index.yaml
index 8e363c5c..057356b9 100644
--- a/index.yaml
+++ b/index.yaml
@@ -1,3 +1,17 @@
apiVersion: v1
-entries: {}
-generated: "2022-11-18T10:05:12.719734+02:00"
+entries:
+ vector-operator:
+ - apiVersion: v2
+ appVersion: v0.0.3
+ created: "2022-11-18T09:59:54.491957+02:00"
+ description: A Helm chart to install Vector Operator
+ digest: 89ea474465728f855baea8d8e2fdfa2c70050ae7443eb84a555cf8cbd233fc67
+ home: https://github.com/kaasops/vector-operator
+ name: vector-operator
+ sources:
+ - https://github.com/kaasops/vector-operator
+ type: application
+ urls:
+ - https://kaasops.github.io/helm-charts/packages/vector-operator-0.0.1.tgz
+ version: 0.0.1
+generated: "2022-11-18T09:59:54.49135+02:00"
From dae57be2a04e42788aa50ed617d8531da39ac7c9 Mon Sep 17 00:00:00 2001
From: Zemtsov Vladimir
Date: Fri, 18 Nov 2022 11:20:51 +0200
Subject: [PATCH 104/316] Update changelog and some fixes for helm
Signed-off-by: Zemtsov Vladimir
---
CHANGELOG.md | 1 +
helm/Makefile | 4 ++--
helm/index.yaml | 8 ++++----
helm/packages/vector-operator-0.0.1.tgz | Bin 12171 -> 12172 bytes
index.yaml | 17 -----------------
5 files changed, 7 insertions(+), 23 deletions(-)
delete mode 100644 index.yaml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e085a10..d12da043 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
### Added
+- [[48](https://github.com/kaasops/vector-operator/pull/48)] **Features**: Add helm repo (with GitHub Pages)
- [[47](https://github.com/kaasops/vector-operator/pull/47)] **Features**: Init Helm chart
### v0.0.3
diff --git a/helm/Makefile b/helm/Makefile
index d46629ed..20dcbb1b 100644
--- a/helm/Makefile
+++ b/helm/Makefile
@@ -1,4 +1,4 @@
-URL=https://kaasops.github.io/helm-charts/
+URL=https://kaasops.github.io/vector-operator/helm
HELM_IMAGE = alpine/helm:3.9.1
HELM_DOCS_IMAGE = jnorwood/helm-docs:v1.11.0
KNOWN_TARGETS=helm
@@ -13,4 +13,4 @@ package:
# Create index file (use only for initial setup)
index:
- helm repo index --url ${URL} /
+ helm repo index --url ${URL} .
diff --git a/helm/index.yaml b/helm/index.yaml
index 057356b9..6c52b96a 100644
--- a/helm/index.yaml
+++ b/helm/index.yaml
@@ -3,15 +3,15 @@ entries:
vector-operator:
- apiVersion: v2
appVersion: v0.0.3
- created: "2022-11-18T09:59:54.491957+02:00"
+ created: "2022-11-18T11:20:17.660078+02:00"
description: A Helm chart to install Vector Operator
- digest: 89ea474465728f855baea8d8e2fdfa2c70050ae7443eb84a555cf8cbd233fc67
+ digest: 2df90ecacf9e4f97a6a28db2561bfa3bffff7cb503edd59a6cd467441810c190
home: https://github.com/kaasops/vector-operator
name: vector-operator
sources:
- https://github.com/kaasops/vector-operator
type: application
urls:
- - https://kaasops.github.io/helm-charts/packages/vector-operator-0.0.1.tgz
+ - https://kaasops.github.io/vector-operator/helm/packages/vector-operator-0.0.1.tgz
version: 0.0.1
-generated: "2022-11-18T09:59:54.49135+02:00"
+generated: "2022-11-18T11:20:17.659417+02:00"
diff --git a/helm/packages/vector-operator-0.0.1.tgz b/helm/packages/vector-operator-0.0.1.tgz
index 04ca1c89c42c8a9f5ea6441e40ca65e6e5354f3b..f4e11750ba67275a3e5e3e372fe7ff7145252a90 100644
GIT binary patch
delta 10515
zcmYLuV|3ro6K>R?X{^RhW81cE+jjCv)7Z9cG`1Ssw(Wd_Cb|9n&$;)$d7hbPcV}MA
z&YrVpA`PMp;+lcs=@>%3m%ZnM+td9-hMC*V{26}c^1A1}=cVZig)0tbN9k=eVk!%k
zMt{~mEA78tcz7_SiD4s(GpcfjF}pM@5~!)`CY-Nh{BCx{7C3(scNr-4FvCTwD6YpduM
zK7Ft5^->fWx!xs*iB053BAnb!!UP2@T!OO{2397vHJVBgy1upG2{`J3xS|*t^V_sm
zO$Y^Su@-=5aF-U6iQTT*d32_XER~iaOOSVpjuLWQ-+h1Sg8mf(B9<{yF%VlnA&3zp
zjmDu&o4Ba})k)DJG>m>G#6mJIs5blsPIaAlPMQuK1@+Gvk*mo5_er=2Nm=ypZ>$x8
zaJ)%bJ%0Qm(x#@&@zRE3DVf->&*KN+sJt;$I{rYexMuw70k|;ShhuU$d3wHtg1<%2
zbIvYXNqtV_+uBKe%i%g*I70(xH%UH`^wbOzkSj|D$0D?Nl*J;(PuT^<8S^q(oM(fR
zNbW@}f@f0r2a7XBltFoD>VPBA;`CcK9wA{zt-i}sii=rkAr_j1gJ$Qffxnyy35Rk#
z*(actz<40#P4yf&RQEcPpTi`Ec9%u#h*=3IOe}w!HKeLkz3>15!#KJ|i8G-Tlr<{Yg=)Zm#SK?p?Dvk8oJ
zj%32=MYeDO*$bp%39L)L!8@<3rX)w4S#}EcxO#U&aDP#!rEI&?vxd`EMZc@;B$NPT
zB~hB#f+~;(mC-QXY8yD~xhTpIENwd^RDM6GI#N8KjP803qrQz<_I+tTi02iZmcqG@
zUP4Q(=CZ3k%{nn7f9V$=oODB#i|V%_D#;Fe(Yt5SM;(ZQ#m0z0mpc+wv~N1P;Piap
zSA8jat)dUA8NPLI;1teNbi@yVeg(V-C1v*VV$>4Vg59zQ54eb?t
z)-5Mn?tOpROmMyC0jZyc
zVtYaK*jNWsIkPmMr8>u-xx57XpCD#}JeewVlq1(nEl<}5l5dkNI1)*8N)ZD#on*{u
zyn@&2swC;fR9Mm^Z6r=nDNMPUt;}ZQB4m&}FT!7P$upm4aJEiM4@T-8sG(Wum}QApH-6_nuM6
z2LkvpmT>xL10&5Gev6JNX
ze$7I$e+9VwwZ}jCyuJULHhx~4Es!E{7K@#pxO-_(U?^;@?OeP3&WjTM6@3@eeYg;s
zMb)>T7IvDz$k_og792JliNq?p`GIV6hk3OomIs0=Qrn6bTB5pZS{hy`JXv-
zX*X5ZKzL(F5qu2zS5TVtBcS)j#voTsC2W-ihu1=Em!L~SPo!u<$S1bT&DNvXJYh_$
zZNCgHJ)*)a(w2yxKBshACLqQcVHoY`OGT+7nsv`9qxn&lOJ+f#fZVF~ty$erdCDS-
zPVaXgREI5`9YR{UDT446rmI&s$?l^Li5zYK#DWjrd>Mr8l$R_c4X_x0*i5EKrW;SD
zz;c&V*DxLlD%D7?MX6w|wyH78M@8gI=h@}t%$l?@pkSGzXSnN8&VMwYo#>59;9O+(
zB+nwSZnQI8$f{&MS!p7T&o1Z66eC9^W3ywBmB_UI9m;@g9wy?X4<;l+Qgp6`?A%Nt
zOe`eaZTeuqWqXQP5BwS^wPyUO@jV8mF^H>?j*VRs`5ir}9+h{U4Z3S?3DOK+|MY!-
zL2@LK%tX~LMv!#I3z~cyMJw@Ha_$g4(oqZpPK{y&MgA0B(IQVekjy*IBAYyg+uoU84#Ka&G8MuTePDw!l6(fL&{il&>re0w
zTrU}|G?&@f9Ugg=ynp&6T7~J>8Uz(Vp36+Nqw06+-a;@vM%NfL)LauO{uc;K>G5)k
zs%_MTafmT2+=^thW3QSXr>=@UpX7u(5>AwORm&xH&A#v<=Ct$;3@pfz?l*>~5+%Xpo6pnIoh#?i~Hd=lFKyvaYj
zm|JE(En#Hyg)XJiZqG8qh;1I{_CX2$w6R$iRq4&m=H8~z*K3(3gh+GA17(5Uj*e{m
zbxyIi(OB8Zs6FOj+w^|yG-a+oKQ`Bi(*zH4nDNsg57@Vmi2VdTuQq6Zrb@&T3gGYe
zfSCOwKeqii{j&)SVk?i2_wCv|3msa1IUFA@EMl5I?1~fG{|7a!|1&=5{95%cKJzd0
zc`iRC6bShI)Tcjry`MaJKfM_CTWmf7>5iV+Er#~H)KL7wR
zm(68a5bLURaYr?hzdU))@PTa`dX0YBE=_gpj6kD)=B1d90O4H_bwZJK11Pq-l(^Ju
zDrMbwCYW!+5d3YcI^d*fv}m
zzVERkT0h*^i$VmBMEfUSHpaq)Kmb>DvJNo`N1^$j_c#uX_%A4dqSGvs%Nks$Sc>gt
zJ^r^pgVNXLp0e+KTS)BXMbl!&kBqcQI|y|LI&1P;IYRMq-CM}`6AsI@*CjOmnr*l
zKLXqA_B(_DcLTi33HqyAz-)X&&x>fRI0)oDj+rdojqV>`jC@n3=9>aK0h=dr=3OjT_aJDKhn`Jw8o**Fk(<(eUa3&HuWBJ9Pq}KV$>~!<;~W
z_0up>={fU6AXAqNXzn{t
zdz|zTQN))`=UdoRiL3$gkvMpD>^emUdyF-%t5m`<$N02h{%sigojkYl7<AJJ7JAW}?rl3&V
z7rSY0~uu%+4H+#sU&RR|s8ol;=yol>mpQnWuyokp=5l@aHOSmJwlFpsoTqmO_EtrOOei
zxzjkdKml@%Qe-;(TDIOtkvCCqrkxS~s}s$6!3%}
zY*I6mxXO^_*mpVXLaIy6f5J3l2DACpzaqFq{a2F3;s0M79?ZgO5P-er4a(rU7n^h-
zE?Eb6h{cN?R`tj%f_YAo;33?W@mg^5Mw-LLPyG7AdPJ;#)JO-`;3XW6mN?8M`neaC
zHZQOJD4FAG^`%B#)Kc*6E^l9V%#*$j_rjCjkr&I8@EAhldy&5Oe$iu^At5e0jx5cF
zfM+)91^GZJzepMO7Vw*l)t&PD_zdyyL2R=2s;OEJ2^JJMM}J53c-Uf5Sp-s-#ync<
zG(84InQ8rSJjbP4?&?0NC1>;2-zbX;A6~1JT)7*|qXJ>Lx@!7Kn*wLxbYXmdSxAk4
zJ!gdV15-Yh&pteLAmwmj+R3AR8|iCQuT?gm$TQJ0NakvOV_>brOBKdI)0jQvOUwM#
zuK*hP{^CLAMrr`Pi$C5_Yee+n>o8Ur&6$C`(2Sn8CaCXROx*?
zx-{Ml&hI2^F#=b3N}?^d&K}XU1>9QB&B(=!`-rZqh_dX#I38fS@bc`TxE=wOUeD}I
zV>)zO^e7Ul1^_qip8{lB=i6a?N~LH`_CG`(0a~%z_AnrKur>6yPVyYO*>TjdjyiP}
zD3@a*f>+j`yp1}HNS8P>A}xt&n-D&hr8@*Tcsn8;UtVVHfATkyvh_y!XnDi8Zc}=&
zY}kEnIc>JsDgNrLPe#o;%RVe*cNSCyu+1Y4sf*lgYyspRs9~`Y=~z4{Z4+_wIp3Bc
zCZn+w0v!zl6TOzQ&{cO18v1B*^T02v1zk43S9z)|{}>5*hdG%PEsbR_n5yJ-5((6zw3ld5_jKkD)14n449U|wN=j3?;S&SaOFwjH^x6X}%P
z{uWS0^8&`cA5IKvd_AZtzHo`ikFq33HQ$dx^_5Qut@FqO>-{Es>S@&9P^K@-kH?JO
zO$Nmh{-j&=o=;13`Nd0y#vzR>JYh;tJ$7OVUVM=1tawMB$s!0xDn599
zxRxTF`9ES9M^HSN0*@#IBPBh5WjQpHa`)i}f4kcmSV9|{g>p#KQG%J~fw3Rup*+aP
zjrslKxaS_UVLd3&yffR~X(k_GJpy~#p`6m~oN4R`{_k@um{u^4r>wujY}#a6j3x^-
znUdEoKG0IriuXl_o|ub?nq4h)HP8vKjxyIq7Nszza~yI6
z%ismbc{XWkZQ}f%8rYFKqPhSnOqvYL(n@c9ycIuLT5}_sr%G-SlZb&uL8pQKoXLbb
z054|?HBmNl}%diI*03Fyy8mV(<3yY&Csk)-F!(Gwe5O8BRH_k=ClM#
zsDY!I2=()taUjz2=$+p9ZLZ2NL%?FQUUeF*$>h^Hk**&n9_P$*6kGfbn(n}54hDyW
znv_d3eu0N9QJ8^-(uLNL0V=*18JyMo$looW
z<<6vqcFO5DQnhG|QeF{3@MWVz3)}Wy`*Txu;-bp34)mT*5g|gsy$sc-2VnQSn?vxJ
zK|7>kY#7N2XtCd*nL!9xVa_l>au!kalfG$8o*+nLZqna#C_-E{aREc}P5rqw^3PW`
zLGS0kGWFrMd7&4e*E0-yswzG7>Hx&WS_)51kp`V5$k=Y@f$x5Yvl;~d!4qy_?FO^B
zf!9N_-!=CClL@Y9kN|@je6>G_y?~bW?ZKfn^rli+2qG+P6<&P0`+=O?#I=PjMbULbPw2tM6B0
zJuZfMp7!zIZe!j(hwZsdII@XBv74@EGeh>=ekKHx6M?OI!s~wlqKG`Bm;xCs|Fu3-;0*H+Y=7Lp&i{WTJa6~!WdQ#7H1PD8T@0_Y
z4EcBdJKcRg{6GF*6s)0@SdN|#z*JyMy2;K(Wh)0;V|~q={qXW99L7PnoY%O@jY-U9
z%>aJ3mye+O>(i_I(dAFA%XOY276+uAPKWD&sZKv4z3r`fmg|-D7K^BCFFp#Ef19vP
zT8Mdu0DF;t3=o;LUOY=#W|=jU%Rx#Qw=AS5H>bs$78_)NYXDR16+51RyvBIe(REb%)Lfv$)#(Gzm4uaJp+1dg`O|&AmnDH%T=dh
zVwS{%#ZCRtZxsoIIwbpror6@o7hnqn7y}C>bvQ0*j_Usg?RsrAok0&}-KQBYIjiC9
zPb%L;ZGM%XeihT)J#Hl5nq^VxUm~#i46Kee6cIbwaC=wX0IGd-n9Pp1RDeG|x(Ka|
z(fAlyKM&i70?#mno&wdqm8;>VqaP(jGnsF~Ypm2Z$sd#9I)|iYeOtk=!Mc9yyMbPA
z?g<%kdOY8+_Rb@*96DIjQ=uUduK9vPukoW@sFF^`-$51*fUn=v*&z7J%z;RR)aP*BT6?x4sGD}P`8Xp4aEZ=Xt(demKDojx?7Carj5Dy@
zkW@V)S5cH-5*2hEb)F+eH4PU-M_aYCzYT5<$;0Y!!n)jx=lwd=`gO+Tcdu4eW&AtyRHR5=o5`xR!Oi%+~vSIeFLl8(xcXS?l@fq3G_N#dX^x|2H$
z`5w|tpv9D_jB!1!om~*IBzLJBS~r)9ooskFeRak9r(KnnjmuWO-Aa!HYr$h(r;~SZqm$gKb44_$oC)m!Hh&%-?twD9@H=~N1w{?mH6wD@O
zB!{!#Mrq~R6j8}VjqDDfGt%E)YMi-R*FsMSUs89D#|R1d|L%J*e7sE~5q`WAz9UBh
z9YTbeQTkt?IG=yIdm8xc!lvq+AJTsF8baTIb!wG`rlDUPH2bg^D~yyuDl4uuJ01#!
zrrs8Qg@MoRs{Lyo2{kZW`qEshUU#ws4}TX6@ZhJ_IGU!&@r|1WtW+k(l3G&{1qdKCVBu{Xg#?b{O8?1n?9-@2`8dKXt$eySbmo`=+mA
zw+Znsu0L-!D;>7q6!PVx+FTGo#PD$icd)a=V1Ouhqf}C&D~m8{AsJqk
zD;vW)aM<6~Vy<4+r|thR
zLDfu7(e(C88bg(0S5etdw(VR#HL<9DTx}&vChhn&|B_3ILzKslYNZN?RZ=sPHBB^`
z27QJaoq^b?rd549v{+LBN{#rin#ofx3G>|C?=W|C?8h&4-k2h~!-}cHz2DraPX~rv
z=i;jhCCXpcFVavm$A%yQFmmmgR<@dphT;QDFPP3AH;)4*2i{{Fhx$
z()GC0`5xB3@s#WhZb+6QOXeSe&N`HgJctB*h%u!o$=(p6V^*@j@npvD_M}%W%Lozz
zeKaG2XtJLmDBPOrB*vNM3F7@?M_K*5G^&@K)Wor4`6gX)g;4pdAt2lSBmmovm3R6UaN>DwpdZitW?$KF^vYFJ-l5Jfp
zoy@p>!csKm+X4&_vV?1A-N*5ok2yePp~Bncci1OGu=k8Gva`;+o~e