diff --git a/docs/resources/cluster_aks.md b/docs/resources/cluster_aks.md
index 5ff545625..a1334479e 100644
--- a/docs/resources/cluster_aks.md
+++ b/docs/resources/cluster_aks.md
@@ -321,12 +321,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_aws.md b/docs/resources/cluster_aws.md
index ba45b5fa9..9deb7d215 100644
--- a/docs/resources/cluster_aws.md
+++ b/docs/resources/cluster_aws.md
@@ -349,12 +349,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_azure.md b/docs/resources/cluster_azure.md
index f01e640e7..bc1f47b7e 100644
--- a/docs/resources/cluster_azure.md
+++ b/docs/resources/cluster_azure.md
@@ -382,12 +382,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_custom_cloud.md b/docs/resources/cluster_custom_cloud.md
index 00ead17f0..b614212dd 100644
--- a/docs/resources/cluster_custom_cloud.md
+++ b/docs/resources/cluster_custom_cloud.md
@@ -348,12 +348,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_edge_native.md b/docs/resources/cluster_edge_native.md
index e32f50f6f..b45200faf 100644
--- a/docs/resources/cluster_edge_native.md
+++ b/docs/resources/cluster_edge_native.md
@@ -310,12 +310,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_edge_vsphere.md b/docs/resources/cluster_edge_vsphere.md
index d600ab171..c157939f7 100644
--- a/docs/resources/cluster_edge_vsphere.md
+++ b/docs/resources/cluster_edge_vsphere.md
@@ -265,12 +265,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_eks.md b/docs/resources/cluster_eks.md
index 8cdcf56a1..ffa22c7f6 100644
--- a/docs/resources/cluster_eks.md
+++ b/docs/resources/cluster_eks.md
@@ -358,12 +358,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_gcp.md b/docs/resources/cluster_gcp.md
index d45eee278..4321c03ae 100644
--- a/docs/resources/cluster_gcp.md
+++ b/docs/resources/cluster_gcp.md
@@ -300,12 +300,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_gke.md b/docs/resources/cluster_gke.md
index 738216f2f..97f28cda4 100644
--- a/docs/resources/cluster_gke.md
+++ b/docs/resources/cluster_gke.md
@@ -263,12 +263,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_maas.md b/docs/resources/cluster_maas.md
index 577768c34..ec2d5dec6 100644
--- a/docs/resources/cluster_maas.md
+++ b/docs/resources/cluster_maas.md
@@ -358,12 +358,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_openstack.md b/docs/resources/cluster_openstack.md
index 8cd2ec28b..75a006fd4 100644
--- a/docs/resources/cluster_openstack.md
+++ b/docs/resources/cluster_openstack.md
@@ -303,12 +303,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/cluster_vsphere.md b/docs/resources/cluster_vsphere.md
index 567898281..9d8fcbf6d 100644
--- a/docs/resources/cluster_vsphere.md
+++ b/docs/resources/cluster_vsphere.md
@@ -355,12 +355,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `scan_policy`
diff --git a/docs/resources/virtual_cluster.md b/docs/resources/virtual_cluster.md
index 0726d01df..54f9fc0a6 100644
--- a/docs/resources/virtual_cluster.md
+++ b/docs/resources/virtual_cluster.md
@@ -194,12 +194,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `resources`
diff --git a/docs/resources/workspace.md b/docs/resources/workspace.md
index a8db000a6..35519309e 100644
--- a/docs/resources/workspace.md
+++ b/docs/resources/workspace.md
@@ -126,6 +126,10 @@ Required:
- `uid` (String)
+Read-Only:
+
+- `cluster_name` (String)
+
### Nested Schema for `backup_policy`
@@ -180,12 +184,22 @@ Optional:
Required:
- `name` (String) Name of the namespace. This is the name of the Kubernetes namespace in the cluster.
-- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`
+- `resource_allocation` (Map of String) Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`
Optional:
+- `cluster_resource_allocations` (Block List) (see [below for nested schema](#nestedblock--namespaces--cluster_resource_allocations))
- `images_blacklist` (List of String) List of images to disallow for the namespace. For example, `['nginx:latest', 'redis:latest']`
+
+### Nested Schema for `namespaces.cluster_resource_allocations`
+
+Required:
+
+- `resource_allocation` (Map of String) Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.
+- `uid` (String)
+
+
### Nested Schema for `workspace_quota`
@@ -193,4 +207,5 @@ Optional:
Optional:
- `cpu` (Number) CPU that the entire workspace is allowed to consume. The default value is 0, which imposes no limit.
+- `gpu` (Number) GPU that the entire workspace is allowed to consume. The default value is 0, which imposes no limit.
- `memory` (Number) Memory in Mib that the entire workspace is allowed to consume. The default value is 0, which imposes no limit.
\ No newline at end of file
diff --git a/examples/resources/spectrocloud_workspace/resource.tf b/examples/resources/spectrocloud_workspace/resource.tf
index 96301bec0..d5b8f4b23 100644
--- a/examples/resources/spectrocloud_workspace/resource.tf
+++ b/examples/resources/spectrocloud_workspace/resource.tf
@@ -1,16 +1,20 @@
+# Example demonstrating workspace with GPU support, cluster-specific resource allocations, and cluster names
+
data "spectrocloud_cluster" "cluster1" {
- name = "tf-si-cluster"
+ name = "api-aks-cazfl"
}
resource "spectrocloud_workspace" "workspace" {
name = "wsp-tf-123"
description = "test123"
workspace_quota {
- cpu = 5
- memory = 4064
+ cpu = 16
+ memory = 32768
+ gpu = 4
}
clusters {
uid = data.spectrocloud_cluster.cluster1.id
+ # cluster_name is computed automatically by fetching cluster details from the API
}
cluster_rbac_binding {
@@ -35,53 +39,43 @@ resource "spectrocloud_workspace" "workspace" {
}
}
- cluster_rbac_binding {
- type = "RoleBinding"
- namespace = "test5ns"
- role = {
- kind = "Role"
- name = "testrolefromns3"
- }
- subjects {
- type = "User"
- name = "testUserRoleFromNS3"
- }
- subjects {
- type = "Group"
- name = "testGroupFromNS3"
- }
- subjects {
- type = "ServiceAccount"
- name = "testrolesubject3"
- namespace = "testrolenamespace"
- }
- }
-
namespaces {
- name = "test5ns"
+ name = "multi-cluster-ns"
resource_allocation = {
- cpu_cores = "2"
- memory_MiB = "2048"
+ cpu_cores = "8"
+ memory_MiB = "8192"
+ gpu_limit = "2"
+ gpu_provider = "nvidia"
+ }
+
+ # Cluster-specific resource allocations
+ cluster_resource_allocations {
+ uid = data.spectrocloud_cluster.cluster1.id
+ resource_allocation = {
+ cpu_cores = "4"
+ memory_MiB = "4096"
+ gpu_limit = "1"
+ }
}
- images_blacklist = ["1", "2", "3"]
+ images_blacklist = ["nginx:latest", "redis:latest"]
}
- backup_policy {
- schedule = "0 0 * * SUN"
- backup_location_id = data.spectrocloud_backup_storage_location.bsl.id
- prefix = "prod-backup"
- expiry_in_hour = 7200
- include_disks = false
- include_cluster_resources = true
+ # backup_policy {
+ # schedule = "0 0 * * SUN"
+ # backup_location_id = data.spectrocloud_backup_storage_location.bsl.id
+ # prefix = "prod-backup"
+ # expiry_in_hour = 7200
+ # include_disks = false
+ # include_cluster_resources = true
- namespaces = ["test5ns"]
- include_all_clusters = true
- cluster_uids = [data.spectrocloud_cluster.cluster1.id]
- }
+ # namespaces = ["test5ns", "multi-cluster-ns"]
+ # include_all_clusters = true
+ # cluster_uids = [data.spectrocloud_cluster.cluster1.id]
+ # }
}
-data "spectrocloud_backup_storage_location" "bsl" {
- name = "test-aws-s3"
-}
+# data "spectrocloud_backup_storage_location" "bsl" {
+# name = "test-aws-s3"
+# }
diff --git a/spectrocloud/resource_workspace.go b/spectrocloud/resource_workspace.go
index 8c6513540..8abebe2e6 100644
--- a/spectrocloud/resource_workspace.go
+++ b/spectrocloud/resource_workspace.go
@@ -3,11 +3,13 @@ package spectrocloud
import (
"context"
"errors"
+ "fmt"
+ "strings"
+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/spectrocloud/palette-sdk-go/api/models"
"github.com/spectrocloud/palette-sdk-go/client"
- "strings"
"github.com/spectrocloud/terraform-provider-spectrocloud/spectrocloud/schemas"
)
@@ -20,6 +22,9 @@ func resourceWorkspace() *schema.Resource {
DeleteContext: resourceWorkspaceDelete,
SchemaVersion: 2,
+ Importer: &schema.ResourceImporter{
+ StateContext: resourceWorkspaceImport,
+ },
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
@@ -54,6 +59,11 @@ func resourceWorkspace() *schema.Resource {
Optional: true,
Description: "Memory in Mib that the entire workspace is allowed to consume. The default value is 0, which imposes no limit.",
},
+ "gpu": {
+ Type: schema.TypeInt,
+ Optional: true,
+ Description: "GPU that the entire workspace is allowed to consume. The default value is 0, which imposes no limit.",
+ },
},
},
},
@@ -67,6 +77,10 @@ func resourceWorkspace() *schema.Resource {
Type: schema.TypeString,
Required: true,
},
+ "cluster_name": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
},
},
},
@@ -82,7 +96,7 @@ func resourceWorkspaceCreate(ctx context.Context, d *schema.ResourceData, m inte
var diags diag.Diagnostics
- workspace := toWorkspace(d)
+ workspace := toWorkspace(d, c)
uid, err := c.CreateWorkspace(workspace)
if err != nil {
@@ -115,7 +129,7 @@ func resourceWorkspaceRead(_ context.Context, d *schema.ResourceData, m interfac
if err := d.Set("workspace_quota", wsQuota); err != nil {
return diag.FromErr(err)
}
- fp := flattenWorkspaceClusters(workspace)
+ fp := flattenWorkspaceClusters(workspace, c)
if err := d.Set("clusters", fp); err != nil {
return diag.FromErr(err)
}
@@ -144,10 +158,19 @@ func resourceWorkspaceRead(_ context.Context, d *schema.ResourceData, m interfac
func flattenWorkspaceQuota(workspace *models.V1Workspace) []interface{} {
wsq := make([]interface{}, 0)
if workspace.Spec.Quota.ResourceAllocation != nil {
- wsq = append(wsq, map[string]interface{}{
+ quota := map[string]interface{}{
"cpu": workspace.Spec.Quota.ResourceAllocation.CPUCores,
"memory": workspace.Spec.Quota.ResourceAllocation.MemoryMiB,
- })
+ }
+
+ // Handle GPU configuration if present
+ if workspace.Spec.Quota.ResourceAllocation.GpuConfig != nil {
+ quota["gpu"] = int(workspace.Spec.Quota.ResourceAllocation.GpuConfig.Limit)
+ } else {
+ quota["gpu"] = 0
+ }
+
+ wsq = append(wsq, quota)
}
return wsq
}
@@ -180,7 +203,7 @@ func resourceWorkspaceUpdate(ctx context.Context, d *schema.ResourceData, m inte
if d.HasChange("clusters") || d.HasChange("workspace_quota") {
// resource allocation should go first because clusters are inside.
- namespaces := toUpdateWorkspaceNamespaces(d)
+ namespaces := toUpdateWorkspaceNamespaces(d, c)
if err := c.UpdateWorkspaceResourceAllocation(d.Id(), namespaces); err != nil {
return diag.FromErr(err)
}
@@ -196,7 +219,7 @@ func resourceWorkspaceUpdate(ctx context.Context, d *schema.ResourceData, m inte
}
}
if d.HasChange("namespaces") {
- if err := c.UpdateWorkspaceResourceAllocation(d.Id(), toUpdateWorkspaceNamespaces(d)); err != nil {
+ if err := c.UpdateWorkspaceResourceAllocation(d.Id(), toUpdateWorkspaceNamespaces(d, c)); err != nil {
return diag.FromErr(err)
}
}
@@ -246,7 +269,7 @@ func resourceWorkspaceDelete(ctx context.Context, d *schema.ResourceData, m inte
return diags
}
-func toWorkspace(d *schema.ResourceData) *models.V1WorkspaceEntity {
+func toWorkspace(d *schema.ResourceData, c *client.V1Client) *models.V1WorkspaceEntity {
annotations := make(map[string]string)
if len(d.Get("description").(string)) > 0 {
annotations["description"] = d.Get("description").(string)
@@ -262,7 +285,7 @@ func toWorkspace(d *schema.ResourceData) *models.V1WorkspaceEntity {
Spec: &models.V1WorkspaceSpec{
ClusterNamespaces: toWorkspaceNamespaces(d),
ClusterRbacs: toWorkspaceRBACs(d),
- ClusterRefs: toClusterRefs(d),
+ ClusterRefs: toClusterRefs(d, c),
Policies: toWorkspacePolicies(d),
Quota: toQuota(d),
},
@@ -270,3 +293,32 @@ func toWorkspace(d *schema.ResourceData) *models.V1WorkspaceEntity {
return workspace
}
+
+func resourceWorkspaceImport(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
+ c := getV1ClientWithResourceContext(m, "")
+
+ // The import ID should be the workspace UID
+ workspaceUID := d.Id()
+
+ // Validate that the workspace exists and we can access it
+ workspace, err := c.GetWorkspace(workspaceUID)
+ if err != nil {
+ return nil, fmt.Errorf("could not retrieve workspace for import: %s", err)
+ }
+ if workspace == nil {
+ return nil, fmt.Errorf("workspace with ID %s not found", workspaceUID)
+ }
+
+ // Set the workspace name from the retrieved workspace
+ if err := d.Set("name", workspace.Metadata.Name); err != nil {
+ return nil, err
+ }
+
+ // Read all workspace data to populate the state
+ diags := resourceWorkspaceRead(ctx, d, m)
+ if diags.HasError() {
+ return nil, fmt.Errorf("could not read workspace for import: %v", diags)
+ }
+
+ return []*schema.ResourceData{d}, nil
+}
diff --git a/spectrocloud/resource_workspace_test.go b/spectrocloud/resource_workspace_test.go
index db3449a30..025522dd7 100644
--- a/spectrocloud/resource_workspace_test.go
+++ b/spectrocloud/resource_workspace_test.go
@@ -91,7 +91,7 @@ func TestToWorkspace(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
// Initialize resource data with input
d := schema.TestResourceDataRaw(t, resourceWorkspace().Schema, tt.input)
- result := toWorkspace(d)
+ result := toWorkspace(d, nil) // nil client for unit test
// Compare the expected and actual result
assert.Equal(t, tt.expected.Metadata.Name, result.Metadata.Name)
diff --git a/spectrocloud/schemas/cluster_namespaces.go b/spectrocloud/schemas/cluster_namespaces.go
index 19ac31893..f03fb8a66 100644
--- a/spectrocloud/schemas/cluster_namespaces.go
+++ b/spectrocloud/schemas/cluster_namespaces.go
@@ -20,7 +20,27 @@ func ClusterNamespacesSchema() *schema.Schema {
Elem: &schema.Schema{
Type: schema.TypeString,
},
- Description: "Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048'}`",
+ Description: "Resource allocation for the namespace. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1', gpu_provider: 'nvidia'}`",
+ },
+ "cluster_resource_allocations": {
+ Type: schema.TypeList,
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "uid": {
+ Type: schema.TypeString,
+ Required: true,
+ },
+ "resource_allocation": {
+ Type: schema.TypeMap,
+ Required: true,
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ Description: "Resource allocation for the cluster. This is a map containing the resource type and the resource value. For example, `{cpu_cores: '2', memory_MiB: '2048', gpu_limit: '1'}`. Note: gpu_provider is not supported here; use the default resource_allocation for GPU provider configuration.",
+ },
+ },
+ },
},
"images_blacklist": {
Type: schema.TypeList,
diff --git a/spectrocloud/workspace_cluster.go b/spectrocloud/workspace_cluster.go
index 9a6df1ed5..36c3ea8b8 100644
--- a/spectrocloud/workspace_cluster.go
+++ b/spectrocloud/workspace_cluster.go
@@ -3,9 +3,10 @@ package spectrocloud
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/spectrocloud/palette-sdk-go/api/models"
+ "github.com/spectrocloud/palette-sdk-go/client"
)
-func toClusterRefs(d *schema.ResourceData) []*models.V1WorkspaceClusterRef {
+func toClusterRefs(d *schema.ResourceData, c *client.V1Client) []*models.V1WorkspaceClusterRef {
clusterRefs := make([]*models.V1WorkspaceClusterRef, 0)
clusters := d.Get("clusters")
@@ -15,8 +16,23 @@ func toClusterRefs(d *schema.ResourceData) []*models.V1WorkspaceClusterRef {
for _, cluster := range clusters.(*schema.Set).List() {
clusterValue := cluster.(map[string]interface{})
uid := clusterValue["uid"].(string)
+
+ // Try to get cluster name from the data first (if available from computed field)
+ clusterName := ""
+ if nameValue, exists := clusterValue["cluster_name"]; exists && nameValue != nil {
+ clusterName = nameValue.(string)
+ }
+
+ // If cluster name is not available in data and client is provided, fetch it from API
+ if clusterName == "" && c != nil {
+ if clusterDetails, err := c.GetCluster(uid); err == nil && clusterDetails != nil {
+ clusterName = clusterDetails.Metadata.Name
+ }
+ }
+
clusterRefs = append(clusterRefs, &models.V1WorkspaceClusterRef{
- ClusterUID: uid,
+ ClusterUID: uid,
+ ClusterName: clusterName,
})
}
diff --git a/spectrocloud/workspace_common.go b/spectrocloud/workspace_common.go
index 4ab437625..c0a4142f4 100644
--- a/spectrocloud/workspace_common.go
+++ b/spectrocloud/workspace_common.go
@@ -3,9 +3,10 @@ package spectrocloud
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/spectrocloud/palette-sdk-go/api/models"
+ "github.com/spectrocloud/palette-sdk-go/client"
)
-func flattenWorkspaceClusters(workspace *models.V1Workspace) []interface{} {
+func flattenWorkspaceClusters(workspace *models.V1Workspace, c *client.V1Client) []interface{} {
clusters := workspace.Spec.ClusterRefs
if len(clusters) > 0 {
@@ -16,6 +17,19 @@ func flattenWorkspaceClusters(workspace *models.V1Workspace) []interface{} {
wsp_cluster["uid"] = cluster.ClusterUID
+ // Fetch cluster name using the API (if client is available)
+ if c != nil {
+ if clusterDetails, err := c.GetCluster(cluster.ClusterUID); err == nil && clusterDetails != nil {
+ wsp_cluster["cluster_name"] = clusterDetails.Metadata.Name
+ } else {
+ // If we can't fetch the cluster name, set it to empty string
+ wsp_cluster["cluster_name"] = ""
+ }
+ } else {
+ // For tests or when client is not available
+ wsp_cluster["cluster_name"] = ""
+ }
+
wsp_clusters = append(wsp_clusters, wsp_cluster)
}
diff --git a/spectrocloud/workspace_namespace.go b/spectrocloud/workspace_namespace.go
index 9acbaca42..b1db7ad54 100644
--- a/spectrocloud/workspace_namespace.go
+++ b/spectrocloud/workspace_namespace.go
@@ -1,14 +1,52 @@
package spectrocloud
import (
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
- "github.com/spectrocloud/palette-sdk-go/api/models"
"math"
"regexp"
"strconv"
"strings"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "github.com/spectrocloud/palette-sdk-go/api/models"
+ "github.com/spectrocloud/palette-sdk-go/client"
)
+// Helper function to create V1WorkspaceResourceAllocation from resource allocation map
+func toWorkspaceResourceAllocation(resourceAllocation map[string]interface{}) (*models.V1WorkspaceResourceAllocation, error) {
+ cpu_cores, err := strconv.ParseFloat(resourceAllocation["cpu_cores"].(string), 64)
+ if err != nil {
+ return nil, err
+ }
+
+ memory_MiB, err := strconv.ParseFloat(resourceAllocation["memory_MiB"].(string), 64)
+ if err != nil {
+ return nil, err
+ }
+
+ resource_alloc := &models.V1WorkspaceResourceAllocation{
+ CPUCores: cpu_cores,
+ MemoryMiB: memory_MiB,
+ }
+
+ // Handle GPU configuration if specified
+ if gpuLimit, exists := resourceAllocation["gpu_limit"]; exists && gpuLimit.(string) != "" {
+ gpuVal, err := strconv.Atoi(gpuLimit.(string))
+ if err == nil && gpuVal > 0 {
+ provider := "nvidia" // Default provider for cluster allocations
+ // gpu_provider is optional - mainly used for default resource allocations
+ if gpuProvider, providerExists := resourceAllocation["gpu_provider"]; providerExists && gpuProvider.(string) != "" {
+ provider = gpuProvider.(string)
+ }
+ resource_alloc.GpuConfig = &models.V1GpuConfig{
+ Limit: int32(gpuVal),
+ Provider: &provider,
+ }
+ }
+ }
+
+ return resource_alloc, nil
+}
+
func toWorkspaceNamespaces(d *schema.ResourceData) []*models.V1WorkspaceClusterNamespace {
workspaceNamespaces := make([]*models.V1WorkspaceClusterNamespace, 0)
if d.Get("namespaces") == nil {
@@ -22,26 +60,38 @@ func toWorkspaceNamespaces(d *schema.ResourceData) []*models.V1WorkspaceClusterN
return workspaceNamespaces
}
-func toWorkspaceNamespace(clusterRbacBinding interface{}) *models.V1WorkspaceClusterNamespace {
- m := clusterRbacBinding.(map[string]interface{})
+func toWorkspaceNamespace(clusterNamespaceConfig interface{}) *models.V1WorkspaceClusterNamespace {
+ m := clusterNamespaceConfig.(map[string]interface{})
+ // Handle default resource allocation
resourceAllocation, _ := m["resource_allocation"].(map[string]interface{})
-
- cpu_cores, err := strconv.ParseFloat(resourceAllocation["cpu_cores"].(string), 64)
+ defaultResourceAlloc, err := toWorkspaceResourceAllocation(resourceAllocation)
if err != nil {
return nil
}
- memory_MiB, err := strconv.ParseFloat(resourceAllocation["memory_MiB"].(string), 64)
- if err != nil {
- return nil
- }
-
- resource_alloc := &models.V1WorkspaceResourceAllocation{
- CPUCores: cpu_cores,
- MemoryMiB: memory_MiB,
+ // Handle cluster resource allocations
+ var clusterResourceAllocations []*models.V1ClusterResourceAllocation
+ if clusterAllocationsData, exists := m["cluster_resource_allocations"]; exists {
+ clusterAllocations := clusterAllocationsData.([]interface{})
+ for _, clusterAlloc := range clusterAllocations {
+ clusterAllocMap := clusterAlloc.(map[string]interface{})
+ uid := clusterAllocMap["uid"].(string)
+ clusterResourceAllocation := clusterAllocMap["resource_allocation"].(map[string]interface{})
+
+ resourceAlloc, err := toWorkspaceResourceAllocation(clusterResourceAllocation)
+ if err != nil {
+ continue // Skip invalid allocations
+ }
+
+ clusterResourceAllocations = append(clusterResourceAllocations, &models.V1ClusterResourceAllocation{
+ ClusterUID: uid,
+ ResourceAllocation: resourceAlloc,
+ })
+ }
}
+ // Handle images blacklist
images, _ := m["images_blacklist"].([]interface{})
blacklist := make([]string, 0)
for _, image := range images {
@@ -58,8 +108,8 @@ func toWorkspaceNamespace(clusterRbacBinding interface{}) *models.V1WorkspaceClu
Name: name,
IsRegex: IsRegex,
NamespaceResourceAllocation: &models.V1WorkspaceNamespaceResourceAllocation{
- ClusterResourceAllocations: nil,
- DefaultResourceAllocation: resource_alloc,
+ ClusterResourceAllocations: clusterResourceAllocations,
+ DefaultResourceAllocation: defaultResourceAlloc,
},
}
@@ -90,30 +140,74 @@ func IsRegex(name string) bool {
}
-func toUpdateWorkspaceNamespaces(d *schema.ResourceData) *models.V1WorkspaceClusterNamespacesEntity {
+func toUpdateWorkspaceNamespaces(d *schema.ResourceData, c *client.V1Client) *models.V1WorkspaceClusterNamespacesEntity {
return &models.V1WorkspaceClusterNamespacesEntity{
ClusterNamespaces: toWorkspaceNamespaces(d),
- ClusterRefs: toClusterRefs(d),
+ ClusterRefs: toClusterRefs(d, c),
Quota: toQuota(d),
}
}
+// Helper function to flatten V1WorkspaceResourceAllocation to resource allocation map
+// includeProvider controls whether to include gpu_provider field (true for default allocations, false for cluster allocations)
+func flattenWorkspaceResourceAllocation(resourceAlloc *models.V1WorkspaceResourceAllocation, includeProvider bool) map[string]interface{} {
+ result := make(map[string]interface{})
+
+ result["cpu_cores"] = strconv.Itoa(int(math.Round(resourceAlloc.CPUCores)))
+ result["memory_MiB"] = strconv.Itoa(int(math.Round(resourceAlloc.MemoryMiB)))
+
+ // Handle GPU configuration if present
+ if resourceAlloc.GpuConfig != nil {
+ result["gpu_limit"] = strconv.Itoa(int(resourceAlloc.GpuConfig.Limit))
+ // Only include gpu_provider for default resource allocations, not cluster-specific ones
+ if includeProvider {
+ if resourceAlloc.GpuConfig.Provider != nil {
+ result["gpu_provider"] = *resourceAlloc.GpuConfig.Provider
+ } else {
+ result["gpu_provider"] = "nvidia" // Default provider
+ }
+ }
+ } else {
+ result["gpu_limit"] = "0"
+ if includeProvider {
+ result["gpu_provider"] = ""
+ }
+ }
+
+ return result
+}
+
func flattenWorkspaceClusterNamespaces(items []*models.V1WorkspaceClusterNamespace) []interface{} {
result := make([]interface{}, 0)
for _, namespace := range items {
flattenNamespace := make(map[string]interface{})
flattenNamespace["name"] = namespace.Name
- flattenResourceAllocation := make(map[string]interface{})
- defaultAllocation := namespace.NamespaceResourceAllocation.DefaultResourceAllocation
- flattenResourceAllocation["cpu_cores"] = strconv.Itoa(int(math.Round(defaultAllocation.CPUCores)))
- flattenResourceAllocation["memory_MiB"] = strconv.Itoa(int(math.Round(defaultAllocation.MemoryMiB)))
+ // Flatten default resource allocation using helper (include gpu_provider)
+ if namespace.NamespaceResourceAllocation != nil && namespace.NamespaceResourceAllocation.DefaultResourceAllocation != nil {
+ flattenNamespace["resource_allocation"] = flattenWorkspaceResourceAllocation(namespace.NamespaceResourceAllocation.DefaultResourceAllocation, true)
+ }
- flattenNamespace["resource_allocation"] = flattenResourceAllocation
+ // Flatten cluster resource allocations (exclude gpu_provider)
+ if namespace.NamespaceResourceAllocation != nil && len(namespace.NamespaceResourceAllocation.ClusterResourceAllocations) > 0 {
+ clusterAllocations := make([]interface{}, 0)
+ for _, clusterAlloc := range namespace.NamespaceResourceAllocation.ClusterResourceAllocations {
+ clusterAllocMap := map[string]interface{}{
+ "uid": clusterAlloc.ClusterUID,
+ }
+ if clusterAlloc.ResourceAllocation != nil {
+ clusterAllocMap["resource_allocation"] = flattenWorkspaceResourceAllocation(clusterAlloc.ResourceAllocation, false)
+ }
+ clusterAllocations = append(clusterAllocations, clusterAllocMap)
+ }
+ flattenNamespace["cluster_resource_allocations"] = clusterAllocations
+ }
+ // Handle images blacklist
if namespace.Image != nil {
flattenNamespace["images_blacklist"] = namespace.Image.BlackListedImages
}
+
result = append(result, flattenNamespace)
}
return result
diff --git a/spectrocloud/workspace_rbac.go b/spectrocloud/workspace_rbac.go
index 0dfae09c9..1df443021 100644
--- a/spectrocloud/workspace_rbac.go
+++ b/spectrocloud/workspace_rbac.go
@@ -30,10 +30,21 @@ func toQuota(d *schema.ResourceData) *models.V1WorkspaceQuota {
}
q := wsQuota.([]interface{})[0].(map[string]interface{})
+ resourceAllocation := &models.V1WorkspaceResourceAllocation{
+ CPUCores: float64(q["cpu"].(int)),
+ MemoryMiB: float64(q["memory"].(int)),
+ }
+
+ // Handle GPU configuration if specified
+ if gpuVal, exists := q["gpu"]; exists && gpuVal.(int) > 0 {
+ provider := "nvidia" // Default to nvidia as it's the only supported provider
+ resourceAllocation.GpuConfig = &models.V1GpuConfig{
+ Limit: int32(gpuVal.(int)),
+ Provider: &provider,
+ }
+ }
+
return &models.V1WorkspaceQuota{
- ResourceAllocation: &models.V1WorkspaceResourceAllocation{
- CPUCores: float64(q["cpu"].(int)),
- MemoryMiB: float64(q["memory"].(int)),
- },
+ ResourceAllocation: resourceAllocation,
}
}
diff --git a/spectrocloud/workspace_test.go b/spectrocloud/workspace_test.go
index 110974770..37e05a144 100644
--- a/spectrocloud/workspace_test.go
+++ b/spectrocloud/workspace_test.go
@@ -1,10 +1,11 @@
package spectrocloud
import (
+ "testing"
+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/spectrocloud/palette-sdk-go/api/models"
"github.com/stretchr/testify/assert"
- "testing"
)
func TestToWorkspacePolicies(t *testing.T) {
@@ -65,10 +66,10 @@ func TestFlattenWorkspaceClusters(t *testing.T) {
},
}
- result := flattenWorkspaceClusters(workspace)
+ result := flattenWorkspaceClusters(workspace, nil) // nil client for unit test
expected := []interface{}{
- map[string]interface{}{"uid": "cluster-1"},
- map[string]interface{}{"uid": "cluster-2"},
+ map[string]interface{}{"uid": "cluster-1", "cluster_name": ""},
+ map[string]interface{}{"uid": "cluster-2", "cluster_name": ""},
}
assert.Equal(t, expected, result)
@@ -81,7 +82,7 @@ func TestFlattenWorkspaceClusters_Empty(t *testing.T) {
},
}
- result := flattenWorkspaceClusters(workspace)
+ result := flattenWorkspaceClusters(workspace, nil) // nil client for unit test
assert.Equal(t, 0, len(result))
}