github.com/vmware/govmomi@v0.37.2/cns/client.go (about)

     1  /*
     2  Copyright (c) 2019 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 cns
    18  
    19  import (
    20  	"context"
    21  
    22  	"github.com/vmware/govmomi/cns/methods"
    23  	cnstypes "github.com/vmware/govmomi/cns/types"
    24  	"github.com/vmware/govmomi/object"
    25  	"github.com/vmware/govmomi/vim25"
    26  	"github.com/vmware/govmomi/vim25/soap"
    27  	vimtypes "github.com/vmware/govmomi/vim25/types"
    28  )
    29  
    30  // Namespace and Path constants
    31  const (
    32  	Namespace = "vsan"
    33  	Path      = "/vsanHealth"
    34  )
    35  
    36  const (
    37  	ReleaseVSAN67u3 = "vSAN 6.7U3"
    38  	ReleaseVSAN70   = "7.0"
    39  	ReleaseVSAN70u1 = "vSAN 7.0U1"
    40  )
    41  
    42  var (
    43  	CnsVolumeManagerInstance = vimtypes.ManagedObjectReference{
    44  		Type:  "CnsVolumeManager",
    45  		Value: "cns-volume-manager",
    46  	}
    47  	CnsDebugManagerInstance = vimtypes.ManagedObjectReference{
    48  		Type:  "CnsDebugManager",
    49  		Value: "cns-debug-manager",
    50  	}
    51  )
    52  
    53  type Client struct {
    54  	*soap.Client
    55  
    56  	RoundTripper soap.RoundTripper
    57  
    58  	vim25Client *vim25.Client
    59  }
    60  
    61  // NewClient creates a new CNS client
    62  func NewClient(ctx context.Context, c *vim25.Client) (*Client, error) {
    63  	sc := c.Client.NewServiceClient(Path, Namespace)
    64  
    65  	// Use current vCenter vsan version by default
    66  	err := sc.UseServiceVersion(Namespace)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	// PropertyCollector related methods (task.Wait) need to send requests to vim25.Path (/sdk).
    72  	// This vim25.Client shares the same http.Transport and Namespace/Version, but requests to '/sdk'
    73  	rt := sc.NewServiceClient(vim25.Path, Namespace)
    74  	rt.Version = sc.Version
    75  
    76  	vc := &vim25.Client{
    77  		ServiceContent: c.ServiceContent,
    78  		Client:         rt,
    79  		RoundTripper:   rt,
    80  	}
    81  
    82  	return &Client{sc, sc, vc}, nil
    83  }
    84  
    85  // RoundTrip dispatches to the RoundTripper field.
    86  func (c *Client) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
    87  	return c.RoundTripper.RoundTrip(ctx, req, res)
    88  }
    89  
    90  // CreateVolume calls the CNS create API.
    91  func (c *Client) CreateVolume(ctx context.Context, createSpecList []cnstypes.CnsVolumeCreateSpec) (*object.Task, error) {
    92  	createSpecList = dropUnknownCreateSpecElements(c, createSpecList)
    93  	req := cnstypes.CnsCreateVolume{
    94  		This:        CnsVolumeManagerInstance,
    95  		CreateSpecs: createSpecList,
    96  	}
    97  	res, err := methods.CnsCreateVolume(ctx, c, &req)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  	return object.NewTask(c.vim25Client, res.Returnval), nil
   102  }
   103  
   104  // UpdateVolumeMetadata calls the CNS CnsUpdateVolumeMetadata API with UpdateSpecs specified in the argument
   105  func (c *Client) UpdateVolumeMetadata(ctx context.Context, updateSpecList []cnstypes.CnsVolumeMetadataUpdateSpec) (*object.Task, error) {
   106  	updateSpecList = dropUnknownVolumeMetadataUpdateSpecElements(c, updateSpecList)
   107  	req := cnstypes.CnsUpdateVolumeMetadata{
   108  		This:        CnsVolumeManagerInstance,
   109  		UpdateSpecs: updateSpecList,
   110  	}
   111  	res, err := methods.CnsUpdateVolumeMetadata(ctx, c, &req)
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  	return object.NewTask(c.vim25Client, res.Returnval), nil
   116  }
   117  
   118  // DeleteVolume calls the CNS delete API.
   119  func (c *Client) DeleteVolume(ctx context.Context, volumeIDList []cnstypes.CnsVolumeId, deleteDisk bool) (*object.Task, error) {
   120  	req := cnstypes.CnsDeleteVolume{
   121  		This:       CnsVolumeManagerInstance,
   122  		VolumeIds:  volumeIDList,
   123  		DeleteDisk: deleteDisk,
   124  	}
   125  	res, err := methods.CnsDeleteVolume(ctx, c, &req)
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  	return object.NewTask(c.vim25Client, res.Returnval), nil
   130  }
   131  
   132  // ExtendVolume calls the CNS Extend API.
   133  func (c *Client) ExtendVolume(ctx context.Context, extendSpecList []cnstypes.CnsVolumeExtendSpec) (*object.Task, error) {
   134  	req := cnstypes.CnsExtendVolume{
   135  		This:        CnsVolumeManagerInstance,
   136  		ExtendSpecs: extendSpecList,
   137  	}
   138  	res, err := methods.CnsExtendVolume(ctx, c, &req)
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  	return object.NewTask(c.vim25Client, res.Returnval), nil
   143  }
   144  
   145  // AttachVolume calls the CNS Attach API.
   146  func (c *Client) AttachVolume(ctx context.Context, attachSpecList []cnstypes.CnsVolumeAttachDetachSpec) (*object.Task, error) {
   147  	req := cnstypes.CnsAttachVolume{
   148  		This:        CnsVolumeManagerInstance,
   149  		AttachSpecs: attachSpecList,
   150  	}
   151  	res, err := methods.CnsAttachVolume(ctx, c, &req)
   152  	if err != nil {
   153  		return nil, err
   154  	}
   155  	return object.NewTask(c.vim25Client, res.Returnval), nil
   156  }
   157  
   158  // DetachVolume calls the CNS Detach API.
   159  func (c *Client) DetachVolume(ctx context.Context, detachSpecList []cnstypes.CnsVolumeAttachDetachSpec) (*object.Task, error) {
   160  	req := cnstypes.CnsDetachVolume{
   161  		This:        CnsVolumeManagerInstance,
   162  		DetachSpecs: detachSpecList,
   163  	}
   164  	res, err := methods.CnsDetachVolume(ctx, c, &req)
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	return object.NewTask(c.vim25Client, res.Returnval), nil
   169  }
   170  
   171  // QueryVolume calls the CNS QueryVolume API.
   172  func (c *Client) QueryVolume(ctx context.Context, queryFilter cnstypes.CnsQueryFilter) (*cnstypes.CnsQueryResult, error) {
   173  	req := cnstypes.CnsQueryVolume{
   174  		This:   CnsVolumeManagerInstance,
   175  		Filter: queryFilter,
   176  	}
   177  	res, err := methods.CnsQueryVolume(ctx, c, &req)
   178  	if err != nil {
   179  		return nil, err
   180  	}
   181  	return &res.Returnval, nil
   182  }
   183  
   184  // QueryVolumeInfo calls the CNS QueryVolumeInfo API and return a task, from which we can extract VolumeInfo
   185  // containing VStorageObject
   186  func (c *Client) QueryVolumeInfo(ctx context.Context, volumeIDList []cnstypes.CnsVolumeId) (*object.Task, error) {
   187  	req := cnstypes.CnsQueryVolumeInfo{
   188  		This:      CnsVolumeManagerInstance,
   189  		VolumeIds: volumeIDList,
   190  	}
   191  	res, err := methods.CnsQueryVolumeInfo(ctx, c, &req)
   192  	if err != nil {
   193  		return nil, err
   194  	}
   195  	return object.NewTask(c.vim25Client, res.Returnval), nil
   196  }
   197  
   198  // QueryAllVolume calls the CNS QueryAllVolume API.
   199  func (c *Client) QueryAllVolume(ctx context.Context, queryFilter cnstypes.CnsQueryFilter, querySelection cnstypes.CnsQuerySelection) (*cnstypes.CnsQueryResult, error) {
   200  	req := cnstypes.CnsQueryAllVolume{
   201  		This:      CnsVolumeManagerInstance,
   202  		Filter:    queryFilter,
   203  		Selection: querySelection,
   204  	}
   205  	res, err := methods.CnsQueryAllVolume(ctx, c, &req)
   206  	if err != nil {
   207  		return nil, err
   208  	}
   209  	return &res.Returnval, nil
   210  }
   211  
   212  // QueryVolumeAsync calls the CNS QueryAsync API and return a task, from which we can extract CnsQueryResult
   213  func (c *Client) QueryVolumeAsync(ctx context.Context, queryFilter cnstypes.CnsQueryFilter, querySelection *cnstypes.CnsQuerySelection) (*object.Task, error) {
   214  	req := cnstypes.CnsQueryAsync{
   215  		This:      CnsVolumeManagerInstance,
   216  		Filter:    queryFilter,
   217  		Selection: querySelection,
   218  	}
   219  	res, err := methods.CnsQueryAsync(ctx, c, &req)
   220  	if err != nil {
   221  		return nil, err
   222  	}
   223  	return object.NewTask(c.vim25Client, res.Returnval), nil
   224  }
   225  
   226  // RelocateVolume calls the CNS Relocate API.
   227  func (c *Client) RelocateVolume(ctx context.Context, relocateSpecs ...cnstypes.BaseCnsVolumeRelocateSpec) (*object.Task, error) {
   228  	req := cnstypes.CnsRelocateVolume{
   229  		This:          CnsVolumeManagerInstance,
   230  		RelocateSpecs: relocateSpecs,
   231  	}
   232  	res, err := methods.CnsRelocateVolume(ctx, c, &req)
   233  	if err != nil {
   234  		return nil, err
   235  	}
   236  	return object.NewTask(c.vim25Client, res.Returnval), nil
   237  }
   238  
   239  // ConfigureVolumeACLs calls the CNS Configure ACL API.
   240  func (c *Client) ConfigureVolumeACLs(ctx context.Context, aclConfigSpecs ...cnstypes.CnsVolumeACLConfigureSpec) (*object.Task, error) {
   241  	req := cnstypes.CnsConfigureVolumeACLs{
   242  		This:           CnsVolumeManagerInstance,
   243  		ACLConfigSpecs: aclConfigSpecs,
   244  	}
   245  	res, err := methods.CnsConfigureVolumeACLs(ctx, c, &req)
   246  	if err != nil {
   247  		return nil, err
   248  	}
   249  	return object.NewTask(c.vim25Client, res.Returnval), nil
   250  }
   251  
   252  // CreateSnapshots calls the CNS CreateSnapshots API
   253  
   254  func (c *Client) CreateSnapshots(ctx context.Context, snapshotCreateSpecList []cnstypes.CnsSnapshotCreateSpec) (*object.Task, error) {
   255  	req := cnstypes.CnsCreateSnapshots{
   256  		This:          CnsVolumeManagerInstance,
   257  		SnapshotSpecs: snapshotCreateSpecList,
   258  	}
   259  	res, err := methods.CnsCreateSnapshots(ctx, c, &req)
   260  	if err != nil {
   261  		return nil, err
   262  	}
   263  
   264  	return object.NewTask(c.vim25Client, res.Returnval), nil
   265  }
   266  
   267  // DeleteSnapshots calls the CNS DeleteSnapshots API
   268  func (c *Client) DeleteSnapshots(ctx context.Context, snapshotDeleteSpecList []cnstypes.CnsSnapshotDeleteSpec) (*object.Task, error) {
   269  	req := cnstypes.CnsDeleteSnapshots{
   270  		This:                CnsVolumeManagerInstance,
   271  		SnapshotDeleteSpecs: snapshotDeleteSpecList,
   272  	}
   273  	res, err := methods.CnsDeleteSnapshots(ctx, c, &req)
   274  	if err != nil {
   275  		return nil, err
   276  	}
   277  	return object.NewTask(c.vim25Client, res.Returnval), nil
   278  }
   279  
   280  // QuerySnapshots calls the CNS QuerySnapshots API
   281  func (c *Client) QuerySnapshots(ctx context.Context, snapshotQueryFilter cnstypes.CnsSnapshotQueryFilter) (*object.Task, error) {
   282  	req := cnstypes.CnsQuerySnapshots{
   283  		This:                CnsVolumeManagerInstance,
   284  		SnapshotQueryFilter: snapshotQueryFilter,
   285  	}
   286  	res, err := methods.CnsQuerySnapshots(ctx, c, &req)
   287  	if err != nil {
   288  		return nil, err
   289  	}
   290  	return object.NewTask(c.vim25Client, res.Returnval), nil
   291  }
   292  
   293  // ReconfigVolumePolicy calls the CnsReconfigVolumePolicy API
   294  func (c *Client) ReconfigVolumePolicy(ctx context.Context, PolicyReconfigSpecs []cnstypes.CnsVolumePolicyReconfigSpec) (*object.Task, error) {
   295  	req := cnstypes.CnsReconfigVolumePolicy{
   296  		This:                      CnsVolumeManagerInstance,
   297  		VolumePolicyReconfigSpecs: PolicyReconfigSpecs,
   298  	}
   299  	res, err := methods.CnsReconfigVolumePolicy(ctx, c, &req)
   300  	if err != nil {
   301  		return nil, err
   302  	}
   303  	return object.NewTask(c.vim25Client, res.Returnval), nil
   304  }
   305  
   306  // SyncDatastore calls the CnsSyncDatastore API
   307  // Note: To be used only by VMware's internal support tools.
   308  // This API triggers a manual sync of internal CNS and FCD DBs which otherwise happens periodially,
   309  // with fullsync it forces synchronization of complete tables.
   310  func (c *Client) SyncDatastore(ctx context.Context, dsURL string, fullSync bool) (*object.Task, error) {
   311  	req := cnstypes.CnsSyncDatastore{
   312  		This:         CnsDebugManagerInstance,
   313  		DatastoreUrl: dsURL,
   314  		FullSync:     &fullSync,
   315  	}
   316  	res, err := methods.CnsSyncDatastore(ctx, c, &req)
   317  	if err != nil {
   318  		return nil, err
   319  	}
   320  	return object.NewTask(c.vim25Client, res.Returnval), nil
   321  }