Skip to content

Commit f35fc81

Browse files
authored
Add vappconfig.md doc (#175)
Add doc for vAppConfig bootstrap.
1 parent c825da1 commit f35fc81

File tree

2 files changed

+129
-13
lines changed

2 files changed

+129
-13
lines changed

docs/concepts/workloads/guest.md

+16-12
Original file line numberDiff line numberDiff line change
@@ -342,19 +342,23 @@ To illustrate, the following YAML can be utilized to deploy a VirtualMachine and
342342
management_gateway: "{{ (index .V1alpha1.Net.Devices 0).Gateway4 }}"
343343
```
344344

345-
#### Supporting Template Functions
346-
347-
| Function Name | Signature | Description |
348-
|-----------------------------|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
349-
| V1alpha1_FirstIP | `func () string` | Get the first non-loopback IP with CIDR from first NIC. |
350-
| V1alpha1_FirstIPFromNIC | `func (index int) string` | Get non-loopback IP address with CIDR from the ith NIC. If index is out of bound, template string won't be parsed. |
351-
| V1alpha1_FormatIP | `func (IP string, netmask string) string` | 1. Format an IP address with network length. A netmask can be either the length, ex. /24, or the decimal notation, ex. 255.255.255.0. 2. Format an IP address with CIDR: if input netmask is empty string, return IP sans CIDR. If input netmask is not valid, return empty string. If input netmask is different with CIDR, replace and return IP with new CIDR. |
352-
| V1alpha1_FormatNameservers | `func (count int, delimiter string) string` | Format the first occurred count of nameservers with specific delimiter. A negative number for count would mean all nameservers. |
353-
| V1alpha1_IP | `func(IP string) string` | Format a static IP address with default netmask CIDR. If IP is not valid, template string won't be parsed. |
354-
| V1alpha1_IPsFromNIC | `func (index int) []string` | List all IPs with CIDR from the ith NIC. If index is out of bound, template string won't be parsed. |
355-
| V1alpha1_SubnetMask | `func(cidr string) (string, error)` | Get subnet mask from a CIDR notation IP address and prefix length. If IP address and prefix length are not valid, throw an error and template string won't be parsed. |
356-
| V1alpha1_FirstNicMacAddr | `func() (string, error)` | Get the first NIC's MAC address. |
345+
=== "vAppConfig with supporting template"
357346

347+
```yaml
348+
apiVersion: v1
349+
kind: Secret
350+
metadata:
351+
name: my-secret
352+
namespace: test-ns
353+
stringData:
354+
# see more details on below Supporting Template Queries section
355+
nameservers: "{{ V1alpha1_FormatNameservers 2 \",\" }}"
356+
management_ip: "{{ V1alpha1_FormatIP \"192.168.1.10\" \"255.255.255.0\" }}"
357+
hostname: "{{ .V1alpha1.VM.Name }} "
358+
management_gateway: "{{ (index .V1alpha1.Net.Devices 0).Gateway4 }}"
359+
```
360+
361+
For more information on vAppConfig, please refer to [tutorial/deploy-vm/vappconfig](https://vm-operator.readthedocs.io/en/latest/tutorials/deploy-vm/vappconfig/).
358362
## Deprecated
359363

360364
The following bootstrap providers are still available, but they are deprecated and are not recommended.
+113-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,115 @@
11
# Deploy a VM with vAppConfig
22

3-
// TODO ([github.com/vmware-tanzu/vm-operator#123](https://github.com/vmware-tanzu/vm-operator/issues/123))
3+
This page reviews the bootstrap method vAppConfig.
4+
5+
## Description
6+
The vAppConfig bootstrap method is useful for legacy VM images that rely on bespoke, boot-time processes that leverage vAppConfig properties for customizing a guest.
7+
8+
## Purpose
9+
As a DevOps user, you can assign Golang-based template strings to vAppConfig values to send information into the guest that is not known ahead of time, such as the IPAM data settings used to configure the VM's network stack.
10+
11+
## Example
12+
=== "VirtualMachine"
13+
14+
```yaml
15+
apiVersion: vmoperator.vmware.com/v1alpha1
16+
kind: VirtualMachine
17+
metadata:
18+
name: legacy-vm
19+
namespace: test-ns
20+
spec:
21+
className: best-effort-small
22+
imageName: haproxy-v0.2.0
23+
powerState: poweredOn
24+
storageClass: wcpglobal-storage-profile
25+
vmMetadata:
26+
secretName: my-secret
27+
transport: vAppConfig
28+
```
29+
30+
=== "vAppConfig"
31+
32+
```yaml
33+
apiVersion: v1
34+
kind: Secret
35+
metadata:
36+
name: my-secret
37+
namespace: test-ns
38+
stringData:
39+
nameservers: "{{ (index .V1alpha1.Net.Nameservers 0) }}"
40+
management_ip: "{{ (index (index .V1alpha1.Net.Devices 0).IPAddresses 0) }}"
41+
hostname: "{{ .V1alpha1.VM.Name }} "
42+
management_gateway: "{{ (index .V1alpha1.Net.Devices 0).Gateway4 }}"
43+
```
44+
45+
=== "vAppConfig with supporting template"
46+
47+
```yaml
48+
apiVersion: v1
49+
kind: Secret
50+
metadata:
51+
name: my-secret
52+
namespace: test-ns
53+
stringData:
54+
# see more details on below Supporting Template Queries section
55+
nameservers: "{{ V1alpha1_FormatNameservers 2 \",\" }}"
56+
management_ip: "{{ V1alpha1_FormatIP \"192.168.1.10\" \"255.255.255.0\" }}"
57+
hostname: "{{ .V1alpha1.VM.Name }} "
58+
management_gateway: "{{ (index .V1alpha1.Net.Devices 0).Gateway4 }}"
59+
```
60+
61+
:wave: The Golang based template string is a representation of [vm-operator virtualmachinetempl_types v1alpha1 api](https://github.com/vmware-tanzu/vm-operator/blob/25fb865e615d377192a870583ab32973e9fbd32a/api/v1alpha1/virtualmachinetempl_types.go#L4)
62+
63+
:wave: The fields `nameservers`, `hostname`, `management_ip` and `management_gateway` are derived from image `haproxy-v0.2.0` OVF properties.
64+
```xml
65+
<Property ovf:key="nameservers" ovf:type="string" ovf:userConfigurable="true" ovf:value="1.1.1.1, 1.0.0.1">
66+
<Label>2.2. DNS</Label>
67+
<Description>A comma-separated list of IP addresses for up to three DNS servers</Description>
68+
</Property>
69+
<Property ovf:key="hostname" ovf:type="string" ovf:userConfigurable="true" ovf:value="ubuntuguest">
70+
<Description>Specifies the hostname for the appliance</Description>
71+
</Property>
72+
<Property ovf:key="management_ip" ovf:type="string" ovf:userConfigurable="true">
73+
<Label>2.3. Management IP</Label>
74+
<Description>The static IP address for the appliance on the Management Port Group in CIDR format (.For eg. ip/subnet mask bits). This cannot be DHCP.</Description>
75+
</Property>
76+
```
77+
78+
## Supporting Template Queries
79+
To spare users the effort to construct a correct template string, there are some supporting template queries vm-operator provides.
80+
81+
| Query name | Signature | Description |
82+
| -------- | -------- | -------- |
83+
| V1alpha1_FirstIP | `func () string` | Get the first non-loopback IP with CIDR from first NIC. |
84+
| V1alpha1_FirstIPFromNIC | `func (index int) string` | Get non-loopback IP address with CIDR from the ith NIC. if index out of bound, template string won't be parsed. |
85+
| V1alpha1_FormatIP | `func (IP string, netmask string) string` | see below for detailed use case.|
86+
| V1alpha1_FirstNicMacAddr | `func() (string, error)` | Get the first NIC's MAC address. |
87+
| V1alpha1_FormatNameservers| `func (count int, delimiter string) string` | Format the first occurred count of nameservers with specific delimiter (A n.For egative number for count would mean all nameservers). |
88+
| V1alpha1_IP | `func(IP string) string` | Format a static IP address with default netmask CIDR. If IP is not valid, template string won't be parsed. |
89+
| V1alpha1_IPsFromNIC | `func (index int) []string` | List all IPs with CIDR from the ith NIC. if index out of bound, template string won't be parsed. |
90+
| V1alpha1_SubnetMask | `func(cidr string) (string, error)` | Get subnet mask from a CIDR notation IP address and prefix length. |
91+
92+
### `V1alpha1_FormatIP`
93+
1. Format an IP address with network length. A netmask can be either the length, ex. /24, or the decimal notation, ex. 255.255.255.0. Return IP sans CIDR when input is valid.
94+
95+
2. Format an IP address with CIDR:
96+
- if input netmask is different with CIDR, replace and return IP with new CIDR.
97+
- if input netmask is empty string, return IP sans CIDR.
98+
- if input netmask is not valid, return empty string.
99+
100+
**Note** when OVF only takes in IP sans CIDR, use `V1alpha1_FormatIP` and pass empty string as input netmask:
101+
```yaml
102+
management_ip: '{{ V1alpha1_FormatIP V1alpha1_FirstIP "" }}' # return first non-loopback IP from first NIC without CIDR. For eg, "192.168.1.10".
103+
```
104+
105+
### Examples
106+
```yaml
107+
management_ip: "{{ V1alpha1_FirstIP }}" # return first non-loopback IP with CIDR from first NIC.
108+
management_ip: "{{ V1alpha1_FirstIPFromNIC 1 }}" # return first non-loopback IP with CIDR from second NIC.
109+
management_ip: "{{ V1alpha1_FormatIP \"192.168.1.10\" \"255.255.255.0\" }}" # return IP with CIDR. For eg,"192.168.1.10/24".
110+
management_ip: "{{ V1alpha1_IP \"192.168.1.37\" }}" # return IP with default netmask CIDR.
111+
nameservers: "{{ V1alpha1_FormatNameservers 2 \",\" }}" # return 2 nameservers with "," as delimiter. For eg,"10.20.145.1, 10.20.145.2".
112+
subnet_mask: "{{ V1alpha1_SubnetMask V1alpha1_FirstIP }}" # return the subnet mask of the first non-loopback IP with CIDR from first NIC. For eg, "255.255.255.0".
113+
mac_address: "{{ v1alpha1_FirstNicMacAddr }}" # return the first NIC's MAC Address.
114+
```
115+

0 commit comments

Comments
 (0)