Skip to content

Commit 8229297

Browse files
authored
PLT-1979 - Add support for create a pvc with "source: blank" and storage in dataVolumeTemplates (#699)
* PLT-1979:Added storage support in datatemplatevolume * pvc optional * Fixed PLT-1975 * removed log file * unit test fix * Revert "unit test fix" This reverts commit 505880c. * unit test fix * PLT-1992: Added boot order support for disks in virtual machine resources (#700) * PLT-1992: Added boot order support for disks in visrtual machine resources * go sec fix
1 parent 48e0759 commit 8229297

File tree

13 files changed

+1299
-51
lines changed

13 files changed

+1299
-51
lines changed

docs/resources/datavolume.md

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,12 @@ Read-Only:
9393
<a id="nestedblock--spec"></a>
9494
### Nested Schema for `spec`
9595

96-
Required:
97-
98-
- `pvc` (Block List, Min: 1, Max: 1) PVC is a pointer to the PVC Spec we want to use. (see [below for nested schema](#nestedblock--spec--pvc))
99-
10096
Optional:
10197

10298
- `content_type` (String) ContentType options: "kubevirt", "archive".
99+
- `pvc` (Block List, Max: 1) PVC is a pointer to the PVC Spec we want to use. (see [below for nested schema](#nestedblock--spec--pvc))
103100
- `source` (Block List, Max: 1) Source is the src of the data for the requested DataVolume. (see [below for nested schema](#nestedblock--spec--source))
101+
- `storage` (Block List, Max: 1) Storage is the requested storage specification for the DataVolume. (see [below for nested schema](#nestedblock--spec--storage))
104102

105103
<a id="nestedblock--spec--pvc"></a>
106104
### Nested Schema for `spec.pvc`
@@ -188,6 +186,47 @@ Optional:
188186

189187

190188

189+
<a id="nestedblock--spec--storage"></a>
190+
### Nested Schema for `spec.storage`
191+
192+
Optional:
193+
194+
- `access_modes` (Set of String) A set of the desired access modes the volume should have. More info: http://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
195+
- `resources` (Block List, Max: 1) A list of the minimum resources the volume should have. More info: http://kubernetes.io/docs/concepts/storage/persistent-volumes#resources (see [below for nested schema](#nestedblock--spec--storage--resources))
196+
- `selector` (Block List, Max: 1) A label query over volumes to consider for binding. (see [below for nested schema](#nestedblock--spec--storage--selector))
197+
- `storage_class_name` (String) Name of the storage class requested by the claim
198+
- `volume_mode` (String) volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.
199+
- `volume_name` (String) The binding reference to the PersistentVolume backing this claim.
200+
201+
<a id="nestedblock--spec--storage--resources"></a>
202+
### Nested Schema for `spec.storage.resources`
203+
204+
Optional:
205+
206+
- `limits` (Map of String) Map describing the maximum amount of compute resources allowed. More info: http://kubernetes.io/docs/user-guide/compute-resources/
207+
- `requests` (Map of String) Map describing the minimum amount of compute resources required. If this is omitted for a container, it defaults to `limits` if that is explicitly specified, otherwise to an implementation-defined value. More info: http://kubernetes.io/docs/user-guide/compute-resources/
208+
209+
210+
<a id="nestedblock--spec--storage--selector"></a>
211+
### Nested Schema for `spec.storage.selector`
212+
213+
Optional:
214+
215+
- `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--spec--storage--selector--match_expressions))
216+
- `match_labels` (Map of String) A map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of `match_expressions`, whose key field is "key", the operator is "In", and the values array contains only "value".
217+
218+
<a id="nestedblock--spec--storage--selector--match_expressions"></a>
219+
### Nested Schema for `spec.storage.selector.match_expressions`
220+
221+
Optional:
222+
223+
- `key` (String) The label key that the selector applies to.
224+
- `operator` (String) A key's relationship to a set of values. Valid operators are `In`, `NotIn`, `Exists` and `DoesNotExist`.
225+
- `values` (Set of String) An array of string values. If the operator is `In` or `NotIn`, the values array must be non-empty. If the operator is `Exists` or `DoesNotExist`, the values array must be empty.
226+
227+
228+
229+
191230

192231
<a id="nestedblock--status"></a>
193232
### Nested Schema for `status`

docs/resources/virtual_machine.md

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -825,14 +825,12 @@ Read-Only:
825825
<a id="nestedblock--data_volume_templates--spec"></a>
826826
### Nested Schema for `data_volume_templates.spec`
827827

828-
Required:
829-
830-
- `pvc` (Block List, Min: 1, Max: 1) PVC is a pointer to the PVC Spec we want to use. (see [below for nested schema](#nestedblock--data_volume_templates--spec--pvc))
831-
832828
Optional:
833829

834830
- `content_type` (String) ContentType options: "kubevirt", "archive".
831+
- `pvc` (Block List, Max: 1) PVC is a pointer to the PVC Spec we want to use. (see [below for nested schema](#nestedblock--data_volume_templates--spec--pvc))
835832
- `source` (Block List, Max: 1) Source is the src of the data for the requested DataVolume. (see [below for nested schema](#nestedblock--data_volume_templates--spec--source))
833+
- `storage` (Block List, Max: 1) Storage is the requested storage specification for the DataVolume. (see [below for nested schema](#nestedblock--data_volume_templates--spec--storage))
836834

837835
<a id="nestedblock--data_volume_templates--spec--pvc"></a>
838836
### Nested Schema for `data_volume_templates.spec.pvc`
@@ -920,6 +918,47 @@ Optional:
920918

921919

922920

921+
<a id="nestedblock--data_volume_templates--spec--storage"></a>
922+
### Nested Schema for `data_volume_templates.spec.storage`
923+
924+
Optional:
925+
926+
- `access_modes` (Set of String) A set of the desired access modes the volume should have. More info: http://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
927+
- `resources` (Block List, Max: 1) A list of the minimum resources the volume should have. More info: http://kubernetes.io/docs/concepts/storage/persistent-volumes#resources (see [below for nested schema](#nestedblock--data_volume_templates--spec--storage--resources))
928+
- `selector` (Block List, Max: 1) A label query over volumes to consider for binding. (see [below for nested schema](#nestedblock--data_volume_templates--spec--storage--selector))
929+
- `storage_class_name` (String) Name of the storage class requested by the claim
930+
- `volume_mode` (String) volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.
931+
- `volume_name` (String) The binding reference to the PersistentVolume backing this claim.
932+
933+
<a id="nestedblock--data_volume_templates--spec--storage--resources"></a>
934+
### Nested Schema for `data_volume_templates.spec.storage.resources`
935+
936+
Optional:
937+
938+
- `limits` (Map of String) Map describing the maximum amount of compute resources allowed. More info: http://kubernetes.io/docs/user-guide/compute-resources/
939+
- `requests` (Map of String) Map describing the minimum amount of compute resources required. If this is omitted for a container, it defaults to `limits` if that is explicitly specified, otherwise to an implementation-defined value. More info: http://kubernetes.io/docs/user-guide/compute-resources/
940+
941+
942+
<a id="nestedblock--data_volume_templates--spec--storage--selector"></a>
943+
### Nested Schema for `data_volume_templates.spec.storage.selector`
944+
945+
Optional:
946+
947+
- `match_expressions` (Block List) A list of label selector requirements. The requirements are ANDed. (see [below for nested schema](#nestedblock--data_volume_templates--spec--storage--selector--match_expressions))
948+
- `match_labels` (Map of String) A map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of `match_expressions`, whose key field is "key", the operator is "In", and the values array contains only "value".
949+
950+
<a id="nestedblock--data_volume_templates--spec--storage--selector--match_expressions"></a>
951+
### Nested Schema for `data_volume_templates.spec.storage.selector.match_expressions`
952+
953+
Optional:
954+
955+
- `key` (String) The label key that the selector applies to.
956+
- `operator` (String) A key's relationship to a set of values. Valid operators are `In`, `NotIn`, `Exists` and `DoesNotExist`.
957+
- `values` (Set of String) An array of string values. If the operator is `In` or `NotIn`, the values array must be non-empty. If the operator is `Exists` or `DoesNotExist`, the values array must be empty.
958+
959+
960+
961+
923962

924963

925964
<a id="nestedblock--disk"></a>
@@ -932,6 +971,7 @@ Required:
932971

933972
Optional:
934973

974+
- `boot_order` (Number) BootOrder is an integer value > 0, used to determine ordering of boot devices. Lower values take precedence.
935975
- `serial` (String) Serial provides the ability to specify a serial number for the disk device.
936976

937977
<a id="nestedblock--disk--disk_device"></a>
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# Example showing how to use the new storage field in dataVolumeTemplates.spec
2+
# This demonstrates the alternative to using the pvc field
3+
4+
data "spectrocloud_cluster" "vm_enabled_base_cluster" {
5+
name = "tenant-cluster-002"
6+
context = "project"
7+
}
8+
9+
locals {
10+
storage_class_name = "spectro-storage-class"
11+
}
12+
13+
# VM using the new storage field instead of pvc field
14+
resource "spectrocloud_virtual_machine" "tf-test-vm-with-storage" {
15+
cluster_uid = data.spectrocloud_cluster.vm_enabled_base_cluster.id
16+
cluster_context = data.spectrocloud_cluster.vm_enabled_base_cluster.context
17+
run_on_launch = true
18+
name = "tf-test-vm-with-storage"
19+
namespace = "default"
20+
labels = {
21+
"tf" = "test"
22+
}
23+
24+
# Using the new storage field in dataVolumeTemplates.spec
25+
data_volume_templates {
26+
metadata {
27+
name = "test-vm-bootvolume-storage"
28+
namespace = "default"
29+
}
30+
spec {
31+
source {
32+
registry {
33+
image_url = "gcr.io/spectro-images-public/release/vm-dashboard/os/ubuntu-container-disk:20.04"
34+
}
35+
}
36+
# Using the new storage field instead of pvc
37+
storage {
38+
access_modes = ["ReadWriteOnce"]
39+
resources {
40+
requests = {
41+
storage = "10Gi"
42+
}
43+
limits = {
44+
storage = "20Gi"
45+
}
46+
}
47+
storage_class_name = local.storage_class_name
48+
volume_mode = "Filesystem"
49+
# Optional selector for label-based volume selection
50+
selector {
51+
match_labels = {
52+
type = "ssd"
53+
tier = "premium"
54+
}
55+
}
56+
}
57+
}
58+
}
59+
60+
volume {
61+
name = "test-vm-datavolumedisk1"
62+
volume_source {
63+
data_volume {
64+
name = "test-vm-bootvolume-storage"
65+
}
66+
}
67+
}
68+
69+
disk {
70+
name = "test-vm-datavolumedisk1"
71+
disk_device {
72+
disk {
73+
bus = "virtio"
74+
}
75+
}
76+
}
77+
78+
cpu {
79+
cores = 2
80+
sockets = 1
81+
threads = 1
82+
}
83+
84+
memory {
85+
size = "4Gi"
86+
}
87+
88+
interface {
89+
name = "default"
90+
interface_binding_method = "InterfaceBridge"
91+
}
92+
93+
network {
94+
name = "default"
95+
network_source = "pod"
96+
}
97+
}
98+
99+
# Example showing both pvc and storage can coexist (for different volumes)
100+
resource "spectrocloud_virtual_machine" "tf-test-vm-mixed-storage" {
101+
cluster_uid = data.spectrocloud_cluster.vm_enabled_base_cluster.id
102+
cluster_context = data.spectrocloud_cluster.vm_enabled_base_cluster.context
103+
run_on_launch = true
104+
name = "tf-test-vm-mixed-storage"
105+
namespace = "default"
106+
labels = {
107+
"tf" = "test"
108+
}
109+
110+
# Boot volume using storage field
111+
data_volume_templates {
112+
metadata {
113+
name = "boot-volume-storage"
114+
namespace = "default"
115+
}
116+
spec {
117+
source {
118+
registry {
119+
image_url = "gcr.io/spectro-images-public/release/vm-dashboard/os/ubuntu-container-disk:20.04"
120+
}
121+
}
122+
storage {
123+
access_modes = ["ReadWriteOnce"]
124+
resources {
125+
requests = {
126+
storage = "10Gi"
127+
}
128+
}
129+
storage_class_name = local.storage_class_name
130+
}
131+
}
132+
}
133+
134+
# Data volume using traditional pvc field
135+
data_volume_templates {
136+
metadata {
137+
name = "data-volume-pvc"
138+
namespace = "default"
139+
}
140+
spec {
141+
source {
142+
blank {}
143+
}
144+
pvc {
145+
access_modes = ["ReadWriteOnce"]
146+
resources {
147+
requests = {
148+
storage = "5Gi"
149+
}
150+
}
151+
storage_class_name = local.storage_class_name
152+
}
153+
}
154+
}
155+
156+
volume {
157+
name = "boot-disk"
158+
volume_source {
159+
data_volume {
160+
name = "boot-volume-storage"
161+
}
162+
}
163+
}
164+
165+
volume {
166+
name = "data-disk"
167+
volume_source {
168+
data_volume {
169+
name = "data-volume-pvc"
170+
}
171+
}
172+
}
173+
174+
disk {
175+
name = "boot-disk"
176+
disk_device {
177+
disk {
178+
bus = "virtio"
179+
}
180+
}
181+
}
182+
183+
disk {
184+
name = "data-disk"
185+
disk_device {
186+
disk {
187+
bus = "virtio"
188+
}
189+
}
190+
}
191+
192+
cpu {
193+
cores = 2
194+
sockets = 1
195+
threads = 1
196+
}
197+
198+
memory {
199+
size = "4Gi"
200+
}
201+
202+
interface {
203+
name = "default"
204+
interface_binding_method = "InterfaceBridge"
205+
}
206+
207+
network {
208+
name = "default"
209+
network_source = "pod"
210+
}
211+
}

spectrocloud/kubevirt/schema/datavolume/source.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,19 +143,29 @@ func expandDataVolumeSource(dataVolumeSource []interface{}) *cdiv1.DataVolumeSou
143143

144144
in := dataVolumeSource[0].(map[string]interface{})
145145

146-
result.Blank = expandDataVolumeSourceBlank(in["blank"].([]interface{}))
147-
result.HTTP = expandDataVolumeSourceHTTP(in["http"].([]interface{}))
148-
result.PVC = expandDataVolumeSourcePVC(in["pvc"].([]interface{}))
149-
result.Registry = expandDataVolumeSourceRegistry(in["registry"].([]interface{}))
146+
if v, ok := in["blank"].([]interface{}); ok {
147+
result.Blank = expandDataVolumeSourceBlank(v)
148+
}
149+
if v, ok := in["http"].([]interface{}); ok {
150+
result.HTTP = expandDataVolumeSourceHTTP(v)
151+
}
152+
if v, ok := in["pvc"].([]interface{}); ok {
153+
result.PVC = expandDataVolumeSourcePVC(v)
154+
}
155+
if v, ok := in["registry"].([]interface{}); ok {
156+
result.Registry = expandDataVolumeSourceRegistry(v)
157+
}
150158

151159
return result
152160
}
153161

154162
func expandDataVolumeSourceBlank(dataVolumeSourceBlank []interface{}) *cdiv1.DataVolumeBlankImage {
155-
if len(dataVolumeSourceBlank) == 0 || dataVolumeSourceBlank[0] == nil {
163+
if len(dataVolumeSourceBlank) == 0 {
156164
return nil
157165
}
158166

167+
// When blank {} is present in Terraform config, we should return a DataVolumeBlankImage
168+
// even if the first element is nil or an empty map
159169
result := &cdiv1.DataVolumeBlankImage{}
160170

161171
return result

0 commit comments

Comments
 (0)