github.com/vmware/govmomi@v0.37.2/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  }