github.com/vmware/govmomi@v0.43.0/vapi/vm/dataset/dataset.go (about) 1 /* 2 Copyright (c) 2023-2023 VMware, Inc. All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package dataset 18 19 import ( 20 "context" 21 "net/http" 22 "net/url" 23 "path" 24 "strconv" 25 26 "github.com/vmware/govmomi/vapi/rest" 27 "github.com/vmware/govmomi/vapi/vm/internal" 28 ) 29 30 // Manager extends rest.Client, adding data set related methods. 31 // 32 // Data sets functionality was introduced in vSphere 8.0, 33 // and requires the VM to have virtual hardware version 20 or newer. 34 // 35 // See the VMware Guest SDK Programming Guide for details on using data sets 36 // from within the guest OS of a VM. 37 // 38 // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/vm/data_sets/ 39 type Manager struct { 40 *rest.Client 41 } 42 43 // NewManager creates a new Manager instance with the given client. 44 func NewManager(client *rest.Client) *Manager { 45 return &Manager{ 46 Client: client, 47 } 48 } 49 50 // Access permission to the entries of a data set. 51 type Access string 52 53 const ( 54 AccessNone = Access("NONE") 55 AccessReadOnly = Access("READ_ONLY") 56 AccessReadWrite = Access("READ_WRITE") 57 ) 58 59 // Describes a data set to be created. 60 type CreateSpec struct { 61 // Name should take the form "com.company.project" to avoid conflict with other uses. 62 // Must not be empty. 63 Name string `json:"name"` 64 65 // Description of the data set. 66 Description string `json:"description"` 67 68 // Host controls access to the data set entries by the ESXi host and the vCenter. 69 // For example, if the host access is set to NONE, the entries of this data set 70 // will not be accessible through the vCenter API. 71 // Must not be empty. 72 Host Access `json:"host"` 73 74 // Guest controls access to the data set entries by the guest OS of the VM (i.e. in-guest APIs). 75 // For example, if the guest access is set to READ_ONLY, it will be forbidden 76 // to create, delete, and update entries in this data set via the VMware Guest SDK. 77 // Must not be empty. 78 Guest Access `json:"guest"` 79 80 // OmitFromSnapshotAndClone controls whether the data set is included in snapshots and clones of the VM. 81 // When a VM is reverted to a snapshot, any data set with OmitFromSnapshotAndClone=true will be destroyed. 82 // Default is false. 83 OmitFromSnapshotAndClone *bool `json:"omit_from_snapshot_and_clone,omitempty"` 84 } 85 86 // Describes modifications to a data set. 87 type UpdateSpec struct { 88 Description *string `json:"description,omitempty"` 89 Host *Access `json:"host,omitempty"` 90 Guest *Access `json:"guest,omitempty"` 91 OmitFromSnapshotAndClone *bool `json:"omit_from_snapshot_and_clone,omitempty"` 92 } 93 94 // Data set information. 95 type Info struct { 96 Name string `json:"name"` 97 Description string `json:"description"` 98 Host Access `json:"host"` 99 Guest Access `json:"guest"` 100 Used int `json:"used"` 101 OmitFromSnapshotAndClone bool `json:"omit_from_snapshot_and_clone"` 102 } 103 104 // Brief data set information. 105 type Summary struct { 106 DataSet string `json:"data_set"` 107 Name string `json:"name"` 108 Description string `json:"description"` 109 } 110 111 const dataSetsPathField = "data-sets" 112 113 func dataSetPath(vm string, dataSet string) string { 114 return path.Join(internal.VCenterVMPath, url.PathEscape(vm), dataSetsPathField, url.PathEscape(dataSet)) 115 } 116 117 func dataSetsPath(vm string) string { 118 return path.Join(internal.VCenterVMPath, url.PathEscape(vm), dataSetsPathField) 119 } 120 121 const entriesPathField = "entries" 122 123 func entryPath(vm string, dataSet string, key string) string { 124 return path.Join(internal.VCenterVMPath, url.PathEscape(vm), dataSetsPathField, url.PathEscape(dataSet), entriesPathField, url.PathEscape(key)) 125 } 126 127 func entriesPath(vm string, dataSet string) string { 128 return path.Join(internal.VCenterVMPath, url.PathEscape(vm), dataSetsPathField, url.PathEscape(dataSet), entriesPathField) 129 } 130 131 // CreateDataSet creates a data set associated with the given virtual machine. 132 func (c *Manager) CreateDataSet(ctx context.Context, vm string, spec *CreateSpec) (string, error) { 133 url := c.Resource(dataSetsPath(vm)) 134 var res string 135 err := c.Do(ctx, url.Request(http.MethodPost, spec), &res) 136 return res, err 137 } 138 139 // DeleteDataSet deletes an existing data set from the given virtual machine. 140 // The operation will fail if the data set is not empty. 141 // Set the force flag to delete a non-empty data set. 142 func (c *Manager) DeleteDataSet(ctx context.Context, vm string, dataSet string, force bool) error { 143 url := c.Resource(dataSetPath(vm, dataSet)) 144 if force { 145 url.WithParam("force", strconv.FormatBool(force)) 146 } 147 return c.Do(ctx, url.Request(http.MethodDelete), nil) 148 } 149 150 // GetDataSet retrieves information about the given data set. 151 func (c *Manager) GetDataSet(ctx context.Context, vm string, dataSet string) (*Info, error) { 152 url := c.Resource(dataSetPath(vm, dataSet)) 153 var res Info 154 err := c.Do(ctx, url.Request(http.MethodGet), &res) 155 return &res, err 156 } 157 158 // UpdateDataSet modifies the given data set. 159 func (c *Manager) UpdateDataSet(ctx context.Context, vm string, dataSet string, spec *UpdateSpec) error { 160 url := c.Resource(dataSetPath(vm, dataSet)) 161 return c.Do(ctx, url.Request(http.MethodPatch, spec), nil) 162 } 163 164 // ListDataSets returns a list of brief descriptions of the data sets on with the given virtual machine. 165 func (c *Manager) ListDataSets(ctx context.Context, vm string) ([]Summary, error) { 166 url := c.Resource(dataSetsPath(vm)) 167 var res []Summary 168 err := c.Do(ctx, url.Request(http.MethodGet), &res) 169 return res, err 170 } 171 172 // SetEntry creates or updates an entry in the given data set. 173 // If an entry with the given key already exists, it will be overwritten. 174 // The key can be at most 4096 bytes. The value can be at most 1MB. 175 func (c *Manager) SetEntry(ctx context.Context, vm string, dataSet string, key string, value string) error { 176 url := c.Resource(entryPath(vm, dataSet, key)) 177 return c.Do(ctx, url.Request(http.MethodPut, value), nil) 178 } 179 180 // GetEntry returns the value of the data set entry with the given key. 181 func (c *Manager) GetEntry(ctx context.Context, vm string, dataSet string, key string) (string, error) { 182 url := c.Resource(entryPath(vm, dataSet, key)) 183 var res string 184 err := c.Do(ctx, url.Request(http.MethodGet), &res) 185 return res, err 186 } 187 188 // DeleteEntry removes an existing entry from the given data set. 189 func (c *Manager) DeleteEntry(ctx context.Context, vm string, dataSet string, key string) error { 190 url := c.Resource(entryPath(vm, dataSet, key)) 191 return c.Do(ctx, url.Request(http.MethodDelete), nil) 192 } 193 194 // ListEntries returns a list of all entry keys in the given data set. 195 func (c *Manager) ListEntries(ctx context.Context, vm string, dataSet string) ([]string, error) { 196 url := c.Resource(entriesPath(vm, dataSet)) 197 var res []string 198 err := c.Do(ctx, url.Request(http.MethodGet), &res) 199 return res, err 200 }