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