From cc2eb2c572f383a1623559ce7bb5f0ff1c8cd4da Mon Sep 17 00:00:00 2001 From: Gregory Thiemonge Date: Fri, 5 Jul 2024 14:41:22 +0000 Subject: [PATCH] Add support for external syslog servers External servers can be configured with spec: adminLogTargets: - host: xx.xx.xx.xx port: 1514 protocol: udp tenantLogTargets: ... JIRA: OSPRH-8233 --- ...octavia.openstack.org_octaviarsyslogs.yaml | 34 +++++++++++++++++++ api/bases/octavia.openstack.org_octavias.yaml | 34 +++++++++++++++++++ api/v1beta1/octaviarsyslog_types.go | 14 ++++++++ api/v1beta1/zz_generated.deepcopy.go | 25 ++++++++++++++ ...octavia.openstack.org_octaviarsyslogs.yaml | 34 +++++++++++++++++++ .../bases/octavia.openstack.org_octavias.yaml | 34 +++++++++++++++++++ controllers/octaviarsyslog_controller.go | 3 +- .../octaviarsyslog/config/10-octavia.conf | 32 +++++++++++++---- 8 files changed, 203 insertions(+), 7 deletions(-) diff --git a/api/bases/octavia.openstack.org_octaviarsyslogs.yaml b/api/bases/octavia.openstack.org_octaviarsyslogs.yaml index 28704fe3..8a160d73 100644 --- a/api/bases/octavia.openstack.org_octaviarsyslogs.yaml +++ b/api/bases/octavia.openstack.org_octaviarsyslogs.yaml @@ -49,6 +49,23 @@ spec: description: OctaviaRsyslogSpec defines common state for all Octavia Amphora Controllers properties: + adminLogTargets: + description: AdminLogTargets is a list of OctaviaRsyslogTarget, the + admin logs are forwarded to those targets + items: + properties: + host: + type: string + port: + type: integer + protocol: + type: string + required: + - host + - port + - protocol + type: object + type: array containerImage: default: quay.io/podified-antelope-centos9/openstack-rsyslog:current-podified description: ContainerImage - Amphora Controller Container Image URL @@ -133,6 +150,23 @@ spec: description: 'ServiceUser - service user name (TODO: beagles, do we need this at all)' type: string + tenantLogTargets: + description: TenantLogTargets is a list of OctaviaRsyslogTarget, the + tenant logs are forwarded to those targets + items: + properties: + host: + type: string + port: + type: integer + protocol: + type: string + required: + - host + - port + - protocol + type: object + type: array required: - serviceAccount type: object diff --git a/api/bases/octavia.openstack.org_octavias.yaml b/api/bases/octavia.openstack.org_octavias.yaml index d749dbe2..2d28c4aa 100644 --- a/api/bases/octavia.openstack.org_octavias.yaml +++ b/api/bases/octavia.openstack.org_octavias.yaml @@ -908,6 +908,23 @@ spec: description: OctaviaRsyslog - Spec definition for the Octavia Rsyslog agent for the Octavia deployment properties: + adminLogTargets: + description: AdminLogTargets is a list of OctaviaRsyslogTarget, + the admin logs are forwarded to those targets + items: + properties: + host: + type: string + port: + type: integer + protocol: + type: string + required: + - host + - port + - protocol + type: object + type: array containerImage: default: quay.io/podified-antelope-centos9/openstack-rsyslog:current-podified description: ContainerImage - Amphora Controller Container Image @@ -994,6 +1011,23 @@ spec: description: 'ServiceUser - service user name (TODO: beagles, do we need this at all)' type: string + tenantLogTargets: + description: TenantLogTargets is a list of OctaviaRsyslogTarget, + the tenant logs are forwarded to those targets + items: + properties: + host: + type: string + port: + type: integer + protocol: + type: string + required: + - host + - port + - protocol + type: object + type: array required: - serviceAccount type: object diff --git a/api/v1beta1/octaviarsyslog_types.go b/api/v1beta1/octaviarsyslog_types.go index c7485345..f67f427a 100644 --- a/api/v1beta1/octaviarsyslog_types.go +++ b/api/v1beta1/octaviarsyslog_types.go @@ -62,6 +62,14 @@ type OctaviaRsyslogSpecCore struct { // +kubebuilder:default={"octavia"} // NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network NetworkAttachments []string `json:"networkAttachments,omitempty"` + + // +kubebuilder:validation:Optional + // AdminLogTargets is a list of OctaviaRsyslogTarget, the admin logs are forwarded to those targets + AdminLogTargets []OctaviaRsyslogTarget `json:"adminLogTargets,omitempty"` + + // +kubebuilder:validation:Optional + // TenantLogTargets is a list of OctaviaRsyslogTarget, the tenant logs are forwarded to those targets + TenantLogTargets []OctaviaRsyslogTarget `json:"tenantLogTargets,omitempty"` } // OctaviaRsyslogStatus defines the observed state of the Octavia Amphora Controller @@ -112,6 +120,12 @@ type OctaviaRsyslogList struct { Items []OctaviaRsyslog `json:"items"` } +type OctaviaRsyslogTarget struct { + Host string `json:"host"` + Port int `json:"port"` + Protocol string `json:"protocol"` +} + func init() { SchemeBuilder.Register(&OctaviaRsyslog{}, &OctaviaRsyslogList{}) } diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 5e34f67e..e6ab9926 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -597,6 +597,16 @@ func (in *OctaviaRsyslogSpecCore) DeepCopyInto(out *OctaviaRsyslogSpecCore) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.AdminLogTargets != nil { + in, out := &in.AdminLogTargets, &out.AdminLogTargets + *out = make([]OctaviaRsyslogTarget, len(*in)) + copy(*out, *in) + } + if in.TenantLogTargets != nil { + in, out := &in.TenantLogTargets, &out.TenantLogTargets + *out = make([]OctaviaRsyslogTarget, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OctaviaRsyslogSpecCore. @@ -653,6 +663,21 @@ func (in *OctaviaRsyslogStatus) DeepCopy() *OctaviaRsyslogStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OctaviaRsyslogTarget) DeepCopyInto(out *OctaviaRsyslogTarget) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OctaviaRsyslogTarget. +func (in *OctaviaRsyslogTarget) DeepCopy() *OctaviaRsyslogTarget { + if in == nil { + return nil + } + out := new(OctaviaRsyslogTarget) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OctaviaSpec) DeepCopyInto(out *OctaviaSpec) { *out = *in diff --git a/config/crd/bases/octavia.openstack.org_octaviarsyslogs.yaml b/config/crd/bases/octavia.openstack.org_octaviarsyslogs.yaml index 28704fe3..8a160d73 100644 --- a/config/crd/bases/octavia.openstack.org_octaviarsyslogs.yaml +++ b/config/crd/bases/octavia.openstack.org_octaviarsyslogs.yaml @@ -49,6 +49,23 @@ spec: description: OctaviaRsyslogSpec defines common state for all Octavia Amphora Controllers properties: + adminLogTargets: + description: AdminLogTargets is a list of OctaviaRsyslogTarget, the + admin logs are forwarded to those targets + items: + properties: + host: + type: string + port: + type: integer + protocol: + type: string + required: + - host + - port + - protocol + type: object + type: array containerImage: default: quay.io/podified-antelope-centos9/openstack-rsyslog:current-podified description: ContainerImage - Amphora Controller Container Image URL @@ -133,6 +150,23 @@ spec: description: 'ServiceUser - service user name (TODO: beagles, do we need this at all)' type: string + tenantLogTargets: + description: TenantLogTargets is a list of OctaviaRsyslogTarget, the + tenant logs are forwarded to those targets + items: + properties: + host: + type: string + port: + type: integer + protocol: + type: string + required: + - host + - port + - protocol + type: object + type: array required: - serviceAccount type: object diff --git a/config/crd/bases/octavia.openstack.org_octavias.yaml b/config/crd/bases/octavia.openstack.org_octavias.yaml index d749dbe2..2d28c4aa 100644 --- a/config/crd/bases/octavia.openstack.org_octavias.yaml +++ b/config/crd/bases/octavia.openstack.org_octavias.yaml @@ -908,6 +908,23 @@ spec: description: OctaviaRsyslog - Spec definition for the Octavia Rsyslog agent for the Octavia deployment properties: + adminLogTargets: + description: AdminLogTargets is a list of OctaviaRsyslogTarget, + the admin logs are forwarded to those targets + items: + properties: + host: + type: string + port: + type: integer + protocol: + type: string + required: + - host + - port + - protocol + type: object + type: array containerImage: default: quay.io/podified-antelope-centos9/openstack-rsyslog:current-podified description: ContainerImage - Amphora Controller Container Image @@ -994,6 +1011,23 @@ spec: description: 'ServiceUser - service user name (TODO: beagles, do we need this at all)' type: string + tenantLogTargets: + description: TenantLogTargets is a list of OctaviaRsyslogTarget, + the tenant logs are forwarded to those targets + items: + properties: + host: + type: string + port: + type: integer + protocol: + type: string + required: + - host + - port + - protocol + type: object + type: array required: - serviceAccount type: object diff --git a/controllers/octaviarsyslog_controller.go b/controllers/octaviarsyslog_controller.go index c613e9fc..09e02ca7 100644 --- a/controllers/octaviarsyslog_controller.go +++ b/controllers/octaviarsyslog_controller.go @@ -374,7 +374,8 @@ func (r *OctaviaRsyslogReconciler) generateServiceConfigMaps( } templateParameters := map[string]interface{}{} - templateParameters["LogTargets"] = []string{} + templateParameters["AdminLogTargets"] = instance.Spec.AdminLogTargets + templateParameters["TenantLogTargets"] = instance.Spec.TenantLogTargets spec := instance.Spec templateParameters["ServiceUser"] = spec.ServiceUser diff --git a/templates/octaviarsyslog/config/10-octavia.conf b/templates/octaviarsyslog/config/10-octavia.conf index 3bd9e555..1135ff12 100644 --- a/templates/octaviarsyslog/config/10-octavia.conf +++ b/templates/octaviarsyslog/config/10-octavia.conf @@ -2,30 +2,50 @@ module(load="imudp") input(type="imudp" address="0.0.0.0" port="514") input(type="imudp" address="::" port="514") +{{ if .TenantLogTargets }} +ruleset(name="tenant_forwarding" queue.type="linkedList" queue.size="10000") { +{{ range $index, $val := .TenantLogTargets }} + action(type="omfwd" + target="{{ $val.Host }}" + port="{{ $val.Port }}" + protocol="{{ $val.Protocol }}" + action.resumeRetryCount="5" + action.resumeInterval="2" + {{ if $index }}action.execOnlyWhenPreviousIsSuspended="on"{{- end }}) +{{- end }} +} +{{- end }} + +{{ if .AdminLogTargets }} ruleset(name="admin_forwarding" queue.type="linkedList" queue.size="10000") { -{{ range $index, $val := .LogTargets }} +{{ range $index, $val := .AdminLogTargets }} action(type="omfwd" target="{{ $val.Host }}" port="{{ $val.Port }}" - protocol="udp" + protocol="{{ $val.Protocol }}" action.resumeRetryCount="5" action.resumeInterval="2" {{ if $index }}action.execOnlyWhenPreviousIsSuspended="on"{{- end }}) {{- end }} } +{{- end }} module(load="omstdout") # Output the amphora tenant traffic flow logs if ($inputname == "imudp" and $syslogfacility-text == "local0" and $syslogseverity-text == "info" and $hostname startswith "amphora") then { action(type="omstdout") - #action(type="omfile" FileCreateMode="0644" File="/var/log/octavia/octavia-tenant-traffic.log") - # call tenant_forwarding + {{ if .TenantLogTargets }} + call tenant_forwarding + {{ end }} + stop } # Output the amphora administrative logs if ($inputname == "imudp" and $syslogfacility-text != "local0" and $hostname startswith "amphora") then { action(type="omstdout") - #action(type="omfile" FileCreateMode="0644" File="/var/log/octavia/octavia-amphora.log") - # call admin_forwarding + {{ if .AdminLogTargets }} + call admin_forwarding + {{ end }} + stop } \ No newline at end of file