diff --git a/apis/kubedb/constants.go b/apis/kubedb/constants.go index 8d21616122..ed703c796a 100644 --- a/apis/kubedb/constants.go +++ b/apis/kubedb/constants.go @@ -2121,6 +2121,16 @@ var ( core.ResourceMemory: resource.MustParse("10Gi"), }, } + + DefaultResourcesNeo4j = core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse(".500"), + core.ResourceMemory: resource.MustParse("2Gi"), + }, + Limits: core.ResourceList{ + core.ResourceMemory: resource.MustParse("2Gi"), + }, + } ) func DefaultArbiter(computeOnly bool) core.ResourceRequirements { diff --git a/apis/kubedb/v1alpha2/neo4j_helpers.go b/apis/kubedb/v1alpha2/neo4j_helpers.go index 5180597cfe..3a6beacdd8 100644 --- a/apis/kubedb/v1alpha2/neo4j_helpers.go +++ b/apis/kubedb/v1alpha2/neo4j_helpers.go @@ -21,10 +21,12 @@ import ( "fmt" "slices" + "kubedb.dev/apimachinery/apis" catalog "kubedb.dev/apimachinery/apis/catalog/v1alpha1" "kubedb.dev/apimachinery/apis/kubedb" "kubedb.dev/apimachinery/crds" + promapi "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" core "k8s.io/api/core/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -35,6 +37,7 @@ import ( meta_util "kmodules.xyz/client-go/meta" "kmodules.xyz/client-go/policy/secomp" appcat "kmodules.xyz/custom-resources/apis/appcatalog/v1alpha1" + mona "kmodules.xyz/monitoring-agent-api/api/v1" ofst "kmodules.xyz/offshoot-api/api/v2" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -131,6 +134,28 @@ func (r *Neo4j) SetDefaults(kc client.Client) { } r.setDefaultContainerSecurityContext(&neoVersion, &r.Spec.PodTemplate) + r.SetHealthCheckerDefaults() + + if r.Spec.Monitor != nil { + if r.Spec.Monitor.Prometheus == nil { + r.Spec.Monitor.Prometheus = &mona.PrometheusSpec{} + } + if r.Spec.Monitor.Prometheus.Exporter.Port == 0 { + r.Spec.Monitor.Prometheus.Exporter.Port = kubedb.Neo4jPrometheusPort + } + r.Spec.Monitor.SetDefaults() + if r.Spec.Monitor.Prometheus.Exporter.SecurityContext.RunAsUser == nil { + r.Spec.Monitor.Prometheus.Exporter.SecurityContext.RunAsUser = neoVersion.Spec.SecurityContext.RunAsUser + } + if r.Spec.Monitor.Prometheus.Exporter.SecurityContext.RunAsGroup == nil { + r.Spec.Monitor.Prometheus.Exporter.SecurityContext.RunAsGroup = neoVersion.Spec.SecurityContext.RunAsUser + } + } + + dbContainer := coreutil.GetContainerByName(r.Spec.PodTemplate.Spec.Containers, kubedb.Neo4jContainerName) + if dbContainer != nil && (dbContainer.Resources.Requests == nil && dbContainer.Resources.Limits == nil) { + apis.SetDefaultResourceLimits(&dbContainer.Resources, kubedb.DefaultResourcesNeo4j) + } } func (r *Neo4j) setDefaultContainerSecurityContext(neoVersion *catalog.Neo4jVersion, podTemplate *ofst.PodTemplateSpec) { @@ -143,6 +168,7 @@ func (r *Neo4j) setDefaultContainerSecurityContext(neoVersion *catalog.Neo4jVers if podTemplate.Spec.SecurityContext.FSGroup == nil { podTemplate.Spec.SecurityContext.FSGroup = neoVersion.Spec.SecurityContext.RunAsUser } + container := coreutil.GetContainerByName(podTemplate.Spec.Containers, kubedb.Neo4jContainerName) if container == nil { container = &core.Container{ @@ -150,6 +176,7 @@ func (r *Neo4j) setDefaultContainerSecurityContext(neoVersion *catalog.Neo4jVers } podTemplate.Spec.Containers = coreutil.UpsertContainer(podTemplate.Spec.Containers, *container) } + if container.SecurityContext == nil { container.SecurityContext = &core.SecurityContext{} } @@ -236,6 +263,9 @@ func (r *Neo4j) AppBindingMeta() appcat.AppBindingMeta { func (r *Neo4j) GetConnectionScheme() string { scheme := "http" // TODO:() + if r.Spec.TLS != nil { + scheme = "https" + } return scheme } @@ -250,3 +280,52 @@ func (r *Neo4j) SetHealthCheckerDefaults() { r.Spec.HealthChecker.FailureThreshold = ptr.To(int32(3)) } } + +func (r *Neo4j) ServiceLabels(alias ServiceAlias, extraLabels ...map[string]string) map[string]string { + svcTemplate := GetServiceTemplate(r.Spec.ServiceTemplates, alias) + return r.offshootLabels(meta_util.OverwriteKeys(r.OffshootSelectors(), extraLabels...), svcTemplate.Labels) +} + +type neo4jStatsService struct { + *Neo4j +} + +func (r neo4jStatsService) GetNamespace() string { + return r.Neo4j.GetNamespace() +} + +func (r neo4jStatsService) ServiceName() string { + return r.OffshootName() + "-stats" +} + +func (r neo4jStatsService) ServiceMonitorName() string { + return r.ServiceName() +} + +func (r neo4jStatsService) ServiceMonitorAdditionalLabels() map[string]string { + return r.OffshootLabels() +} + +func (r neo4jStatsService) Path() string { + return kubedb.DefaultStatsPath +} + +func (r neo4jStatsService) Scheme() string { + scheme := "http" // TODO:() + if r.Spec.TLS != nil { + scheme = "https" + } + return scheme +} + +func (r neo4jStatsService) TLSConfig() *promapi.TLSConfig { + return nil +} + +func (r *Neo4j) StatsService() mona.StatsAccessor { + return &neo4jStatsService{r} +} + +func (r *Neo4j) StatsServiceLabels() map[string]string { + return r.ServiceLabels(StatsServiceAlias, map[string]string{kubedb.LabelRole: kubedb.RoleStats}) +} diff --git a/apis/kubedb/v1alpha2/neo4j_types.go b/apis/kubedb/v1alpha2/neo4j_types.go index 80c4c70a17..2a07a2b591 100644 --- a/apis/kubedb/v1alpha2/neo4j_types.go +++ b/apis/kubedb/v1alpha2/neo4j_types.go @@ -20,6 +20,7 @@ import ( core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kmapi "kmodules.xyz/client-go/api/v1" + mona "kmodules.xyz/monitoring-agent-api/api/v1" ofst "kmodules.xyz/offshoot-api/api/v2" ) @@ -93,6 +94,14 @@ type Neo4jSpec struct { // +optional // +kubebuilder:default={periodSeconds: 10, timeoutSeconds: 10, failureThreshold: 3} HealthChecker kmapi.HealthCheckSpec `json:"healthChecker"` + + // Monitor is used monitor database instance + // +optional + Monitor *mona.AgentSpec `json:"monitor,omitempty"` + + // TLS contains tls configurations + // +optional + TLS *kmapi.TLSConfig `json:"tls,omitempty"` } // Neo4jStatus defines the observed state of Neo4j. diff --git a/apis/kubedb/v1alpha2/openapi_generated.go b/apis/kubedb/v1alpha2/openapi_generated.go index 32e396959e..149c91430b 100644 --- a/apis/kubedb/v1alpha2/openapi_generated.go +++ b/apis/kubedb/v1alpha2/openapi_generated.go @@ -776,6 +776,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.mssqlserverStatsService": schema_apimachinery_apis_kubedb_v1alpha2_mssqlserverStatsService(ref), "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.mysqlApp": schema_apimachinery_apis_kubedb_v1alpha2_mysqlApp(ref), "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.mysqlStatsService": schema_apimachinery_apis_kubedb_v1alpha2_mysqlStatsService(ref), + "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.neo4jStatsService": schema_apimachinery_apis_kubedb_v1alpha2_neo4jStatsService(ref), "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.oracleApp": schema_apimachinery_apis_kubedb_v1alpha2_oracleApp(ref), "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.oracleStatsService": schema_apimachinery_apis_kubedb_v1alpha2_oracleStatsService(ref), "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.perconaXtraDBApp": schema_apimachinery_apis_kubedb_v1alpha2_perconaXtraDBApp(ref), @@ -34746,12 +34747,24 @@ func schema_apimachinery_apis_kubedb_v1alpha2_Neo4jSpec(ref common.ReferenceCall Ref: ref("kmodules.xyz/client-go/api/v1.HealthCheckSpec"), }, }, + "monitor": { + SchemaProps: spec.SchemaProps{ + Description: "Monitor is used monitor database instance", + Ref: ref("kmodules.xyz/monitoring-agent-api/api/v1.AgentSpec"), + }, + }, + "tls": { + SchemaProps: spec.SchemaProps{ + Description: "TLS contains tls configurations", + Ref: ref("kmodules.xyz/client-go/api/v1.TLSConfig"), + }, + }, }, Required: []string{"version"}, }, }, Dependencies: []string{ - "k8s.io/api/core/v1.PersistentVolumeClaimSpec", "kmodules.xyz/client-go/api/v1.HealthCheckSpec", "kmodules.xyz/offshoot-api/api/v2.PodTemplateSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.ConfigurationSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.NamedServiceTemplateSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.SecretReference"}, + "k8s.io/api/core/v1.PersistentVolumeClaimSpec", "kmodules.xyz/client-go/api/v1.HealthCheckSpec", "kmodules.xyz/client-go/api/v1.TLSConfig", "kmodules.xyz/monitoring-agent-api/api/v1.AgentSpec", "kmodules.xyz/offshoot-api/api/v2.PodTemplateSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.ConfigurationSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.NamedServiceTemplateSpec", "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.SecretReference"}, } } @@ -40331,6 +40344,26 @@ func schema_apimachinery_apis_kubedb_v1alpha2_mysqlStatsService(ref common.Refer } } +func schema_apimachinery_apis_kubedb_v1alpha2_neo4jStatsService(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "Neo4j": { + SchemaProps: spec.SchemaProps{ + Ref: ref("kubedb.dev/apimachinery/apis/kubedb/v1alpha2.Neo4j"), + }, + }, + }, + Required: []string{"Neo4j"}, + }, + }, + Dependencies: []string{ + "kubedb.dev/apimachinery/apis/kubedb/v1alpha2.Neo4j"}, + } +} + func schema_apimachinery_apis_kubedb_v1alpha2_oracleApp(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/apis/kubedb/v1alpha2/zz_generated.deepcopy.go b/apis/kubedb/v1alpha2/zz_generated.deepcopy.go index 5894b7b844..45c8429803 100644 --- a/apis/kubedb/v1alpha2/zz_generated.deepcopy.go +++ b/apis/kubedb/v1alpha2/zz_generated.deepcopy.go @@ -4923,6 +4923,16 @@ func (in *Neo4jSpec) DeepCopyInto(out *Neo4jSpec) { copy(*out, *in) } in.HealthChecker.DeepCopyInto(&out.HealthChecker) + if in.Monitor != nil { + in, out := &in.Monitor, &out.Monitor + *out = new(monitoringagentapiapiv1.AgentSpec) + (*in).DeepCopyInto(*out) + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(apiv1.TLSConfig) + (*in).DeepCopyInto(*out) + } return } diff --git a/crds/kubedb.com_neo4js.yaml b/crds/kubedb.com_neo4js.yaml index 971c36d68c..b3a64b52f0 100644 --- a/crds/kubedb.com_neo4js.yaml +++ b/crds/kubedb.com_neo4js.yaml @@ -122,6 +122,226 @@ spec: format: int32 type: integer type: object + monitor: + properties: + agent: + enum: + - prometheus.io/operator + - prometheus.io + - prometheus.io/builtin + type: string + prometheus: + properties: + exporter: + properties: + args: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + 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 + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + port: + default: 56790 + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + 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 + 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + serviceMonitor: + properties: + interval: + type: string + labels: + additionalProperties: + type: string + type: object + type: object + type: object + type: object podTemplate: properties: controller: @@ -3526,6 +3746,107 @@ spec: - Durable - Ephemeral type: string + tls: + properties: + certificates: + items: + properties: + alias: + type: string + dnsNames: + items: + type: string + type: array + duration: + type: string + emailAddresses: + items: + type: string + type: array + ipAddresses: + items: + type: string + type: array + issuerRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + privateKey: + properties: + encoding: + enum: + - PKCS1 + - PKCS8 + type: string + type: object + renewBefore: + type: string + secretName: + type: string + subject: + properties: + countries: + items: + type: string + type: array + localities: + items: + type: string + type: array + organizationalUnits: + items: + type: string + type: array + organizations: + items: + type: string + type: array + postalCodes: + items: + type: string + type: array + provinces: + items: + type: string + type: array + serialNumber: + type: string + streetAddresses: + items: + type: string + type: array + type: object + uris: + items: + type: string + type: array + required: + - alias + type: object + type: array + issuerRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: object version: type: string required: