Skip to content

Commit d54521e

Browse files
Kurmanadh VallaSrividyaKamakshi
authored andcommitted
Added - Support for OCI Cache - RBAC/ACL Support
1 parent 885996f commit d54521e

25 files changed

+3144
-0
lines changed
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
2+
// Licensed under the Mozilla Public License v2.0
3+
4+
variable "region" {
5+
default = "us-ashburn-1"
6+
}
7+
8+
variable "compartment_id" {}
9+
#OciCacheCluster vars
10+
11+
variable "redis_cluster_freeform_tags" {
12+
default = { "bar-key" = "value" }
13+
}
14+
15+
variable "redis_cluster_node_count" {
16+
default = 2
17+
}
18+
19+
variable "redis_cluster_node_memory_in_gbs" {
20+
default = 2.0
21+
}
22+
23+
variable "redis_cluster_software_version" {
24+
default = "VALKEY_7_2"
25+
}
26+
27+
28+
variable "redis_cluster_display_name" {
29+
type = string
30+
default = "test-tf-redis-cluster"
31+
}
32+
33+
#OciCacheUser vars
34+
variable "oci_cache_user_description" {
35+
type = string
36+
default = "Test Cache user created via Terraform"
37+
}
38+
39+
variable "oci_cache_user_acl_string" {
40+
type = string
41+
default = "~* +get +set"
42+
}
43+
44+
variable "oci_cache_user_password_auth_name" {
45+
type = string
46+
default = "test-tf-pwd-user"
47+
}
48+
49+
variable "oci_cache_user_iam_auth_name" {
50+
type = string
51+
default = "test-tf-iam-user"
52+
}
53+
54+
variable "oci_cache_user_freeform_tags" {
55+
default = { "department" = "engineering" }
56+
}
57+
58+
variable "oci_cache_user_status" {
59+
default = "ON"
60+
}
61+
62+
variable "redis_cluster_get_oci_cache_user_display_name" {
63+
type = string
64+
default = "test-tf-oci-cache-users"
65+
}
66+
67+
variable "oci_cache_user_get_redis_cluster_display_name" {
68+
type = string
69+
default = "test-tf-redis-clusters"
70+
}
71+
72+
# Create a list of user IDs for attaching to the cluster
73+
locals {
74+
cache_user_ids = [
75+
oci_redis_oci_cache_user.test_cache_user_password.id,
76+
oci_redis_oci_cache_user.test_cache_user_iam.id
77+
]
78+
}
79+
80+
provider "oci" {
81+
auth = "SecurityToken"
82+
config_file_profile = "DEFAULT"
83+
region = var.region
84+
}
85+
86+
87+
resource "oci_core_vcn" "test_vcn" {
88+
cidr_block = "10.0.0.0/16"
89+
compartment_id = var.compartment_id
90+
}
91+
92+
resource "oci_core_security_list" "test_security_list" {
93+
compartment_id = var.compartment_id
94+
vcn_id = oci_core_vcn.test_vcn.id
95+
display_name = "redis-security-list"
96+
97+
// allow outbound udp traffic on a port range
98+
egress_security_rules {
99+
destination = "0.0.0.0/0"
100+
protocol = "17" // udp
101+
stateless = true
102+
}
103+
104+
// allow inbound ssh traffic from a specific port
105+
ingress_security_rules {
106+
protocol = "6" // tcp
107+
source = "0.0.0.0/0"
108+
stateless = false
109+
}
110+
}
111+
112+
resource "oci_core_subnet" "test_subnet" {
113+
cidr_block = "10.0.0.0/24"
114+
compartment_id = var.compartment_id
115+
vcn_id = oci_core_vcn.test_vcn.id
116+
security_list_ids = [oci_core_security_list.test_security_list.id]
117+
}
118+
119+
resource "oci_redis_redis_cluster" "test_redis_cluster" {
120+
#Required
121+
compartment_id = var.compartment_id
122+
display_name = var.redis_cluster_display_name
123+
node_count = var.redis_cluster_node_count
124+
node_memory_in_gbs = var.redis_cluster_node_memory_in_gbs
125+
software_version = var.redis_cluster_software_version
126+
subnet_id = oci_core_subnet.test_subnet.id
127+
128+
#Optional
129+
// defined_tags = map(oci_identity_tag_namespace.tag-namespace1.name.oci_identity_tag.tag1.name, var.redis_cluster_defined_tags_value)
130+
freeform_tags = var.redis_cluster_freeform_tags
131+
}
132+
133+
134+
resource "oci_redis_oci_cache_user" "test_cache_user_password" {
135+
#Required
136+
compartment_id = var.compartment_id
137+
name = var.oci_cache_user_password_auth_name
138+
description = var.oci_cache_user_description
139+
acl_string = var.oci_cache_user_acl_string
140+
141+
authentication_mode {
142+
authentication_type = "PASSWORD"
143+
hashed_passwords = ["741f67765bef6f01f37bf5cb1724509a83409324efa6ad2586d27f4e3edea296"]
144+
}
145+
146+
#Optional
147+
freeform_tags = var.oci_cache_user_freeform_tags
148+
status = var.oci_cache_user_status
149+
depends_on = [
150+
oci_redis_redis_cluster.test_redis_cluster
151+
]
152+
}
153+
154+
resource "oci_redis_oci_cache_user" "test_cache_user_iam" {
155+
#Required
156+
compartment_id = var.compartment_id
157+
name = var.oci_cache_user_iam_auth_name
158+
description = "${var.oci_cache_user_description} with IAM authentication"
159+
acl_string = "~* +@read"
160+
161+
authentication_mode {
162+
authentication_type = "IAM"
163+
}
164+
165+
#Optional
166+
freeform_tags = var.oci_cache_user_freeform_tags
167+
status = var.oci_cache_user_status
168+
depends_on = [
169+
oci_redis_redis_cluster.test_redis_cluster
170+
]
171+
}
172+
173+
# Attach both users to the Redis cluster
174+
resource "oci_redis_redis_cluster_attach_oci_cache_user" "test_redis_cluster_attach_oci_cache_user" {
175+
#Required
176+
oci_cache_users = local.cache_user_ids
177+
redis_cluster_id = oci_redis_redis_cluster.test_redis_cluster.id
178+
179+
depends_on = [
180+
oci_redis_oci_cache_user.test_cache_user_password,
181+
oci_redis_oci_cache_user.test_cache_user_iam
182+
]
183+
}
184+
185+
# Get cache users attached to a specific Redis cluster
186+
resource "oci_redis_redis_cluster_get_oci_cache_user" "test_redis_cluster_get_oci_cache_user" {
187+
#Required
188+
redis_cluster_id = oci_redis_redis_cluster.test_redis_cluster.id
189+
190+
#Optional
191+
compartment_id = var.compartment_id
192+
display_name = var.redis_cluster_get_oci_cache_user_display_name
193+
194+
depends_on = [
195+
oci_redis_redis_cluster_attach_oci_cache_user.test_redis_cluster_attach_oci_cache_user
196+
]
197+
}
198+
199+
# Get Redis clusters to which ociCacheUser is attached
200+
resource "oci_redis_oci_cache_user_get_redis_cluster" "test_oci_cache_user_get_redis_cluster" {
201+
#Required
202+
oci_cache_user_id = oci_redis_oci_cache_user.test_cache_user_password.id
203+
204+
#Optional
205+
compartment_id = var.compartment_id
206+
display_name = var.oci_cache_user_get_redis_cluster_display_name
207+
208+
depends_on = [
209+
oci_redis_redis_cluster_attach_oci_cache_user.test_redis_cluster_attach_oci_cache_user
210+
]
211+
}
212+
213+
# Detach both users from the Redis cluster
214+
resource "oci_redis_redis_cluster_detach_oci_cache_user" "test_redis_cluster_detach_oci_cache_user" {
215+
#Required
216+
oci_cache_users = local.cache_user_ids
217+
redis_cluster_id = oci_redis_redis_cluster.test_redis_cluster.id
218+
219+
depends_on = [
220+
oci_redis_redis_cluster_get_oci_cache_user.test_redis_cluster_get_oci_cache_user,
221+
oci_redis_oci_cache_user_get_redis_cluster.test_oci_cache_user_get_redis_cluster
222+
]
223+
}
224+
225+
# Data source for retrieving information about all cache users in a compartment
226+
data "oci_redis_oci_cache_users" "all_cache_users" {
227+
#Required
228+
compartment_id = var.compartment_id
229+
}
230+
231+
# Data source for retrieving information about a specific cache user
232+
data "oci_redis_oci_cache_user" "test_cache_user" {
233+
#Required
234+
oci_cache_user_id = oci_redis_oci_cache_user.test_cache_user_password.id
235+
}
236+
237+
# Output the details of the created cache users and their relationships
238+
output "password_auth_cache_user_id" {
239+
value = oci_redis_oci_cache_user.test_cache_user_password.id
240+
}
241+
242+
output "iam_auth_cache_user_id" {
243+
value = oci_redis_oci_cache_user.test_cache_user_iam.id
244+
}
245+
246+
output "attached_cache_users" {
247+
value = oci_redis_redis_cluster_get_oci_cache_user.test_redis_cluster_get_oci_cache_user
248+
}
249+
250+
output "attached_redis_clusters" {
251+
value = oci_redis_oci_cache_user_get_redis_cluster.test_oci_cache_user_get_redis_cluster
252+
}

