diff --git a/Makefile b/Makefile index bdc724df..1d051916 100644 --- a/Makefile +++ b/Makefile @@ -167,7 +167,8 @@ enable-nfs-knative: ## Enable NFS for Knative .PHONY: install-logging install-logging: ## Install logging operator on the kind cluster - helm upgrade --install --wait --create-namespace --namespace logging logging-operator oci://ghcr.io/kube-logging/helm-charts/logging-operator --set logging.enabled=true + helm upgrade --install --wait --create-namespace --namespace logging logging-operator oci://ghcr.io/kube-logging/helm-charts/logging-operator + kubectl apply -f hack/logging-operator-resources.yaml KNATIVE_URL ?= https://github.com/knative-extensions/kn-plugin-quickstart/releases/download/knative-v1.11.2/kn-quickstart-linux-amd64 KNATIVE_HPA_URL ?= https://github.com/knative/serving/releases/download/knative-v1.11.2/serving-hpa.yaml diff --git a/README.md b/README.md index dea7fcd9..5728d941 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The `container-app-operator` project can work as a standalone solution, but is m - [x] Support for autoscaler (`HPA` or `KPA`) according to the chosen `scaleMetric` (`concurrency`, `rps`, `cpu`, `memory`) with default settings. - [x] Support for HTTP/HTTPS `DomainMapping` for accessing applications via `Ingress`/`Route`. - [x] Support for all `Knative Serving` configurations. -- [x] Support for exporting logs to `Elasticsearch` and `Splunk` indexes. +- [x] Support for exporting logs to an `Elasticsearch` index. - [x] Support for changing the state of `Capp` from `enabled` (workload is in running state) to `disabled` (workload is not in running state). - [x] Support for external NFS storage connected to `Capp` by using `volumeMounts`. @@ -136,9 +136,8 @@ spec: type: elastic host: 10.11.12.13 index: main - username: elastic - passwordSecretName: es-elastic-user - sslVerify: false + user: elastic + passwordSecret: es-elastic-user scaleMetric: concurrency state: enabled ``` diff --git a/api/v1alpha1/capp_types.go b/api/v1alpha1/capp_types.go index d534e916..c2038279 100755 --- a/api/v1alpha1/capp_types.go +++ b/api/v1alpha1/capp_types.go @@ -107,7 +107,8 @@ type RouteSpec struct { // LogSpec defines the configuration for shipping Capp logs. type LogSpec struct { // Type defines where to send the Capp logs - // Possible values : "elastic" and "splunk". + // +kubebuilder:default:="elastic" + // +kubebuilder:validation:Enum=elastic // +optional Type string `json:"type,omitempty"` @@ -115,27 +116,18 @@ type LogSpec struct { // +optional Host string `json:"host,omitempty"` - // SSLVerify determines whether to skip ssl verification. - // +optional - SSLVerify bool `json:"sslVerify,omitempty"` - // Index defines the index name to write events to. // +optional Index string `json:"index,omitempty"` - // UserName defines a User for authentication. + // User defines a User for authentication. // +optional - UserName string `json:"username,omitempty"` + User string `json:"username,omitempty"` - // PasswordSecretName defines the name of the secret + // PasswordSecret defines the name of the secret // containing the password for authentication. // +optional - PasswordSecretName string `json:"passwordSecretName,omitempty"` - - // HecTokenSecretName defines the name of the secret - // containing the Splunk Hec token. - // +optional - HecTokenSecretName string `json:"hecTokenSecretName,omitempty"` + PasswordSecret string `json:"passwordSecretName,omitempty"` } // ApplicationLinks contains relevant information about @@ -171,17 +163,17 @@ type StateStatus struct { LastChange metav1.Time `json:"lastChange,omitempty"` } -// LoggingStatus defines the state of the Flow and Output objects linked to the Capp. +// LoggingStatus defines the state of the SyslogNGFlow and SyslogNGOutput objects linked to the Capp. type LoggingStatus struct { - // Flow represents the Status of the Flow used by the Capp. + // SyslogNGFlow represents the Status of the SyslogNGFlow used by the Capp. // +optional - Flow loggingv1beta1.FlowStatus `json:"flow,omitempty"` + SyslogNGFlow loggingv1beta1.SyslogNGFlowStatus `json:"syslogngflow,omitempty"` - // Output represents the Status of the Output used by the Capp. + // SyslogNGOutput represents the Status of the SyslogNGOutput used by the Capp. // +optional - Output loggingv1beta1.OutputStatus `json:"output,omitempty"` + SyslogNGOutput loggingv1beta1.SyslogNGOutputStatus `json:"syslogngoutput,omitempty"` - // Conditions contain details about the current state of the Output and Flow used by the Capp. + // Conditions contain details about the current state of the SyslogNGFlow and SyslogNGOutput used by the Capp. // +optional Conditions []metav1.Condition `json:"conditions,omitempty"` } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index c680a5f3..6d5f3c14 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -172,8 +172,8 @@ func (in *LogSpec) DeepCopy() *LogSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LoggingStatus) DeepCopyInto(out *LoggingStatus) { *out = *in - in.Flow.DeepCopyInto(&out.Flow) - in.Output.DeepCopyInto(&out.Output) + in.SyslogNGFlow.DeepCopyInto(&out.SyslogNGFlow) + in.SyslogNGOutput.DeepCopyInto(&out.SyslogNGOutput) if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]metav1.Condition, len(*in)) diff --git a/capp.yaml b/capp.yaml new file mode 100644 index 00000000..39ebd30b --- /dev/null +++ b/capp.yaml @@ -0,0 +1,42 @@ +apiVersion: rcs.dana.io/v1alpha1 +kind: Capp +metadata: + name: capp-sample + namespace: capp-sample +spec: + configurationSpec: + template: + spec: + containers: + - env: + - name: APP_NAME + value: capp-env-var + image: 'quay.io/danateamorg/example-python-app:v1-flask' + name: capp-sample + volumeMounts: + - name: testpvc + mountPath: /data + volumes: + - name: testpvc + persistentVolumeClaim: + claimName: nfspvc + readOnly: false + routeSpec: + hostname: capp.dev + tlsEnabled: true + tlsSecret: cappTlsSecretName + volumesSpec: + nfsVolumes: + - server: test + path: /test + name: nfspvc + capacity: + storage: 200Gi + logSpec: + type: splunk + host: 10.11.12.13 + index: main + username: elastic + passwordSecretName: es-elastic-user + scaleMetric: concurrency + state: enabled diff --git a/config/crd/bases/rcs.dana.io_capps.yaml b/config/crd/bases/rcs.dana.io_capps.yaml index 94dbabb6..0e15d273 100644 --- a/config/crd/bases/rcs.dana.io_capps.yaml +++ b/config/crd/bases/rcs.dana.io_capps.yaml @@ -7642,11 +7642,6 @@ spec: logSpec: description: LogSpec defines the configuration for shipping Capp logs. properties: - hecTokenSecretName: - description: |- - HecTokenSecretName defines the name of the secret - containing the Splunk Hec token. - type: string host: description: Host defines Elasticsearch or Splunk host. type: string @@ -7655,19 +7650,17 @@ spec: type: string passwordSecretName: description: |- - PasswordSecretName defines the name of the secret + PasswordSecret defines the name of the secret containing the password for authentication. type: string - sslVerify: - description: SSLVerify determines whether to skip ssl verification. - type: boolean type: - description: |- - Type defines where to send the Capp logs - Possible values : "elastic" and "splunk". + default: elastic + description: Type defines where to send the Capp logs + enum: + - elastic type: string username: - description: UserName defines a User for authentication. + description: User defines a User for authentication. type: string type: object routeSpec: @@ -8165,7 +8158,7 @@ spec: properties: conditions: description: Conditions contain details about the current state - of the Output and Flow used by the Capp. + of the SyslogNGFlow and SyslogNGOutput used by the Capp. items: description: "Condition contains details for one aspect of the current state of this API Resource.\n---\nThis struct is intended @@ -8236,9 +8229,9 @@ spec: - type type: object type: array - flow: - description: Flow represents the Status of the Flow used by the - Capp. + syslogngflow: + description: SyslogNGFlow represents the Status of the SyslogNGFlow + used by the Capp. properties: active: type: boolean @@ -8249,9 +8242,9 @@ spec: problemsCount: type: integer type: object - output: - description: Output represents the Status of the Output used by - the Capp. + syslogngoutput: + description: SyslogNGOutput represents the Status of the SyslogNGOutput + used by the Capp. properties: active: type: boolean diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 5c5f0b84..ad13e96b 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -1,2 +1,8 @@ resources: - manager.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: controller + newTag: latest diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 40e7394e..990f2fe0 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -53,7 +53,7 @@ rules: - apiGroups: - logging.banzaicloud.io resources: - - flows + - syslogngflows verbs: - create - delete @@ -64,7 +64,7 @@ rules: - apiGroups: - logging.banzaicloud.io resources: - - outputs + - syslogngoutputs verbs: - create - delete diff --git a/go.mod b/go.mod index 8e732c36..da0f618f 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,11 @@ require ( github.com/dana-team/nfspvc-operator v0.2.2 github.com/go-logr/logr v1.4.1 github.com/go-logr/zapr v1.3.0 - github.com/kube-logging/logging-operator/pkg/sdk v0.11.0 + github.com/kube-logging/logging-operator/pkg/sdk v0.11.1-0.20240314152935-421fefebc813 github.com/onsi/ginkgo/v2 v2.17.1 github.com/onsi/gomega v1.31.1 github.com/openshift/api v0.0.0-20240410141538-3c0461467316 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 go.elastic.co/ecszap v1.0.2 go.uber.org/zap v1.27.0 golang.org/x/net v0.24.0 @@ -29,7 +29,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blendle/zapdriver v1.3.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect @@ -57,8 +57,8 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.68.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.72.0 // indirect github.com/prometheus/client_golang v1.19.0 // indirect github.com/prometheus/client_model v0.6.0 // indirect github.com/prometheus/common v0.52.2 // indirect diff --git a/go.sum b/go.sum index 64a5688d..ea887ba4 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,9 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/dana-team/nfspvc-operator v0.2.2 h1:/FwVD34O39ky9lQyOiVsyv8Et7K0Wkai6kseDThmR2o= github.com/dana-team/nfspvc-operator v0.2.2/go.mod h1:l4J/LPQPf2ksPDZJu3RO3k4srKnXJ3fCS3JG0XTYZ5o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= @@ -99,8 +100,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kube-logging/logging-operator/pkg/sdk v0.11.0 h1:3yg+fdk6LnS+wVThEOr85qTtTKmS+6e5DrCtG1j6yFA= -github.com/kube-logging/logging-operator/pkg/sdk v0.11.0/go.mod h1:dWCUhDTFiW5V21LQJ2hoFzqZb1y6U1mFQU7ZXzd9tFE= +github.com/kube-logging/logging-operator/pkg/sdk v0.11.1-0.20240314152935-421fefebc813 h1:OMV8NhQGJYD2XQe5V1elb6USyp7XwdugCUIc34+o8G4= +github.com/kube-logging/logging-operator/pkg/sdk v0.11.1-0.20240314152935-421fefebc813/go.mod h1:KyAHHsYc1nA6ImWIYYZwqlw8KlalpHCwjOUqd+iv8N8= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -125,10 +126,11 @@ github.com/openshift/api v0.0.0-20240410141538-3c0461467316/go.mod h1:CxgbWAlvu2 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.68.0 h1:yl9ceUSUBo9woQIO+8eoWpcxZkdZgm89g+rVvu37TUw= -github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.68.0/go.mod h1:9Uuu3pEU2jB8PwuqkHvegQ0HV/BlZRJUyfTYAqfdVF8= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.72.0 h1:9h7PxMhT1S8lOdadEKJnBh3ELMdO60XkoDV98grYjuM= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.72.0/go.mod h1:4FiLCL664L4dNGeqZewiiD0NS7hhqi/CxyM4UOq5dfM= github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= @@ -156,8 +158,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= diff --git a/hack/kind-config.yaml b/hack/kind-config.yaml deleted file mode 100644 index 658ea43e..00000000 --- a/hack/kind-config.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# four node (one control plane + three workers) cluster config for k8s e2e test in github workflow! -# for the local registry config see https://kind.sigs.k8s.io/docs/user/local-registry/ -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -nodes: - - role: control-plane - - role: worker - - role: worker - - role: worker -containerdConfigPatches: - - |- - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."kind-registry:5000"] - endpoint = ["http://kind-registry:5000"] \ No newline at end of file diff --git a/hack/logging-operator-resources.yaml b/hack/logging-operator-resources.yaml new file mode 100644 index 00000000..5775f110 --- /dev/null +++ b/hack/logging-operator-resources.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: logging.banzaicloud.io/v1beta1 +kind: Logging +metadata: + name: logging +spec: + controlNamespace: logging +--- +apiVersion: logging.banzaicloud.io/v1beta1 +kind: SyslogNGConfig +metadata: + name: logging + namespace: logging +spec: {} \ No newline at end of file diff --git a/internal/controllers/capp_controller.go b/internal/controllers/capp_controller.go index 6f852c90..3d7f7f94 100644 --- a/internal/controllers/capp_controller.go +++ b/internal/controllers/capp_controller.go @@ -3,6 +3,7 @@ package controllers import ( "context" "fmt" + loggingv1beta1 "github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1" "time" "k8s.io/apimachinery/pkg/types" @@ -46,8 +47,8 @@ type CappReconciler struct { // +kubebuilder:rbac:groups=serving.knative.dev,resources=services,verbs=get;list;watch;update;create;delete // +kubebuilder:rbac:groups=serving.knative.dev,resources=domainmappings,verbs=get;list;watch;update;create;delete // +kubebuilder:rbac:groups=serving.knative.dev,resources=revisions,verbs=get;list;watch;update;create -// +kubebuilder:rbac:groups=logging.banzaicloud.io,resources=flows,verbs=get;list;watch;update;create;delete -// +kubebuilder:rbac:groups=logging.banzaicloud.io,resources=outputs,verbs=get;list;watch;update;create;delete +// +kubebuilder:rbac:groups=logging.banzaicloud.io,resources=syslogngflows,verbs=get;list;watch;update;create;delete +// +kubebuilder:rbac:groups=logging.banzaicloud.io,resources=syslogngoutputs,verbs=get;list;watch;update;create;delete // +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch;update;create // +kubebuilder:rbac:groups="",resources=nodes,verbs=get;list;watch; // +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch; @@ -62,7 +63,7 @@ func (r *CappReconciler) SetupWithManager(mgr ctrl.Manager) error { For(&cappv1alpha1.Capp{}). Watches( &knativev1.Service{}, - handler.EnqueueRequestsFromMapFunc(r.findCappFromKnative), + handler.EnqueueRequestsFromMapFunc(r.findCappFromEvent), builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}), ). Watches( @@ -70,14 +71,24 @@ func (r *CappReconciler) SetupWithManager(mgr ctrl.Manager) error { handler.EnqueueRequestsFromMapFunc(r.findCappFromDomainMapping), builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}), ). + Watches( + &loggingv1beta1.SyslogNGOutput{}, + handler.EnqueueRequestsFromMapFunc(r.findCappFromEvent), + builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}), + ). + Watches( + &loggingv1beta1.SyslogNGFlow{}, + handler.EnqueueRequestsFromMapFunc(r.findCappFromEvent), + builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}), + ). Complete(r) } -// findCappFromKnative maps Knative reconciliation requests to Capp reconciliation requests. -func (r *CappReconciler) findCappFromKnative(ctx context.Context, knativeService client.Object) []reconcile.Request { +// findCappFromKnative maps reconciliation requests to Capp reconciliation requests. +func (r *CappReconciler) findCappFromEvent(ctx context.Context, object client.Object) []reconcile.Request { request := reconcile.Request{NamespacedName: types.NamespacedName{ - Namespace: knativeService.GetNamespace(), - Name: knativeService.GetName()}} + Namespace: object.GetNamespace(), + Name: object.GetName()}} return []reconcile.Request{request} } @@ -108,8 +119,8 @@ func (r *CappReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. resourceManagers := map[string]rmanagers.ResourceManager{ rmanagers.DomainMapping: rmanagers.KnativeDomainMappingManager{Ctx: ctx, Log: logger, K8sclient: r.Client, EventRecorder: r.EventRecorder}, rmanagers.KnativeServing: rmanagers.KnativeServiceManager{Ctx: ctx, Log: logger, K8sclient: r.Client, EventRecorder: r.EventRecorder}, - rmanagers.Flow: rmanagers.FlowManager{Ctx: ctx, Log: logger, K8sclient: r.Client, EventRecorder: r.EventRecorder}, - rmanagers.Output: rmanagers.OutputManager{Ctx: ctx, Log: logger, K8sclient: r.Client, EventRecorder: r.EventRecorder}, + rmanagers.SyslogNGFlow: rmanagers.SyslogNGFlowManager{Ctx: ctx, Log: logger, K8sclient: r.Client, EventRecorder: r.EventRecorder}, + rmanagers.SyslogNGOutput: rmanagers.SyslogNGOutputManager{Ctx: ctx, Log: logger, K8sclient: r.Client, EventRecorder: r.EventRecorder}, rmanagers.NFSPVC: rmanagers.NFSPVCManager{Ctx: ctx, Log: logger, K8sclient: r.Client, EventRecorder: r.EventRecorder}, } @@ -117,12 +128,15 @@ func (r *CappReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. if err != nil { return ctrl.Result{}, fmt.Errorf("failed to handle Capp deletion: %s", err.Error()) } + if deleted { return ctrl.Result{}, nil } + if err := finalizer.EnsureFinalizer(ctx, capp, r.Client); err != nil { return ctrl.Result{}, fmt.Errorf("failed to ensure finalizer in Capp: %s", err.Error()) } + if err := r.SyncApplication(ctx, capp, resourceManagers, logger); err != nil { if errors.IsConflict(err) { logger.Info(fmt.Sprintf("Conflict detected requeuing: %s", err.Error())) diff --git a/internal/finalizer/finalizer.go b/internal/finalizer/finalizer.go index 797f4645..04104108 100644 --- a/internal/finalizer/finalizer.go +++ b/internal/finalizer/finalizer.go @@ -15,7 +15,7 @@ const FinalizerCleanupCapp = "dana.io/capp-cleanup" func HandleResourceDeletion(ctx context.Context, capp cappv1alpha1.Capp, r client.Client, resourceManagers map[string]rmanagers.ResourceManager) (error, bool) { if capp.ObjectMeta.DeletionTimestamp != nil { if controllerutil.ContainsFinalizer(&capp, FinalizerCleanupCapp) { - if err := finalizeService(capp, resourceManagers); err != nil { + if err := finalizeCapp(capp, resourceManagers); err != nil { return err, false } return RemoveFinalizer(ctx, capp, r), true @@ -33,8 +33,8 @@ func RemoveFinalizer(ctx context.Context, capp cappv1alpha1.Capp, r client.Clien return nil } -// fnializeService runs the cleanup of all the resource mangers. -func finalizeService(capp cappv1alpha1.Capp, resourceManagers map[string]rmanagers.ResourceManager) error { +// finalizeCapp runs the cleanup of all the resource managers. +func finalizeCapp(capp cappv1alpha1.Capp, resourceManagers map[string]rmanagers.ResourceManager) error { for _, manager := range resourceManagers { if err := manager.CleanUp(capp); err != nil { return err diff --git a/internal/resource-managers/flow.go b/internal/resource-managers/flow.go deleted file mode 100644 index f8c9aef1..00000000 --- a/internal/resource-managers/flow.go +++ /dev/null @@ -1,126 +0,0 @@ -package resourceprepares - -import ( - "context" - "fmt" - "reflect" - - cappv1alpha1 "github.com/dana-team/container-app-operator/api/v1alpha1" - rclient "github.com/dana-team/container-app-operator/internal/wrappers" - "github.com/go-logr/logr" - loggingv1beta1 "github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1" - "github.com/kube-logging/logging-operator/pkg/sdk/logging/model/filter" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" - - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type FlowManager struct { - Ctx context.Context - K8sclient client.Client - Log logr.Logger - EventRecorder record.EventRecorder -} - -// prepareResource prepares a flow resource based on the provided capp. -func (f FlowManager) prepareResource(capp cappv1alpha1.Capp) loggingv1beta1.Flow { - flowName := capp.GetName() + "-flow" - outputName := capp.GetName() + "-output" - flow := loggingv1beta1.Flow{ - ObjectMeta: metav1.ObjectMeta{ - Name: flowName, - Namespace: capp.GetNamespace(), - }, - Spec: loggingv1beta1.FlowSpec{ - Filters: []loggingv1beta1.Filter{ - { - TagNormaliser: &filter.TagNormaliser{}, - }, - { - Parser: &filter.ParserConfig{ - RemoveKeyNameField: true, - ReserveData: true, - Parse: filter.ParseSection{ - Type: NginxPraser, - }, - }, - }, - }, - Match: []loggingv1beta1.Match{ - { - Select: &loggingv1beta1.Select{ - Labels: map[string]string{ - KnativeConfiguration: capp.GetName(), - }, - }, - }, - }, - LocalOutputRefs: []string{outputName}, - }, - } - return flow -} - -// CleanUp deletes the flow resource associated with the Capp object. -// The flow resource is deleted by calling the DeleteResource method of the resourceManager object. -func (f FlowManager) CleanUp(capp cappv1alpha1.Capp) error { - if f.IsRequired(capp) { - flowName := capp.GetName() + "-flow" - resourceManager := rclient.ResourceBaseManagerClient{Ctx: f.Ctx, K8sclient: f.K8sclient, Log: f.Log} - flow := loggingv1beta1.Flow{} - if err := resourceManager.DeleteResource(&flow, flowName, capp.Namespace); err != nil { - return fmt.Errorf("unable to delete flow %q: %w", flowName, err) - } - - } - return nil -} - -// IsRequired is responsible to determine if resource logging operator flow is required. -func (f FlowManager) IsRequired(capp cappv1alpha1.Capp) bool { - if capp.Spec.LogSpec != (cappv1alpha1.LogSpec{}) { - return capp.Spec.LogSpec.Type == LogTypeElastic || capp.Spec.LogSpec.Type == LogTypeSplunk - } - return false -} - -// CreateOrUpdateObject creates or updates a flow object based on the provided capp. -// It returns an error if any operation fails. -func (f FlowManager) CreateOrUpdateObject(capp cappv1alpha1.Capp) error { - flowName := capp.GetName() + "-flow" - logger := f.Log.WithValues("FlowName", flowName, "FlowNamespace", capp.Namespace) - - if f.IsRequired(capp) { - generatedFlow := f.prepareResource(capp) - // get instance of current flow - currentFlow := loggingv1beta1.Flow{} - resourceManager := rclient.ResourceBaseManagerClient{Ctx: f.Ctx, K8sclient: f.K8sclient, Log: f.Log} - logger.Info("Trying to fetch existing flow") - switch err := f.K8sclient.Get(f.Ctx, types.NamespacedName{Namespace: capp.Namespace, Name: flowName}, ¤tFlow); { - case errors.IsNotFound(err): - logger.Info("didn't find flow") - - if err := resourceManager.CreateResource(&generatedFlow); err != nil { - f.EventRecorder.Event(&capp, corev1.EventTypeWarning, eventCappFlowCreationFailed, fmt.Sprintf("Failed to create flow %s for Capp %s", flowName, capp.Name)) - return fmt.Errorf("failed to create flow %q: %w", flowName, err) - } - logger.Info("Created flow successfully") - f.EventRecorder.Event(&capp, corev1.EventTypeNormal, eventCappFlowCreated, fmt.Sprintf("Created flow %s for Capp %s", flowName, capp.Name)) - case err != nil: - return fmt.Errorf("failed to fetch existing flow %q: %w", flowName, err) - } - if !reflect.DeepEqual(currentFlow.Spec, generatedFlow.Spec) { - currentFlow.Spec = generatedFlow.Spec - logger.Info("Trying to update the current flow") - if err := resourceManager.UpdateResource(¤tFlow); err != nil { - return fmt.Errorf("failed to update the current flow %q: %w", flowName, err) - } - logger.Info("Current flow successfully updated") - } - } - return nil -} diff --git a/internal/resource-managers/output.go b/internal/resource-managers/output.go deleted file mode 100644 index 03e86f81..00000000 --- a/internal/resource-managers/output.go +++ /dev/null @@ -1,193 +0,0 @@ -package resourceprepares - -import ( - "context" - "fmt" - "reflect" - - "github.com/cisco-open/operator-tools/pkg/secret" - cappv1alpha1 "github.com/dana-team/container-app-operator/api/v1alpha1" - rclient "github.com/dana-team/container-app-operator/internal/wrappers" - "github.com/go-logr/logr" - loggingv1beta1 "github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1" - "github.com/kube-logging/logging-operator/pkg/sdk/logging/model/output" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" - - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type OutputManager struct { - Ctx context.Context - K8sclient client.Client - Log logr.Logger - EventRecorder record.EventRecorder -} - -const ( - LogTypeElastic string = "elastic" - LogTypeSplunk string = "splunk" - KnativeConfiguration = "serving.knative.dev/configuration" - NginxPraser = "nginx" - ElasticPort = 9200 - SplunkHecPort = 8088 - ElasticSSLVersion = "TLSv1_2" - BufferTimekey = "1m" - BufferTimekeyWait = "30s" - BufferTimekeyUseUtc = true -) - -// createElasticsearchOutput creates an Elasticsearch output object based on the provided logSpec. -// It constructs the Elasticsearch output which is returned as an OutputSpec. -func createElasticsearchOutput(logSpec cappv1alpha1.LogSpec) loggingv1beta1.OutputSpec { - protocol := "http" - falseVar := false - if logSpec.SSLVerify { - protocol = "https" - } - outputSpec := loggingv1beta1.OutputSpec{ - ElasticsearchOutput: &output.ElasticsearchOutput{ - Host: logSpec.Host, - Port: ElasticPort, - Scheme: protocol, - SslVerify: &falseVar, - SslVersion: ElasticSSLVersion, - User: logSpec.UserName, - Password: &secret.Secret{ - ValueFrom: &secret.ValueFrom{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: logSpec.PasswordSecretName}, - Key: "elastic", - }, - }, - }, - IndexName: logSpec.Index, - Buffer: &output.Buffer{ - Timekey: BufferTimekey, - TimekeyWait: BufferTimekeyWait, - TimekeyUseUtc: BufferTimekeyUseUtc, - }, - }, - } - return outputSpec -} - -// createSplunkHecOutput creates a splunk output object based on the provided logSpec. -// It constructs the splunk output which is returned as an OutputSpec. -func createSplunkHecOutput(logSpec cappv1alpha1.LogSpec) loggingv1beta1.OutputSpec { - protocol := "http" - if logSpec.SSLVerify { - protocol = "https" - } - insecureSSL := !logSpec.SSLVerify - outputSpec := loggingv1beta1.OutputSpec{ - SplunkHecOutput: &output.SplunkHecOutput{ - HecHost: logSpec.Host, - HecPort: SplunkHecPort, - InsecureSSL: &insecureSSL, - HecToken: &secret.Secret{ - ValueFrom: &secret.ValueFrom{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: logSpec.HecTokenSecretName}, - Key: "SplunkHecToken", - }, - }, - }, - Index: logSpec.Index, - Protocol: protocol, - Format: &output.Format{Type: "json"}, - Buffer: &output.Buffer{ - Timekey: BufferTimekey, - TimekeyWait: BufferTimekeyWait, - TimekeyUseUtc: BufferTimekeyUseUtc, - }, - }, - } - return outputSpec -} - -// outputCreators is a map that associates log types with their corresponding output creation functions. -var outputCreators = map[string]func(cappv1alpha1.LogSpec) loggingv1beta1.OutputSpec{ - LogTypeElastic: createElasticsearchOutput, - LogTypeSplunk: createSplunkHecOutput, -} - -// prepareResource prepares an output resource based on the provided capp. -func (o OutputManager) prepareResource(capp cappv1alpha1.Capp) loggingv1beta1.Output { - outputName := capp.GetName() + "-output" - if createFunc, ok := outputCreators[capp.Spec.LogSpec.Type]; ok { - outputSpec := createFunc(capp.Spec.LogSpec) - output := loggingv1beta1.Output{ - ObjectMeta: metav1.ObjectMeta{ - Name: outputName, - Namespace: capp.GetNamespace(), - }, - Spec: outputSpec, - } - return output - } - return loggingv1beta1.Output{} -} - -// CleanUp deletes the output resource associated with the Capp object. -// The output resource is deleted by calling the DeleteResource method of the resourceManager object. -func (o OutputManager) CleanUp(capp cappv1alpha1.Capp) error { - if o.IsRequired(capp) { - outputName := capp.GetName() + "-output" - resourceManager := rclient.ResourceBaseManagerClient{Ctx: o.Ctx, K8sclient: o.K8sclient, Log: o.Log} - outputObject := loggingv1beta1.Output{} - if err := resourceManager.DeleteResource(&outputObject, outputName, capp.Namespace); err != nil { - return fmt.Errorf("unable to delete output %q: %w ", outputName, err) - } - } - - return nil -} - -// IsRequired is responsible to determine if resource logging operator is required. -func (o OutputManager) IsRequired(capp cappv1alpha1.Capp) bool { - if capp.Spec.LogSpec != (cappv1alpha1.LogSpec{}) { - return capp.Spec.LogSpec.Type == LogTypeElastic || capp.Spec.LogSpec.Type == LogTypeSplunk - } - return false -} - -// CreateOrUpdateObject creates or updates an output object based on the provided Capp. -// It returns an error if any operation fails. -func (o OutputManager) CreateOrUpdateObject(capp cappv1alpha1.Capp) error { - outputName := capp.GetName() + "-output" - logger := o.Log.WithValues("OutputName", outputName, "OutputNamespace", capp.Namespace) - if o.IsRequired(capp) { - generatedOutput := o.prepareResource(capp) - // get instance of current output - currentOutput := loggingv1beta1.Output{} - resourceManager := rclient.ResourceBaseManagerClient{Ctx: o.Ctx, K8sclient: o.K8sclient, Log: o.Log} - logger.Info("Trying to fetch existing output") - switch err := o.K8sclient.Get(o.Ctx, types.NamespacedName{Namespace: capp.Namespace, Name: outputName}, ¤tOutput); { - case errors.IsNotFound(err): - logger.Error(err, "didn't find existing output") - if err := resourceManager.CreateResource(&generatedOutput); err != nil { - logger.Error(err, "failed to create output") - o.EventRecorder.Event(&capp, corev1.EventTypeWarning, eventCappOutputCreationFailed, fmt.Sprintf("Failed to create output %s for Capp %s", outputName, capp.Name)) - return err - } - logger.Info("Created output successfully") - o.EventRecorder.Event(&capp, corev1.EventTypeNormal, eventCappOutputCreated, fmt.Sprintf("Created output %s for Capp %s", outputName, capp.Name)) - case err != nil: - logger.Error(err, "failed to fetch existing output") - return err - } - if !reflect.DeepEqual(currentOutput.Spec, generatedOutput.Spec) { - currentOutput.Spec = generatedOutput.Spec - logger.Info("Trying to update the current") - if err := resourceManager.UpdateResource(¤tOutput); err != nil { - return fmt.Errorf("failed to update the current output %q: %w ", currentOutput.Name, err) - } - logger.Info("Current output successfully updated") - } - } - return nil -} diff --git a/internal/resource-managers/resource_prepare_interface.go b/internal/resource-managers/resource_prepare_interface.go index 35d5fb9d..3ea79d4e 100644 --- a/internal/resource-managers/resource_prepare_interface.go +++ b/internal/resource-managers/resource_prepare_interface.go @@ -11,19 +11,23 @@ type ResourceManager interface { } const ( - eventCappFlowCreationFailed = "FlowCreationFailed" - eventCappFlowCreated = "FlowCreated" - eventCappDomainMappingCreationFailed = "DomainMappingCreationFailed" - eventCappKnativeServiceCreationFailed = "KnativeServiceCreationFailed" - eventCappOutputCreationFailed = "OutputCreationFailed" - eventCappOutputCreated = "OutputCreated" - eventCappDisabled = "CappDisabled" - eventCappEnabled = "CappEnabled" - eventNFSPVCCreationFailed = "NfsPvcCreationFailed" - eventNFSPVCCreated = "NfsPvcCreated" - DomainMapping = "domainMapping" + eventCappDisabled = "CappDisabled" + eventCappEnabled = "CappEnabled" + KnativeServing = "knativeServing" - Flow = "flow" - Output = "output" - NFSPVC = "NfsPvc" + eventCappKnativeServiceCreationFailed = "KnativeServiceCreationFailed" + + DomainMapping = "domainMapping" + eventCappDomainMappingCreationFailed = "DomainMappingCreationFailed" + + NFSPVC = "NfsPvc" + eventNFSPVCCreationFailed = "NfsPvcCreationFailed" + eventNFSPVCCreated = "NfsPvcCreated" + + SyslogNGFlow = "syslogNGFlow" + SyslogNGOutput = "syslogNGOutput" + eventCappSyslogNGFlowCreationFailed = "SyslogNGFlowCreationFailed" + eventCappSyslogNGFlowCreated = "SyslogNGFlowCreated" + eventCappSyslogNGOutputCreationFailed = "SyslogNGOutputCreationFailed" + eventCappSyslogNGlSOutputCreated = "SyslogNGOutputCreated" ) diff --git a/internal/resource-managers/syslogngflow.go b/internal/resource-managers/syslogngflow.go new file mode 100644 index 00000000..3de8d544 --- /dev/null +++ b/internal/resource-managers/syslogngflow.go @@ -0,0 +1,123 @@ +package resourceprepares + +import ( + "context" + "fmt" + "reflect" + + cappv1alpha1 "github.com/dana-team/container-app-operator/api/v1alpha1" + rclient "github.com/dana-team/container-app-operator/internal/wrappers" + "github.com/go-logr/logr" + loggingv1beta1 "github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1" + "github.com/kube-logging/logging-operator/pkg/sdk/logging/model/syslogng/filter" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/record" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type SyslogNGFlowManager struct { + Ctx context.Context + K8sclient client.Client + Log logr.Logger + EventRecorder record.EventRecorder +} + +const KnativeConfiguration = "serving.knative.dev/configuration" + +// prepareResource prepares a SyslogNGFlow resource based on the provided Capp. +func (f SyslogNGFlowManager) prepareResource(capp cappv1alpha1.Capp) loggingv1beta1.SyslogNGFlow { + syslogNGFlowName := capp.GetName() + syslogNGOutputName := capp.GetName() + + syslogNGFlow := loggingv1beta1.SyslogNGFlow{ + ObjectMeta: metav1.ObjectMeta{ + Name: syslogNGFlowName, + Namespace: capp.GetNamespace(), + }, + Spec: loggingv1beta1.SyslogNGFlowSpec{ + Filters: []loggingv1beta1.SyslogNGFilter{ + { + Match: &filter.MatchConfig{ + Regexp: &filter.RegexpMatchExpr{ + Pattern: capp.GetName(), + Type: "string", + Value: fmt.Sprintf("json#kubernetes#json#%s", KnativeConfiguration), + }, + }, + }, + }, + LocalOutputRefs: []string{syslogNGOutputName}, + }, + } + return syslogNGFlow +} + +// CleanUp deletes the SyslogNGFlow resource associated with the Capp object. +// The SyslogNGFlow resource is deleted by calling the DeleteResource method of the resourceManager object. +func (f SyslogNGFlowManager) CleanUp(capp cappv1alpha1.Capp) error { + if f.IsRequired(capp) { + syslogNGFlowName := capp.GetName() + resourceManager := rclient.ResourceBaseManagerClient{Ctx: f.Ctx, K8sclient: f.K8sclient, Log: f.Log} + + syslogNGFlow := loggingv1beta1.SyslogNGFlow{} + if err := resourceManager.DeleteResource(&syslogNGFlow, syslogNGFlowName, capp.Namespace); err != nil { + return fmt.Errorf("unable to delete SyslogNGFlow %q: %w", syslogNGFlowName, err) + } + + } + + return nil +} + +// IsRequired is responsible to determine if resource logging operator SyslogNGFlow is required. +func (f SyslogNGFlowManager) IsRequired(capp cappv1alpha1.Capp) bool { + if capp.Spec.LogSpec != (cappv1alpha1.LogSpec{}) { + return capp.Spec.LogSpec.Type == LogTypeElastic + } + return false +} + +// CreateOrUpdateObject creates or updates a SyslogNGFlow object based on the provided Capp. +// It returns an error if any operation fails. +func (f SyslogNGFlowManager) CreateOrUpdateObject(capp cappv1alpha1.Capp) error { + syslogNGFlowName := capp.GetName() + logger := f.Log.WithValues("SyslogNGFlowName", syslogNGFlowName, "SyslogNGFlowNamespace", capp.Namespace) + + if f.IsRequired(capp) { + generatedSyslogNGFlow := f.prepareResource(capp) + currentSyslogNGFlow := loggingv1beta1.SyslogNGFlow{} + + resourceManager := rclient.ResourceBaseManagerClient{Ctx: f.Ctx, K8sclient: f.K8sclient, Log: f.Log} + err := f.K8sclient.Get(f.Ctx, types.NamespacedName{Namespace: capp.Namespace, Name: syslogNGFlowName}, ¤tSyslogNGFlow) + + if errors.IsNotFound(err) { + if err := resourceManager.CreateResource(&generatedSyslogNGFlow); err != nil { + f.EventRecorder.Event(&capp, corev1.EventTypeWarning, eventCappSyslogNGFlowCreationFailed, fmt.Sprintf("Failed to create SyslogNGFlow %s for Capp %s", syslogNGFlowName, capp.Name)) + return fmt.Errorf("failed to create SyslogNGFlow %q: %w", syslogNGFlowName, err) + } + + logger.Info("Successfully created SyslogNGFlow") + f.EventRecorder.Event(&capp, corev1.EventTypeNormal, eventCappSyslogNGFlowCreated, fmt.Sprintf("Created SyslogNGFlow %s for Capp %s", syslogNGFlowName, capp.Name)) + } + + if err != nil { + return fmt.Errorf("failed to fetch existing SyslogNGFlow %q: %w", syslogNGFlowName, err) + } + + if !reflect.DeepEqual(currentSyslogNGFlow.Spec, generatedSyslogNGFlow.Spec) { + currentSyslogNGFlow.Spec = generatedSyslogNGFlow.Spec + logger.Info("Trying to update the current SyslogNGFlow") + + if err := resourceManager.UpdateResource(¤tSyslogNGFlow); err != nil { + return fmt.Errorf("failed to update the current SyslogNGFlow %q: %w", syslogNGFlowName, err) + } + logger.Info("Current SyslogNGFlow successfully updated") + } + } + + return nil +} diff --git a/internal/resource-managers/syslogngoutput.go b/internal/resource-managers/syslogngoutput.go new file mode 100644 index 00000000..3e36c739 --- /dev/null +++ b/internal/resource-managers/syslogngoutput.go @@ -0,0 +1,156 @@ +package resourceprepares + +import ( + "context" + "fmt" + "reflect" + + "github.com/cisco-open/operator-tools/pkg/secret" + cappv1alpha1 "github.com/dana-team/container-app-operator/api/v1alpha1" + rclient "github.com/dana-team/container-app-operator/internal/wrappers" + "github.com/go-logr/logr" + loggingv1beta1 "github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1" + "github.com/kube-logging/logging-operator/pkg/sdk/logging/model/syslogng/output" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/record" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type SyslogNGOutputManager struct { + Ctx context.Context + K8sclient client.Client + Log logr.Logger + EventRecorder record.EventRecorder +} + +const ( + LogTypeElastic string = "elastic" + ElasticSSLVersion = "tlsv1_2" + ElasticTemplate = "$(format-json --subkeys json# --key-delimiter #)" + ElasticSecretKey = "elastic" +) + +// syslogNGOutputCreators is a map that associates log types with their corresponding SyslogNGOutput creation functions. +var syslogNGOutputCreators = map[string]func(cappv1alpha1.LogSpec) loggingv1beta1.SyslogNGOutputSpec{ + LogTypeElastic: createElasticsearchOutput, +} + +// createElasticsearchOutput creates an Elasticsearch SyslogNGOutput object based on the provided logSpec. +// It constructs the Elasticsearch SyslogNGOutput which is returned as a SyslogNGOutputSpec. +func createElasticsearchOutput(logSpec cappv1alpha1.LogSpec) loggingv1beta1.SyslogNGOutputSpec { + peerVerify := false + + syslogNGOutputSpec := loggingv1beta1.SyslogNGOutputSpec{ + Elasticsearch: &output.ElasticsearchOutput{ + Index: logSpec.Index, + Template: ElasticTemplate, + HTTPOutput: output.HTTPOutput{ + URL: logSpec.Host, + User: logSpec.User, + Password: secret.Secret{ + ValueFrom: &secret.ValueFrom{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: logSpec.PasswordSecret}, + Key: ElasticSecretKey, + }, + }, + }, + TLS: &output.TLS{ + PeerVerify: &peerVerify, + SslVersion: ElasticSSLVersion, + }, + }, + }, + } + + return syslogNGOutputSpec +} + +// prepareResource prepares a SyslogNGOutput resource based on the provided Capp. +func (o SyslogNGOutputManager) prepareResource(capp cappv1alpha1.Capp) loggingv1beta1.SyslogNGOutput { + syslogNGOutputName := capp.GetName() + + if createFunc, ok := syslogNGOutputCreators[capp.Spec.LogSpec.Type]; ok { + syslogNGOutputSpec := createFunc(capp.Spec.LogSpec) + + syslogNGOutput := loggingv1beta1.SyslogNGOutput{ + ObjectMeta: metav1.ObjectMeta{ + Name: syslogNGOutputName, + Namespace: capp.GetNamespace(), + }, + Spec: syslogNGOutputSpec, + } + return syslogNGOutput + } + + return loggingv1beta1.SyslogNGOutput{} +} + +// CleanUp deletes the SyslogNGOutput resource associated with the Capp object. +// The SyslogNGOutput resource is deleted by calling the DeleteResource method of the resourceManager object. +func (o SyslogNGOutputManager) CleanUp(capp cappv1alpha1.Capp) error { + if o.IsRequired(capp) { + syslogNGOutputName := capp.GetName() + resourceManager := rclient.ResourceBaseManagerClient{Ctx: o.Ctx, K8sclient: o.K8sclient, Log: o.Log} + syslogNGOutputObject := loggingv1beta1.SyslogNGOutput{} + + if err := resourceManager.DeleteResource(&syslogNGOutputObject, syslogNGOutputName, capp.Namespace); err != nil { + return fmt.Errorf("unable to delete SyslogNGOutput %q: %w", syslogNGOutputName, err) + } + } + + return nil +} + +// IsRequired is responsible to determine if resource logging operator is required. +func (o SyslogNGOutputManager) IsRequired(capp cappv1alpha1.Capp) bool { + if capp.Spec.LogSpec != (cappv1alpha1.LogSpec{}) { + return capp.Spec.LogSpec.Type == LogTypeElastic + } + + return false +} + +// CreateOrUpdateObject creates or updates a SyslogNGOutput object based on the provided Capp. +// It returns an error if any operation fails. +func (o SyslogNGOutputManager) CreateOrUpdateObject(capp cappv1alpha1.Capp) error { + syslogNGOutputName := capp.GetName() + logger := o.Log.WithValues("SyslogNGOutputName", syslogNGOutputName, "SyslogNGOutputNamespace", capp.Namespace) + + if o.IsRequired(capp) { + generatedSyslogNGOutput := o.prepareResource(capp) + currentSyslogNGOutput := loggingv1beta1.SyslogNGOutput{} + resourceManager := rclient.ResourceBaseManagerClient{Ctx: o.Ctx, K8sclient: o.K8sclient, Log: o.Log} + + logger.Info("Trying to fetch existing SyslogNGOutput") + err := o.K8sclient.Get(o.Ctx, types.NamespacedName{Namespace: capp.Namespace, Name: syslogNGOutputName}, ¤tSyslogNGOutput) + if errors.IsNotFound(err) { + if err := resourceManager.CreateResource(&generatedSyslogNGOutput); err != nil { + logger.Error(err, "failed to create SyslogNGOutput") + o.EventRecorder.Event(&capp, corev1.EventTypeWarning, eventCappSyslogNGOutputCreationFailed, fmt.Sprintf("Failed to create SyslogNGOutput %s for Capp %s", syslogNGOutputName, capp.Name)) + return err + } + + logger.Info("Created SyslogNGOutput successfully") + o.EventRecorder.Event(&capp, corev1.EventTypeNormal, eventCappSyslogNGlSOutputCreated, fmt.Sprintf("Created SyslogNGOutput %s for Capp %s", syslogNGOutputName, capp.Name)) + } + + if err != nil { + logger.Error(err, "failed to fetch existing SyslogNGOutput") + return err + } + + if !reflect.DeepEqual(currentSyslogNGOutput.Spec, generatedSyslogNGOutput.Spec) { + currentSyslogNGOutput.Spec = generatedSyslogNGOutput.Spec + if err := resourceManager.UpdateResource(¤tSyslogNGOutput); err != nil { + return fmt.Errorf("failed to update the current SyslogNGOutput %q: %w ", currentSyslogNGOutput.Name, err) + } + } + } + return nil +} diff --git a/internal/status/capp.go b/internal/status/capp.go index 7f094bbf..b76de16d 100644 --- a/internal/status/capp.go +++ b/internal/status/capp.go @@ -33,8 +33,8 @@ func SyncStatus(ctx context.Context, capp cappv1alpha1.Capp, log logr.Logger, r return err } - knativeServiceManger := resourceManagers[rmanagers.KnativeServing] - knativeObjectStatus, revisionInfo, err := buildKnativeStatus(ctx, r, capp, knativeServiceManger.IsRequired(capp)) + knativeServiceManager := resourceManagers[rmanagers.KnativeServing] + knativeObjectStatus, revisionInfo, err := buildKnativeStatus(ctx, r, capp, knativeServiceManager.IsRequired(capp)) if err != nil { return err } @@ -42,22 +42,22 @@ func SyncStatus(ctx context.Context, capp cappv1alpha1.Capp, log logr.Logger, r cappObject.Status.KnativeObjectStatus = knativeObjectStatus cappObject.Status.RevisionInfo = revisionInfo - FlowManager := resourceManagers[rmanagers.Flow] - loggingStatus, err := buildLoggingStatus(ctx, capp, log, r, FlowManager.IsRequired(capp)) + syslogNGFlowManager := resourceManagers[rmanagers.SyslogNGFlow] + loggingStatus, err := buildLoggingStatus(ctx, capp, log, r, syslogNGFlowManager.IsRequired(capp)) if err != nil { return err } cappObject.Status.LoggingStatus = loggingStatus - DomainMappinManger := resourceManagers[rmanagers.DomainMapping] - routeStatus, err := buildRouteStatus(ctx, r, capp, DomainMappinManger.IsRequired(capp)) + domainMappingManager := resourceManagers[rmanagers.DomainMapping] + routeStatus, err := buildRouteStatus(ctx, r, capp, domainMappingManager.IsRequired(capp)) if err != nil { return err } cappObject.Status.RouteStatus = routeStatus - NFSPVCManager := resourceManagers[rmanagers.NFSPVC] - volumesStatus, err := buildVolumesStatus(ctx, r, capp, NFSPVCManager.IsRequired(capp)) + nfspvcManager := resourceManagers[rmanagers.NFSPVC] + volumesStatus, err := buildVolumesStatus(ctx, r, capp, nfspvcManager.IsRequired(capp)) if err != nil { return err } @@ -67,8 +67,9 @@ func SyncStatus(ctx context.Context, capp cappv1alpha1.Capp, log logr.Logger, r cappObject.Status.KnativeObjectStatus = knativeObjectStatus cappObject.Status.RevisionInfo = revisionInfo cappObject.Status.ApplicationLinks = *applicationLinks + if err := r.Status().Update(ctx, &cappObject); err != nil { - log.Error(err, "can't update capp status") + log.Error(err, "failed to update Capp status") return err } diff --git a/internal/status/logging.go b/internal/status/logging.go index 70be847d..eb163400 100644 --- a/internal/status/logging.go +++ b/internal/status/logging.go @@ -13,53 +13,57 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -// buildLoggingStatus builds the Logging status of the Capp CRD by getting the Flow and Output objects +const ( + loggingResourceInvalid = "LoggingResourceInvalid" + loggingReady = "LoggingIsReady" + conditionReady = "ready" +) + +// buildLoggingStatus builds the Logging status of the Capp CRD by getting the SyslogNGFlow and SyslogNGOutput objects // bundled to the Capp and adding their status. It also creates a condition in accordance with their situation. func buildLoggingStatus(ctx context.Context, capp cappv1alpha1.Capp, log logr.Logger, r client.Client, isRequired bool) (cappv1alpha1.LoggingStatus, error) { - logger := log.WithValues("FlowName", capp.Name+"-flow", "OutputName", capp.Name+"-output") + logger := log.WithValues("SyslogNGFlowName", capp.Name, "SyslogNGOutputName", capp.Name) loggingStatus := cappv1alpha1.LoggingStatus{} if !isRequired { return loggingStatus, nil } - flow := &loggingv1beta1.Flow{} + syslogNGFlow := &loggingv1beta1.SyslogNGFlow{} logger.Info("Building logger status") - logger.Info("Trying to fetch existing flow") - if err := r.Get(ctx, types.NamespacedName{Namespace: capp.Namespace, Name: capp.Name + "-flow"}, - flow); err != nil { - logger.Error(err, "Failed to fetch flow") + if err := r.Get(ctx, types.NamespacedName{Namespace: capp.Namespace, Name: capp.Name}, syslogNGFlow); err != nil { + logger.Error(err, "Failed to fetch SyslogNGFlow") return loggingStatus, err } - logger.Info("Fetched flow successfully.") - logger.Info("Trying to fetch existing output") - output := &loggingv1beta1.Output{} - if err := r.Get(ctx, types.NamespacedName{Namespace: capp.Namespace, Name: capp.Name + "-output"}, - output); err != nil { - logger.Error(err, "Failed to fetch output") + syslogNGOutput := &loggingv1beta1.SyslogNGOutput{} + if err := r.Get(ctx, types.NamespacedName{Namespace: capp.Namespace, Name: capp.Name}, syslogNGOutput); err != nil { + logger.Error(err, "Failed to fetch SyslogNGOutput") return loggingStatus, err } + logger.Info("Fetched output successfully.") - loggingStatus.Flow = flow.Status - loggingStatus.Output = output.Status + loggingStatus.SyslogNGFlow = syslogNGFlow.Status + loggingStatus.SyslogNGOutput = syslogNGOutput.Status problems := "True" - reason := "Ready" - if flow.Status.ProblemsCount != 0 || output.Status.ProblemsCount != 0 { - reason = "LoggingResourceInvalid" + reason := conditionReady + + if syslogNGFlow.Status.ProblemsCount != 0 || syslogNGOutput.Status.ProblemsCount != 0 { + reason = loggingResourceInvalid problems = "False" } condition := metav1.Condition{ - Type: "LoggingIsReady", + Type: loggingReady, Status: metav1.ConditionStatus(problems), LastTransitionTime: metav1.Time{Time: time.Now()}, Reason: reason, } meta.SetStatusCondition(&loggingStatus.Conditions, condition) - logger.Info("Built logger status successfully ") + logger.Info("Built logger status successfully") + return loggingStatus, nil } diff --git a/test/e2e_tests/logger_e2e_test.go b/test/e2e_tests/logger_e2e_test.go index 4d1dc082..ee337a61 100644 --- a/test/e2e_tests/logger_e2e_test.go +++ b/test/e2e_tests/logger_e2e_test.go @@ -11,61 +11,52 @@ import ( . "github.com/onsi/gomega" ) -// checkOutputIndexValue checks if the output index value matches the desired value based on the logger type. -func checkOutputIndexValue(logType string, outputName string, outputNamespace string, IndexDesiredValue string) { +// checkOutputIndexValue checks if the SyslogLogOutput index value matches the desired value based on the logger type. +func checkOutputIndexValue(logType string, syslogNGOutputName string, syslogNGOutputNamespace string, IndexDesiredValue string) { switch logType { case mock.ElasticType: Eventually(func() string { - output := utilst.GetOutput(k8sClient, outputName, outputNamespace) - return output.Spec.ElasticsearchOutput.IndexName - }, testconsts.Timeout, testconsts.Interval).Should(Equal(IndexDesiredValue)) - case mock.SplunkType: - Eventually(func() string { - output := utilst.GetOutput(k8sClient, outputName, outputNamespace) - return output.Spec.SplunkHecOutput.Index + syslogNGOutput := utilst.GetSyslogNGOutput(k8sClient, syslogNGOutputName, syslogNGOutputNamespace) + return syslogNGOutput.Spec.Elasticsearch.Index }, testconsts.Timeout, testconsts.Interval).Should(Equal(IndexDesiredValue)) } } -// testCappWithLogger performs a comprehensive test for creating, updating, and deleting a Capp instance with a specified logger type. +// testCappWithLogger performs a comprehensive test for creating, updating, and deleting +// a Capp instance with a specified logger type. func testCappWithLogger(logType string) { - It(fmt.Sprintf("Should create, update, and delete flow and output when creating, updating, and deleting a Capp instance with %s logger", logType), func() { - By(fmt.Sprintf("Creating a capp with %s logger", logType)) + It(fmt.Sprintf("Should create, update, and delete SyslogNGFlow and SyslogNGOutput when creating, updating, and deleting a Capp instance with %s logger", logType), func() { + By(fmt.Sprintf("Creating a Capp with %s logger", logType)) createdCapp := utilst.CreateCappWithLogger(logType, k8sClient) - By("Checking if the output is reporting a problem when secret credentials secrert is missing") - outputName := createdCapp.Name + testconsts.OutputSuffix - outputObject := mock.CreateOutputObject(outputName) - Eventually(func() bool { - return utilst.DoesResourceExist(k8sClient, outputObject) - }, testconsts.Timeout, testconsts.Interval).Should(BeTrue(), "Should find a resource.") - Eventually(func() int { - output := utilst.GetOutput(k8sClient, outputName, createdCapp.Namespace) - return output.Status.ProblemsCount - }, testconsts.Timeout, testconsts.Interval).Should(Equal(1)) + syslogNGOutputName := createdCapp.Name + syslogNGOutputObject := mock.CreateSyslogNGOutputObject(syslogNGOutputName) By(fmt.Sprintf("Creating a secret containing %s credentials", logType)) utilst.CreateCredentialsSecret(logType, k8sClient) - By("Checking if the output is active and has no problems") + By("Checking if the SyslogNGOutput is active and has no problems") Eventually(func() bool { - output := utilst.GetOutput(k8sClient, outputName, createdCapp.Namespace) - return *output.Status.Active + syslogNGOutput := utilst.GetSyslogNGOutput(k8sClient, syslogNGOutputName, createdCapp.Namespace) + return *syslogNGOutput.Status.Active }, testconsts.Timeout, testconsts.Interval).Should(BeTrue()) + Eventually(func() int { - output := utilst.GetOutput(k8sClient, outputName, createdCapp.Namespace) - return output.Status.ProblemsCount + syslogNGOutput := utilst.GetSyslogNGOutput(k8sClient, syslogNGOutputName, createdCapp.Namespace) + return syslogNGOutput.Status.ProblemsCount }, testconsts.Timeout, testconsts.Interval).Should(Equal(0)) - By("Checking if the flow was created successfully and active") - flowName := createdCapp.Name + testconsts.FlowSuffix - flowObject := mock.CreateFlowObject(flowName) + By("Checking if the SyslogNGFlow was created successfully and active") + syslogNGFlowName := createdCapp.Name + syslogNGFlowObject := mock.CreateSyslogNGFlowObject(syslogNGFlowName) + Eventually(func() bool { - return utilst.DoesResourceExist(k8sClient, flowObject) + return utilst.DoesResourceExist(k8sClient, syslogNGFlowObject) }, testconsts.Timeout, testconsts.Interval).Should(BeTrue(), "Should find a resource.") + Eventually(func() bool { - flow := utilst.GetFlow(k8sClient, flowName, createdCapp.Namespace) - return *flow.Status.Active + syslogNGFlow := utilst.GetSyslogNGFlow(k8sClient, syslogNGFlowName, createdCapp.Namespace) + return *syslogNGFlow.Status.Active }, testconsts.Timeout, testconsts.Interval).Should(BeTrue()) By(fmt.Sprintf("Updating the capp %s logger index", logType)) @@ -73,28 +64,27 @@ func testCappWithLogger(logType string) { toBeUpdatedCapp.Spec.LogSpec.Index = testconsts.TestIndex utilst.UpdateCapp(k8sClient, toBeUpdatedCapp) - By("checking if the output index was updated") - checkOutputIndexValue(logType, outputName, createdCapp.Namespace, testconsts.TestIndex) + By("Checking if the SyslogNGOutput index was updated") + checkOutputIndexValue(logType, syslogNGOutputName, createdCapp.Namespace, testconsts.TestIndex) - By("Deleting the capp instance") + By("Deleting the Capp instance") utilst.DeleteCapp(k8sClient, createdCapp) Eventually(func() bool { return utilst.DoesResourceExist(k8sClient, createdCapp) }, testconsts.Timeout, testconsts.Interval).ShouldNot(BeTrue(), "Should not find a resource.") - By("Checking if the output was deleted successfully") + By("Checking if the SyslogNGOutput was deleted successfully") Eventually(func() bool { - return utilst.DoesResourceExist(k8sClient, outputObject) + return utilst.DoesResourceExist(k8sClient, syslogNGOutputObject) }, testconsts.Timeout, testconsts.Interval).ShouldNot(BeTrue(), "Should not find a resource.") - By("Checking if the flow was deleted successfully") + By("Checking if the SyslogNGFlow was deleted successfully") Eventually(func() bool { - return utilst.DoesResourceExist(k8sClient, flowObject) + return utilst.DoesResourceExist(k8sClient, syslogNGFlowObject) }, testconsts.Timeout, testconsts.Interval).ShouldNot(BeTrue(), "Should not find a resource.") }) } var _ = Describe("Validate Logger functionality", func() { testCappWithLogger(mock.ElasticType) - testCappWithLogger(mock.SplunkType) }) diff --git a/test/e2e_tests/mocks/logger.go b/test/e2e_tests/mocks/logger.go index eb3f9421..acbf6e69 100644 --- a/test/e2e_tests/mocks/logger.go +++ b/test/e2e_tests/mocks/logger.go @@ -9,56 +9,38 @@ import ( var ( ElasticType = "elastic" - SplunkType = "splunk" - ElasticHost = "20.76.217.187" - SplunkHost = "74.234.208.141" + ElasticHost = "1.2.3.4" MainIndex = "main" ElasticUserName = "elastic" - SplunkUserName = "bGFiZXI=" - SplunkPassword = "QWExMjM0NTYh" - HecTokenKey = "hec_token" - SplunkHecToken = "ODVhZTc2YmYtYjYyMS00MDk5LWIyYzMtOGI5OTk3NTA0OTgy" - ElasticSecretName = "quickstart-es-elastic-user" - SplunkSecretName = "splunk-single-standalone-secrets" - UsernameKey = "username" - PasswordKey = "password" - SplunkHecTokenKey = "SplunkHecToken" + ElasticSecretName = "credentials" ) +// CreateElasticLogSpec creates a Logging Spec for Elasticsearch. func CreateElasticLogSpec() cappv1alpha1.LogSpec { return cappv1alpha1.LogSpec{ - Type: ElasticType, - Host: ElasticHost, - SSLVerify: false, - Index: MainIndex, - UserName: ElasticUserName, - PasswordSecretName: ElasticSecretName, + Type: ElasticType, + Host: ElasticHost, + Index: MainIndex, + User: ElasticUserName, + PasswordSecret: ElasticSecretName, } } -func CreateSplunkLogSpec() cappv1alpha1.LogSpec { - return cappv1alpha1.LogSpec{ - Type: SplunkType, - Host: SplunkHost, - SSLVerify: false, - Index: MainIndex, - HecTokenSecretName: SplunkSecretName, - } -} - -func CreateOutputObject(outputName string) *loggingv1beta1.Output { - return &loggingv1beta1.Output{ +// CreateSyslogNGOutputObject returns a SyslogNGOutput object. +func CreateSyslogNGOutputObject(name string) *loggingv1beta1.SyslogNGOutput { + return &loggingv1beta1.SyslogNGOutput{ ObjectMeta: metav1.ObjectMeta{ - Name: outputName, + Name: name, Namespace: NSName, }, } } -func CreateFlowObject(flowName string) *loggingv1beta1.Flow { - return &loggingv1beta1.Flow{ +// CreateSyslogNGFlowObject returns a SyslogNGFlow object. +func CreateSyslogNGFlowObject(name string) *loggingv1beta1.SyslogNGFlow { + return &loggingv1beta1.SyslogNGFlow{ ObjectMeta: metav1.ObjectMeta{ - Name: flowName, + Name: name, Namespace: NSName, }, } @@ -75,15 +57,3 @@ func CreateElasticSecretObject() *corev1.Secret { Data: map[string][]byte{ElasticUserName: []byte(SecretValue)}, } } - -func CreateSplunkSecretObject() *corev1.Secret { - return &corev1.Secret{ - TypeMeta: metav1.TypeMeta{}, - ObjectMeta: metav1.ObjectMeta{ - Name: SplunkSecretName, - Namespace: NSName, - }, - Type: "Opaque", - Data: map[string][]byte{HecTokenKey: []byte(SplunkHecToken), UsernameKey: []byte(SplunkUserName), PasswordKey: []byte(SplunkPassword), SplunkHecTokenKey: []byte(SplunkHecToken)}, - } -} diff --git a/test/e2e_tests/testconsts/testconsts.go b/test/e2e_tests/testconsts/testconsts.go index 27379f69..02151b2f 100644 --- a/test/e2e_tests/testconsts/testconsts.go +++ b/test/e2e_tests/testconsts/testconsts.go @@ -21,7 +21,5 @@ const ( TestContainerName = "capp-test-container" FirstRevisionSuffix = "-00001" KnativeAutoscaleTargetKey = "autoscaling.knative.dev/target" - OutputSuffix = "-output" - FlowSuffix = "-flow" TestIndex = "test" ) diff --git a/test/e2e_tests/utils/logger_adapter.go b/test/e2e_tests/utils/logger_adapter.go index 79e1a520..71457802 100644 --- a/test/e2e_tests/utils/logger_adapter.go +++ b/test/e2e_tests/utils/logger_adapter.go @@ -13,8 +13,6 @@ func CreateCappWithLogger(logType string, client client.Client) *v1alpha1.Capp { switch logType { case mock.ElasticType: capp.Spec.LogSpec = mock.CreateElasticLogSpec() - case mock.SplunkType: - capp.Spec.LogSpec = mock.CreateSplunkLogSpec() } return CreateCapp(client, capp) } @@ -25,22 +23,19 @@ func CreateCredentialsSecret(logType string, client client.Client) { case mock.ElasticType: elasticSecret := mock.CreateElasticSecretObject() CreateSecret(client, elasticSecret) - case mock.SplunkType: - splunkSecret := mock.CreateSplunkSecretObject() - CreateSecret(client, splunkSecret) } } -// GetOutput fetches existing and returns an instance of Output. -func GetOutput(k8sClient client.Client, name string, namespace string) *loggingv1beta1.Output { - output := &loggingv1beta1.Output{} - GetResource(k8sClient, output, name, namespace) - return output +// GetSyslogNGOutput fetches existing and returns an instance of SyslogNGOutput. +func GetSyslogNGOutput(k8sClient client.Client, name string, namespace string) *loggingv1beta1.SyslogNGOutput { + syslogNGOutput := &loggingv1beta1.SyslogNGOutput{} + GetResource(k8sClient, syslogNGOutput, name, namespace) + return syslogNGOutput } -// GetFlow fetches existing and returns an instance of Flow. -func GetFlow(k8sClient client.Client, name string, namespace string) *loggingv1beta1.Flow { - flow := &loggingv1beta1.Flow{} - GetResource(k8sClient, flow, name, namespace) - return flow +// GetSyslogNGFlow fetches existing and returns an instance of SyslogNGFlow. +func GetSyslogNGFlow(k8sClient client.Client, name string, namespace string) *loggingv1beta1.SyslogNGFlow { + syslogNGFlow := &loggingv1beta1.SyslogNGFlow{} + GetResource(k8sClient, syslogNGFlow, name, namespace) + return syslogNGFlow } diff --git a/test/e2e_tests/volumes_e2e_test.go b/test/e2e_tests/volumes_e2e_test.go index 8cdb0c46..6e00a679 100644 --- a/test/e2e_tests/volumes_e2e_test.go +++ b/test/e2e_tests/volumes_e2e_test.go @@ -17,8 +17,8 @@ import ( const ( NfsPvcName = "test-volume" - TimeoutNfs = 80 * time.Second - NfsCreationInterval = 1 * time.Second + TimeoutNfs = 180 * time.Second + NfsCreationInterval = 5 * time.Second ) var _ = Describe("Validate NFSPVC functionality", func() {