Skip to content

Commit 541e81e

Browse files
madanrajhari10Nishtha Goel
authored andcommitted
Added - Support for Container Instance Service: Configure Linux Capabilities
1 parent ec407b3 commit 541e81e

File tree

4 files changed

+127
-9
lines changed

4 files changed

+127
-9
lines changed

examples/container_instances/main.tf

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ resource "oci_core_network_security_group" "test_network_security_group" {
2626
vcn_id = oci_core_vcn.test_vcn.id
2727
lifecycle {
2828
ignore_changes = [
29-
"defined_tags"]
29+
"defined_tags"]
3030
}
3131
}
3232

@@ -36,7 +36,7 @@ resource "oci_core_vcn" "test_vcn" {
3636
dns_label = "testvcn"
3737
lifecycle {
3838
ignore_changes = [
39-
"defined_tags"]
39+
"defined_tags"]
4040
}
4141
}
4242

@@ -46,11 +46,11 @@ resource "oci_core_subnet" "test_subnet" {
4646
dns_label = "testsubnet"
4747
route_table_id = oci_core_route_table.test_route_table.id
4848
security_list_ids = [
49-
"${oci_core_security_list.test_sec_list.id}"]
49+
"${oci_core_security_list.test_sec_list.id}"]
5050
vcn_id = oci_core_vcn.test_vcn.id
5151
lifecycle {
5252
ignore_changes = [
53-
"defined_tags"]
53+
"defined_tags"]
5454
}
5555
}
5656

@@ -137,9 +137,9 @@ resource "oci_container_instances_container_instance" "test_container_instance"
137137
#Optional
138138
arguments = [
139139
"-c",
140-
"cat /mnt/my_file"]
140+
"cat /mnt/my_file"]
141141
command = [
142-
"/bin/sh"]
142+
"/bin/sh"]
143143
display_name = "displayName"
144144
environment_variables = {
145145
"environment" = "variable"
@@ -194,6 +194,10 @@ resource "oci_container_instances_container_instance" "test_container_instance"
194194
is_root_file_system_readonly = true
195195
run_as_group = 10
196196
run_as_user = 10
197+
capabilities {
198+
add_capabilities = ["CAP_CHOWN", "CAP_KILL"]
199+
drop_capabilities = ["ALL"]
200+
}
197201
}
198202
}
199203
shape = "CI.Standard.E4.Flex"
@@ -226,11 +230,11 @@ resource "oci_container_instances_container_instance" "test_container_instance"
226230

