Skip to content

Commit 656cdf0

Browse files
eedugonbarkbay
andauthored
service template support for remoteClusterServer interface (#8892)
* service template support for remoteClusterServer interface Co-authored-by: Michael Morello <[email protected]>
1 parent 8f27b0b commit 656cdf0

File tree

8 files changed

+1219
-16
lines changed

8 files changed

+1219
-16
lines changed

config/crds/v1/all-crds.yaml

Lines changed: 370 additions & 0 deletions
Large diffs are not rendered by default.

config/crds/v1/resources/elasticsearch.k8s.elastic.co_elasticsearches.yaml

Lines changed: 370 additions & 0 deletions
Large diffs are not rendered by default.

deploy/eck-operator/charts/eck-operator-crds/templates/all-crds.yaml

Lines changed: 370 additions & 0 deletions
Large diffs are not rendered by default.

docs/reference/api-reference/main.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ ServiceTemplate defines the template for a Kubernetes Service.
671671
:::{admonition} Appears In:
672672
* [HTTPConfig](#httpconfig)
673673
* [LogstashService](#logstashservice)
674+
* [RemoteClusterServer](#remoteclusterserver)
674675
* [TransportConfig](#transportconfig)
675676

676677
:::
@@ -1276,6 +1277,7 @@ RemoteClusterAccess models the API key specification as documented in https://ww
12761277
| Field | Description |
12771278
| --- | --- |
12781279
| *`enabled`* __boolean__ | |
1280+
| *`service`* __[ServiceTemplate](#servicetemplate)__ | Service defines the template for the remote cluster server Service object. |
12791281

12801282

12811283
### Replication [#replication]

pkg/apis/elasticsearch/v1/elasticsearch_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ type ElasticsearchSpec struct {
155155
type RemoteClusterServer struct {
156156
// +kubebuilder:validation:Optional
157157
Enabled bool `json:"enabled,omitempty"`
158+
// Service defines the template for the remote cluster server Service object.
159+
Service commonv1.ServiceTemplate `json:"service,omitempty"`
158160
}
159161

160162
// VolumeClaimDeletePolicy describes the delete policy for handling PersistentVolumeClaims that hold Elasticsearch data.

pkg/apis/elasticsearch/v1/zz_generated.deepcopy.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/controller/elasticsearch/services/services.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -161,29 +161,31 @@ func NewInternalService(es esv1.Elasticsearch, meta metadata.Metadata) *corev1.S
161161

162162
// NewRemoteClusterService returns the service associated to the remote cluster service for the given cluster.
163163
func NewRemoteClusterService(es esv1.Elasticsearch, meta metadata.Metadata) *corev1.Service {
164-
svc := &corev1.Service{
165-
ObjectMeta: metav1.ObjectMeta{
166-
Name: RemoteClusterServiceName(es.Name),
167-
Namespace: es.Namespace,
168-
Labels: meta.Labels,
169-
Annotations: meta.Annotations,
170-
},
171-
Spec: corev1.ServiceSpec{
172-
Type: corev1.ServiceTypeClusterIP,
173-
Selector: label.NewLabels(k8s.ExtractNamespacedName(&es)),
174-
PublishNotReadyAddresses: true,
175-
ClusterIP: "None",
176-
},
164+
nsn := k8s.ExtractNamespacedName(&es)
165+
svc := corev1.Service{
166+
ObjectMeta: es.Spec.RemoteClusterServer.Service.ObjectMeta,
167+
Spec: es.Spec.RemoteClusterServer.Service.Spec,
177168
}
178-
selector := label.NewLabels(k8s.ExtractNamespacedName(&es))
169+
170+
svc.ObjectMeta.Namespace = es.Namespace
171+
svc.ObjectMeta.Name = RemoteClusterServiceName(es.Name)
172+
// Allow connections to pods that are not yet ready
173+
svc.Spec.PublishNotReadyAddresses = true
174+
if svc.Spec.Type == "" {
175+
svc.Spec.Type = corev1.ServiceTypeClusterIP
176+
// ClusterIP None creates a headless service, allowing direct access to all pods for remote cluster connections
177+
svc.Spec.ClusterIP = "None"
178+
}
179+
selector := label.NewLabels(nsn)
179180
ports := []corev1.ServicePort{
180181
{
181182
Name: RemoteClusterServicePortName,
182183
Protocol: corev1.ProtocolTCP,
183184
Port: network.RemoteClusterPort,
184185
},
185186
}
186-
return defaults.SetServiceDefaults(svc, meta, selector, ports)
187+
188+
return defaults.SetServiceDefaults(&svc, meta, selector, ports)
187189
}
188190

189191
type urlProvider struct {

pkg/controller/elasticsearch/services/services_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,92 @@ func TestNewTransportService(t *testing.T) {
284284
}
285285
}
286286

287+
func mkRemoteClusterService() corev1.Service {
288+
return corev1.Service{
289+
ObjectMeta: metav1.ObjectMeta{
290+
Name: "elasticsearch-test-es-remote-cluster",
291+
Namespace: "test",
292+
Labels: map[string]string{
293+
label.ClusterNameLabelName: "elasticsearch-test",
294+
commonv1.TypeLabelName: label.Type,
295+
},
296+
},
297+
Spec: corev1.ServiceSpec{
298+
PublishNotReadyAddresses: true,
299+
ClusterIP: "None",
300+
Type: corev1.ServiceTypeClusterIP,
301+
Ports: []corev1.ServicePort{
302+
{
303+
Name: RemoteClusterServicePortName,
304+
Protocol: corev1.ProtocolTCP,
305+
Port: network.RemoteClusterPort,
306+
},
307+
},
308+
Selector: map[string]string{
309+
label.ClusterNameLabelName: "elasticsearch-test",
310+
commonv1.TypeLabelName: label.Type,
311+
},
312+
},
313+
}
314+
}
315+
316+
func TestNewRemoteClusterService(t *testing.T) {
317+
tests := []struct {
318+
name string
319+
remoteClusterServer esv1.RemoteClusterServer
320+
want func() corev1.Service
321+
}{
322+
{
323+
name: "Sets defaults",
324+
remoteClusterServer: esv1.RemoteClusterServer{
325+
Enabled: true,
326+
},
327+
want: mkRemoteClusterService,
328+
},
329+
{
330+
name: "Respects user provided template",
331+
remoteClusterServer: esv1.RemoteClusterServer{
332+
Enabled: true,
333+
Service: commonv1.ServiceTemplate{
334+
ObjectMeta: metav1.ObjectMeta{
335+
Annotations: map[string]string{
336+
"my-custom": "annotation",
337+
},
338+
},
339+
Spec: corev1.ServiceSpec{
340+
Type: corev1.ServiceTypeLoadBalancer,
341+
},
342+
},
343+
},
344+
want: func() corev1.Service {
345+
svc := mkRemoteClusterService()
346+
svc.ObjectMeta.Annotations = map[string]string{
347+
"my-custom": "annotation",
348+
}
349+
svc.Spec.Type = corev1.ServiceTypeLoadBalancer
350+
svc.Spec.ClusterIP = ""
351+
return svc
352+
},
353+
},
354+
}
355+
for _, tt := range tests {
356+
t.Run(tt.name, func(t *testing.T) {
357+
es := esv1.Elasticsearch{
358+
ObjectMeta: metav1.ObjectMeta{
359+
Name: "elasticsearch-test",
360+
Namespace: "test",
361+
},
362+
Spec: esv1.ElasticsearchSpec{
363+
RemoteClusterServer: tt.remoteClusterServer,
364+
},
365+
}
366+
want := tt.want()
367+
got := NewRemoteClusterService(es, metadata.Propagate(&es, metadata.Metadata{Labels: es.GetIdentityLabels()}))
368+
require.Nil(t, deep.Equal(*got, want))
369+
})
370+
}
371+
}
372+
287373
func Test_urlProvider_PodURL(t *testing.T) {
288374
type fields struct {
289375
pods func() ([]corev1.Pod, error)

0 commit comments

Comments
 (0)