internal/client/redis_clients.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,30 @@ import (
1010
)
1111

1212
func init() {
13+
RegisterOracleClient("oci_redis.OciCacheUserClient", &OracleClient{InitClientFn: initRedisOciCacheUserClient})
1314
RegisterOracleClient("oci_redis.RedisClusterClient", &OracleClient{InitClientFn: initRedisRedisClusterClient})
1415
}
1516

17+
func initRedisOciCacheUserClient(configProvider oci_common.ConfigurationProvider, configureClient ConfigureClient, serviceClientOverrides ServiceClientOverrides) (interface{}, error) {
18+
client, err := oci_redis.NewOciCacheUserClientWithConfigurationProvider(configProvider)
19+
if err != nil {
20+
return nil, err
21+
}
22+
err = configureClient(&client.BaseClient)
23+
if err != nil {
24+
return nil, err
25+
}
26+
27+
if serviceClientOverrides.HostUrlOverride != "" {
28+
client.Host = serviceClientOverrides.HostUrlOverride
29+
}
30+
return &client, nil
31+
}
32+
33+
func (m *OracleClients) OciCacheUserClient() *oci_redis.OciCacheUserClient {
34+
return m.GetClient("oci_redis.OciCacheUserClient").(*oci_redis.OciCacheUserClient)
35+
}
36+
1637
func initRedisRedisClusterClient(configProvider oci_common.ConfigurationProvider, configureClient ConfigureClient, serviceClientOverrides ServiceClientOverrides) (interface{}, error) {
1738
client, err := oci_redis.NewRedisClusterClientWithConfigurationProvider(configProvider)
1839
if err != nil {
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
2+
// Licensed under the Mozilla Public License v2.0
3+
4+
package integrationtest
5+
6+
import (
7+
"fmt"
8+
"strconv"
9+
"testing"
10+
11+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
12+
"github.com/hashicorp/terraform-plugin-testing/terraform"
13+
14+
"github.com/oracle/terraform-provider-oci/httpreplay"
15+
"github.com/oracle/terraform-provider-oci/internal/acctest"
16+
"github.com/oracle/terraform-provider-oci/internal/resourcediscovery"
17+
18+
"github.com/oracle/terraform-provider-oci/internal/utils"
19+
)
20+
21+
var (
22+
RedisOciCacheUserGetRedisClusterRequiredOnlyResource = RedisOciCacheUserGetRedisClusterResourceDependencies +
23+
acctest.GenerateResourceFromRepresentationMap("oci_redis_oci_cache_user_get_redis_cluster", "test_oci_cache_user_get_redis_cluster", acctest.Required, acctest.Create, RedisOciCacheUserGetRedisClusterRepresentation)
24+
25+
RedisOciCacheUserGetRedisClusterDataSourceRepresentation = map[string]interface{}{
26+
"filter": acctest.RepresentationGroup{RepType: acctest.Required, Group: RedisOciCacheUserGetRedisClusterDataSourceFilterRepresentation}}
27+
RedisOciCacheUserGetRedisClusterDataSourceFilterRepresentation = map[string]interface{}{
28+
"name": acctest.Representation{RepType: acctest.Required, Create: `id`},
29+
"values": acctest.Representation{RepType: acctest.Required, Create: []string{`${oci_redis_oci_cache_user_get_redis_cluster.test_oci_cache_user_get_redis_cluster.id}`}},
30+
}
31+
32+
RedisOciCacheUserGetRedisClusterRepresentation = map[string]interface{}{
33+
"oci_cache_user_id": acctest.Representation{RepType: acctest.Required, Create: `${oci_redis_oci_cache_user.test_oci_cache_user.id}`},
34+
"compartment_id": acctest.Representation{RepType: acctest.Optional, Create: `${var.compartment_id}`},
35+
"display_name": acctest.Representation{RepType: acctest.Optional, Create: `displayName`},
36+
}
37+
38+
RedisOciCacheUserGetRedisClusterResourceDependencies = acctest.GenerateResourceFromRepresentationMap("oci_redis_oci_cache_user", "test_oci_cache_user", acctest.Required, acctest.Create, RedisOciCacheUserRepresentation)
39+
)
40+
41+
// issue-routing-tag: redis/default
42+
func TestRedisOciCacheUserGetRedisClusterResource_basic(t *testing.T) {
43+
httpreplay.SetScenario("TestRedisOciCacheUserGetRedisClusterResource_basic")
44+
defer httpreplay.SaveScenario()
45+
46+
config := acctest.ProviderTestConfig()
47+
48+
compartmentId := utils.GetEnvSettingWithBlankDefault("compartment_ocid")
49+
compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)
50+
51+
resourceName := "oci_redis_oci_cache_user_get_redis_cluster.test_oci_cache_user_get_redis_cluster"
52+
var resId string
53+
// Save TF content to Create resource with optional properties. This has to be exactly the same as the config part in the "create with optionals" step in the test.
54+
acctest.SaveConfigContent(config+compartmentIdVariableStr+RedisOciCacheUserGetRedisClusterResourceDependencies+
55+
acctest.GenerateResourceFromRepresentationMap("oci_redis_oci_cache_user_get_redis_cluster", "test_oci_cache_user_get_redis_cluster", acctest.Optional, acctest.Create, RedisOciCacheUserGetRedisClusterRepresentation), "redis", "ociCacheUserGetRedisCluster", t)
56+
57+
acctest.ResourceTest(t, nil, []resource.TestStep{
58+
// verify Create
59+
{
60+
Config: config + compartmentIdVariableStr + RedisOciCacheUserGetRedisClusterResourceDependencies +
61+
acctest.GenerateResourceFromRepresentationMap("oci_redis_oci_cache_user_get_redis_cluster", "test_oci_cache_user_get_redis_cluster", acctest.Required, acctest.Create, RedisOciCacheUserGetRedisClusterRepresentation),
62+
Check: acctest.ComposeAggregateTestCheckFuncWrapper(
63+
resource.TestCheckResourceAttrSet(resourceName, "oci_cache_user_id"),
64+
),
65+
},
66+
67+
// delete before next Create
68+
{
69+
Config: config + compartmentIdVariableStr + RedisOciCacheUserGetRedisClusterResourceDependencies,
70+
},
71+
// verify Create with optionals
72+
{
73+
Config: config + compartmentIdVariableStr + RedisOciCacheUserGetRedisClusterResourceDependencies +
74+
acctest.GenerateResourceFromRepresentationMap("oci_redis_oci_cache_user_get_redis_cluster", "test_oci_cache_user_get_redis_cluster", acctest.Optional, acctest.Create, RedisOciCacheUserGetRedisClusterRepresentation),
75+
Check: acctest.ComposeAggregateTestCheckFuncWrapper(
76+
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentId),
77+
resource.TestCheckResourceAttr(resourceName, "display_name", "displayName"),
78+
resource.TestCheckResourceAttr(resourceName, "oci_cache_clusters.#", "0"),
79+
80+
resource.TestCheckResourceAttrSet(resourceName, "oci_cache_user_id"),
81+
82+
func(s *terraform.State) (err error) {
83+
resId, err = acctest.FromInstanceState(s, resourceName, "id")
84+
if isEnableExportCompartment, _ := strconv.ParseBool(utils.GetEnvSettingWithDefault("enable_export_compartment", "true")); isEnableExportCompartment {
85+
if errExport := resourcediscovery.TestExportCompartmentWithResourceName(&resId, &compartmentId, resourceName); errExport != nil {
86+
return errExport
87+
}
88+
}
89+
return err
90+
},
91+
),
92+
},
93+
})
94+
}

0 commit comments

Comments
 (0)