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