github.com/vmware/govmomi@v0.51.0/vapi/namespace/namespace.go (about)

     1  // © Broadcom. All Rights Reserved.
     2  // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package namespace
     6  
     7  import (
     8  	"bytes"
     9  	"context"
    10  	"encoding/json"
    11  	"fmt"
    12  	"net/http"
    13  	"os"
    14  	"path"
    15  
    16  	"github.com/vmware/govmomi/vapi/namespace/internal"
    17  	"github.com/vmware/govmomi/vapi/rest"
    18  	"github.com/vmware/govmomi/vim25/types"
    19  )
    20  
    21  // Manager extends rest.Client, adding namespace related methods.
    22  type Manager struct {
    23  	*rest.Client
    24  }
    25  
    26  // NewManager creates a new Manager instance with the given client.
    27  func NewManager(client *rest.Client) *Manager {
    28  	return &Manager{
    29  		Client: client,
    30  	}
    31  }
    32  
    33  // EnableClusterSpec defines a Tanzu Supervisor Cluster for creation.
    34  // See: https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Clusters/EnableSpec/
    35  // Since 7.0.0:-
    36  type EnableClusterSpec struct {
    37  	MasterDNSSearchDomains []string               `json:"master_DNS_search_domains,omitempty"`
    38  	ImageStorage           ImageStorageSpec       `json:"image_storage"`
    39  	NcpClusterNetworkSpec  *NcpClusterNetworkSpec `json:"ncp_cluster_network_spec,omitempty"`
    40  	// Note: NcpClusterNetworkSpec is replaced by WorkloadNetworksSpec in vSphere 7.0u2+
    41  	// Since 7.0u1:-
    42  	WorkloadNetworksSpec    *WorkloadNetworksEnableSpec `json:"workload_networks_spec,omitempty"`
    43  	MasterManagementNetwork *MasterManagementNetwork    `json:"master_management_network"`
    44  	MasterDNSNames          []string                    `json:"Master_DNS_names,omitempty"`
    45  	MasterNTPServers        []string                    `json:"master_NTP_servers,omitempty"`
    46  	EphemeralStoragePolicy  string                      `json:"ephemeral_storage_policy,omitempty"`
    47  	DefaultImageRepository  string                      `json:"default_image_repository,omitempty"`
    48  	ServiceCidr             *Cidr                       `json:"service_cidr"`
    49  	LoginBanner             string                      `json:"login_banner,omitempty"`
    50  	// Was string until #2860:-
    51  	SizeHint             *SizingHint           `json:"size_hint"`
    52  	WorkerDNS            []string              `json:"worker_DNS,omitempty"`
    53  	DefaultImageRegistry *DefaultImageRegistry `json:"default_image_registry,omitempty"`
    54  	MasterDNS            []string              `json:"master_DNS,omitempty"`
    55  	// Was string until #2860:-
    56  	NetworkProvider                        *NetworkProvider        `json:"network_provider"`
    57  	MasterStoragePolicy                    string                  `json:"master_storage_policy,omitempty"`
    58  	DefaultKubernetesServiceContentLibrary string                  `json:"default_kubernetes_service_content_library,omitempty"`
    59  	WorkloadNTPServers                     []string                `json:"workload_ntp_servers,omitempty"`
    60  	LoadBalancerConfigSpec                 *LoadBalancerConfigSpec `json:"load_balancer_config_spec,omitempty"`
    61  }
    62  
    63  // SizingHint determines the size of the Tanzu Kubernetes Grid
    64  // Supervisor cluster's kubeapi instances.
    65  // Note: Only use TinySizingHint in non-production environments.
    66  // Note: This is a secure coding pattern to avoid Stringly typed fields.
    67  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/SizingHint/
    68  // Since 7.0.0
    69  type SizingHint struct {
    70  	slug string
    71  }
    72  
    73  var (
    74  	UndefinedSizingHint = SizingHint{""}
    75  	TinySizingHint      = SizingHint{"TINY"}
    76  	SmallSizingHint     = SizingHint{"SMALL"}
    77  	MediumSizingHint    = SizingHint{"MEDIUM"}
    78  	LargeSizingHint     = SizingHint{"LARGE"}
    79  )
    80  
    81  func (v SizingHint) String() string {
    82  	return v.slug
    83  }
    84  
    85  func (v *SizingHint) UnmarshalJSON(b []byte) error {
    86  	var s string
    87  	if err := json.Unmarshal(b, &s); nil != err {
    88  		return err
    89  	}
    90  	v.FromString(s)
    91  	return nil
    92  }
    93  
    94  func (v SizingHint) MarshalJSON() ([]byte, error) {
    95  	return json.Marshal(v.slug)
    96  }
    97  
    98  func (v *SizingHint) FromString(s string) {
    99  	v.slug = SizingHintFromString(s).slug
   100  }
   101  
   102  func SizingHintFromString(s string) SizingHint {
   103  	if "TINY" == s {
   104  		return TinySizingHint
   105  	}
   106  	if "SMALL" == s {
   107  		return SmallSizingHint
   108  	}
   109  	if "MEDIUM" == s {
   110  		return MediumSizingHint
   111  	}
   112  	if "LARGE" == s {
   113  		return LargeSizingHint
   114  	}
   115  	return UndefinedSizingHint
   116  }
   117  
   118  // ImageStorageSpec defines the storage policy ID (not name) assigned to
   119  // a Tanzu Kubernetes Grid cluster (supervisor or workload clusters)
   120  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Clusters/ImageStorageSpec/
   121  // Since 7.0.0:-
   122  type ImageStorageSpec struct {
   123  	StoragePolicy string `json:"storage_policy"`
   124  }
   125  
   126  // Cidr defines an IPv4 CIDR range for a subnet.
   127  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/Namespaces/Instances/Ipv4Cidr/
   128  // TODO decide whether to rename this in the Go API to match the vSphere API.
   129  // Since 7.0.0:-
   130  type Cidr struct {
   131  	Address string `json:"address"`
   132  	Prefix  int    `json:"prefix"`
   133  }
   134  
   135  // NcpClusterNetworkSpec defines an NSX-T network for a Tanzu Kubernetes
   136  // Grid workload cluster in vSphere 7.0.0 until 7.0u1.
   137  // Note: NcpClusterNetworkSpec is replaced by WorkloadNetworksSpec in 7.0u2+.
   138  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Clusters/NCPClusterNetworkEnableSpec/
   139  // TODO decide whether to rename this in the Go API to match the vSphere API.
   140  // Since 7.0.0:-
   141  type NcpClusterNetworkSpec struct {
   142  	NsxEdgeCluster           string `json:"nsx_edge_cluster,omitempty"`
   143  	PodCidrs                 []Cidr `json:"pod_cidrs"`
   144  	EgressCidrs              []Cidr `json:"egress_cidrs"`
   145  	ClusterDistributedSwitch string `json:"cluster_distributed_switch,omitempty"`
   146  	IngressCidrs             []Cidr `json:"ingress_cidrs"`
   147  }
   148  
   149  // NsxNetwork defines a supervisor or workload NSX-T network for use with
   150  // a Tanzu Kubernetes Cluster.
   151  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Networks/NsxNetworkCreateSpec/
   152  // TODO decide whether to rename this in the Go API to match the vSphere API.
   153  // Since 7.0u3:-
   154  type NsxNetwork struct {
   155  	EgressCidrs           []Cidr `json:"egress_cidrs"`
   156  	IngressCidrs          []Cidr `json:"ingress_cidrs"`
   157  	LoadBalancerSize      string `json:"load_balancer_size"`
   158  	NamespaceNetworkCidrs []Cidr `json:"namespace_network_cidrs"`
   159  	NsxTier0Gateway       string `json:"nsx_tier0_gateway"`
   160  	RoutedMode            bool   `json:"routed_mode"`
   161  	SubnetPrefixLength    int    `json:"subnet_prefix_length"`
   162  }
   163  
   164  // IpRange specifies a contiguous set of IPv4 Addresses
   165  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/IPRange/
   166  // TODO decide whether to rename this in the Go API to match the vSphere API.
   167  // Note: omitempty allows AddressRanges: []IpRange to become json []
   168  // Since 7.0u1:-
   169  type IpRange struct {
   170  	Address string `json:"address,omitempty"`
   171  	Count   int    `json:"count,omitempty"`
   172  }
   173  
   174  // IpAssignmentMode specifies whether DHCP or a static range assignment
   175  // method is used. This is used for both Supervisor Cluster and Workload
   176  // Cluster networks in 7.0u3 and above.
   177  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Networks/IPAssignmentMode/
   178  // TODO decide whether to rename this in the Go API to match the vSphere API.
   179  // Since 7.0u3:-
   180  type IpAssignmentMode struct {
   181  	slug string
   182  }
   183  
   184  var (
   185  	UndefinedIpAssignmentMode   = IpAssignmentMode{""}
   186  	DhcpIpAssignmentMode        = IpAssignmentMode{"DHCP"}
   187  	StaticRangeIpAssignmentMode = IpAssignmentMode{"STATICRANGE"}
   188  	// NOTE: Add new types at the END of this const to preserve previous values
   189  )
   190  
   191  func (v IpAssignmentMode) String() string {
   192  	return v.slug
   193  }
   194  func (v *IpAssignmentMode) UnmarshalJSON(b []byte) error {
   195  	var s string
   196  	if err := json.Unmarshal(b, &s); nil != err {
   197  		return err
   198  	}
   199  	v.FromString(s)
   200  	return nil
   201  }
   202  
   203  func (v IpAssignmentMode) MarshalJSON() ([]byte, error) {
   204  	return json.Marshal(v.slug)
   205  }
   206  
   207  func (v *IpAssignmentMode) FromString(s string) {
   208  	v.slug = IpAssignmentModeFromString(s).slug
   209  }
   210  
   211  func IpAssignmentModeFromString(s string) IpAssignmentMode {
   212  	if "DHCP" == s {
   213  		return DhcpIpAssignmentMode
   214  	}
   215  	if "STATICRANGE" == s {
   216  		return StaticRangeIpAssignmentMode
   217  	}
   218  	return UndefinedIpAssignmentMode
   219  }
   220  
   221  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Networks/VsphereDVPGNetworkCreateSpec/
   222  // Since 7.0u1:-
   223  type VsphereDVPGNetworkCreateSpec struct {
   224  	AddressRanges []IpRange `json:"address_ranges"`
   225  	Gateway       string    `json:"gateway"`
   226  	PortGroup     string    `json:"portgroup"`
   227  	SubnetMask    string    `json:"subnet_mask"`
   228  	// Since 7.0u3:-
   229  	IpAssignmentMode *IpAssignmentMode `json:"ip_assignment_mode,omitempty"`
   230  }
   231  
   232  // NetworkProvider defines which type of
   233  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Clusters/NetworkProvider/
   234  // Since 7.0.0:-
   235  type NetworkProvider struct {
   236  	slug string
   237  }
   238  
   239  var (
   240  	UndefinedNetworkProvider           = NetworkProvider{""}
   241  	NsxtContainerPluginNetworkProvider = NetworkProvider{"NSXT_CONTAINER_PLUGIN"}
   242  	// Since 7.0u1:-
   243  	VSphereNetworkProvider = NetworkProvider{"VSPHERE_NETWORK"}
   244  	// TODO vSphere (as in product), Vsphere (as in tag), or VSphere (as in camel case)???
   245  	// E.g. see from 7.0u3: https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/NSXTier0Gateway/Summary/
   246  )
   247  
   248  func (v NetworkProvider) String() string {
   249  	return v.slug
   250  }
   251  
   252  func (v *NetworkProvider) UnmarshalJSON(b []byte) error {
   253  	var s string
   254  	if err := json.Unmarshal(b, &s); nil != err {
   255  		return err
   256  	}
   257  	v.FromString(s)
   258  	return nil
   259  }
   260  
   261  func (v NetworkProvider) MarshalJSON() ([]byte, error) {
   262  	return json.Marshal(v.slug)
   263  }
   264  
   265  func (v *NetworkProvider) FromString(s string) {
   266  	v.slug = ClusterNetworkProviderFromString(s).slug
   267  }
   268  
   269  func ClusterNetworkProviderFromString(s string) NetworkProvider {
   270  	if "NSXT_CONTAINER_PLUGIN" == s {
   271  		return NsxtContainerPluginNetworkProvider
   272  	}
   273  	if "VSPHERE_NETWORK" == s {
   274  		return VSphereNetworkProvider
   275  	}
   276  	return UndefinedNetworkProvider
   277  }
   278  
   279  // NetworksCreateSpec specifies a Tanzu Kubernetes Grid Supervisor
   280  // or Workload network that should be created.
   281  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Networks/CreateSpec/
   282  // Since 7.0u1:-
   283  type NetworksCreateSpec struct {
   284  	Network         string                        `json:"network"`
   285  	NetworkProvider *NetworkProvider              `json:"network_provider"`
   286  	VSphereNetwork  *VsphereDVPGNetworkCreateSpec `json:"vsphere_network,omitempty"`
   287  	// Since 7.0u3:-
   288  	NsxNetwork *NsxNetwork `json:"nsx_network,omitempty"`
   289  }
   290  
   291  // WorkloadNetworksEnableSpec defines the primary workload network for a new
   292  // Tanzu Kubernetes Grid supervisor cluster. This may be used by namespaces
   293  // for workloads too.
   294  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Clusters/WorkloadNetworksEnableSpec/
   295  // TODO decide whether to rename this in the Go API to match the vSphere API.
   296  // Since 7.0u1:-
   297  type WorkloadNetworksEnableSpec struct {
   298  	SupervisorPrimaryWorkloadNetwork *NetworksCreateSpec `json:"supervisor_primary_workload_network"`
   299  	// TODO also support other workload networks in network_list
   300  	//      (These are not used for EnableCluster, and so left out for now)
   301  }
   302  
   303  // LoadBalancersServer defines an Avi or HA Proxy load balancer location.
   304  // Host can be an IP Address (normally an Avi Management Virtual IP for
   305  // the Avi Controller(s)) or a hostname.
   306  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/LoadBalancers/Server/
   307  // Since 7.0u1:-
   308  type LoadBalancersServer struct {
   309  	Host string `json:"host"`
   310  	Port int    `json:"port"`
   311  }
   312  
   313  // AviConfigCreateSpec defines full information for the linking of
   314  // a Tanzu Kubernetes Grid enabled vSphere cluster to an NSX
   315  // Advanced Load Balancer (formerly Avi Load Balancer)
   316  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/LoadBalancers/AviConfigCreateSpec/
   317  // Since 7.0u2:-
   318  type AviConfigCreateSpec struct {
   319  	CertificateAuthorityChain string               `json:"certificate_authority_chain"`
   320  	Password                  string               `json:"password"`
   321  	Server                    *LoadBalancersServer `json:"server"`
   322  	Username                  string               `json:"username"`
   323  }
   324  
   325  // HAProxyConfigCreateSpec defines full information for the linking of
   326  // a Tanzu Kubernetes Grid enabled vSphere cluster to a HA Proxy
   327  // Load Balancer.
   328  // Note: HA Proxy is not supported in vSphere 7.0u3 and above. Use Avi
   329  //
   330  //	with vSphere networking, or NSX-T networking, instead.
   331  //
   332  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/LoadBalancers/HAProxyConfigCreateSpec/
   333  // Since 7.0u1:-
   334  // Deprecated: HA Proxy is being deprecated in vSphere 9.0. Use
   335  // Avi with vSphere networking, or NSX-T networking, instead.
   336  type HAProxyConfigCreateSpec struct {
   337  	CertificateAuthorityChain string                `json:"certificate_authority_chain"`
   338  	Password                  string                `json:"password"`
   339  	Servers                   []LoadBalancersServer `json:"servers"`
   340  	Username                  string                `json:"username"`
   341  }
   342  
   343  // A LoadBalancerProvider is an enum type that defines
   344  // the Load Balancer technology in use in a Tanzu Kubernetes Grid
   345  // cluster.
   346  // Note: If invalid or undefined (E.g. if a newer/older vSphere
   347  //
   348  //	version is used whose option isn't listed) then the
   349  //	UndefinedLoadBalancerProvider value shall be set.
   350  //	This translates to an empty string, removing its element
   351  //	from the produces JSON.
   352  //
   353  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/LoadBalancers/Provider/
   354  type LoadBalancerProvider struct {
   355  	slug string
   356  }
   357  
   358  var (
   359  	UndefinedLoadBalancerProvider = LoadBalancerProvider{""}
   360  	// Deprecated: HA Proxy is being deprecated in vSphere 9.0. Use
   361  	// Avi vSphere networking, or NSX-T networking, instead.
   362  	HAProxyLoadBalancerProvider = LoadBalancerProvider{"HA_PROXY"}
   363  	AviLoadBalancerProvider     = LoadBalancerProvider{"AVI"}
   364  )
   365  
   366  func (v LoadBalancerProvider) String() string {
   367  	return v.slug
   368  }
   369  
   370  func (v *LoadBalancerProvider) UnmarshalJSON(b []byte) error {
   371  	var s string
   372  	if err := json.Unmarshal(b, &s); nil != err {
   373  		return err
   374  	}
   375  	v.FromString(s)
   376  	return nil
   377  }
   378  
   379  func (v LoadBalancerProvider) MarshalJSON() ([]byte, error) {
   380  	return json.Marshal(v.slug)
   381  }
   382  
   383  func (v *LoadBalancerProvider) FromString(s string) {
   384  	v.slug = LoadBalancerFromString(s).slug
   385  }
   386  
   387  func LoadBalancerFromString(s string) LoadBalancerProvider {
   388  	if "HA_PROXY" == s {
   389  		return HAProxyLoadBalancerProvider
   390  	}
   391  	if "AVI" == s {
   392  		return AviLoadBalancerProvider
   393  	}
   394  	return UndefinedLoadBalancerProvider
   395  }
   396  
   397  // LoadBalancerConfigSpec defines LoadBalancer options for Tanzu
   398  // Kubernetes Grid, both for the Supervisor Cluster and for
   399  // Workload Cluster kubeapi endpoints, and services of type
   400  // LoadBalancer
   401  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/LoadBalancers/ConfigSpec/
   402  // Since 7.0u1:-
   403  type LoadBalancerConfigSpec struct {
   404  	// AddressRanges removed since 7.0u2:- (Now in workload network spec)
   405  	AddressRanges           []IpRange                `json:"address_ranges,omitempty"` // omitempty to prevent null being the value
   406  	HAProxyConfigCreateSpec *HAProxyConfigCreateSpec `json:"ha_proxy_config_create_spec,omitempty"`
   407  	// Optional for create:-
   408  	Id       string                `json:"id"`
   409  	Provider *LoadBalancerProvider `json:"provider"`
   410  	// Since 7.0u2:-
   411  	AviConfigCreateSpec *AviConfigCreateSpec `json:"avi_config_create_spec,omitempty"`
   412  }
   413  
   414  // Since 7.0.0:-
   415  type AddressRange struct {
   416  	SubnetMask      string `json:"subnet_mask,omitempty"`
   417  	StartingAddress string `json:"starting_address"`
   418  	Gateway         string `json:"gateway"`
   419  	AddressCount    int    `json:"address_count,omitempty"`
   420  }
   421  
   422  // Since 7.0.0:-
   423  type MasterManagementNetwork struct {
   424  	Mode         *IpAssignmentMode `json:"mode"`
   425  	FloatingIP   string            `json:"floating_IP,omitempty"`
   426  	AddressRange *AddressRange     `json:"address_range,omitempty"`
   427  	Network      string            `json:"network"`
   428  }
   429  
   430  // Since 7.0.0:-
   431  type DefaultImageRegistry struct {
   432  	Hostname string `json:"hostname"`
   433  	Port     int    `json:"port,omitempty"`
   434  }
   435  
   436  // EnableCluster enables vSphere Namespaces on the specified cluster, using the given spec.
   437  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/api/vcenter/namespace-management/clusters/clusteractionenable/post/
   438  func (c *Manager) EnableCluster(ctx context.Context, id string, spec *EnableClusterSpec) error {
   439  	var response any
   440  	url := c.Resource(path.Join(internal.NamespaceClusterPath, id)).WithParam("action", "enable")
   441  	fmt.Fprint(os.Stdout, spec)
   442  	err := c.Do(ctx, url.Request(http.MethodPost, spec), response)
   443  	return err
   444  }
   445  
   446  // EnableCluster enables vSphere Namespaces on the specified cluster, using the given spec.
   447  func (c *Manager) DisableCluster(ctx context.Context, id string) error {
   448  	var response any
   449  	url := c.Resource(path.Join(internal.NamespaceClusterPath, id)).WithParam("action", "disable")
   450  	err := c.Do(ctx, url.Request(http.MethodPost), response)
   451  	return err
   452  }
   453  
   454  type KubernetesStatus struct {
   455  	slug string
   456  }
   457  
   458  var (
   459  	UndefinedKubernetesStatus = KubernetesStatus{""}
   460  	ReadyKubernetesStatus     = KubernetesStatus{"READY"}
   461  	WarningKubernetesStatus   = KubernetesStatus{"WARNING"}
   462  	ErrorKubernetesStatus     = KubernetesStatus{"ERROR"}
   463  	// NOTE: Add new types at the END of this const to preserve previous values
   464  )
   465  
   466  func (v KubernetesStatus) String() string {
   467  	return v.slug
   468  }
   469  
   470  func (v *KubernetesStatus) UnmarshalJSON(b []byte) error {
   471  	var s string
   472  	if err := json.Unmarshal(b, &s); nil != err {
   473  		return err
   474  	}
   475  	v.FromString(s)
   476  	return nil
   477  }
   478  
   479  func (v KubernetesStatus) MarshalJSON() ([]byte, error) {
   480  	return json.Marshal(v.slug)
   481  }
   482  
   483  func (v *KubernetesStatus) FromString(s string) {
   484  	v.slug = KubernetesStatusFromString(s).slug
   485  }
   486  
   487  func KubernetesStatusFromString(s string) KubernetesStatus {
   488  	if "READY" == s {
   489  		return ReadyKubernetesStatus
   490  	}
   491  	if "WARNING" == s {
   492  		return WarningKubernetesStatus
   493  	}
   494  	if "ERROR" == s {
   495  		return ErrorKubernetesStatus
   496  	}
   497  	return UndefinedKubernetesStatus
   498  }
   499  
   500  type ConfigStatus struct {
   501  	slug string
   502  }
   503  
   504  var (
   505  	UndefinedConfigStatus   = ConfigStatus{""}
   506  	ConfiguringConfigStatus = ConfigStatus{"CONFIGURING"}
   507  	RemovingConfigStatus    = ConfigStatus{"REMOVING"}
   508  	RunningConfigStatus     = ConfigStatus{"RUNNING"}
   509  	ErrorConfigStatus       = ConfigStatus{"ERROR"}
   510  	// NOTE: Add new types at the END of this const to preserve previous values
   511  )
   512  
   513  func (v ConfigStatus) String() string {
   514  	return v.slug
   515  }
   516  
   517  func (v *ConfigStatus) UnmarshalJSON(b []byte) error {
   518  	var s string
   519  	if err := json.Unmarshal(b, &s); nil != err {
   520  		return err
   521  	}
   522  	v.FromString(s)
   523  	return nil
   524  }
   525  
   526  func (v ConfigStatus) MarshalJSON() ([]byte, error) {
   527  	return json.Marshal(v.slug)
   528  }
   529  
   530  func (v *ConfigStatus) FromString(s string) {
   531  	v.slug = ConfigStatusFromString(s).slug
   532  }
   533  
   534  func ConfigStatusFromString(s string) ConfigStatus {
   535  	if "CONFIGURING" == s {
   536  		return ConfiguringConfigStatus
   537  	}
   538  	if "REMOVING" == s {
   539  		return RemovingConfigStatus
   540  	}
   541  	if "RUNNING" == s {
   542  		return RunningConfigStatus
   543  	}
   544  	if "ERROR" == s {
   545  		return ErrorConfigStatus
   546  	}
   547  	return UndefinedConfigStatus
   548  }
   549  
   550  // TODO CHANGE ENUMS TO: https://stackoverflow.com/questions/53569573/parsing-string-to-enum-from-json-in-golang
   551  // Also: https://eagain.net/articles/go-json-kind/
   552  
   553  // ClusterSummary for a cluster with vSphere Namespaces enabled.
   554  // See https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/data-structures/NamespaceManagement/Clusters/Summary/
   555  // TODO plural vs singular - consistency with REST API above vs Go
   556  // Since 7.0.0:-
   557  type ClusterSummary struct {
   558  	ID   string `json:"cluster"`
   559  	Name string `json:"cluster_name"`
   560  	// Was string until #2860:-
   561  	KubernetesStatus *KubernetesStatus `json:"kubernetes_status"`
   562  	// Was string until #2860:-
   563  	ConfigStatus *ConfigStatus `json:"config_status"`
   564  }
   565  
   566  // TODO whether to replace the below with a Go GUID (json to string) reference type? (I.e. replace ClusterSummary.ID string with ID ManagedObjectID)
   567  // Reference implements the mo.Reference interface
   568  func (c *ClusterSummary) Reference() types.ManagedObjectReference {
   569  	return types.ManagedObjectReference{
   570  		Type:  "ClusterComputeResource",
   571  		Value: c.ID, // TODO replace with c.ID.(string) when ID changes from String to ManagedObjectID
   572  	}
   573  }
   574  
   575  // ListClusters returns a summary of all clusters with vSphere Namespaces enabled.
   576  func (c *Manager) ListClusters(ctx context.Context) ([]ClusterSummary, error) {
   577  	var res []ClusterSummary
   578  	url := c.Resource(internal.NamespaceClusterPath)
   579  	return res, c.Do(ctx, url.Request(http.MethodGet), &res)
   580  }
   581  
   582  // SupportBundleToken information about the token required in the HTTP GET request to generate the support bundle.
   583  // Since 7.0.0:-
   584  type SupportBundleToken struct {
   585  	Expiry string `json:"expiry"`
   586  	Token  string `json:"token"`
   587  }
   588  
   589  // SupportBundleLocation contains the URL to download the per-cluster support bundle from, as well as a token required.
   590  // Since 7.0.0:-
   591  type SupportBundleLocation struct {
   592  	Token SupportBundleToken `json:"wcp_support_bundle_token"`
   593  	URL   string             `json:"url"`
   594  }
   595  
   596  // CreateSupportBundle retrieves the cluster's Namespaces-related support bundle.
   597  func (c *Manager) CreateSupportBundle(ctx context.Context, id string) (*SupportBundleLocation, error) {
   598  	var res SupportBundleLocation
   599  	url := c.Resource(path.Join(internal.NamespaceClusterPath, id, "support-bundle"))
   600  	return &res, c.Do(ctx, url.Request(http.MethodPost), &res)
   601  }
   602  
   603  // SupportBundleRequest returns an http.Request which can be used to download the given support bundle.
   604  func (c *Manager) SupportBundleRequest(ctx context.Context, bundle *SupportBundleLocation) (*http.Request, error) {
   605  	token := internal.SupportBundleToken{Value: bundle.Token.Token}
   606  
   607  	var b bytes.Buffer
   608  	err := json.NewEncoder(&b).Encode(token)
   609  	if err != nil {
   610  		return nil, err
   611  	}
   612  
   613  	return http.NewRequest(http.MethodPost, bundle.URL, &b)
   614  }
   615  
   616  // Since 7.0.0:-
   617  type DistributedSwitchCompatibilitySummary struct {
   618  	Compatible        bool   `json:"compatible"`
   619  	DistributedSwitch string `json:"distributed_switch"`
   620  }
   621  
   622  func (c *Manager) ListCompatibleDistributedSwitches(ctx context.Context, clusterId string) (result []DistributedSwitchCompatibilitySummary, err error) {
   623  	listUrl := c.Resource(internal.NamespaceDistributedSwitchCompatibility).
   624  		WithParam("cluster", clusterId).
   625  		WithParam("compatible", "true")
   626  	return result, c.Do(ctx, listUrl.Request(http.MethodGet), &result)
   627  }
   628  
   629  // Since 7.0.0:-
   630  type EdgeClusterCompatibilitySummary struct {
   631  	Compatible  bool   `json:"compatible"`
   632  	EdgeCluster string `json:"edge_cluster"`
   633  	DisplayName string `json:"display_name"`
   634  }
   635  
   636  func (c *Manager) ListCompatibleEdgeClusters(ctx context.Context, clusterId string, switchId string) (result []EdgeClusterCompatibilitySummary, err error) {
   637  	listUrl := c.Resource(internal.NamespaceEdgeClusterCompatibility).
   638  		WithParam("cluster", clusterId).
   639  		WithParam("compatible", "true").
   640  		WithPathEncodedParam("distributed_switch", switchId)
   641  	return result, c.Do(ctx, listUrl.Request(http.MethodGet), &result)
   642  }
   643  
   644  // NamespacesInstanceStats https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/Namespaces/Instances/Stats/
   645  type NamespacesInstanceStats struct {
   646  	CpuUsed     int64 `json:"cpu_used"`
   647  	MemoryUsed  int64 `json:"memory_used"`
   648  	StorageUsed int64 `json:"storage_used"`
   649  }
   650  
   651  // NamespacesInstanceSummary https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/Namespaces/Instances/Summary/
   652  type NamespacesInstanceSummary struct {
   653  	ClusterId            string                  `json:"cluster"`
   654  	Namespace            string                  `json:"namespace"`
   655  	ConfigStatus         string                  `json:"config_status"`
   656  	Description          string                  `json:"description"`
   657  	Stats                NamespacesInstanceStats `json:"stats"`
   658  	SelfServiceNamespace bool                    `json:"self_service_namespace,omitempty"`
   659  }
   660  
   661  type LocalizableMessage struct {
   662  	Details  any    `json:"details"`
   663  	Severity string `json:"severity"`
   664  }
   665  
   666  // NamespacesInstanceInfo https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/Namespaces/Instances/Info/
   667  type NamespacesInstanceInfo struct {
   668  	ClusterId            string                  `json:"cluster"`
   669  	ConfigStatus         string                  `json:"config_status"`
   670  	Description          string                  `json:"description"`
   671  	Stats                NamespacesInstanceStats `json:"stats"`
   672  	SelfServiceNamespace bool                    `json:"self_service_namespace,omitempty"`
   673  	Messages             []LocalizableMessage    `json:"message"`
   674  	VmServiceSpec        VmServiceSpec           `json:"vm_service_spec,omitempty"`
   675  	StorageSpecs         []StorageSpec           `json:"storage_specs,omitempty"`
   676  }
   677  
   678  // NamespacesInstanceCreateSpec https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/Namespaces/Instances/CreateSpec/
   679  type NamespacesInstanceCreateSpec struct {
   680  	Cluster       string        `json:"cluster"`
   681  	Namespace     string        `json:"namespace"`
   682  	VmServiceSpec VmServiceSpec `json:"vm_service_spec,omitempty"`
   683  	StorageSpecs  []StorageSpec `json:"storage_specs,omitempty"`
   684  }
   685  
   686  // VmServiceSpec https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/Namespaces/Instances/VMServiceSpec/
   687  type VmServiceSpec struct {
   688  	ContentLibraries []string `json:"content_libraries,omitempty"`
   689  	VmClasses        []string `json:"vm_classes,omitempty"`
   690  }
   691  
   692  // StorageSpec https://developer.broadcom.com/apis/vsphere-automation-api/v7.0U3/vcenter/data-structures/Namespaces_Instances_StorageSpec/
   693  type StorageSpec struct {
   694  	Policy string `json:"policy"`
   695  	Limit  int64  `json:"limit,omitempty"`
   696  }
   697  
   698  // NamespacesInstanceUpdateSpec https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/Namespaces/Instances/UpdateSpec/
   699  type NamespacesInstanceUpdateSpec struct {
   700  	VmServiceSpec VmServiceSpec `json:"vm_service_spec,omitempty"`
   701  	StorageSpecs  []StorageSpec `json:"storage_specs,omitempty"`
   702  }
   703  
   704  // ListNamespaces https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespaces/instances/get/
   705  func (c *Manager) ListNamespaces(ctx context.Context) ([]NamespacesInstanceSummary, error) {
   706  	resource := c.Resource(internal.NamespacesPath)
   707  	request := resource.Request(http.MethodGet)
   708  	var result []NamespacesInstanceSummary
   709  	return result, c.Do(ctx, request, &result)
   710  }
   711  
   712  // GetNamespace https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespaces/instances/namespace/get/
   713  func (c *Manager) GetNamespace(ctx context.Context, namespace string) (NamespacesInstanceInfo, error) {
   714  	resource := c.Resource(internal.NamespacesPath).WithSubpath(namespace)
   715  	request := resource.Request(http.MethodGet)
   716  	var result NamespacesInstanceInfo
   717  	return result, c.Do(ctx, request, &result)
   718  }
   719  
   720  // CreateNamespace https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespaces/instances/post/
   721  func (c *Manager) CreateNamespace(ctx context.Context, spec NamespacesInstanceCreateSpec) error {
   722  	resource := c.Resource(internal.NamespacesPath)
   723  	request := resource.Request(http.MethodPost, spec)
   724  	return c.Do(ctx, request, nil)
   725  }
   726  
   727  // UpdateNamespace https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespaces/instances/namespace/patch/
   728  func (c *Manager) UpdateNamespace(ctx context.Context, namespace string, spec NamespacesInstanceUpdateSpec) error {
   729  	resource := c.Resource(internal.NamespacesPath).WithSubpath(namespace)
   730  	request := resource.Request(http.MethodPatch, spec)
   731  	return c.Do(ctx, request, nil)
   732  }
   733  
   734  // DeleteNamespace https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespaces/instances/namespace/delete/
   735  func (c *Manager) DeleteNamespace(ctx context.Context, namespace string) error {
   736  	resource := c.Resource(internal.NamespacesPath).WithSubpath(namespace)
   737  	request := resource.Request(http.MethodDelete)
   738  	return c.Do(ctx, request, nil)
   739  }
   740  
   741  // RegisterVM https://developer.broadcom.com/xapis/vsphere-automation-api/latest/vcenter/api/vcenter/namespaces/instances/namespace/registervm/post/
   742  func (c *Manager) RegisterVM(ctx context.Context, namespace string, spec RegisterVMSpec) (string, error) {
   743  	resource := c.Resource(internal.NamespacesPath).WithSubpath(namespace).WithSubpath("registervm")
   744  	request := resource.Request(http.MethodPost, spec)
   745  	var task string
   746  	return task, c.Do(ctx, request, &task)
   747  }
   748  
   749  // VirtualMachineClassInfo https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/NamespaceManagement/VirtualMachineClasses/Info/
   750  type VirtualMachineClassInfo struct {
   751  	ConfigStatus      string               `json:"config_status"`
   752  	Description       string               `json:"description"`
   753  	Id                string               `json:"id"`
   754  	CpuCount          int64                `json:"cpu_count"`
   755  	MemoryMb          int64                `json:"memory_mb"`
   756  	Messages          []LocalizableMessage `json:"messages"`
   757  	Namespaces        []string             `json:"namespaces"`
   758  	Vms               []string             `json:"vms"`
   759  	Devices           VirtualDevices       `json:"devices"`
   760  	CpuReservation    int64                `json:"cpu_reservation,omitempty"`
   761  	MemoryReservation int64                `json:"memory_reservation,omitempty"`
   762  }
   763  
   764  // VirtualMachineClassCreateSpec https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/NamespaceManagement/VirtualMachineClasses/CreateSpec/
   765  type VirtualMachineClassCreateSpec struct {
   766  	Id                string         `json:"id"`
   767  	CpuCount          int64          `json:"cpu_count"`
   768  	MemoryMb          int64          `json:"memory_MB"`
   769  	CpuReservation    int64          `json:"cpu_reservation,omitempty"`
   770  	MemoryReservation int64          `json:"memory_reservation,omitempty"`
   771  	Devices           VirtualDevices `json:"devices"`
   772  }
   773  
   774  // VirtualMachineClassUpdateSpec https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/NamespaceManagement/VirtualMachineClasses/UpdateSpec/
   775  type VirtualMachineClassUpdateSpec struct {
   776  	Id                string         `json:"id"`
   777  	CpuCount          int64          `json:"cpu_count"`
   778  	MemoryMb          int64          `json:"memory_MB"`
   779  	CpuReservation    int64          `json:"cpu_reservation,omitempty"`
   780  	MemoryReservation int64          `json:"memory_reservation,omitempty"`
   781  	Devices           VirtualDevices `json:"devices"`
   782  }
   783  
   784  // DirectPathIoDevice https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/NamespaceManagement/VirtualMachineClasses/DynamicDirectPathIODevice/
   785  type DirectPathIoDevice struct {
   786  	CustomLabel string `json:"custom_label,omitempty"`
   787  	DeviceId    int64  `json:"device_id"`
   788  	VendorId    int64  `json:"vendor_id"`
   789  }
   790  
   791  // VgpuDevice https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/NamespaceManagement/VirtualMachineClasses/VGPUDevice/
   792  type VgpuDevice struct {
   793  	ProfileName string `json:"profile_name"`
   794  }
   795  
   796  // VirtualDevices https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/data-structures/NamespaceManagement/VirtualMachineClasses/VirtualDevices/
   797  type VirtualDevices struct {
   798  	DirectPathIoDevices []DirectPathIoDevice `json:"direct_path_io_devices,omitempty"`
   799  	VgpuDevices         []VgpuDevice         `json:"vgpu_devices,omitempty"`
   800  }
   801  
   802  // RegisterVMSpec https://developer.broadcom.com/xapis/vsphere-automation-api/latest/vcenter/data-structures/Namespaces_Instances_RegisterVMSpec/
   803  type RegisterVMSpec struct {
   804  	VM string `json:"vm"`
   805  }
   806  
   807  // ListVmClasses https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespace-management/virtual-machine-classes/get/
   808  func (c *Manager) ListVmClasses(ctx context.Context) ([]VirtualMachineClassInfo, error) {
   809  	resource := c.Resource(internal.VmClassesPath)
   810  	request := resource.Request(http.MethodGet)
   811  	var result []VirtualMachineClassInfo
   812  	return result, c.Do(ctx, request, &result)
   813  }
   814  
   815  // GetVmClass https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespace-management/virtual-machine-classes/vm_class/get/
   816  func (c *Manager) GetVmClass(ctx context.Context, vmClass string) (VirtualMachineClassInfo, error) {
   817  	resource := c.Resource(internal.VmClassesPath).WithSubpath(vmClass)
   818  	request := resource.Request(http.MethodGet)
   819  	var result VirtualMachineClassInfo
   820  	return result, c.Do(ctx, request, &result)
   821  }
   822  
   823  // CreateVmClass https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespace-management/virtual-machine-classes/post/
   824  func (c *Manager) CreateVmClass(ctx context.Context, spec VirtualMachineClassCreateSpec) error {
   825  	resource := c.Resource(internal.VmClassesPath)
   826  	request := resource.Request(http.MethodPost, spec)
   827  	return c.Do(ctx, request, nil)
   828  }
   829  
   830  // DeleteVmClass https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespace-management/virtual-machine-classes/vm_class/delete/
   831  func (c *Manager) DeleteVmClass(ctx context.Context, vmClass string) error {
   832  	resource := c.Resource(internal.VmClassesPath).WithSubpath(vmClass)
   833  	request := resource.Request(http.MethodDelete)
   834  	return c.Do(ctx, request, nil)
   835  }
   836  
   837  // UpdateVmClass https://developer.vmware.com/apis/vsphere-automation/v7.0U3/vcenter/api/vcenter/namespace-management/virtual-machine-classes/vm_class/patch/
   838  func (c *Manager) UpdateVmClass(ctx context.Context, vmClass string, spec VirtualMachineClassUpdateSpec) error {
   839  	resource := c.Resource(internal.VmClassesPath).WithSubpath(vmClass)
   840  	request := resource.Request(http.MethodPatch, spec)
   841  	return c.Do(ctx, request, nil)
   842  }