Skip to content

Commit 24ebea8

Browse files
authored
Add endpoint slice data source (#2847)
Register endpoint slice in provider Add test file Add documentaiton and modified test file add changelog entry fix changelog entry fix changelog fix changelog 2 changed copright Add headers
1 parent 6f3c8d0 commit 24ebea8

File tree

5 files changed

+311
-0
lines changed

5 files changed

+311
-0
lines changed

.changelog/2847.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:feature
2+
kubernetes: Add `kubernetes_endpoint_slice_v1` data source
3+
```
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
---
2+
subcategory: "discovery/v1"
3+
page_title: "Kubernetes: kubernetes_endpoint_slice_v1"
4+
description: |-
5+
An EndpointSlice contains references to a set of network endpoints. This data source allows you to pull data about such endpoint slice.
6+
---
7+
8+
# kubernetes_endpoint_slice_v1
9+
10+
An EndpointSlice contains references to a set of network endpoints. This data source allows you to pull data about such endpoint slice.
11+
12+
<!-- schema generated by tfplugindocs -->
13+
## Schema
14+
15+
### Required
16+
17+
- `metadata` (Block List, Min: 1, Max: 1) Standard endpoint_slice's metadata. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata (see [below for nested schema](#nestedblock--metadata))
18+
19+
### Read-Only
20+
21+
- `address_type` (String) address_type specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation.
22+
- `endpoint` (List of Object) endpoint is a list of unique endpoints in this slice. Each slice may include a maximum of 1000 endpoints. (see [below for nested schema](#nestedatt--endpoint))
23+
- `id` (String) The ID of this resource.
24+
- `port` (List of Object) port specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. Each slice may include a maximum of 100 ports. (see [below for nested schema](#nestedatt--port))
25+
26+
<a id="nestedatt--endpoint"></a>
27+
### Nested Schema for `endpoint`
28+
29+
Read-Only:
30+
31+
- `addresses` (List of String) addresses of this endpoint. The contents of this field are interpreted according to the corresponding EndpointSlice addressType field.
32+
- `condition` (List of Object) condition contains information about the current status of the endpoint. (see [below for nested schema](#nestedobjatt--endpoint--condition))
33+
- `hostname` (String) hostname of this endpoint. This field may be used by consumers of endpoints to distinguish endpoints from each other.
34+
- `node_name` (String) nodeName represents the name of the Node hosting this endpoint. This can be used to determine endpoints local to a Node.
35+
- `target_ref` (List of Object) targetRef is a reference to a Kubernetes object that represents this endpoint. (see [below for nested schema](#nestedobjatt--endpoint--target_ref))
36+
- `zone` (String) zone is the name of the Zone this endpoint exists in.
37+
38+
<a id="nestedobjatt--endpoint--condition"></a>
39+
### Nested Schema for `endpoint.condition`
40+
41+
Read-Only:
42+
43+
- `ready` (Boolean) ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint.
44+
- `serving` (Boolean) serving is identical to ready except that it is set regardless of the terminating state of endpoints.
45+
- `terminating` (Boolean) terminating indicates that this endpoint is terminating.
46+
47+
48+
<a id="nestedobjatt--endpoint--target_ref"></a>
49+
### Nested Schema for `endpoint.target_ref`
50+
51+
Read-Only:
52+
53+
- `field_path` (String) If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
54+
- `name` (String) Name of the referent.
55+
- `namespace` (String) Namespace of the referent.
56+
- `resource_version` (String) Specific resourceVersion to which this reference is made, if any.
57+
- `uid` (String) If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
58+
59+
60+
61+
<a id="nestedblock--metadata"></a>
62+
### Nested Schema for `metadata`
63+
64+
Optional:
65+
66+
- `annotations` (Map of String) An unstructured key value map stored with the endpoint_slice that may be used to store arbitrary metadata. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
67+
- `generate_name` (String) Prefix, used by the server, to generate a unique name ONLY IF the `name` field has not been provided. This value will also be combined with a unique suffix. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#idempotency
68+
- `labels` (Map of String) Map of string keys and values that can be used to organize and categorize (scope and select) the endpoint_slice. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
69+
- `name` (String) Name of the endpoint_slice, must be unique. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
70+
- `namespace` (String) Namespace defines the space within which name of the endpoint_slice must be unique.
71+
72+
Read-Only:
73+
74+
- `generation` (Number) A sequence number representing a specific generation of the desired state.
75+
- `resource_version` (String) An opaque value that represents the internal version of this endpoint_slice that can be used by clients to determine when endpoint_slice has changed. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
76+
- `uid` (String) The unique in time and space value for this endpoint_slice. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
77+
78+
79+
<a id="nestedatt--port"></a>
80+
### Nested Schema for `port`
81+
82+
Read-Only:
83+
84+
- `app_protocol` (String) The application protocol for this port. This is used as a hint for implementations to offer richer behavior for protocols that they understand.
85+
- `name` (String) name represents the name of this port. All ports in an EndpointSlice must have a unique name.
86+
- `port` (String) port represents the port number of the endpoint.
87+
- `protocol` (String) protocol represents the IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.
88+
89+
90+
91+
92+
## Example Usage
93+
94+
```terraform
95+
data "kubernetes_endpoint_slice_v1" "example" {
96+
metadata {
97+
name = "example-endpoint-slice"
98+
namespace = "default"
99+
}
100+
}
101+
102+
output "endpoint_addresses" {
103+
value = flatten([
104+
for e in data.kubernetes_endpoint_slice_v1.example.endpoint :
105+
e.addresses if e.condition[0].ready
106+
])
107+
}
108+
```
109+
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright (c) IBM Corp. 2017, 2026
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package kubernetes
5+
6+
import (
7+
"context"
8+
"log"
9+
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
apierrors "k8s.io/apimachinery/pkg/api/errors"
13+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
)
15+
16+
func dataSourceKubernetesEndpointSliceV1() *schema.Resource {
17+
return &schema.Resource{
18+
Description: "An EndpointSlice contains references to a set of network endpoints. This data source allows you to pull data about such endpoint slice.",
19+
ReadContext: dataSourceKubernetesEndpointSliceV1Read,
20+
Schema: map[string]*schema.Schema{
21+
"metadata": namespacedMetadataSchema("endpoint_slice", true),
22+
"address_type": {
23+
Type: schema.TypeString,
24+
Description: "address_type specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation.",
25+
Computed: true,
26+
},
27+
"endpoint": {
28+
Type: schema.TypeList,
29+
Description: "endpoint is a list of unique endpoints in this slice. Each slice may include a maximum of 1000 endpoints.",
30+
Computed: true,
31+
Elem: schemaEndpointSliceSubsetEndpoints(),
32+
},
33+
"port": {
34+
Type: schema.TypeList,
35+
Description: "port specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. Each slice may include a maximum of 100 ports.",
36+
Computed: true,
37+
Elem: schemaEndpointSliceSubsetPorts(),
38+
},
39+
},
40+
}
41+
}
42+
43+
func dataSourceKubernetesEndpointSliceV1Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
44+
conn, err := meta.(KubeClientsets).MainClientset()
45+
if err != nil {
46+
return diag.FromErr(err)
47+
}
48+
49+
metadata := expandMetadata(d.Get("metadata").([]interface{}))
50+
51+
om := metav1.ObjectMeta{
52+
Namespace: metadata.Namespace,
53+
Name: metadata.Name,
54+
}
55+
d.SetId(buildId(om))
56+
57+
log.Printf("[INFO] Reading endpoint slice %s", metadata.Name)
58+
ep, err := conn.DiscoveryV1().EndpointSlices(metadata.Namespace).Get(ctx, metadata.Name, metav1.GetOptions{})
59+
if err != nil {
60+
if apierrors.IsNotFound(err) {
61+
return nil
62+
}
63+
log.Printf("[DEBUG] Received error: %#v", err)
64+
return diag.Errorf("Failed to read endpoint slice because: %s", err)
65+
}
66+
log.Printf("[INFO] Received endpoint slice: %#v", ep)
67+
68+
err = d.Set("metadata", flattenMetadataFields(ep.ObjectMeta))
69+
if err != nil {
70+
return diag.FromErr(err)
71+
}
72+
73+
err = d.Set("address_type", string(ep.AddressType))
74+
if err != nil {
75+
return diag.FromErr(err)
76+
}
77+
78+
err = d.Set("endpoint", flattenEndpointSliceEndpoints(ep.Endpoints))
79+
if err != nil {
80+
return diag.FromErr(err)
81+
}
82+
83+
err = d.Set("port", flattenEndpointSlicePorts(ep.Ports))
84+
if err != nil {
85+
return diag.FromErr(err)
86+
}
87+
88+
return nil
89+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright (c) IBM Corp. 2017, 2026
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
//nolint:all
5+
package kubernetes
6+
7+
import (
8+
"fmt"
9+
"testing"
10+
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
12+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
13+
)
14+
15+
func TestAccKubernetesDataSourceEndpointSliceV1_basic(t *testing.T) {
16+
resourceName := "kubernetes_endpoint_slice_v1.test"
17+
dataSourceName := "data.kubernetes_endpoint_slice_v1.test"
18+
name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
19+
20+
resource.ParallelTest(t, resource.TestCase{
21+
PreCheck: func() { testAccPreCheck(t) },
22+
ProviderFactories: testAccProviderFactories,
23+
Steps: []resource.TestStep{
24+
{
25+
Config: testAccKubernetesEndpointSliceV1Config_basic(name),
26+
Check: resource.ComposeAggregateTestCheckFunc(
27+
resource.TestCheckResourceAttr(resourceName, "metadata.0.name", name),
28+
resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
29+
resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
30+
resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
31+
resource.TestCheckResourceAttr(resourceName, "endpoint.#", "1"),
32+
resource.TestCheckResourceAttr(resourceName, "endpoint.0.condition.#", "0"),
33+
resource.TestCheckResourceAttr(resourceName, "endpoint.0.addresses.#", "1"),
34+
resource.TestCheckResourceAttr(resourceName, "endpoint.0.addresses.0", "129.144.50.56"),
35+
resource.TestCheckResourceAttr(resourceName, "port.#", "1"),
36+
resource.TestCheckResourceAttr(resourceName, "port.0.port", "90"),
37+
resource.TestCheckResourceAttr(resourceName, "port.0.name", "first"),
38+
resource.TestCheckResourceAttr(resourceName, "port.0.app_protocol", "test"),
39+
),
40+
},
41+
{
42+
Config: testAccKubernetesEndpointSliceV1Config_modified(name) + testAccKubernetesDataSourceEndpointSliceV1_read(),
43+
Check: resource.ComposeAggregateTestCheckFunc(
44+
resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
45+
resource.TestCheckResourceAttrSet(dataSourceName, "metadata.0.generation"),
46+
resource.TestCheckResourceAttrSet(dataSourceName, "metadata.0.resource_version"),
47+
resource.TestCheckResourceAttrSet(dataSourceName, "metadata.0.uid"),
48+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.#", "1"),
49+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.condition.#", "1"),
50+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.condition.0.ready", "true"),
51+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.condition.0.serving", "false"),
52+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.condition.0.terminating", "false"),
53+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.hostname", "test"),
54+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.node_name", "test"),
55+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.addresses.#", "2"),
56+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.target_ref.0.name", "test"),
57+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.addresses.0", "2001:db8:3333:4444:5555:6666:7777:8888"),
58+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.0.addresses.1", "2002:db8:3333:4444:5555:6666:7777:8888"),
59+
resource.TestCheckResourceAttr(dataSourceName, "port.#", "2"),
60+
resource.TestCheckResourceAttr(dataSourceName, "port.0.port", "90"),
61+
resource.TestCheckResourceAttr(dataSourceName, "port.0.name", "first"),
62+
resource.TestCheckResourceAttr(dataSourceName, "port.0.app_protocol", "test"),
63+
resource.TestCheckResourceAttr(dataSourceName, "port.1.port", "900"),
64+
resource.TestCheckResourceAttr(dataSourceName, "port.1.name", "second"),
65+
resource.TestCheckResourceAttr(dataSourceName, "port.1.app_protocol", "test"),
66+
resource.TestCheckResourceAttr(dataSourceName, "address_type", "IPv6"),
67+
),
68+
},
69+
},
70+
})
71+
}
72+
73+
func TestAccKubernetesDataSourceEndpointSliceV1_not_found(t *testing.T) {
74+
dataSourceName := "data.kubernetes_endpoint_slice_v1.test"
75+
name := fmt.Sprintf("ceci-n.est-pas-une-endpoint-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
76+
77+
resource.ParallelTest(t, resource.TestCase{
78+
PreCheck: func() { testAccPreCheck(t) },
79+
ProviderFactories: testAccProviderFactories,
80+
Steps: []resource.TestStep{
81+
{
82+
Config: testAccKubernetesDataSourceEndpointSliceV1_nonexistent(name),
83+
Check: resource.ComposeAggregateTestCheckFunc(
84+
resource.TestCheckResourceAttr(dataSourceName, "metadata.0.name", name),
85+
resource.TestCheckResourceAttr(dataSourceName, "endpoint.#", "0"),
86+
resource.TestCheckResourceAttr(dataSourceName, "port.#", "0"),
87+
),
88+
},
89+
},
90+
})
91+
}
92+
93+
func testAccKubernetesDataSourceEndpointSliceV1_read() string {
94+
return `data "kubernetes_endpoint_slice_v1" "test" {
95+
metadata {
96+
name = "${kubernetes_endpoint_slice_v1.test.metadata.0.name}"
97+
}
98+
}
99+
`
100+
}
101+
102+
func testAccKubernetesDataSourceEndpointSliceV1_nonexistent(name string) string {
103+
return fmt.Sprintf(`data "kubernetes_endpoint_slice_v1" "test" {
104+
metadata {
105+
name = "%s"
106+
}
107+
}
108+
`, name)
109+
}

kubernetes/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ func Provider() *schema.Provider {
225225
"kubernetes_secret": dataSourceKubernetesSecretV1("Deprecated; use kubernetes_secret_v1."),
226226
"kubernetes_secret_v1": dataSourceKubernetesSecretV1(""),
227227
"kubernetes_endpoints_v1": dataSourceKubernetesEndpointsV1(),
228+
"kubernetes_endpoint_slice_v1": dataSourceKubernetesEndpointSliceV1(),
228229
"kubernetes_service": dataSourceKubernetesServiceV1("Deprecated; use kubernetes_service_v1."),
229230
"kubernetes_service_v1": dataSourceKubernetesServiceV1(""),
230231
"kubernetes_pod": dataSourceKubernetesPodV1("Deprecated; use kubernetes_pod_v1."),

0 commit comments

Comments
 (0)