227231
#Optional
228232
nameservers = [
229-
"8.8.8.8"]
233+
"8.8.8.8"]
230234
options = [
231-
"options"]
235+
"options"]
232236
searches = [
233-
"search domain"]
237+
"search domain"]
234238
}
235239
freeform_tags = {
236240
"bar-key" = "foo-value"

internal/integrationtest/container_instances_container_instance_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ var (
155155
"vcpus_limit": acctest.Representation{RepType: acctest.Optional, Create: `1`},
156156
}
157157
ContainerInstancesContainerInstanceContainersSecurityContextRepresentation = map[string]interface{}{
158+
"capabilities": acctest.RepresentationGroup{RepType: acctest.Optional, Group: ContainerInstancesContainerInstanceContainersSecurityContextCapabilitiesRepresentation},
158159
"is_non_root_user_check_enabled": acctest.Representation{RepType: acctest.Optional, Create: `false`},
159160
"is_root_file_system_readonly": acctest.Representation{RepType: acctest.Optional, Create: `false`},
160161
"run_as_group": acctest.Representation{RepType: acctest.Optional, Create: `10`},
@@ -205,6 +206,10 @@ var (
205206
"name": acctest.Representation{RepType: acctest.Optional, Create: `name`},
206207
"value": acctest.Representation{RepType: acctest.Optional, Create: `value`},
207208
}
209+
ContainerInstancesContainerInstanceContainersSecurityContextCapabilitiesRepresentation = map[string]interface{}{
210+
"add_capabilities": acctest.Representation{RepType: acctest.Optional, Create: []oci_container_instances.ContainerCapabilityTypeEnum{`addCapabilities`}},
211+
"drop_capabilities": acctest.Representation{RepType: acctest.Optional, Create: []oci_container_instances.ContainerCapabilityTypeEnum{`dropCapabilities`}},
212+
}
208213

209214
CISecurityListTCPEgressSecurityRulesRepresentation = map[string]interface{}{
210215
"destination": acctest.Representation{RepType: acctest.Required, Create: `0.0.0.0/0`},
@@ -437,6 +442,9 @@ func TestContainerInstancesContainerInstanceResource_basic(t *testing.T) {
437442
resource.TestCheckResourceAttr(resourceName, "containers.0.resource_config.0.memory_limit_in_gbs", "1"),
438443
resource.TestCheckResourceAttr(resourceName, "containers.0.resource_config.0.vcpus_limit", "1"),
439444
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.#", "1"),
445+
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.capabilities.#", "1"),
446+
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.capabilities.0.add_capabilities.#", "0"),
447+
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.capabilities.0.drop_capabilities.#", "0"),
440448
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.is_non_root_user_check_enabled", "false"),
441449
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.is_root_file_system_readonly", "false"),
442450
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.run_as_group", "10"),
@@ -514,6 +522,9 @@ func TestContainerInstancesContainerInstanceResource_basic(t *testing.T) {
514522
resource.TestCheckResourceAttr(resourceName, "containers.0.resource_config.0.memory_limit_in_gbs", "1"),
515523
resource.TestCheckResourceAttr(resourceName, "containers.0.resource_config.0.vcpus_limit", "1"),
516524
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.#", "1"),
525+
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.capabilities.#", "1"),
526+
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.capabilities.0.add_capabilities.#", "0"),
527+
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.capabilities.0.drop_capabilities.#", "0"),
517528
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.is_non_root_user_check_enabled", "false"),
518529
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.is_root_file_system_readonly", "false"),
519530
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.run_as_group", "10"),
@@ -586,6 +597,9 @@ func TestContainerInstancesContainerInstanceResource_basic(t *testing.T) {
586597
resource.TestCheckResourceAttr(resourceName, "containers.0.resource_config.0.memory_limit_in_gbs", "1"),
587598
resource.TestCheckResourceAttr(resourceName, "containers.0.resource_config.0.vcpus_limit", "1"),
588599
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.#", "1"),
600+
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.capabilities.#", "1"),
601+
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.capabilities.0.add_capabilities.#", "0"),
602+
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.capabilities.0.drop_capabilities.#", "0"),
589603
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.is_non_root_user_check_enabled", "false"),
590604
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.is_root_file_system_readonly", "false"),
591605
resource.TestCheckResourceAttr(resourceName, "containers.0.security_context.0.run_as_group", "10"),

internal/service/container_instances/container_instances_container_instance_resource.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,41 @@ func ContainerInstancesContainerInstanceResource() *schema.Resource {
277277
// Required
278278

279279
// Optional
280+
"capabilities": {
281+
Type: schema.TypeList,
282+
Optional: true,
283+
Computed: true,
284+
ForceNew: true,
285+
MaxItems: 1,
286+
MinItems: 1,
287+
Elem: &schema.Resource{
288+
Schema: map[string]*schema.Schema{
289+
// Required
290+
291+
// Optional
292+
"add_capabilities": {
293+
Type: schema.TypeList,
294+
Optional: true,
295+
Computed: true,
296+
ForceNew: true,
297+
Elem: &schema.Schema{
298+
Type: schema.TypeString,
299+
},
300+
},
301+
"drop_capabilities": {
302+
Type: schema.TypeList,
303+
Optional: true,
304+
Computed: true,
305+
ForceNew: true,
306+
Elem: &schema.Schema{
307+
Type: schema.TypeString,
308+
},
309+
},
310+
311+
// Computed
312+
},
313+
},
314+
},
280315
"is_non_root_user_check_enabled": {
281316
Type: schema.TypeBool,
282317
Optional: true,
@@ -1551,6 +1586,48 @@ func (s *ContainerInstancesContainerInstanceResourceCrud) StopContainerInstance(
15511586
return tfresource.WaitForResourceCondition(s, retentionPolicyFunc, s.D.Timeout(schema.TimeoutUpdate))
15521587
}
15531588

1589+
func (s *ContainerInstancesContainerInstanceResourceCrud) mapToContainerCapabilities(fieldKeyFormat string) (oci_container_instances.ContainerCapabilities, error) {
1590+
result := oci_container_instances.ContainerCapabilities{}
1591+
1592+
if addCapabilities, ok := s.D.GetOkExists(fmt.Sprintf(fieldKeyFormat, "add_capabilities")); ok {
1593+
interfaces := addCapabilities.([]interface{})
1594+
tmp := make([]oci_container_instances.ContainerCapabilityTypeEnum, len(interfaces))
1595+
for i := range interfaces {
1596+
if interfaces[i] != nil {
1597+
tmp[i], _ = oci_container_instances.GetMappingContainerCapabilityTypeEnum(interfaces[i].(string))
1598+
}
1599+
}
1600+
if len(tmp) != 0 || s.D.HasChange(fmt.Sprintf(fieldKeyFormat, "add_capabilities")) {
1601+
result.AddCapabilities = tmp
1602+
}
1603+
}
1604+
1605+
if dropCapabilities, ok := s.D.GetOkExists(fmt.Sprintf(fieldKeyFormat, "drop_capabilities")); ok {
1606+
interfaces := dropCapabilities.([]interface{})
1607+
tmp := make([]oci_container_instances.ContainerCapabilityTypeEnum, len(interfaces))
1608+
for i := range interfaces {
1609+
if interfaces[i] != nil {
1610+
tmp[i], _ = oci_container_instances.GetMappingContainerCapabilityTypeEnum(interfaces[i].(string))
1611+
}
1612+
}
1613+
if len(tmp) != 0 || s.D.HasChange(fmt.Sprintf(fieldKeyFormat, "drop_capabilities")) {
1614+
result.DropCapabilities = tmp
1615+
}
1616+
}
1617+
1618+
return result, nil
1619+
}
1620+
1621+
func ContainerCapabilitiesToMap(obj *oci_container_instances.ContainerCapabilities) map[string]interface{} {
1622+
result := map[string]interface{}{}
1623+
1624+
result["add_capabilities"] = obj.AddCapabilities
1625+
1626+
result["drop_capabilities"] = obj.DropCapabilities
1627+
1628+
return result
1629+
}
1630+
15541631
func (s *ContainerInstancesContainerInstanceResourceCrud) mapToContainerConfigFile(fieldKeyFormat string) (oci_container_instances.ContainerConfigFile, error) {
15551632
result := oci_container_instances.ContainerConfigFile{}
15561633

@@ -2427,6 +2504,16 @@ func (s *ContainerInstancesContainerInstanceResourceCrud) mapToCreateSecurityCon
24272504
switch strings.ToLower(securityContextType) {
24282505
case strings.ToLower("LINUX"):
24292506
details := oci_container_instances.CreateLinuxSecurityContextDetails{}
2507+
if capabilities, ok := s.D.GetOkExists(fmt.Sprintf(fieldKeyFormat, "capabilities")); ok {
2508+
if tmpList := capabilities.([]interface{}); len(tmpList) > 0 {
2509+
fieldKeyFormatNextLevel := fmt.Sprintf("%s.%d.%%s", fmt.Sprintf(fieldKeyFormat, "capabilities"), 0)
2510+
tmp, err := s.mapToContainerCapabilities(fieldKeyFormatNextLevel)
2511+
if err != nil {
2512+
return details, fmt.Errorf("unable to convert capabilities, encountered error: %v", err)
2513+
}
2514+
details.Capabilities = &tmp
2515+
}
2516+
}
24302517
if isNonRootUserCheckEnabled, ok := s.D.GetOkExists(fmt.Sprintf(fieldKeyFormat, "is_non_root_user_check_enabled")); ok {
24312518
tmp := isNonRootUserCheckEnabled.(bool)
24322519
details.IsNonRootUserCheckEnabled = &tmp
@@ -2456,6 +2543,10 @@ func SecurityContextToMap(obj *oci_container_instances.SecurityContext) map[stri
24562543
case oci_container_instances.LinuxSecurityContext:
24572544
result["security_context_type"] = "LINUX"
24582545

2546+
if v.Capabilities != nil {
2547+
result["capabilities"] = []interface{}{ContainerCapabilitiesToMap(v.Capabilities)}
2548+
}
2549+
24592550
if v.IsNonRootUserCheckEnabled != nil {
24602551
result["is_non_root_user_check_enabled"] = bool(*v.IsNonRootUserCheckEnabled)
24612552
}

website/docs/r/container_instances_container_instance.html.markdown

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ resource "oci_container_instances_container_instance" "test_container_instance"
6363
security_context {
6464
6565
#Optional
66+
capabilities {
67+
68+
#Optional
69+
add_capabilities = var.container_instance_containers_security_context_capabilities_add_capabilities
70+
drop_capabilities = var.container_instance_containers_security_context_capabilities_drop_capabilities
71+
}
6672
is_non_root_user_check_enabled = var.container_instance_containers_security_context_is_non_root_user_check_enabled
6773
is_root_file_system_readonly = var.container_instance_containers_security_context_is_root_file_system_readonly
6874
run_as_group = var.container_instance_containers_security_context_run_as_group
@@ -201,6 +207,9 @@ The following arguments are supported:
201207

202208
A container with a 2.0 vcpusLimit could consume up to 100% of the CPU resources available on the container instance. Values can be fractional. A value of "1.5" means that the container can consume at most the equivalent of 1 and a half logical CPUs worth of CPU capacity.
203209
* `security_context` - (Optional) Security context for container.
210+
* `capabilities` - (Optional) Linux Container capabilities to configure capabilities of container.
211+
* `add_capabilities` - (Optional) A list of additional configurable container capabilities.
212+
* `drop_capabilities` - (Optional) A list of container capabilities that can be dropped.
204213
* `is_non_root_user_check_enabled` - (Optional) Indicates if the container must run as a non-root user. If true, the service validates the container image at runtime to ensure that it is not going to run with UID 0 (root) and fails the container instance creation if the validation fails.
205214
* `is_root_file_system_readonly` - (Optional) Determines if the container will have a read-only root file system. Default value is false.
206215
* `run_as_group` - (Optional) The group ID (GID) to run the entrypoint process of the container. Uses runtime default if not provided.

0 commit comments

Comments
 (0)