From 566d573f441a633814a09098893fd0a758ff1c87 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 10:00:41 +0200 Subject: [PATCH 01/11] Rename nodes to nodeSets, nodeCount to count --- NOTICE.txt | 29 -- .../crds/apm.k8s.elastic.co_apmservers.yaml | 336 ------------------ .../crds/kibana.k8s.elastic.co_kibanas.yaml | 326 ----------------- config/samples/apm/apm_es_kibana.yaml | 8 +- config/samples/apm/apmserver.yaml | 2 +- .../samples/elasticsearch/elasticsearch.yaml | 4 +- config/samples/kibana/kibana.yaml | 28 +- config/samples/kibana/kibana_es.yaml | 6 +- docs/advanced-node-scheduling.asciidoc | 48 ++- docs/apm.asciidoc | 8 +- docs/elasticsearch-spec.asciidoc | 12 +- docs/k8s-quickstart.asciidoc | 15 +- docs/openshift.asciidoc | 11 +- docs/snapshots.asciidoc | 12 +- pkg/apis/apm/v1beta1/apmserver_types.go | 6 +- .../v1beta1/elasticsearch_types.go | 24 +- .../v1beta1/zz_generated.deepcopy.go | 14 +- pkg/apis/kibana/v1alpha1/kibana_types.go | 2 +- pkg/apis/kibana/v1beta1/kibana_types.go | 6 +- .../apmserver/apmserver_controller.go | 2 +- .../common/association/conf_test.go | 20 +- .../elasticsearch/driver/esstate.go | 2 +- .../elasticsearch/driver/upscale.go | 2 +- pkg/controller/elasticsearch/name/name.go | 6 +- .../elasticsearch/name/name_test.go | 2 +- .../elasticsearch/nodespec/podspec.go | 4 +- .../elasticsearch/nodespec/podspec_test.go | 14 +- .../elasticsearch/nodespec/resources.go | 6 +- .../elasticsearch/nodespec/statefulset.go | 4 +- .../elasticsearch/nodespec/volumes.go | 2 +- .../validation/validation_test.go | 8 +- .../elasticsearch/validation/validations.go | 18 +- .../validation/validations_test.go | 32 +- pkg/controller/kibana/driver.go | 2 +- pkg/controller/kibana/driver_test.go | 6 +- .../license_controller_integration_test.go | 6 +- test/e2e/es/naming_test.go | 4 +- test/e2e/es/reversal_test.go | 14 +- test/e2e/test/apmserver/builder.go | 6 +- test/e2e/test/apmserver/checks_k8s.go | 10 +- test/e2e/test/elasticsearch/builder.go | 48 +-- test/e2e/test/elasticsearch/checks_data.go | 4 +- test/e2e/test/elasticsearch/checks_es.go | 8 +- test/e2e/test/elasticsearch/checks_volume.go | 2 +- test/e2e/test/elasticsearch/settings.go | 6 +- test/e2e/test/elasticsearch/steps_mutation.go | 2 +- test/e2e/test/kibana/builder.go | 2 +- test/e2e/test/kibana/checks_k8s.go | 10 +- test/e2e/test/kibana/checks_kb.go | 2 +- 49 files changed, 243 insertions(+), 908 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 47660bcf8b..2441d9fbce 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -8,35 +8,6 @@ Third party libraries used by the Elastic Cloud on Kubernetes project ================================================================================ --------------------------------------------------------------------------------- -Module : github.com/Masterminds/sprig -Version : v2.20.0+incompatible -Time : 2019-06-18 15:54:40 +0000 UTC - -Contents of probable licence file $GOMODCACHE/github.com/!masterminds/sprig@v2.20.0+incompatible/LICENSE.txt: - -Sprig -Copyright (C) 2013 Masterminds - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -------------------------------------------------------------------------------- Module : github.com/davecgh/go-spew Version : v1.1.1 diff --git a/config/crds/apm.k8s.elastic.co_apmservers.yaml b/config/crds/apm.k8s.elastic.co_apmservers.yaml index 7a78e85cf1..5ebbecc1d2 100644 --- a/config/crds/apm.k8s.elastic.co_apmservers.yaml +++ b/config/crds/apm.k8s.elastic.co_apmservers.yaml @@ -34,342 +34,6 @@ spec: scope: Namespaced subresources: status: {} - validation: - openAPIV3Schema: - description: ApmServer is the Schema for the apmservers 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/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/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ApmServerSpec defines the desired state of ApmServer - properties: - config: - description: Config represents the APM configuration. - type: object - elasticsearchRef: - description: ElasticsearchRef references an Elasticsearch resource in - the Kubernetes cluster. If the namespace is not specified, the current - resource namespace will be used. - properties: - name: - type: string - namespace: - type: string - required: - - name - type: object - http: - description: HTTP contains settings for HTTP. - properties: - service: - description: Service is a template for the Kubernetes Service - properties: - metadata: - description: ObjectMeta is metadata for the service. The name - and namespace provided here is managed by ECK and will be - ignored. - type: object - spec: - description: Spec defines the behavior of the service. - properties: - clusterIP: - description: 'clusterIP is the IP address of the service - and is usually assigned randomly by the master. If an - address is specified manually and is not in use by others, - it will be allocated to the service; otherwise, creation - of the service will fail. This field can not be changed - through updates. Valid values are "None", empty string - (""), or a valid IP address. "None" can be specified for - headless services when proxying is not required. Only - applies to types ClusterIP, NodePort, and LoadBalancer. - Ignored if type is ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' - type: string - externalIPs: - description: externalIPs is a list of IP addresses for which - nodes in the cluster will also accept traffic for this - service. These IPs are not managed by Kubernetes. The - user is responsible for ensuring that traffic arrives - at a node with this IP. A common example is external - load-balancers that are not part of the Kubernetes system. - items: - type: string - type: array - externalName: - description: externalName is the external reference that - kubedns or equivalent will return as a CNAME record for - this service. No proxying will be involved. Must be a - valid RFC-1123 hostname (https://tools.ietf.org/html/rfc1123) - and requires Type to be ExternalName. - type: string - externalTrafficPolicy: - description: externalTrafficPolicy denotes if this Service - desires to route external traffic to node-local or cluster-wide - endpoints. "Local" preserves the client source IP and - avoids a second hop for LoadBalancer and Nodeport type - services, but risks potentially imbalanced traffic spreading. - "Cluster" obscures the client source IP and may cause - a second hop to another node, but should have good overall - load-spreading. - type: string - healthCheckNodePort: - description: healthCheckNodePort specifies the healthcheck - nodePort for the service. If not specified, HealthCheckNodePort - is created by the service api backend with the allocated - nodePort. Will use user-specified nodePort value if specified - by the client. Only effects when Type is set to LoadBalancer - and ExternalTrafficPolicy is set to Local. - format: int32 - type: integer - loadBalancerIP: - description: 'Only applies to Service Type: LoadBalancer - LoadBalancer will get created with the IP specified in - this field. This feature depends on whether the underlying - cloud-provider supports specifying the loadBalancerIP - when a load balancer is created. This field will be ignored - if the cloud-provider does not support the feature.' - type: string - loadBalancerSourceRanges: - description: 'If specified and supported by the platform, - this will restrict traffic through the cloud-provider - load-balancer will be restricted to the specified client - IPs. This field will be ignored if the cloud-provider - does not support the feature." More info: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/' - items: - type: string - type: array - ports: - description: 'The list of ports that are exposed by this - service. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' - items: - description: ServicePort contains information on service's - port. - properties: - name: - description: The name of this port within the service. - This must be a DNS_LABEL. All ports within a ServiceSpec - must have unique names. This maps to the 'Name' - field in EndpointPort objects. Optional if only - one ServicePort is defined on this service. - type: string - nodePort: - description: 'The port on each node on which this - service is exposed when type=NodePort or LoadBalancer. - Usually assigned by the system. If specified, it - will be allocated to the service if unused or else - creation of the service will fail. Default is to - auto-allocate a port if the ServiceType of this - Service requires one. More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport' - format: int32 - type: integer - port: - description: The port that will be exposed by this - service. - format: int32 - type: integer - protocol: - description: The IP protocol for this port. Supports - "TCP", "UDP", and "SCTP". Default is TCP. - type: string - targetPort: - anyOf: - - type: string - - type: integer - description: 'Number or name of the port to access - on the pods targeted by the service. Number must - be in the range 1 to 65535. Name must be an IANA_SVC_NAME. - If this is a string, it will be looked up as a named - port in the target Pod''s container ports. If this - is not specified, the value of the ''port'' field - is used (an identity map). This field is ignored - for services with clusterIP=None, and should be - omitted or set equal to the ''port'' field. More - info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service' - required: - - port - type: object - type: array - publishNotReadyAddresses: - description: publishNotReadyAddresses, when set to true, - indicates that DNS implementations must publish the notReadyAddresses - of subsets for the Endpoints associated with the Service. - The default value is false. The primary use case for setting - this field is to use a StatefulSet's Headless Service - to propagate SRV records for its Pods without respect - to their readiness for purpose of peer discovery. - type: boolean - selector: - additionalProperties: - type: string - description: 'Route service traffic to pods with label keys - and values matching this selector. If empty or not present, - the service is assumed to have an external process managing - its endpoints, which Kubernetes will not modify. Only - applies to types ClusterIP, NodePort, and LoadBalancer. - Ignored if type is ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/' - type: object - sessionAffinity: - description: 'Supports "ClientIP" and "None". Used to maintain - session affinity. Enable client IP based session affinity. - Must be ClientIP or None. Defaults to None. More info: - https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' - type: string - sessionAffinityConfig: - description: sessionAffinityConfig contains the configurations - of session affinity. - properties: - clientIP: - description: clientIP contains the configurations of - Client IP based session affinity. - properties: - timeoutSeconds: - description: timeoutSeconds specifies the seconds - of ClientIP type session sticky time. The value - must be >0 && <=86400(for 1 day) if ServiceAffinity - == "ClientIP". Default value is 10800(for 3 hours). - format: int32 - type: integer - type: object - type: object - type: - description: 'type determines how the Service is exposed. - Defaults to ClusterIP. Valid options are ExternalName, - ClusterIP, NodePort, and LoadBalancer. "ExternalName" - maps to the specified externalName. "ClusterIP" allocates - a cluster-internal IP address for load-balancing to endpoints. - Endpoints are determined by the selector or if that is - not specified, by manual construction of an Endpoints - object. If clusterIP is "None", no virtual IP is allocated - and the endpoints are published as a set of endpoints - rather than a stable IP. "NodePort" builds on ClusterIP - and allocates a port on every node which routes to the - clusterIP. "LoadBalancer" builds on NodePort and creates - an external load-balancer (if supported in the current - cloud) which routes to the clusterIP. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types' - type: string - type: object - type: object - tls: - description: TLS describe additional options to consider when generating - HTTP TLS certificates. - properties: - certificate: - description: "Certificate is a reference to a secret that contains - the certificate and private key to be used. \n The secret - should have the following content: \n - `ca.crt`: The certificate - authority (optional) - `tls.crt`: The certificate (or a chain). - - `tls.key`: The private key to the first certificate in the - certificate chain." - properties: - secretName: - type: string - type: object - selfSignedCertificate: - description: SelfSignedCertificate define options to apply to - self-signed certificate managed by the operator. - properties: - disabled: - description: Disabled turns off the provisioning of self-signed - HTTP TLS certificates. - type: boolean - subjectAltNames: - description: 'SubjectAlternativeNames is a list of SANs - to include in the HTTP TLS certificates. For example: - a wildcard DNS to expose the cluster.' - items: - properties: - dns: - type: string - ip: - type: string - type: object - type: array - type: object - type: object - type: object - image: - description: Image represents the docker image that will be used. - type: string - nodeCount: - description: NodeCount defines how many nodes the Apm Server deployment - must have. - format: int32 - type: integer - secureSettings: - description: SecureSettings references secrets containing secure settings, - to be injected into the APM keystore on each node. Each individual - key/value entry in the referenced secrets is considered as an individual - secure setting to be injected. You can use the `entries` and `key` - fields to consider only a subset of the secret entries and the `path` - field to change the target path of a secret entry key. The secret - must exist in the same namespace as the APM resource. - items: - properties: - entries: - description: If unspecified, each key-value pair in the Data field - of the referenced Secret will be projected into the volume as - a file whose name is the key and content is the value. If specified, - the listed keys will be projected into the specified paths, - and unlisted keys will not be present. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: The key to project. - type: string - path: - description: The relative path of the file to map the key - to. May not be an absolute path. May not contain the path - element '..'. May not start with the string '..'. - type: string - required: - - key - type: object - type: array - secretName: - description: 'Name of the secret in the pod''s namespace to use. - More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - type: string - required: - - secretName - type: object - type: array - version: - description: Version represents the version of the APM Server - type: string - type: object - status: - description: ApmServerStatus defines the observed state of ApmServer - properties: - associationStatus: - description: Association is the status of any auto-linking to Elasticsearch - clusters. - type: string - availableNodes: - type: integer - health: - description: ApmServerHealth expresses the status of the Apm Server - instances. - type: string - secretTokenSecret: - description: SecretTokenSecretName is the name of the Secret that contains - the secret token - type: string - service: - description: ExternalService is the name of the service the agents should - connect to. - type: string - type: object - type: object version: v1alpha1 versions: - name: v1alpha1 diff --git a/config/crds/kibana.k8s.elastic.co_kibanas.yaml b/config/crds/kibana.k8s.elastic.co_kibanas.yaml index fe2e21bfcc..d30a436415 100644 --- a/config/crds/kibana.k8s.elastic.co_kibanas.yaml +++ b/config/crds/kibana.k8s.elastic.co_kibanas.yaml @@ -34,332 +34,6 @@ spec: scope: Namespaced subresources: status: {} - validation: - openAPIV3Schema: - description: Kibana is the Schema for the kibanas 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/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/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: KibanaSpec defines the desired state of Kibana - properties: - config: - description: Config represents Kibana configuration. - type: object - elasticsearchRef: - description: ElasticsearchRef references an Elasticsearch resource in - the Kubernetes cluster. If the namespace is not specified, the current - resource namespace will be used. - properties: - name: - type: string - namespace: - type: string - required: - - name - type: object - http: - description: HTTP contains settings for HTTP. - properties: - service: - description: Service is a template for the Kubernetes Service - properties: - metadata: - description: ObjectMeta is metadata for the service. The name - and namespace provided here is managed by ECK and will be - ignored. - type: object - spec: - description: Spec defines the behavior of the service. - properties: - clusterIP: - description: 'clusterIP is the IP address of the service - and is usually assigned randomly by the master. If an - address is specified manually and is not in use by others, - it will be allocated to the service; otherwise, creation - of the service will fail. This field can not be changed - through updates. Valid values are "None", empty string - (""), or a valid IP address. "None" can be specified for - headless services when proxying is not required. Only - applies to types ClusterIP, NodePort, and LoadBalancer. - Ignored if type is ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' - type: string - externalIPs: - description: externalIPs is a list of IP addresses for which - nodes in the cluster will also accept traffic for this - service. These IPs are not managed by Kubernetes. The - user is responsible for ensuring that traffic arrives - at a node with this IP. A common example is external - load-balancers that are not part of the Kubernetes system. - items: - type: string - type: array - externalName: - description: externalName is the external reference that - kubedns or equivalent will return as a CNAME record for - this service. No proxying will be involved. Must be a - valid RFC-1123 hostname (https://tools.ietf.org/html/rfc1123) - and requires Type to be ExternalName. - type: string - externalTrafficPolicy: - description: externalTrafficPolicy denotes if this Service - desires to route external traffic to node-local or cluster-wide - endpoints. "Local" preserves the client source IP and - avoids a second hop for LoadBalancer and Nodeport type - services, but risks potentially imbalanced traffic spreading. - "Cluster" obscures the client source IP and may cause - a second hop to another node, but should have good overall - load-spreading. - type: string - healthCheckNodePort: - description: healthCheckNodePort specifies the healthcheck - nodePort for the service. If not specified, HealthCheckNodePort - is created by the service api backend with the allocated - nodePort. Will use user-specified nodePort value if specified - by the client. Only effects when Type is set to LoadBalancer - and ExternalTrafficPolicy is set to Local. - format: int32 - type: integer - loadBalancerIP: - description: 'Only applies to Service Type: LoadBalancer - LoadBalancer will get created with the IP specified in - this field. This feature depends on whether the underlying - cloud-provider supports specifying the loadBalancerIP - when a load balancer is created. This field will be ignored - if the cloud-provider does not support the feature.' - type: string - loadBalancerSourceRanges: - description: 'If specified and supported by the platform, - this will restrict traffic through the cloud-provider - load-balancer will be restricted to the specified client - IPs. This field will be ignored if the cloud-provider - does not support the feature." More info: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/' - items: - type: string - type: array - ports: - description: 'The list of ports that are exposed by this - service. More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' - items: - description: ServicePort contains information on service's - port. - properties: - name: - description: The name of this port within the service. - This must be a DNS_LABEL. All ports within a ServiceSpec - must have unique names. This maps to the 'Name' - field in EndpointPort objects. Optional if only - one ServicePort is defined on this service. - type: string - nodePort: - description: 'The port on each node on which this - service is exposed when type=NodePort or LoadBalancer. - Usually assigned by the system. If specified, it - will be allocated to the service if unused or else - creation of the service will fail. Default is to - auto-allocate a port if the ServiceType of this - Service requires one. More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport' - format: int32 - type: integer - port: - description: The port that will be exposed by this - service. - format: int32 - type: integer - protocol: - description: The IP protocol for this port. Supports - "TCP", "UDP", and "SCTP". Default is TCP. - type: string - targetPort: - anyOf: - - type: string - - type: integer - description: 'Number or name of the port to access - on the pods targeted by the service. Number must - be in the range 1 to 65535. Name must be an IANA_SVC_NAME. - If this is a string, it will be looked up as a named - port in the target Pod''s container ports. If this - is not specified, the value of the ''port'' field - is used (an identity map). This field is ignored - for services with clusterIP=None, and should be - omitted or set equal to the ''port'' field. More - info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service' - required: - - port - type: object - type: array - publishNotReadyAddresses: - description: publishNotReadyAddresses, when set to true, - indicates that DNS implementations must publish the notReadyAddresses - of subsets for the Endpoints associated with the Service. - The default value is false. The primary use case for setting - this field is to use a StatefulSet's Headless Service - to propagate SRV records for its Pods without respect - to their readiness for purpose of peer discovery. - type: boolean - selector: - additionalProperties: - type: string - description: 'Route service traffic to pods with label keys - and values matching this selector. If empty or not present, - the service is assumed to have an external process managing - its endpoints, which Kubernetes will not modify. Only - applies to types ClusterIP, NodePort, and LoadBalancer. - Ignored if type is ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/' - type: object - sessionAffinity: - description: 'Supports "ClientIP" and "None". Used to maintain - session affinity. Enable client IP based session affinity. - Must be ClientIP or None. Defaults to None. More info: - https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies' - type: string - sessionAffinityConfig: - description: sessionAffinityConfig contains the configurations - of session affinity. - properties: - clientIP: - description: clientIP contains the configurations of - Client IP based session affinity. - properties: - timeoutSeconds: - description: timeoutSeconds specifies the seconds - of ClientIP type session sticky time. The value - must be >0 && <=86400(for 1 day) if ServiceAffinity - == "ClientIP". Default value is 10800(for 3 hours). - format: int32 - type: integer - type: object - type: object - type: - description: 'type determines how the Service is exposed. - Defaults to ClusterIP. Valid options are ExternalName, - ClusterIP, NodePort, and LoadBalancer. "ExternalName" - maps to the specified externalName. "ClusterIP" allocates - a cluster-internal IP address for load-balancing to endpoints. - Endpoints are determined by the selector or if that is - not specified, by manual construction of an Endpoints - object. If clusterIP is "None", no virtual IP is allocated - and the endpoints are published as a set of endpoints - rather than a stable IP. "NodePort" builds on ClusterIP - and allocates a port on every node which routes to the - clusterIP. "LoadBalancer" builds on NodePort and creates - an external load-balancer (if supported in the current - cloud) which routes to the clusterIP. More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types' - type: string - type: object - type: object - tls: - description: TLS describe additional options to consider when generating - HTTP TLS certificates. - properties: - certificate: - description: "Certificate is a reference to a secret that contains - the certificate and private key to be used. \n The secret - should have the following content: \n - `ca.crt`: The certificate - authority (optional) - `tls.crt`: The certificate (or a chain). - - `tls.key`: The private key to the first certificate in the - certificate chain." - properties: - secretName: - type: string - type: object - selfSignedCertificate: - description: SelfSignedCertificate define options to apply to - self-signed certificate managed by the operator. - properties: - disabled: - description: Disabled turns off the provisioning of self-signed - HTTP TLS certificates. - type: boolean - subjectAltNames: - description: 'SubjectAlternativeNames is a list of SANs - to include in the HTTP TLS certificates. For example: - a wildcard DNS to expose the cluster.' - items: - properties: - dns: - type: string - ip: - type: string - type: object - type: array - type: object - type: object - type: object - image: - description: Image represents the docker image that will be used. - type: string - nodeCount: - description: NodeCount defines how many nodes the Kibana deployment - must have. - format: int32 - type: integer - secureSettings: - description: SecureSettings references secrets containing secure settings, - to be injected into Kibana keystore on each node. Each individual - key/value entry in the referenced secrets is considered as an individual - secure setting to be injected. You can use the `entries` and `key` - fields to consider only a subset of the secret entries and the `path` - field to change the target path of a secret entry key. The secret - must exist in the same namespace as the Kibana resource. - items: - properties: - entries: - description: If unspecified, each key-value pair in the Data field - of the referenced Secret will be projected into the volume as - a file whose name is the key and content is the value. If specified, - the listed keys will be projected into the specified paths, - and unlisted keys will not be present. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: The key to project. - type: string - path: - description: The relative path of the file to map the key - to. May not be an absolute path. May not contain the path - element '..'. May not start with the string '..'. - type: string - required: - - key - type: object - type: array - secretName: - description: 'Name of the secret in the pod''s namespace to use. - More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - type: string - required: - - secretName - type: object - type: array - version: - description: Version represents the version of Kibana - type: string - type: object - status: - description: KibanaStatus defines the observed state of Kibana - properties: - associationStatus: - description: AssociationStatus is the status of an association resource. - type: string - availableNodes: - type: integer - health: - description: KibanaHealth expresses the status of the Kibana instances. - type: string - type: object - type: object version: v1alpha1 versions: - name: v1alpha1 diff --git a/config/samples/apm/apm_es_kibana.yaml b/config/samples/apm/apm_es_kibana.yaml index 678e506fb7..f9ed330416 100644 --- a/config/samples/apm/apm_es_kibana.yaml +++ b/config/samples/apm/apm_es_kibana.yaml @@ -6,9 +6,9 @@ metadata: name: es-apm-sample spec: version: 7.4.0 - nodes: + nodeSets: - name: default - nodeCount: 3 + count: 3 --- apiVersion: apm.k8s.elastic.co/v1beta1 kind: ApmServer @@ -16,7 +16,7 @@ metadata: name: apm-apm-sample spec: version: 7.4.0 - nodeCount: 1 + count: 1 elasticsearchRef: name: "es-apm-sample" --- @@ -26,6 +26,6 @@ metadata: name: kb-apm-sample spec: version: 7.4.0 - nodeCount: 1 + count: 1 elasticsearchRef: name: "es-apm-sample" diff --git a/config/samples/apm/apmserver.yaml b/config/samples/apm/apmserver.yaml index 7ee330eb93..0ca72fe776 100644 --- a/config/samples/apm/apmserver.yaml +++ b/config/samples/apm/apmserver.yaml @@ -4,7 +4,7 @@ metadata: name: apmserver-sample spec: version: 7.4.0 - nodeCount: 1 + count: 1 config: output.console: pretty: true diff --git a/config/samples/elasticsearch/elasticsearch.yaml b/config/samples/elasticsearch/elasticsearch.yaml index 0f517a3f47..6af26b1800 100644 --- a/config/samples/elasticsearch/elasticsearch.yaml +++ b/config/samples/elasticsearch/elasticsearch.yaml @@ -5,7 +5,7 @@ metadata: name: elasticsearch-sample spec: version: 7.4.0 - nodes: + nodeSets: - name: default config: # most Elasticsearch configuration parameters are possible to set, e.g: @@ -30,7 +30,7 @@ spec: env: - name: ES_JAVA_OPTS value: "-Xms2g -Xmx2g" - nodeCount: 3 + count: 3 # # request 2Gi of persistent data storage for pods in this topology element # volumeClaimTemplates: # - metadata: diff --git a/config/samples/kibana/kibana.yaml b/config/samples/kibana/kibana.yaml index 8655e522fd..441860caf4 100644 --- a/config/samples/kibana/kibana.yaml +++ b/config/samples/kibana/kibana.yaml @@ -5,16 +5,24 @@ metadata: name: kibana-sample spec: version: 7.4.0 - elasticsearch: - url: https://url.to.elasticsearch:9200 - auth: - # reference to a secret containing credentials in the given key - secret: - name: secret-name - key: user # key is the user, value is the password for that user - certificateAuthorities: - secretName: my-ca-cert # reference to a secret containing certificates under "tls.crt" - nodeCount: 1 + config: + elasticsearch.hosts: + - https://url.to.elasticsearch:9200 + elasticsearch.username: my-kibana-user + elasticsearch.password: $PASSWORD + elasticsearch.ssl.certificateAuthorities: /mnt/certs/elasticsearch/ca.crt + count: 1 + podTemplate: + spec: + containers: + - name: kibana + volumeMounts: + - name: certs + mountPath: /mnt/certs/elasticsearch + volumes: + - name: certs + secret: + secretName: my-es-http-certs # http: # service: # spec: diff --git a/config/samples/kibana/kibana_es.yaml b/config/samples/kibana/kibana_es.yaml index 18a7a25b01..7b570be7c3 100644 --- a/config/samples/kibana/kibana_es.yaml +++ b/config/samples/kibana/kibana_es.yaml @@ -5,9 +5,9 @@ metadata: name: elasticsearch-sample spec: version: 7.4.0 - nodes: + nodeSets: - name: default - nodeCount: 1 + count: 1 --- apiVersion: kibana.k8s.elastic.co/v1beta1 kind: Kibana @@ -15,7 +15,7 @@ metadata: name: kibana-sample spec: version: 7.4.0 - nodeCount: 1 + count: 1 elasticsearchRef: name: "elasticsearch-sample" #http: diff --git a/docs/advanced-node-scheduling.asciidoc b/docs/advanced-node-scheduling.asciidoc index 5b0a3f962e..de71da3c11 100644 --- a/docs/advanced-node-scheduling.asciidoc +++ b/docs/advanced-node-scheduling.asciidoc @@ -25,16 +25,18 @@ metadata: name: quickstart spec: version: {version} - nodes: + nodeSets: # 3 dedicated master nodes - - nodeCount: 3 + - name: master + count: 3 config: node.master: true node.data: false node.ingest: false cluster.remote.connect: false # 3 ingest-data nodes - - nodeCount: 3 + - name: ingest-data + count: 3 config: node.master: false node.data: true @@ -60,8 +62,8 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 3 + nodesSets: + - count: 3 podTemplate: spec: affinity: @@ -87,8 +89,9 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 3 + nodeSet: + - name: default + count: 3 podTemplate: spec: affinity: {} @@ -104,8 +107,9 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 3 + nodeSets: + - name: default + count: 3 podTemplate: spec: affinity: @@ -149,8 +153,9 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 3 + nodeSets: + - name: default + count: 3 podTemplate: spec: nodeSelector: @@ -168,8 +173,9 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 3 + nodeSets: + - name: default + count: 3 podTemplate: spec: affinity: @@ -208,8 +214,9 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 1 + nodeSets: + - name: group-a + count: 1 config: node.attr.zone: europe-west3-a cluster.routing.allocation.awareness.attributes: zone @@ -227,7 +234,8 @@ spec: operator: In values: - europe-west3-a - - nodeCount: 1 + - name: group-b + count: 1 config: node.attr.zone: europe-west3-b cluster.routing.allocation.awareness.attributes: zone @@ -276,9 +284,10 @@ metadata: name: quickstart spec: version: {version} - nodes: + nodeSets: # hot nodes, with high CPU and fast IO - - nodeCount: 3 + - name: hot + count: 3 config: node.attr.data: hot podTemplate: @@ -309,7 +318,8 @@ spec: storage: 1Ti storageClassName: local-storage # warm nodes, with high storage - - nodeCount: 3 + - name: warm + count: 3 config: node.attr.data: warm podTemplate: diff --git a/docs/apm.asciidoc b/docs/apm.asciidoc index 12450a10f6..50e30aa6b7 100644 --- a/docs/apm.asciidoc +++ b/docs/apm.asciidoc @@ -33,7 +33,7 @@ metadata: namespace: default spec: version: {version} - nodeCount: 1 + count: 1 elasticsearchRef: name: quickstart EOF @@ -87,7 +87,7 @@ metadata: namespace: default spec: version: {version} - nodeCount: 1 + count: 1 config: output: elasticsearch: @@ -122,7 +122,7 @@ metadata: namespace: default spec: version: {version} - nodeCount: 1 + count: 1 secureSettings: - secretName: apm-secret-settings config: @@ -161,7 +161,7 @@ metadata: namespace: default spec: version: {version} - nodeCount: 1 + count: 1 secureSettings: - secretName: apm-secret-settings config: diff --git a/docs/elasticsearch-spec.asciidoc b/docs/elasticsearch-spec.asciidoc index 5800c832b1..16d5b7aaeb 100644 --- a/docs/elasticsearch-spec.asciidoc +++ b/docs/elasticsearch-spec.asciidoc @@ -292,7 +292,7 @@ But you can use the same approach for any kind of file you want to mount into th [source,yaml] ---- spec: - nodes: + nodeSets: - podTemplate: spec: containers: @@ -411,8 +411,9 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 3 + nodeSets: + - name: default + count: 3 podDisruptionBudget: spec: maxUnavailable: 2 @@ -431,8 +432,9 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 3 + nodeSets: + - name: default + count: 3 podDisruptionBudget: {} ---- diff --git a/docs/k8s-quickstart.asciidoc b/docs/k8s-quickstart.asciidoc index 9f7b89abb9..66e3af8caa 100644 --- a/docs/k8s-quickstart.asciidoc +++ b/docs/k8s-quickstart.asciidoc @@ -55,8 +55,9 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 1 + nodeSets: + - name: default + count: 1 config: node.master: true node.data: true @@ -182,7 +183,7 @@ metadata: name: quickstart spec: version: {version} - nodeCount: 1 + count: 1 elasticsearchRef: name: quickstart EOF @@ -247,7 +248,8 @@ metadata: spec: version: {version} nodes: - - nodeCount: 3 + - name: default + count: 3 config: node.master: true node.data: true @@ -272,8 +274,9 @@ metadata: name: quickstart spec: version: {version} - nodes: - - nodeCount: 3 + nodeSets: + - name: default + count: 3 config: node.master: true node.data: true diff --git a/docs/openshift.asciidoc b/docs/openshift.asciidoc index 96569d2e38..bcfa63a019 100644 --- a/docs/openshift.asciidoc +++ b/docs/openshift.asciidoc @@ -83,11 +83,12 @@ metadata: spec: version: {version} setVmMaxMapCount: false - nodes: - - config: + nodeSets: + - name: default + config: node.master: true node.data: true - nodeCount: 1 + count: 1 --- apiVersion: route.openshift.io/v1 kind: Route @@ -119,7 +120,7 @@ metadata: name: kibana-sample spec: version: {version} - nodeCount: 1 + count: 1 elasticsearchRef: name: "elasticsearch-sample" podTemplate: @@ -187,7 +188,7 @@ metadata: name: apm-server-sample spec: version: {version} - nodeCount: 1 + count: 1 elasticsearchRef: name: "elasticsearch-sample" podTemplate: diff --git a/docs/snapshots.asciidoc b/docs/snapshots.asciidoc index 06689fe3d5..1455ffe8bc 100644 --- a/docs/snapshots.asciidoc +++ b/docs/snapshots.asciidoc @@ -30,8 +30,9 @@ metadata: spec: version: {version} image: your/custom/image:tag - nodes: - - nodeCount: 1 + nodeSets: + - name: default + count: 1 ---- Alternatively, install the plugin when the Pod is created by using an init container: @@ -44,8 +45,9 @@ metadata: name: elasticsearch-sample spec: version: {version} - nodes: - - podTemplate: + nodeSets: + - name: default + podTemplate: spec: initContainers: - name: install-plugins @@ -54,7 +56,7 @@ spec: - -c - | bin/elasticsearch-plugin install --batch repository-gcs - nodeCount: 1 + count: 1 ---- Assuming you stored this in a file called `elasticsearch.yaml` you can in both cases create the Elasticsearch cluster with: diff --git a/pkg/apis/apm/v1beta1/apmserver_types.go b/pkg/apis/apm/v1beta1/apmserver_types.go index c15a0239c6..5545352e78 100644 --- a/pkg/apis/apm/v1beta1/apmserver_types.go +++ b/pkg/apis/apm/v1beta1/apmserver_types.go @@ -23,8 +23,8 @@ type ApmServerSpec struct { // Image represents the docker image that will be used. Image string `json:"image,omitempty"` - // NodeCount defines how many nodes the Apm Server deployment must have. - NodeCount int32 `json:"nodeCount,omitempty"` + // Count defines how many nodes the Apm Server deployment must have. + Count int32 `json:"count,omitempty"` // Config represents the APM configuration. Config *commonv1beta1.Config `json:"config,omitempty"` @@ -38,7 +38,7 @@ type ApmServerSpec struct { // PodTemplate can be used to propagate configuration to APM Server pods. // This allows specifying custom annotations, labels, environment variables, - // affinity, resources, etc. for the pods created from this NodeSpec. + // affinity, resources, etc. for the pods created from this spec. // +kubebuilder:validation:Optional PodTemplate corev1.PodTemplateSpec `json:"podTemplate,omitempty"` diff --git a/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go b/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go index 444e8f85a7..dde00a8e89 100644 --- a/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go +++ b/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go @@ -32,8 +32,8 @@ type ElasticsearchSpec struct { // HTTP contains settings for HTTP. HTTP commonv1beta1.HTTPConfig `json:"http,omitempty"` - // Nodes represents a list of groups of nodes with the same configuration to be part of the cluster - Nodes []NodeSpec `json:"nodes,omitempty"` + // NodeSets represents a list of groups of nodes with the same configuration to be part of the cluster + NodeSets []NodeSet `json:"nodeSets,omitempty"` // UpdateStrategy specifies how updates to the cluster should be performed. UpdateStrategy UpdateStrategy `json:"updateStrategy,omitempty"` @@ -55,17 +55,17 @@ type ElasticsearchSpec struct { SecureSettings []commonv1beta1.SecretSource `json:"secureSettings,omitempty"` } -// NodeCount returns the total number of nodes of the Elasticsearch cluster +// Count returns the total number of nodes of the Elasticsearch cluster func (es ElasticsearchSpec) NodeCount() int32 { count := int32(0) - for _, topoElem := range es.Nodes { - count += topoElem.NodeCount + for _, topoElem := range es.NodeSets { + count += topoElem.Count } return count } -// NodeSpec defines a common topology for a set of Elasticsearch nodes -type NodeSpec struct { +// NodeSet defines a common topology for a set of Elasticsearch nodes +type NodeSet struct { // Name is a logical name for this set of nodes. Used as a part of the managed Elasticsearch node.name setting. // +kubebuilder:validation:Pattern=[a-zA-Z0-9-]+ // +kubebuilder:validation:MaxLength=23 @@ -74,12 +74,12 @@ type NodeSpec struct { // Config represents Elasticsearch configuration. Config *commonv1beta1.Config `json:"config,omitempty"` - // NodeCount defines how many nodes have this topology - NodeCount int32 `json:"nodeCount,omitempty"` + // Count defines how many nodes have this topology + Count int32 `json:"count,omitempty"` // PodTemplate can be used to propagate configuration to Elasticsearch pods. // This allows specifying custom annotations, labels, environment variables, - // volumes, affinity, resources, etc. for the pods created from this NodeSpec. + // volumes, affinity, resources, etc. for the pods created from this NodeSet. // +kubebuilder:validation:Optional PodTemplate corev1.PodTemplateSpec `json:"podTemplate,omitempty"` @@ -93,8 +93,8 @@ type NodeSpec struct { VolumeClaimTemplates []corev1.PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty"` } -// GetESContainerTemplate returns the Elasticsearch container (if set) from the NodeSpec's PodTemplate -func (n NodeSpec) GetESContainerTemplate() *corev1.Container { +// GetESContainerTemplate returns the Elasticsearch container (if set) from the NodeSet's PodTemplate +func (n NodeSet) GetESContainerTemplate() *corev1.Container { for _, c := range n.PodTemplate.Spec.Containers { if c.Name == ElasticsearchContainerName { return &c diff --git a/pkg/apis/elasticsearch/v1beta1/zz_generated.deepcopy.go b/pkg/apis/elasticsearch/v1beta1/zz_generated.deepcopy.go index 53a7ed6cc8..48560e595b 100644 --- a/pkg/apis/elasticsearch/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/elasticsearch/v1beta1/zz_generated.deepcopy.go @@ -134,9 +134,9 @@ func (in *ElasticsearchSpec) DeepCopyInto(out *ElasticsearchSpec) { **out = **in } in.HTTP.DeepCopyInto(&out.HTTP) - if in.Nodes != nil { - in, out := &in.Nodes, &out.Nodes - *out = make([]NodeSpec, len(*in)) + if in.NodeSets != nil { + in, out := &in.NodeSets, &out.NodeSets + *out = make([]NodeSet, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -198,7 +198,7 @@ func (in *Node) DeepCopy() *Node { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeSpec) DeepCopyInto(out *NodeSpec) { +func (in *NodeSet) DeepCopyInto(out *NodeSet) { *out = *in if in.Config != nil { in, out := &in.Config, &out.Config @@ -214,12 +214,12 @@ func (in *NodeSpec) DeepCopyInto(out *NodeSpec) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeSpec. -func (in *NodeSpec) DeepCopy() *NodeSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeSet. +func (in *NodeSet) DeepCopy() *NodeSet { if in == nil { return nil } - out := new(NodeSpec) + out := new(NodeSet) in.DeepCopyInto(out) return out } diff --git a/pkg/apis/kibana/v1alpha1/kibana_types.go b/pkg/apis/kibana/v1alpha1/kibana_types.go index f87d38e55e..c92871ce26 100644 --- a/pkg/apis/kibana/v1alpha1/kibana_types.go +++ b/pkg/apis/kibana/v1alpha1/kibana_types.go @@ -39,7 +39,7 @@ type KibanaSpec struct { // PodTemplate can be used to propagate configuration to Kibana pods. // This allows specifying custom annotations, labels, environment variables, - // affinity, resources, etc. for the pods created from this NodeSpec. + // affinity, resources, etc. for the pods created from this spec. // +kubebuilder:validation:Optional PodTemplate corev1.PodTemplateSpec `json:"podTemplate,omitempty"` diff --git a/pkg/apis/kibana/v1beta1/kibana_types.go b/pkg/apis/kibana/v1beta1/kibana_types.go index 21caea1628..f2ed67298d 100644 --- a/pkg/apis/kibana/v1beta1/kibana_types.go +++ b/pkg/apis/kibana/v1beta1/kibana_types.go @@ -24,8 +24,8 @@ type KibanaSpec struct { // Image represents the docker image that will be used. Image string `json:"image,omitempty"` - // NodeCount defines how many nodes the Kibana deployment must have. - NodeCount int32 `json:"nodeCount,omitempty"` + // Count defines how many nodes the Kibana deployment must have. + Count int32 `json:"nodeCount,omitempty"` // ElasticsearchRef references an Elasticsearch resource in the Kubernetes cluster. // If the namespace is not specified, the current resource namespace will be used. @@ -39,7 +39,7 @@ type KibanaSpec struct { // PodTemplate can be used to propagate configuration to Kibana pods. // This allows specifying custom annotations, labels, environment variables, - // affinity, resources, etc. for the pods created from this NodeSpec. + // affinity, resources, etc. for the pods created from this NodeSet. // +kubebuilder:validation:Optional PodTemplate corev1.PodTemplateSpec `json:"podTemplate,omitempty"` diff --git a/pkg/controller/apmserver/apmserver_controller.go b/pkg/controller/apmserver/apmserver_controller.go index 797fd0bf84..7dc08dca88 100644 --- a/pkg/controller/apmserver/apmserver_controller.go +++ b/pkg/controller/apmserver/apmserver_controller.go @@ -385,7 +385,7 @@ func (r *ReconcileApmServer) deploymentParams( return deployment.Params{ Name: apmname.Deployment(as.Name), Namespace: as.Namespace, - Replicas: as.Spec.NodeCount, + Replicas: as.Spec.Count, Selector: labels.NewLabels(as.Name), Labels: labels.NewLabels(as.Name), PodTemplateSpec: podSpec, diff --git a/pkg/controller/common/association/conf_test.go b/pkg/controller/common/association/conf_test.go index c18f8fe450..58e08402df 100644 --- a/pkg/controller/common/association/conf_test.go +++ b/pkg/controller/common/association/conf_test.go @@ -79,7 +79,7 @@ func testFetchAPMServer(t *testing.T) { require.Equal(t, "apm-server-test", got.Name) require.Equal(t, "apm-ns", got.Namespace) require.Equal(t, "test-image", got.Spec.Image) - require.EqualValues(t, 1, got.Spec.NodeCount) + require.EqualValues(t, 1, got.Spec.Count) require.Equal(t, tc.wantAssocConf, got.AssociationConf()) } }) @@ -93,8 +93,8 @@ func mkAPMServer(withAnnotations bool) *apmv1beta1.ApmServer { Namespace: "apm-ns", }, Spec: apmv1beta1.ApmServerSpec{ - Image: "test-image", - NodeCount: 1, + Image: "test-image", + Count: 1, }, } @@ -161,7 +161,7 @@ func testFetchKibana(t *testing.T) { require.Equal(t, "kb-test", got.Name) require.Equal(t, "kb-ns", got.Namespace) require.Equal(t, "test-image", got.Spec.Image) - require.EqualValues(t, 1, got.Spec.NodeCount) + require.EqualValues(t, 1, got.Spec.Count) require.Equal(t, tc.wantAssocConf, got.AssociationConf()) } }) @@ -175,8 +175,8 @@ func mkKibana(withAnnotations bool) *kbv1beta1.Kibana { Namespace: "kb-ns", }, Spec: kbv1beta1.KibanaSpec{ - Image: "test-image", - NodeCount: 1, + Image: "test-image", + Count: 1, }, } @@ -209,7 +209,7 @@ func TestUpdateAssociationConf(t *testing.T) { require.Equal(t, "kb-test", got.Name) require.Equal(t, "kb-ns", got.Namespace) require.Equal(t, "test-image", got.Spec.Image) - require.EqualValues(t, 1, got.Spec.NodeCount) + require.EqualValues(t, 1, got.Spec.Count) require.Equal(t, assocConf, got.AssociationConf()) // update and check the new values @@ -228,7 +228,7 @@ func TestUpdateAssociationConf(t *testing.T) { require.Equal(t, "kb-test", got.Name) require.Equal(t, "kb-ns", got.Namespace) require.Equal(t, "test-image", got.Spec.Image) - require.EqualValues(t, 1, got.Spec.NodeCount) + require.EqualValues(t, 1, got.Spec.Count) require.Equal(t, newAssocConf, got.AssociationConf()) } @@ -252,7 +252,7 @@ func TestRemoveAssociationConf(t *testing.T) { require.Equal(t, "kb-test", got.Name) require.Equal(t, "kb-ns", got.Namespace) require.Equal(t, "test-image", got.Spec.Image) - require.EqualValues(t, 1, got.Spec.NodeCount) + require.EqualValues(t, 1, got.Spec.Count) require.Equal(t, assocConf, got.AssociationConf()) // remove and check the new values @@ -264,6 +264,6 @@ func TestRemoveAssociationConf(t *testing.T) { require.Equal(t, "kb-test", got.Name) require.Equal(t, "kb-ns", got.Namespace) require.Equal(t, "test-image", got.Spec.Image) - require.EqualValues(t, 1, got.Spec.NodeCount) + require.EqualValues(t, 1, got.Spec.Count) require.Nil(t, got.AssociationConf()) } diff --git a/pkg/controller/elasticsearch/driver/esstate.go b/pkg/controller/elasticsearch/driver/esstate.go index 2a24a27f02..ad44335e11 100644 --- a/pkg/controller/elasticsearch/driver/esstate.go +++ b/pkg/controller/elasticsearch/driver/esstate.go @@ -51,7 +51,7 @@ func initOnce(once *sync.Once, f func() error) error { return err } -// -- Nodes +// -- NodeSets // memoizingNodes provides nodes information. type memoizingNodes struct { diff --git a/pkg/controller/elasticsearch/driver/upscale.go b/pkg/controller/elasticsearch/driver/upscale.go index 6026e94fbc..9b6491aa32 100644 --- a/pkg/controller/elasticsearch/driver/upscale.go +++ b/pkg/controller/elasticsearch/driver/upscale.go @@ -30,7 +30,7 @@ type upscaleCtx struct { expectations *expectations.Expectations } -// HandleUpscaleAndSpecChanges reconciles expected NodeSpec resources. +// HandleUpscaleAndSpecChanges reconciles expected NodeSet resources. // It does: // - create any new StatefulSets // - update existing StatefulSets specification, to be used for future pods rotation diff --git a/pkg/controller/elasticsearch/name/name.go b/pkg/controller/elasticsearch/name/name.go index 37e6b85a82..772b9a2fc7 100644 --- a/pkg/controller/elasticsearch/name/name.go +++ b/pkg/controller/elasticsearch/name/name.go @@ -58,7 +58,7 @@ func Validate(es v1beta1.Elasticsearch) error { } // validate ssets - for _, nodeSpec := range es.Spec.Nodes { + for _, nodeSpec := range es.Spec.NodeSets { if errs := apimachineryvalidation.NameIsDNSSubdomain(nodeSpec.Name, false); len(errs) > 0 { return fmt.Errorf("invalid nodeSpec name '%s': [%s]", nodeSpec.Name, strings.Join(errs, ",")) } @@ -69,7 +69,7 @@ func Validate(es v1beta1.Elasticsearch) error { } // length of the ordinal suffix that will be added to the pods of this sset (dash + ordinal) - podOrdinalSuffixLen := len(strconv.FormatInt(int64(nodeSpec.NodeCount), 10)) + 1 + podOrdinalSuffixLen := len(strconv.FormatInt(int64(nodeSpec.Count), 10)) + 1 // there should be enough space for the ordinal suffix if validation.DNS1123SubdomainMaxLength-len(ssetName) < podOrdinalSuffixLen { return fmt.Errorf("generated StatefulSet name '%s' exceeds allowed length of %d", @@ -88,7 +88,7 @@ func Validate(es v1beta1.Elasticsearch) error { return nil } -// StatefulSet returns the name of the StatefulSet corresponding to the given NodeSpec. +// StatefulSet returns the name of the StatefulSet corresponding to the given NodeSet. func StatefulSet(esName string, nodeSpecName string) string { return ESNamer.Suffix(esName, nodeSpecName) } diff --git a/pkg/controller/elasticsearch/name/name_test.go b/pkg/controller/elasticsearch/name/name_test.go index a557749e44..0d76c1a896 100644 --- a/pkg/controller/elasticsearch/name/name_test.go +++ b/pkg/controller/elasticsearch/name/name_test.go @@ -60,7 +60,7 @@ func TestValidate(t *testing.T) { } for _, nodeSpecName := range tc.nodeSpecNames { - es.Spec.Nodes = append(es.Spec.Nodes, v1beta1.NodeSpec{Name: nodeSpecName, NodeCount: 10}) + es.Spec.NodeSets = append(es.Spec.NodeSets, v1beta1.NodeSet{Name: nodeSpecName, Count: 10}) } err := Validate(es) diff --git a/pkg/controller/elasticsearch/nodespec/podspec.go b/pkg/controller/elasticsearch/nodespec/podspec.go index df09397895..cd1c1782d8 100644 --- a/pkg/controller/elasticsearch/nodespec/podspec.go +++ b/pkg/controller/elasticsearch/nodespec/podspec.go @@ -28,7 +28,7 @@ import ( // BuildPodTemplateSpec builds a new PodTemplateSpec for an Elasticsearch node. func BuildPodTemplateSpec( es v1beta1.Elasticsearch, - nodeSpec v1beta1.NodeSpec, + nodeSpec v1beta1.NodeSet, cfg settings.CanonicalConfig, keystoreResources *keystore.Resources, ) (corev1.PodTemplateSpec, error) { @@ -79,7 +79,7 @@ func transportCertificatesVolume(esName string) volume.SecretVolume { func buildLabels( es v1beta1.Elasticsearch, cfg settings.CanonicalConfig, - nodeSpec v1beta1.NodeSpec, + nodeSpec v1beta1.NodeSet, keystoreResources *keystore.Resources, ) (map[string]string, error) { // label with a hash of the config to rotate the pod on config changes diff --git a/pkg/controller/elasticsearch/nodespec/podspec_test.go b/pkg/controller/elasticsearch/nodespec/podspec_test.go index b89e83c2f8..ea1f441725 100644 --- a/pkg/controller/elasticsearch/nodespec/podspec_test.go +++ b/pkg/controller/elasticsearch/nodespec/podspec_test.go @@ -35,10 +35,10 @@ var sampleES = v1beta1.Elasticsearch{ }, Spec: v1beta1.ElasticsearchSpec{ Version: "7.2.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { - Name: "nodespec-1", - NodeCount: 2, + Name: "nodespec-1", + Count: 2, Config: &commonv1beta1.Config{ Data: map[string]interface{}{ "node.attr.foo": "bar", @@ -80,8 +80,8 @@ var sampleES = v1beta1.Elasticsearch{ VolumeClaimTemplates: []corev1.PersistentVolumeClaim{}, }, { - Name: "nodespec-1", - NodeCount: 2, + Name: "nodespec-1", + Count: 2, }, }, }, @@ -89,13 +89,13 @@ var sampleES = v1beta1.Elasticsearch{ func TestBuildPodTemplateSpec(t *testing.T) { certResources := certificates.CertificateResources{HTTPCACertProvided: true} - nodeSpec := sampleES.Spec.Nodes[0] + nodeSpec := sampleES.Spec.NodeSets[0] ver, err := version.Parse(sampleES.Spec.Version) require.NoError(t, err) cfg, err := settings.NewMergedESConfig(sampleES.Name, *ver, sampleES.Spec.HTTP, *nodeSpec.Config, &certResources) require.NoError(t, err) - actual, err := BuildPodTemplateSpec(sampleES, sampleES.Spec.Nodes[0], cfg, nil) + actual, err := BuildPodTemplateSpec(sampleES, sampleES.Spec.NodeSets[0], cfg, nil) require.NoError(t, err) // build expected PodTemplateSpec diff --git a/pkg/controller/elasticsearch/nodespec/resources.go b/pkg/controller/elasticsearch/nodespec/resources.go index e9ac21595a..26c61220b6 100644 --- a/pkg/controller/elasticsearch/nodespec/resources.go +++ b/pkg/controller/elasticsearch/nodespec/resources.go @@ -20,7 +20,7 @@ import ( "github.com/elastic/cloud-on-k8s/pkg/utils/k8s" ) -// Resources contain per-NodeSpec resources to be created. +// Resources contain per-NodeSet resources to be created. type Resources struct { StatefulSet appsv1.StatefulSet HeadlessService corev1.Service @@ -38,14 +38,14 @@ func (l ResourcesList) StatefulSets() sset.StatefulSetList { } func BuildExpectedResources(es v1beta1.Elasticsearch, keystoreResources *keystore.Resources, scheme *runtime.Scheme, certResources *certificates.CertificateResources) (ResourcesList, error) { - nodesResources := make(ResourcesList, 0, len(es.Spec.Nodes)) + nodesResources := make(ResourcesList, 0, len(es.Spec.NodeSets)) ver, err := version.Parse(es.Spec.Version) if err != nil { return nil, err } - for _, nodeSpec := range es.Spec.Nodes { + for _, nodeSpec := range es.Spec.NodeSets { // build es config userCfg := commonv1beta1.Config{} if nodeSpec.Config != nil { diff --git a/pkg/controller/elasticsearch/nodespec/statefulset.go b/pkg/controller/elasticsearch/nodespec/statefulset.go index 90ac9e1514..52e5360747 100644 --- a/pkg/controller/elasticsearch/nodespec/statefulset.go +++ b/pkg/controller/elasticsearch/nodespec/statefulset.go @@ -48,7 +48,7 @@ func HeadlessService(es types.NamespacedName, ssetName string) corev1.Service { func BuildStatefulSet( es v1beta1.Elasticsearch, - nodeSpec v1beta1.NodeSpec, + nodeSpec v1beta1.NodeSet, cfg settings.CanonicalConfig, keystoreResources *keystore.Resources, scheme *runtime.Scheme, @@ -106,7 +106,7 @@ func BuildStatefulSet( MatchLabels: ssetSelector, }, - Replicas: &nodeSpec.NodeCount, + Replicas: &nodeSpec.Count, VolumeClaimTemplates: claims, Template: podTemplate, }, diff --git a/pkg/controller/elasticsearch/nodespec/volumes.go b/pkg/controller/elasticsearch/nodespec/volumes.go index 6346f6eec7..df062c0c66 100644 --- a/pkg/controller/elasticsearch/nodespec/volumes.go +++ b/pkg/controller/elasticsearch/nodespec/volumes.go @@ -18,7 +18,7 @@ import ( esvolume "github.com/elastic/cloud-on-k8s/pkg/controller/elasticsearch/volume" ) -func buildVolumes(esName string, nodeSpec v1beta1.NodeSpec, keystoreResources *keystore.Resources) ([]corev1.Volume, []corev1.VolumeMount) { +func buildVolumes(esName string, nodeSpec v1beta1.NodeSet, keystoreResources *keystore.Resources) ([]corev1.Volume, []corev1.VolumeMount) { configVolume := settings.ConfigSecretVolume(name.StatefulSet(esName, nodeSpec.Name)) probeSecret := volume.NewSelectiveSecretVolumeWithMountPath( diff --git a/pkg/controller/elasticsearch/validation/validation_test.go b/pkg/controller/elasticsearch/validation/validation_test.go index 49f9091e05..0d5367d298 100644 --- a/pkg/controller/elasticsearch/validation/validation_test.go +++ b/pkg/controller/elasticsearch/validation/validation_test.go @@ -114,7 +114,7 @@ func TestValidate(t *testing.T) { }, Spec: estype.ElasticsearchSpec{ Version: "7.0.0", - Nodes: []estype.NodeSpec{ + NodeSets: []estype.NodeSet{ { Name: "default", Config: &common.Config{ @@ -125,7 +125,7 @@ func TestValidate(t *testing.T) { estype.NodeML: "false", }, }, - NodeCount: 1, + Count: 1, }}, }, }, @@ -169,9 +169,9 @@ func TestValidate(t *testing.T) { }, }, }, - Nodes: []estype.NodeSpec{ + NodeSets: []estype.NodeSet{ { - NodeCount: 1, + Count: 1, Config: &common.Config{ Data: map[string]interface{}{ estype.NodeMaster: false, diff --git a/pkg/controller/elasticsearch/validation/validations.go b/pkg/controller/elasticsearch/validation/validations.go index f9d0d6f35e..c40da783c0 100644 --- a/pkg/controller/elasticsearch/validation/validations.go +++ b/pkg/controller/elasticsearch/validation/validations.go @@ -56,12 +56,12 @@ func supportedVersion(ctx Context) validation.Result { // hasMaster checks if the given Elasticsearch cluster has at least one master node. func hasMaster(ctx Context) validation.Result { var hasMaster bool - for _, t := range ctx.Proposed.Elasticsearch.Spec.Nodes { + for _, t := range ctx.Proposed.Elasticsearch.Spec.NodeSets { cfg, err := v1beta1.UnpackConfig(t.Config) if err != nil { return validation.Result{Reason: cfgInvalidMsg} } - hasMaster = hasMaster || (cfg.Node.Master && t.NodeCount > 0) + hasMaster = hasMaster || (cfg.Node.Master && t.Count > 0) } if hasMaster { return validation.OK @@ -71,7 +71,7 @@ func hasMaster(ctx Context) validation.Result { func noBlacklistedSettings(ctx Context) validation.Result { violations := make(map[int]set.StringSet) - for i, n := range ctx.Proposed.Elasticsearch.Spec.Nodes { + for i, n := range ctx.Proposed.Elasticsearch.Spec.NodeSets { if n.Config == nil { continue } @@ -95,7 +95,7 @@ func noBlacklistedSettings(ctx Context) validation.Result { var sb strings.Builder var sep string // iterate again to build validation message in node order - for i := range ctx.Proposed.Elasticsearch.Spec.Nodes { + for i := range ctx.Proposed.Elasticsearch.Spec.NodeSets { vs := violations[i] if vs == nil { continue @@ -146,7 +146,7 @@ func pvcModification(ctx Context) validation.Result { if ctx.Current == nil { return validation.OK } - for _, node := range ctx.Proposed.Elasticsearch.Spec.Nodes { + for _, node := range ctx.Proposed.Elasticsearch.Spec.NodeSets { currNode := getNode(node.Name, ctx.Current.Elasticsearch) if currNode == nil { // this is a new sset, so there is nothing to check @@ -165,10 +165,10 @@ func pvcModification(ctx Context) validation.Result { return validation.OK } -func getNode(name string, es v1beta1.Elasticsearch) *v1beta1.NodeSpec { - for i := range es.Spec.Nodes { - if es.Spec.Nodes[i].Name == name { - return &es.Spec.Nodes[i] +func getNode(name string, es v1beta1.Elasticsearch) *v1beta1.NodeSet { + for i := range es.Spec.NodeSets { + if es.Spec.NodeSets[i].Name == name { + return &es.Spec.NodeSets[i] } } return nil diff --git a/pkg/controller/elasticsearch/validation/validations_test.go b/pkg/controller/elasticsearch/validation/validations_test.go index 4964ff1075..d5b20ed443 100644 --- a/pkg/controller/elasticsearch/validation/validations_test.go +++ b/pkg/controller/elasticsearch/validation/validations_test.go @@ -47,7 +47,7 @@ func Test_hasMaster(t *testing.T) { esCluster: v1beta1.Elasticsearch{ Spec: v1beta1.ElasticsearchSpec{ Version: "7.0.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { Config: &common.Config{ Data: map[string]interface{}{ @@ -70,7 +70,7 @@ func Test_hasMaster(t *testing.T) { esCluster: v1beta1.Elasticsearch{ Spec: v1beta1.ElasticsearchSpec{ Version: "7.0.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { Config: &common.Config{ Data: map[string]interface{}{ @@ -93,7 +93,7 @@ func Test_hasMaster(t *testing.T) { esCluster: v1beta1.Elasticsearch{ Spec: v1beta1.ElasticsearchSpec{ Version: "7.0.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { Config: &common.Config{ Data: map[string]interface{}{ @@ -103,7 +103,7 @@ func Test_hasMaster(t *testing.T) { v1beta1.NodeML: "false", }, }, - NodeCount: 1, + Count: 1, }, }, }, @@ -197,14 +197,14 @@ func Test_noBlacklistedSettings(t *testing.T) { es: estype.Elasticsearch{ Spec: estype.ElasticsearchSpec{ Version: "7.0.0", - Nodes: []estype.NodeSpec{ + NodeSets: []estype.NodeSet{ { Config: &common.Config{ Data: map[string]interface{}{ settings.ClusterInitialMasterNodes: "foo", }, }, - NodeCount: 1, + Count: 1, }, }, }, @@ -218,7 +218,7 @@ func Test_noBlacklistedSettings(t *testing.T) { es: estype.Elasticsearch{ Spec: estype.ElasticsearchSpec{ Version: "7.0.0", - Nodes: []estype.NodeSpec{ + NodeSets: []estype.NodeSet{ { Config: &common.Config{ Data: map[string]interface{}{ @@ -248,7 +248,7 @@ func Test_noBlacklistedSettings(t *testing.T) { es: estype.Elasticsearch{ Spec: estype.ElasticsearchSpec{ Version: "7.0.0", - Nodes: []estype.NodeSpec{ + NodeSets: []estype.NodeSet{ { Config: &common.Config{ Data: map[string]interface{}{ @@ -268,7 +268,7 @@ func Test_noBlacklistedSettings(t *testing.T) { es: estype.Elasticsearch{ Spec: estype.ElasticsearchSpec{ Version: "7.0.0", - Nodes: []estype.NodeSpec{ + NodeSets: []estype.NodeSet{ { Config: &common.Config{ Data: map[string]interface{}{ @@ -288,7 +288,7 @@ func Test_noBlacklistedSettings(t *testing.T) { es: estype.Elasticsearch{ Spec: estype.ElasticsearchSpec{ Version: "7.0.0", - Nodes: []estype.NodeSpec{ + NodeSets: []estype.NodeSet{ { Config: &common.Config{ Data: map[string]interface{}{ @@ -460,7 +460,7 @@ func Test_pvcModified(t *testing.T) { proposed: v1beta1.Elasticsearch{ Spec: v1beta1.ElasticsearchSpec{ Version: "7.2.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { Name: "master", VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ @@ -490,7 +490,7 @@ func Test_pvcModified(t *testing.T) { proposed: v1beta1.Elasticsearch{ Spec: v1beta1.ElasticsearchSpec{ Version: "7.2.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { Name: "master", VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ @@ -520,7 +520,7 @@ func Test_pvcModified(t *testing.T) { proposed: v1beta1.Elasticsearch{ Spec: v1beta1.ElasticsearchSpec{ Version: "7.2.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { Name: "master", VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ @@ -562,7 +562,7 @@ func Test_pvcModified(t *testing.T) { proposed: v1beta1.Elasticsearch{ Spec: v1beta1.ElasticsearchSpec{ Version: "7.2.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { Name: "master", VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ @@ -592,7 +592,7 @@ func Test_pvcModified(t *testing.T) { proposed: v1beta1.Elasticsearch{ Spec: v1beta1.ElasticsearchSpec{ Version: "7.2.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { Name: "master", VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ @@ -655,7 +655,7 @@ func getEsCluster() *v1beta1.Elasticsearch { return &v1beta1.Elasticsearch{ Spec: v1beta1.ElasticsearchSpec{ Version: "7.2.0", - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { Name: "master", VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ diff --git a/pkg/controller/kibana/driver.go b/pkg/controller/kibana/driver.go index 4c2f399873..49235a9809 100644 --- a/pkg/controller/kibana/driver.go +++ b/pkg/controller/kibana/driver.go @@ -201,7 +201,7 @@ func (d *driver) deploymentParams(kb *kbtype.Kibana) (deployment.Params, error) return deployment.Params{ Name: kbname.KBNamer.Suffix(kb.Name), Namespace: kb.Namespace, - Replicas: kb.Spec.NodeCount, + Replicas: kb.Spec.Count, Selector: label.NewLabels(kb.Name), Labels: label.NewLabels(kb.Name), PodTemplateSpec: kibanaPodSpec, diff --git a/pkg/controller/kibana/driver_test.go b/pkg/controller/kibana/driver_test.go index 93235d4197..1ab6504b04 100644 --- a/pkg/controller/kibana/driver_test.go +++ b/pkg/controller/kibana/driver_test.go @@ -328,9 +328,9 @@ func kibanaFixture() *kbtype.Kibana { Namespace: "default", }, Spec: kbtype.KibanaSpec{ - Version: "7.0.0", - Image: "my-image", - NodeCount: 1, + Version: "7.0.0", + Image: "my-image", + Count: 1, }, } diff --git a/pkg/controller/license/license_controller_integration_test.go b/pkg/controller/license/license_controller_integration_test.go index 206b3c51e7..333b42a8a8 100644 --- a/pkg/controller/license/license_controller_integration_test.go +++ b/pkg/controller/license/license_controller_integration_test.go @@ -97,10 +97,10 @@ func TestReconcile(t *testing.T) { Spec: v1beta1.ElasticsearchSpec{ Version: "7.0.0", SetVMMaxMapCount: &varFalse, - Nodes: []v1beta1.NodeSpec{ + NodeSets: []v1beta1.NodeSet{ { - Name: "all", - NodeCount: 3, + Name: "all", + Count: 3, }, }, }, diff --git a/test/e2e/es/naming_test.go b/test/e2e/es/naming_test.go index 4ad957220d..545707e325 100644 --- a/test/e2e/es/naming_test.go +++ b/test/e2e/es/naming_test.go @@ -42,7 +42,7 @@ func testLongestPossibleName(t *testing.T) { WithNamespace(test.Ctx().ManagedNamespace(0)). WithVersion(test.Ctx().ElasticStackVersion). WithRestrictedSecurityContext(). - WithNodeSpec(estype.NodeSpec{ + WithNodeSpec(estype.NodeSet{ Name: nodeSpecName, }) @@ -78,7 +78,7 @@ func testRejectionOfLongName(t *testing.T) { WithNamespace(test.Ctx().ManagedNamespace(0)). WithVersion(test.Ctx().ElasticStackVersion). WithRestrictedSecurityContext(). - WithNodeSpec(estype.NodeSpec{ + WithNodeSpec(estype.NodeSet{ Name: "default", }) diff --git a/test/e2e/es/reversal_test.go b/test/e2e/es/reversal_test.go index 937cd8a2c8..93b75980b4 100644 --- a/test/e2e/es/reversal_test.go +++ b/test/e2e/es/reversal_test.go @@ -47,7 +47,7 @@ func TestReversalStatefulSetRename(t *testing.T) { b := elasticsearch.NewBuilder("test-sset-rename-reversal"). WithESMasterDataNodes(1, elasticsearch.DefaultResources) - copy := b.Elasticsearch.Spec.Nodes[0] + copy := b.Elasticsearch.Spec.NodeSets[0] copy.Name = "other" renamed := b.WithNoESTopology().WithNodeSpec(copy) @@ -57,9 +57,9 @@ func TestReversalStatefulSetRename(t *testing.T) { func TestRiskyMasterReconfiguration(t *testing.T) { b := elasticsearch.NewBuilder("test-sset-reconfig-reversal"). WithESMasterDataNodes(1, elasticsearch.DefaultResources). - WithNodeSpec(v1beta1.NodeSpec{ - Name: "other-master", - NodeCount: 1, + WithNodeSpec(v1beta1.NodeSet{ + Name: "other-master", + Count: 1, Config: &common.Config{ Data: map[string]interface{}{ v1beta1.NodeMaster: true, @@ -71,9 +71,9 @@ func TestRiskyMasterReconfiguration(t *testing.T) { // this currently breaks the cluster (something we might fix in the future at which point this just tests a temp downscale) noMasterMaster := b.WithNoESTopology().WithESMasterDataNodes(1, elasticsearch.DefaultResources). - WithNodeSpec(v1beta1.NodeSpec{ - Name: "other-master", - NodeCount: 1, + WithNodeSpec(v1beta1.NodeSet{ + Name: "other-master", + Count: 1, Config: &common.Config{ Data: map[string]interface{}{ v1beta1.NodeMaster: false, diff --git a/test/e2e/test/apmserver/builder.go b/test/e2e/test/apmserver/builder.go index 1de019603a..ac38c2a597 100644 --- a/test/e2e/test/apmserver/builder.go +++ b/test/e2e/test/apmserver/builder.go @@ -38,8 +38,8 @@ func newBuilder(name, randSuffix string) Builder { ApmServer: apmtype.ApmServer{ ObjectMeta: meta, Spec: apmtype.ApmServerSpec{ - NodeCount: 1, - Version: test.Ctx().ElasticStackVersion, + Count: 1, + Version: test.Ctx().ElasticStackVersion, Config: &commonv1beta1.Config{ Data: map[string]interface{}{ "apm-server.ilm.enabled": false, @@ -78,7 +78,7 @@ func (b Builder) WithVersion(version string) Builder { } func (b Builder) WithNodeCount(count int) Builder { - b.ApmServer.Spec.NodeCount = int32(count) + b.ApmServer.Spec.Count = int32(count) return b } diff --git a/test/e2e/test/apmserver/checks_k8s.go b/test/e2e/test/apmserver/checks_k8s.go index 18ab855fbf..93a505c5ca 100644 --- a/test/e2e/test/apmserver/checks_k8s.go +++ b/test/e2e/test/apmserver/checks_k8s.go @@ -34,14 +34,14 @@ func CheckApmServerDeployment(b Builder, k *test.K8sClient) test.Step { Namespace: b.ApmServer.Namespace, Name: b.ApmServer.Name + "-apm-server", }, &dep) - if b.ApmServer.Spec.NodeCount == 0 && apierrors.IsNotFound(err) { + if b.ApmServer.Spec.Count == 0 && apierrors.IsNotFound(err) { return nil } if err != nil { return err } - if *dep.Spec.Replicas != b.ApmServer.Spec.NodeCount { - return fmt.Errorf("invalid ApmServer replicas count: expected %d, got %d", b.ApmServer.Spec.NodeCount, *dep.Spec.Replicas) + if *dep.Spec.Replicas != b.ApmServer.Spec.Count { + return fmt.Errorf("invalid ApmServer replicas count: expected %d, got %d", b.ApmServer.Spec.Count, *dep.Spec.Replicas) } return nil }), @@ -53,7 +53,7 @@ func CheckApmServerPodsCount(b Builder, k *test.K8sClient) test.Step { return test.Step{ Name: "ApmServer pods count should match the expected one", Test: test.Eventually(func() error { - return k.CheckPodCount(int(b.ApmServer.Spec.NodeCount), test.ApmServerPodListOptions(b.ApmServer.Namespace, b.ApmServer.Name)...) + return k.CheckPodCount(int(b.ApmServer.Spec.Count), test.ApmServerPodListOptions(b.ApmServer.Namespace, b.ApmServer.Name)...) }), } } @@ -100,7 +100,7 @@ func CheckServicesEndpoints(b Builder, k *test.K8sClient) test.Step { Name: "ApmServer services should have endpoints", Test: test.Eventually(func() error { for endpointName, addrCount := range map[string]int{ - b.ApmServer.Name + "-apm-http": int(b.ApmServer.Spec.NodeCount), + b.ApmServer.Name + "-apm-http": int(b.ApmServer.Spec.Count), } { endpoints, err := k.GetEndpoints(b.ApmServer.Namespace, endpointName) if err != nil { diff --git a/test/e2e/test/elasticsearch/builder.go b/test/e2e/test/elasticsearch/builder.go index f127abca33..db28deb760 100644 --- a/test/e2e/test/elasticsearch/builder.go +++ b/test/e2e/test/elasticsearch/builder.go @@ -80,8 +80,8 @@ func (b Builder) Ref() commonv1beta1.ObjectSelector { // WithRestrictedSecurityContext helps to enforce a restricted security context on the objects. func (b Builder) WithRestrictedSecurityContext() Builder { b.Elasticsearch.Spec.SetVMMaxMapCount = test.BoolPtr(false) - for idx := range b.Elasticsearch.Spec.Nodes { - node := &b.Elasticsearch.Spec.Nodes[idx] + for idx := range b.Elasticsearch.Spec.NodeSets { + node := &b.Elasticsearch.Spec.NodeSets[idx] node.PodTemplate.Spec.SecurityContext = test.DefaultSecurityContext() } return b @@ -122,14 +122,14 @@ func (b Builder) WithHTTPSAN(ip string) Builder { // -- ES Nodes func (b Builder) WithNoESTopology() Builder { - b.Elasticsearch.Spec.Nodes = []estype.NodeSpec{} + b.Elasticsearch.Spec.NodeSets = []estype.NodeSet{} return b } func (b Builder) WithESMasterNodes(count int, resources corev1.ResourceRequirements) Builder { - return b.WithNodeSpec(estype.NodeSpec{ - Name: "master", - NodeCount: int32(count), + return b.WithNodeSpec(estype.NodeSet{ + Name: "master", + Count: int32(count), Config: &commonv1beta1.Config{ Data: map[string]interface{}{ estype.NodeData: "false", @@ -140,9 +140,9 @@ func (b Builder) WithESMasterNodes(count int, resources corev1.ResourceRequireme } func (b Builder) WithESDataNodes(count int, resources corev1.ResourceRequirements) Builder { - return b.WithNodeSpec(estype.NodeSpec{ - Name: "data", - NodeCount: int32(count), + return b.WithNodeSpec(estype.NodeSet{ + Name: "data", + Count: int32(count), Config: &commonv1beta1.Config{ Data: map[string]interface{}{ estype.NodeMaster: "false", @@ -153,9 +153,9 @@ func (b Builder) WithESDataNodes(count int, resources corev1.ResourceRequirement } func (b Builder) WithESMasterDataNodes(count int, resources corev1.ResourceRequirements) Builder { - return b.WithNodeSpec(estype.NodeSpec{ - Name: "masterdata", - NodeCount: int32(count), + return b.WithNodeSpec(estype.NodeSet{ + Name: "masterdata", + Count: int32(count), Config: &commonv1beta1.Config{ Data: map[string]interface{}{}, }, @@ -163,8 +163,8 @@ func (b Builder) WithESMasterDataNodes(count int, resources corev1.ResourceRequi }) } -func (b Builder) WithNodeSpec(nodeSpec estype.NodeSpec) Builder { - b.Elasticsearch.Spec.Nodes = append(b.Elasticsearch.Spec.Nodes, nodeSpec) +func (b Builder) WithNodeSpec(nodeSpec estype.NodeSet) Builder { + b.Elasticsearch.Spec.NodeSets = append(b.Elasticsearch.Spec.NodeSets, nodeSpec) return b } @@ -178,8 +178,8 @@ func (b Builder) WithESSecureSettings(secretNames ...string) Builder { } func (b Builder) WithEmptyDirVolumes() Builder { - for i := range b.Elasticsearch.Spec.Nodes { - b.Elasticsearch.Spec.Nodes[i].PodTemplate.Spec.Volumes = []corev1.Volume{ + for i := range b.Elasticsearch.Spec.NodeSets { + b.Elasticsearch.Spec.NodeSets[i].PodTemplate.Spec.Volumes = []corev1.Volume{ { Name: volume.ElasticsearchDataVolumeName, VolumeSource: corev1.VolumeSource{ @@ -192,9 +192,9 @@ func (b Builder) WithEmptyDirVolumes() Builder { } func (b Builder) WithPersistentVolumes(volumeName string) Builder { - for i := range b.Elasticsearch.Spec.Nodes { + for i := range b.Elasticsearch.Spec.NodeSets { name := volumeName - b.Elasticsearch.Spec.Nodes[i].VolumeClaimTemplates = append(b.Elasticsearch.Spec.Nodes[i].VolumeClaimTemplates, + b.Elasticsearch.Spec.NodeSets[i].VolumeClaimTemplates = append(b.Elasticsearch.Spec.NodeSets[i].VolumeClaimTemplates, corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -210,7 +210,7 @@ func (b Builder) WithPersistentVolumes(volumeName string) Builder { }, }, }) - b.Elasticsearch.Spec.Nodes[i].PodTemplate.Spec.Volumes = []corev1.Volume{ + b.Elasticsearch.Spec.NodeSets[i].PodTemplate.Spec.Volumes = []corev1.Volume{ { Name: name, VolumeSource: corev1.VolumeSource{ @@ -226,16 +226,16 @@ func (b Builder) WithPersistentVolumes(volumeName string) Builder { } func (b Builder) WithPodTemplate(pt corev1.PodTemplateSpec) Builder { - for i := range b.Elasticsearch.Spec.Nodes { - b.Elasticsearch.Spec.Nodes[i].PodTemplate = pt + for i := range b.Elasticsearch.Spec.NodeSets { + b.Elasticsearch.Spec.NodeSets[i].PodTemplate = pt } return b } func (b Builder) WithAdditionalConfig(nodeSpecCfg map[string]map[string]interface{}) Builder { - var newNodes []estype.NodeSpec + var newNodes []estype.NodeSet for node, cfg := range nodeSpecCfg { - for _, n := range b.Elasticsearch.Spec.Nodes { + for _, n := range b.Elasticsearch.Spec.NodeSets { if n.Name == node { newCfg := n.Config.DeepCopy() for k, v := range cfg { @@ -246,7 +246,7 @@ func (b Builder) WithAdditionalConfig(nodeSpecCfg map[string]map[string]interfac newNodes = append(newNodes, n) } } - b.Elasticsearch.Spec.Nodes = newNodes + b.Elasticsearch.Spec.NodeSets = newNodes return b } diff --git a/test/e2e/test/elasticsearch/checks_data.go b/test/e2e/test/elasticsearch/checks_data.go index 3c1b0c0ca6..38226ea530 100644 --- a/test/e2e/test/elasticsearch/checks_data.go +++ b/test/e2e/test/elasticsearch/checks_data.go @@ -164,8 +164,8 @@ func dataIntegrityReplicas(b Builder) int { // are tricky to capture and ignored here. isVersionUpgrade := initial.Elasticsearch.Spec.Version != b.Elasticsearch.Spec.Version httpOptionsChange := reflect.DeepEqual(initial.Elasticsearch.Spec.HTTP, b.Elasticsearch.Spec.HTTP) - for _, initialNs := range initial.Elasticsearch.Spec.Nodes { - for _, mutatedNs := range b.Elasticsearch.Spec.Nodes { + for _, initialNs := range initial.Elasticsearch.Spec.NodeSets { + for _, mutatedNs := range b.Elasticsearch.Spec.NodeSets { if initialNs.Name == mutatedNs.Name && (isVersionUpgrade || httpOptionsChange || !reflect.DeepEqual(initialNs, mutatedNs)) { // a rolling upgrade is scheduled for that NodeSpec diff --git a/test/e2e/test/elasticsearch/checks_es.go b/test/e2e/test/elasticsearch/checks_es.go index a8a1cff708..762d7928ad 100644 --- a/test/e2e/test/elasticsearch/checks_es.go +++ b/test/e2e/test/elasticsearch/checks_es.go @@ -133,9 +133,9 @@ func (e *esClusterChecks) CheckESNodesTopology(es estype.Elasticsearch) test.Ste } // flatten the topology - var expectedTopology []estype.NodeSpec - for _, node := range es.Spec.Nodes { - for i := 0; i < int(node.NodeCount); i++ { + var expectedTopology []estype.NodeSet + for _, node := range es.Spec.NodeSets { + for i := 0; i < int(node.Count); i++ { expectedTopology = append(expectedTopology, node) } } @@ -202,7 +202,7 @@ func rolesToConfig(roles []string) estype.Node { return node } -func compareMemoryLimit(topologyElement estype.NodeSpec, cgroupMemoryLimitsInBytes int64) bool { +func compareMemoryLimit(topologyElement estype.NodeSet, cgroupMemoryLimitsInBytes int64) bool { var memoryLimit *resource.Quantity for _, c := range topologyElement.PodTemplate.Spec.Containers { if c.Name == v1beta1.ElasticsearchContainerName { diff --git a/test/e2e/test/elasticsearch/checks_volume.go b/test/e2e/test/elasticsearch/checks_volume.go index 5a15081da5..47c352c8bc 100644 --- a/test/e2e/test/elasticsearch/checks_volume.go +++ b/test/e2e/test/elasticsearch/checks_volume.go @@ -15,7 +15,7 @@ import ( func usesEmptyDir(es estype.Elasticsearch) bool { var emptyDirUsed bool - for _, n := range es.Spec.Nodes { + for _, n := range es.Spec.NodeSets { for _, v := range n.PodTemplate.Spec.Volumes { if v.EmptyDir != nil && v.Name == volume.ElasticsearchDataVolumeName { emptyDirUsed = true diff --git a/test/e2e/test/elasticsearch/settings.go b/test/e2e/test/elasticsearch/settings.go index 70490cec99..b47567b99d 100644 --- a/test/e2e/test/elasticsearch/settings.go +++ b/test/e2e/test/elasticsearch/settings.go @@ -12,15 +12,15 @@ import ( func MustNumDataNodes(es v1beta1.Elasticsearch) int { var numNodes int - for _, n := range es.Spec.Nodes { + for _, n := range es.Spec.NodeSets { if isDataNode(n) { - numNodes += int(n.NodeCount) + numNodes += int(n.Count) } } return numNodes } -func isDataNode(node v1beta1.NodeSpec) bool { +func isDataNode(node v1beta1.NodeSet) bool { if node.Config == nil { return v1beta1.DefaultCfg.Node.Data // if not specified use the default } diff --git a/test/e2e/test/elasticsearch/steps_mutation.go b/test/e2e/test/elasticsearch/steps_mutation.go index 803ab9e939..1fb6d9f0b5 100644 --- a/test/e2e/test/elasticsearch/steps_mutation.go +++ b/test/e2e/test/elasticsearch/steps_mutation.go @@ -120,7 +120,7 @@ func IsOneDataNodeRollingUpgrade(b Builder) bool { // consider we're in the 1-node rolling upgrade scenario if we mutate // from one data node to one data node with the same name if MustNumDataNodes(initial) == 1 && MustNumDataNodes(mutated) == 1 && - initial.Spec.Nodes[0].Name == mutated.Spec.Nodes[0].Name { + initial.Spec.NodeSets[0].Name == mutated.Spec.NodeSets[0].Name { return true } return false diff --git a/test/e2e/test/kibana/builder.go b/test/e2e/test/kibana/builder.go index 8d067f2dab..694187fca4 100644 --- a/test/e2e/test/kibana/builder.go +++ b/test/e2e/test/kibana/builder.go @@ -78,7 +78,7 @@ func (b Builder) WithVersion(version string) Builder { } func (b Builder) WithNodeCount(count int) Builder { - b.Kibana.Spec.NodeCount = int32(count) + b.Kibana.Spec.Count = int32(count) return b } diff --git a/test/e2e/test/kibana/checks_k8s.go b/test/e2e/test/kibana/checks_k8s.go index e33665bef2..179b5c177f 100644 --- a/test/e2e/test/kibana/checks_k8s.go +++ b/test/e2e/test/kibana/checks_k8s.go @@ -35,14 +35,14 @@ func CheckKibanaDeployment(b Builder, k *test.K8sClient) test.Step { Namespace: b.Kibana.Namespace, Name: kbname.Deployment(b.Kibana.Name), }, &dep) - if b.Kibana.Spec.NodeCount == 0 && apierrors.IsNotFound(err) { + if b.Kibana.Spec.Count == 0 && apierrors.IsNotFound(err) { return nil } if err != nil { return err } - if *dep.Spec.Replicas != b.Kibana.Spec.NodeCount { - return fmt.Errorf("invalid Kibana replicas count: expected %d, got %d", b.Kibana.Spec.NodeCount, *dep.Spec.Replicas) + if *dep.Spec.Replicas != b.Kibana.Spec.Count { + return fmt.Errorf("invalid Kibana replicas count: expected %d, got %d", b.Kibana.Spec.Count, *dep.Spec.Replicas) } return nil }), @@ -54,7 +54,7 @@ func CheckKibanaPodsCount(b Builder, k *test.K8sClient) test.Step { return test.Step{ Name: "Kibana pods count should match the expected one", Test: test.Eventually(func() error { - return k.CheckPodCount(int(b.Kibana.Spec.NodeCount), test.KibanaPodListOptions(b.Kibana.Namespace, b.Kibana.Name)...) + return k.CheckPodCount(int(b.Kibana.Spec.Count), test.KibanaPodListOptions(b.Kibana.Namespace, b.Kibana.Name)...) }), } } @@ -101,7 +101,7 @@ func CheckServicesEndpoints(b Builder, k *test.K8sClient) test.Step { Name: "Kibana services should have endpoints", Test: test.Eventually(func() error { for endpointName, addrCount := range map[string]int{ - kbname.HTTPService(b.Kibana.Name): int(b.Kibana.Spec.NodeCount), + kbname.HTTPService(b.Kibana.Name): int(b.Kibana.Spec.Count), } { if addrCount == 0 { continue // maybe no Kibana in this b diff --git a/test/e2e/test/kibana/checks_kb.go b/test/e2e/test/kibana/checks_kb.go index 29529aac8b..74de7fd31f 100644 --- a/test/e2e/test/kibana/checks_kb.go +++ b/test/e2e/test/kibana/checks_kb.go @@ -23,7 +23,7 @@ type kbChecks struct { } func (b Builder) CheckStackTestSteps(k *test.K8sClient) test.StepList { - if b.Kibana.Spec.NodeCount == 0 { + if b.Kibana.Spec.Count == 0 { return test.StepList{} } From 3b0b933e6faa5d5ff74364c9bc1bd651cc57f86f Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 10:09:55 +0200 Subject: [PATCH 02/11] correct misspelled nodeSets --- docs/advanced-node-scheduling.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/advanced-node-scheduling.asciidoc b/docs/advanced-node-scheduling.asciidoc index de71da3c11..b1b7309dc7 100644 --- a/docs/advanced-node-scheduling.asciidoc +++ b/docs/advanced-node-scheduling.asciidoc @@ -89,7 +89,7 @@ metadata: name: quickstart spec: version: {version} - nodeSet: + nodeSets: - name: default count: 3 podTemplate: From c7acbffcf07f0dc368484f2f87fcbdc2fc9db198 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 10:19:34 +0200 Subject: [PATCH 03/11] fix overaggressive replace --- pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go b/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go index dde00a8e89..44934d3c76 100644 --- a/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go +++ b/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go @@ -55,7 +55,7 @@ type ElasticsearchSpec struct { SecureSettings []commonv1beta1.SecretSource `json:"secureSettings,omitempty"` } -// Count returns the total number of nodes of the Elasticsearch cluster +// NodeCount returns the total number of nodes of the Elasticsearch cluster func (es ElasticsearchSpec) NodeCount() int32 { count := int32(0) for _, topoElem := range es.NodeSets { @@ -74,7 +74,7 @@ type NodeSet struct { // Config represents Elasticsearch configuration. Config *commonv1beta1.Config `json:"config,omitempty"` - // Count defines how many nodes have this topology + // Count defines how many nodes this topology has Count int32 `json:"count,omitempty"` // PodTemplate can be used to propagate configuration to Elasticsearch pods. From 62066d8071ae91e78b8b6a30b5d54273643c9a87 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 10:21:35 +0200 Subject: [PATCH 04/11] Kibana has no nodeSets --- pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go | 2 +- pkg/apis/kibana/v1beta1/kibana_types.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go b/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go index 44934d3c76..a150ccb833 100644 --- a/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go +++ b/pkg/apis/elasticsearch/v1beta1/elasticsearch_types.go @@ -74,7 +74,7 @@ type NodeSet struct { // Config represents Elasticsearch configuration. Config *commonv1beta1.Config `json:"config,omitempty"` - // Count defines how many nodes this topology has + // Count defines how many nodes this topology should have. Count int32 `json:"count,omitempty"` // PodTemplate can be used to propagate configuration to Elasticsearch pods. diff --git a/pkg/apis/kibana/v1beta1/kibana_types.go b/pkg/apis/kibana/v1beta1/kibana_types.go index f2ed67298d..7e1bc0b2d8 100644 --- a/pkg/apis/kibana/v1beta1/kibana_types.go +++ b/pkg/apis/kibana/v1beta1/kibana_types.go @@ -39,7 +39,7 @@ type KibanaSpec struct { // PodTemplate can be used to propagate configuration to Kibana pods. // This allows specifying custom annotations, labels, environment variables, - // affinity, resources, etc. for the pods created from this NodeSet. + // affinity, resources, etc. for the pods created from this spec. // +kubebuilder:validation:Optional PodTemplate corev1.PodTemplateSpec `json:"podTemplate,omitempty"` From 28090ac84a09f7980f466427a51586dba4b92599 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 10:23:39 +0200 Subject: [PATCH 05/11] adjust variable names --- pkg/controller/elasticsearch/driver/esstate.go | 2 +- pkg/controller/elasticsearch/name/name.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/controller/elasticsearch/driver/esstate.go b/pkg/controller/elasticsearch/driver/esstate.go index ad44335e11..2a24a27f02 100644 --- a/pkg/controller/elasticsearch/driver/esstate.go +++ b/pkg/controller/elasticsearch/driver/esstate.go @@ -51,7 +51,7 @@ func initOnce(once *sync.Once, f func() error) error { return err } -// -- NodeSets +// -- Nodes // memoizingNodes provides nodes information. type memoizingNodes struct { diff --git a/pkg/controller/elasticsearch/name/name.go b/pkg/controller/elasticsearch/name/name.go index 772b9a2fc7..56f1b48f41 100644 --- a/pkg/controller/elasticsearch/name/name.go +++ b/pkg/controller/elasticsearch/name/name.go @@ -58,18 +58,18 @@ func Validate(es v1beta1.Elasticsearch) error { } // validate ssets - for _, nodeSpec := range es.Spec.NodeSets { - if errs := apimachineryvalidation.NameIsDNSSubdomain(nodeSpec.Name, false); len(errs) > 0 { - return fmt.Errorf("invalid nodeSpec name '%s': [%s]", nodeSpec.Name, strings.Join(errs, ",")) + for _, nodeSet := range es.Spec.NodeSets { + if errs := apimachineryvalidation.NameIsDNSSubdomain(nodeSet.Name, false); len(errs) > 0 { + return fmt.Errorf("invalid nodeSet name '%s': [%s]", nodeSet.Name, strings.Join(errs, ",")) } - ssetName, err := ESNamer.SafeSuffix(esName, nodeSpec.Name) + ssetName, err := ESNamer.SafeSuffix(esName, nodeSet.Name) if err != nil { - return errors.Wrapf(err, "error generating StatefulSet name for nodeSpec: '%s'", nodeSpec.Name) + return errors.Wrapf(err, "error generating StatefulSet name for nodeSet: '%s'", nodeSet.Name) } // length of the ordinal suffix that will be added to the pods of this sset (dash + ordinal) - podOrdinalSuffixLen := len(strconv.FormatInt(int64(nodeSpec.Count), 10)) + 1 + podOrdinalSuffixLen := len(strconv.FormatInt(int64(nodeSet.Count), 10)) + 1 // there should be enough space for the ordinal suffix if validation.DNS1123SubdomainMaxLength-len(ssetName) < podOrdinalSuffixLen { return fmt.Errorf("generated StatefulSet name '%s' exceeds allowed length of %d", From e9cbc4fbe9402db6ef31135f38e48849dcf655b2 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 10:29:24 +0200 Subject: [PATCH 06/11] adjust variable names --- pkg/controller/elasticsearch/name/name_test.go | 2 +- pkg/controller/elasticsearch/nodespec/podspec.go | 12 ++++++------ .../elasticsearch/nodespec/podspec_test.go | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pkg/controller/elasticsearch/name/name_test.go b/pkg/controller/elasticsearch/name/name_test.go index 0d76c1a896..7e4bc1b7b1 100644 --- a/pkg/controller/elasticsearch/name/name_test.go +++ b/pkg/controller/elasticsearch/name/name_test.go @@ -45,7 +45,7 @@ func TestValidate(t *testing.T) { esName: "test-es", nodeSpecNames: []string{"default", "my_ha_set"}, wantErr: true, - wantErrMsg: "invalid nodeSpec name", + wantErrMsg: "invalid nodeSet name", }, } diff --git a/pkg/controller/elasticsearch/nodespec/podspec.go b/pkg/controller/elasticsearch/nodespec/podspec.go index cd1c1782d8..5b9400fef7 100644 --- a/pkg/controller/elasticsearch/nodespec/podspec.go +++ b/pkg/controller/elasticsearch/nodespec/podspec.go @@ -28,17 +28,17 @@ import ( // BuildPodTemplateSpec builds a new PodTemplateSpec for an Elasticsearch node. func BuildPodTemplateSpec( es v1beta1.Elasticsearch, - nodeSpec v1beta1.NodeSet, + nodeSet v1beta1.NodeSet, cfg settings.CanonicalConfig, keystoreResources *keystore.Resources, ) (corev1.PodTemplateSpec, error) { - volumes, volumeMounts := buildVolumes(es.Name, nodeSpec, keystoreResources) - labels, err := buildLabels(es, cfg, nodeSpec, keystoreResources) + volumes, volumeMounts := buildVolumes(es.Name, nodeSet, keystoreResources) + labels, err := buildLabels(es, cfg, nodeSet, keystoreResources) if err != nil { return corev1.PodTemplateSpec{}, err } - builder := defaults.NewPodTemplateBuilder(nodeSpec.PodTemplate, v1beta1.ElasticsearchContainerName). + builder := defaults.NewPodTemplateBuilder(nodeSet.PodTemplate, v1beta1.ElasticsearchContainerName). WithDockerImage(es.Spec.Image, stringsutil.Concat(DefaultImageRepository, ":", es.Spec.Version)) initContainers, err := initcontainer.NewInitContainers( @@ -79,7 +79,7 @@ func transportCertificatesVolume(esName string) volume.SecretVolume { func buildLabels( es v1beta1.Elasticsearch, cfg settings.CanonicalConfig, - nodeSpec v1beta1.NodeSet, + nodeSet v1beta1.NodeSet, keystoreResources *keystore.Resources, ) (map[string]string, error) { // label with a hash of the config to rotate the pod on config changes @@ -98,7 +98,7 @@ func buildLabels( podLabels, err := label.NewPodLabels( k8s.ExtractNamespacedName(&es), - name.StatefulSet(es.Name, nodeSpec.Name), + name.StatefulSet(es.Name, nodeSet.Name), *ver, nodeRoles, cfgHash, es.Spec.HTTP.Scheme(), ) if err != nil { diff --git a/pkg/controller/elasticsearch/nodespec/podspec_test.go b/pkg/controller/elasticsearch/nodespec/podspec_test.go index ea1f441725..300834b624 100644 --- a/pkg/controller/elasticsearch/nodespec/podspec_test.go +++ b/pkg/controller/elasticsearch/nodespec/podspec_test.go @@ -37,7 +37,7 @@ var sampleES = v1beta1.Elasticsearch{ Version: "7.2.0", NodeSets: []v1beta1.NodeSet{ { - Name: "nodespec-1", + Name: "nodeset-1", Count: 2, Config: &commonv1beta1.Config{ Data: map[string]interface{}{ @@ -80,7 +80,7 @@ var sampleES = v1beta1.Elasticsearch{ VolumeClaimTemplates: []corev1.PersistentVolumeClaim{}, }, { - Name: "nodespec-1", + Name: "nodeset-1", Count: 2, }, }, @@ -89,10 +89,10 @@ var sampleES = v1beta1.Elasticsearch{ func TestBuildPodTemplateSpec(t *testing.T) { certResources := certificates.CertificateResources{HTTPCACertProvided: true} - nodeSpec := sampleES.Spec.NodeSets[0] + nodeSet := sampleES.Spec.NodeSets[0] ver, err := version.Parse(sampleES.Spec.Version) require.NoError(t, err) - cfg, err := settings.NewMergedESConfig(sampleES.Name, *ver, sampleES.Spec.HTTP, *nodeSpec.Config, &certResources) + cfg, err := settings.NewMergedESConfig(sampleES.Name, *ver, sampleES.Spec.HTTP, *nodeSet.Config, &certResources) require.NoError(t, err) actual, err := BuildPodTemplateSpec(sampleES, sampleES.Spec.NodeSets[0], cfg, nil) @@ -103,7 +103,7 @@ func TestBuildPodTemplateSpec(t *testing.T) { terminationGracePeriodSeconds := DefaultTerminationGracePeriodSeconds varFalse := false - volumes, volumeMounts := buildVolumes(sampleES.Name, nodeSpec, nil) + volumes, volumeMounts := buildVolumes(sampleES.Name, nodeSet, nil) // should be sorted sort.Slice(volumes, func(i, j int) bool { return volumes[i].Name < volumes[j].Name }) sort.Slice(volumeMounts, func(i, j int) bool { return volumeMounts[i].Name < volumeMounts[j].Name }) @@ -146,7 +146,7 @@ func TestBuildPodTemplateSpec(t *testing.T) { "elasticsearch.k8s.elastic.co/node-ingest": "true", "elasticsearch.k8s.elastic.co/node-master": "true", "elasticsearch.k8s.elastic.co/node-ml": "true", - "elasticsearch.k8s.elastic.co/statefulset": "name-es-nodespec-1", + "elasticsearch.k8s.elastic.co/statefulset": "name-es-nodeset-1", "elasticsearch.k8s.elastic.co/version": "7.2.0", "pod-template-label-name": "pod-template-label-value", }, From e1b79cb9b20c68fc1c00fa21678cae73bca23315 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 10:36:19 +0200 Subject: [PATCH 07/11] adjust variable names --- .../elasticsearch/nodespec/statefulset.go | 16 ++++++++-------- .../elasticsearch/validation/validations.go | 8 ++++---- test/e2e/test/elasticsearch/builder.go | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/pkg/controller/elasticsearch/nodespec/statefulset.go b/pkg/controller/elasticsearch/nodespec/statefulset.go index 52e5360747..2a5c209bdd 100644 --- a/pkg/controller/elasticsearch/nodespec/statefulset.go +++ b/pkg/controller/elasticsearch/nodespec/statefulset.go @@ -48,22 +48,22 @@ func HeadlessService(es types.NamespacedName, ssetName string) corev1.Service { func BuildStatefulSet( es v1beta1.Elasticsearch, - nodeSpec v1beta1.NodeSet, + nodeSet v1beta1.NodeSet, cfg settings.CanonicalConfig, keystoreResources *keystore.Resources, scheme *runtime.Scheme, ) (appsv1.StatefulSet, error) { - statefulSetName := name.StatefulSet(es.Name, nodeSpec.Name) + statefulSetName := name.StatefulSet(es.Name, nodeSet.Name) // ssetSelector is used to match the sset pods ssetSelector := label.NewStatefulSetLabels(k8s.ExtractNamespacedName(&es), statefulSetName) // add default PVCs to the node spec - nodeSpec.VolumeClaimTemplates = defaults.AppendDefaultPVCs( - nodeSpec.VolumeClaimTemplates, nodeSpec.PodTemplate.Spec, esvolume.DefaultVolumeClaimTemplates..., + nodeSet.VolumeClaimTemplates = defaults.AppendDefaultPVCs( + nodeSet.VolumeClaimTemplates, nodeSet.PodTemplate.Spec, esvolume.DefaultVolumeClaimTemplates..., ) // build pod template - podTemplate, err := BuildPodTemplateSpec(es, nodeSpec, cfg, keystoreResources) + podTemplate, err := BuildPodTemplateSpec(es, nodeSet, cfg, keystoreResources) if err != nil { return appsv1.StatefulSet{}, err } @@ -77,8 +77,8 @@ func BuildStatefulSet( // set the owner reference of all volume claims to the ES resource, // so PVC get deleted automatically upon Elasticsearch resource deletion - claims := make([]corev1.PersistentVolumeClaim, 0, len(nodeSpec.VolumeClaimTemplates)) - for _, claim := range nodeSpec.VolumeClaimTemplates { + claims := make([]corev1.PersistentVolumeClaim, 0, len(nodeSet.VolumeClaimTemplates)) + for _, claim := range nodeSet.VolumeClaimTemplates { if err := controllerutil.SetControllerReference(&es, &claim, scheme); err != nil { return appsv1.StatefulSet{}, err } @@ -106,7 +106,7 @@ func BuildStatefulSet( MatchLabels: ssetSelector, }, - Replicas: &nodeSpec.Count, + Replicas: &nodeSet.Count, VolumeClaimTemplates: claims, Template: podTemplate, }, diff --git a/pkg/controller/elasticsearch/validation/validations.go b/pkg/controller/elasticsearch/validation/validations.go index c40da783c0..18fa76ce76 100644 --- a/pkg/controller/elasticsearch/validation/validations.go +++ b/pkg/controller/elasticsearch/validation/validations.go @@ -147,15 +147,15 @@ func pvcModification(ctx Context) validation.Result { return validation.OK } for _, node := range ctx.Proposed.Elasticsearch.Spec.NodeSets { - currNode := getNode(node.Name, ctx.Current.Elasticsearch) - if currNode == nil { + currNodeSet := getNodeSet(node.Name, ctx.Current.Elasticsearch) + if currNodeSet == nil { // this is a new sset, so there is nothing to check continue } // ssets do not allow modifications to fields other than 'replicas', 'template', and 'updateStrategy' // reflection isn't ideal, but okay here since the ES object does not have the status of the claims - if !reflect.DeepEqual(node.VolumeClaimTemplates, currNode.VolumeClaimTemplates) { + if !reflect.DeepEqual(node.VolumeClaimTemplates, currNodeSet.VolumeClaimTemplates) { return validation.Result{ Allowed: false, Reason: pvcImmutableMsg, @@ -165,7 +165,7 @@ func pvcModification(ctx Context) validation.Result { return validation.OK } -func getNode(name string, es v1beta1.Elasticsearch) *v1beta1.NodeSet { +func getNodeSet(name string, es v1beta1.Elasticsearch) *v1beta1.NodeSet { for i := range es.Spec.NodeSets { if es.Spec.NodeSets[i].Name == name { return &es.Spec.NodeSets[i] diff --git a/test/e2e/test/elasticsearch/builder.go b/test/e2e/test/elasticsearch/builder.go index db28deb760..31bfc396c4 100644 --- a/test/e2e/test/elasticsearch/builder.go +++ b/test/e2e/test/elasticsearch/builder.go @@ -232,21 +232,21 @@ func (b Builder) WithPodTemplate(pt corev1.PodTemplateSpec) Builder { return b } -func (b Builder) WithAdditionalConfig(nodeSpecCfg map[string]map[string]interface{}) Builder { - var newNodes []estype.NodeSet - for node, cfg := range nodeSpecCfg { +func (b Builder) WithAdditionalConfig(nodeSetCfg map[string]map[string]interface{}) Builder { + var newNodeSets []estype.NodeSet + for nodeSetName, cfg := range nodeSetCfg { for _, n := range b.Elasticsearch.Spec.NodeSets { - if n.Name == node { + if n.Name == nodeSetName { newCfg := n.Config.DeepCopy() for k, v := range cfg { newCfg.Data[k] = v } n.Config = newCfg } - newNodes = append(newNodes, n) + newNodeSets = append(newNodeSets, n) } } - b.Elasticsearch.Spec.NodeSets = newNodes + b.Elasticsearch.Spec.NodeSets = newNodeSets return b } From a49b99b19490fa7194b4e0a72f9a982ddfb769f6 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 10:50:26 +0200 Subject: [PATCH 08/11] restore notice file --- NOTICE.txt | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/NOTICE.txt b/NOTICE.txt index 2441d9fbce..47660bcf8b 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -8,6 +8,35 @@ Third party libraries used by the Elastic Cloud on Kubernetes project ================================================================================ +-------------------------------------------------------------------------------- +Module : github.com/Masterminds/sprig +Version : v2.20.0+incompatible +Time : 2019-06-18 15:54:40 +0000 UTC + +Contents of probable licence file $GOMODCACHE/github.com/!masterminds/sprig@v2.20.0+incompatible/LICENSE.txt: + +Sprig +Copyright (C) 2013 Masterminds + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + -------------------------------------------------------------------------------- Module : github.com/davecgh/go-spew Version : v1.1.1 From 98204e84148355fb5f6ea9fa8b64ea6d18ffaad4 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 11:07:24 +0200 Subject: [PATCH 09/11] add missed renames --- docs/k8s-quickstart.asciidoc | 2 +- pkg/apis/kibana/v1beta1/kibana_types.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/k8s-quickstart.asciidoc b/docs/k8s-quickstart.asciidoc index 66e3af8caa..ac65505c9d 100644 --- a/docs/k8s-quickstart.asciidoc +++ b/docs/k8s-quickstart.asciidoc @@ -247,7 +247,7 @@ metadata: name: quickstart spec: version: {version} - nodes: + nodeSets: - name: default count: 3 config: diff --git a/pkg/apis/kibana/v1beta1/kibana_types.go b/pkg/apis/kibana/v1beta1/kibana_types.go index 7e1bc0b2d8..f710e0d623 100644 --- a/pkg/apis/kibana/v1beta1/kibana_types.go +++ b/pkg/apis/kibana/v1beta1/kibana_types.go @@ -25,7 +25,7 @@ type KibanaSpec struct { Image string `json:"image,omitempty"` // Count defines how many nodes the Kibana deployment must have. - Count int32 `json:"nodeCount,omitempty"` + Count int32 `json:"count,omitempty"` // ElasticsearchRef references an Elasticsearch resource in the Kubernetes cluster. // If the namespace is not specified, the current resource namespace will be used. From 56ce0a159ab0d3636cc08962efed04f16b8a2449 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 11:11:01 +0200 Subject: [PATCH 10/11] add missed renames --- docs/elasticsearch-spec.asciidoc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/elasticsearch-spec.asciidoc b/docs/elasticsearch-spec.asciidoc index 16d5b7aaeb..8de7a53366 100644 --- a/docs/elasticsearch-spec.asciidoc +++ b/docs/elasticsearch-spec.asciidoc @@ -74,13 +74,14 @@ See also: link:https://www.elastic.co/guide/en/elasticsearch/reference/current/h [id="{p}-node-configuration"] === Node configuration -Any setting defined in the `elasticsearch.yml` configuration file can also be defined for each topology of nodes in the `spec.nodes[?].config` section. +Any setting defined in the `elasticsearch.yml` configuration file can also be defined for each topology of nodes in the `spec.nodeSets[?].config` section. [source,yaml] ---- spec: - nodes: - - nodeCount: 3 + nodeSets: + - name: masters + count: 3 config: node.master: true node.data: false @@ -88,7 +89,8 @@ spec: node.ml: false xpack.ml.enabled: true cluster.remote.connect: false - - nodeCount: 10 + - name: data + count: 10 config: node.master: false node.data: true @@ -109,7 +111,7 @@ You can customize the volume claim templates used by Elasticsearch to adjust the [source,yaml] ---- spec: - nodes: + nodeSets: - volumeClaimTemplates: - metadata: name: elasticsearch-data @@ -127,7 +129,7 @@ If you want to use an `emptyDir` volume, specify the `elasticsearch-data` volume [source,yaml] ---- spec: - nodes: + nodeSets: - config: podTemplate: spec: @@ -190,8 +192,8 @@ link:https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modul [source,yaml] ---- spec: - nodes: - - nodeCount: 3 + nodeSets: + - count: 3 config: index.store.type: niofs ---- @@ -271,7 +273,7 @@ nodes start, use an init container to run the link:https://www.elastic.co/guide/ [source,yaml] ---- spec: - nodes: + nodeSets: - podTemplate: spec: initContainers: From 2d6446f9c911e47463806c39071e9d7229e518b0 Mon Sep 17 00:00:00 2001 From: Peter Brachwitz Date: Wed, 2 Oct 2019 12:01:59 +0200 Subject: [PATCH 11/11] post merge fixup --- test/e2e/es/forced_upgrade_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/es/forced_upgrade_test.go b/test/e2e/es/forced_upgrade_test.go index cbc90bd54b..9c0e4919ff 100644 --- a/test/e2e/es/forced_upgrade_test.go +++ b/test/e2e/es/forced_upgrade_test.go @@ -18,13 +18,13 @@ func TestForceUpgradePendingPods(t *testing.T) { // create a cluster whose Pods will stay Pending forever initial := elasticsearch.NewBuilder("force-upgrade-pending"). WithESMasterDataNodes(3, elasticsearch.DefaultResources) - initial.Elasticsearch.Spec.Nodes[0].PodTemplate.Spec.NodeSelector = map[string]string{ + initial.Elasticsearch.Spec.NodeSets[0].PodTemplate.Spec.NodeSelector = map[string]string{ "cannot": "be-scheduled", } // fix that cluster to remove the wrong NodeSelector fixed := elasticsearch.Builder{} fixed.Elasticsearch = *initial.Elasticsearch.DeepCopy() - fixed.Elasticsearch.Spec.Nodes[0].PodTemplate.Spec.NodeSelector = nil + fixed.Elasticsearch.Spec.NodeSets[0].PodTemplate.Spec.NodeSelector = nil k := test.NewK8sClientOrFatal() elasticsearch.ForcedUpgradeTestSteps( @@ -49,7 +49,7 @@ func TestForceUpgradeBootloopingPods(t *testing.T) { // fix that cluster to remove the wrong configuration fixed := elasticsearch.Builder{} fixed.Elasticsearch = *initial.Elasticsearch.DeepCopy() - fixed.Elasticsearch.Spec.Nodes[0].Config = nil + fixed.Elasticsearch.Spec.NodeSets[0].Config = nil k := test.NewK8sClientOrFatal() elasticsearch.ForcedUpgradeTestSteps(