github.com/vmware/govmomi@v0.51.0/vslm/global_object_manager.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 vslm 6 7 import ( 8 "context" 9 "time" 10 11 "github.com/vmware/govmomi/object" 12 "github.com/vmware/govmomi/vim25/mo" 13 "github.com/vmware/govmomi/vim25/soap" 14 vim "github.com/vmware/govmomi/vim25/types" 15 "github.com/vmware/govmomi/vslm/methods" 16 "github.com/vmware/govmomi/vslm/types" 17 ) 18 19 type Task struct { 20 c *Client 21 object.Common 22 vim.ManagedObjectReference 23 } 24 25 func NewTask(client *Client, mref vim.ManagedObjectReference) *Task { 26 m := Task{ 27 ManagedObjectReference: mref, 28 c: client, 29 } 30 return &m 31 } 32 33 func (this *Task) QueryResult(ctx context.Context) (vim.AnyType, error) { 34 req := types.VslmQueryTaskResult{ 35 This: this.ManagedObjectReference, 36 } 37 res, err := methods.VslmQueryTaskResult(ctx, this.c, &req) 38 if err != nil { 39 return nil, err 40 } 41 return res.Returnval, nil 42 } 43 44 func (this *Task) QueryInfo(ctx context.Context) (*types.VslmTaskInfo, error) { 45 req := types.VslmQueryInfo{ 46 This: this.ManagedObjectReference, 47 } 48 res, err := methods.VslmQueryInfo(ctx, this.c, &req) 49 if err != nil { 50 return nil, err 51 } 52 return &res.Returnval, nil 53 } 54 55 func (this *Task) Cancel(ctx context.Context) error { 56 req := types.VslmCancelTask{ 57 This: this.ManagedObjectReference, 58 } 59 _, err := methods.VslmCancelTask(ctx, this.c, &req) 60 return err 61 } 62 63 func (this *Task) Wait(ctx context.Context, timeoutNS time.Duration) (vim.AnyType, error) { 64 return this.WaitNonDefault(ctx, timeoutNS, 10000, true, 10000000) 65 } 66 67 func (this *Task) WaitNonDefault(ctx context.Context, timeoutNS time.Duration, startIntervalNS time.Duration, 68 exponential bool, maxIntervalNS time.Duration) (vim.AnyType, error) { 69 waitIntervalNS := startIntervalNS 70 startTimeNS := time.Now() 71 for time.Now().Sub(startTimeNS) < timeoutNS { 72 info, err := this.QueryInfo(ctx) 73 if err != nil { 74 return nil, err 75 } 76 if info.State == types.VslmTaskInfoStateQueued || info.State == types.VslmTaskInfoStateRunning { 77 time.Sleep(waitIntervalNS) 78 if exponential { 79 waitIntervalNS = waitIntervalNS * 2 80 if maxIntervalNS > 0 && waitIntervalNS > maxIntervalNS { 81 waitIntervalNS = maxIntervalNS 82 } 83 } 84 } else if info.State == types.VslmTaskInfoStateError { 85 return nil, soap.WrapVimFault(info.Error.Fault) 86 } else { 87 break 88 } 89 // Check context here to see if we should exit 90 } 91 return this.QueryResult(ctx) 92 } 93 94 type GlobalObjectManager struct { 95 vim.ManagedObjectReference 96 c *Client 97 } 98 99 // NewGlobalObjectManager returns an ObjectManager referecing the vslm VcenterVStorageObjectManager endpoint. 100 // This endpoint is always connected to vpxd and utilizes the global catalog to locate objects and does 101 // not require a datastore. To connect to the VStorageObjectManager on the host or in vpxd use the 102 // vslm.ObjectManager type. 103 func NewGlobalObjectManager(client *Client) *GlobalObjectManager { 104 mref := client.ServiceContent.VStorageObjectManager 105 106 m := GlobalObjectManager{ 107 ManagedObjectReference: mref, 108 c: client, 109 } 110 111 return &m 112 } 113 114 func (this *GlobalObjectManager) CreateDisk(ctx context.Context, spec vim.VslmCreateSpec) (*Task, error) { 115 req := types.VslmCreateDisk_Task{ 116 This: this.Reference(), 117 Spec: spec, 118 } 119 120 res, err := methods.VslmCreateDisk_Task(ctx, this.c, &req) 121 if err != nil { 122 return nil, err 123 } 124 125 return NewTask(this.c, res.Returnval), nil 126 } 127 128 func (this *GlobalObjectManager) RegisterDisk(ctx context.Context, path string, name string) (*vim.VStorageObject, error) { 129 req := types.VslmRegisterDisk{ 130 This: this.Reference(), 131 Path: path, 132 Name: name, 133 } 134 135 res, err := methods.VslmRegisterDisk(ctx, this.c, &req) 136 if err != nil { 137 return nil, err 138 } 139 140 return &res.Returnval, nil 141 } 142 143 func (this *GlobalObjectManager) ExtendDisk(ctx context.Context, id vim.ID, newCapacityInMB int64) (*Task, error) { 144 req := types.VslmExtendDisk_Task{ 145 This: this.Reference(), 146 Id: id, 147 NewCapacityInMB: newCapacityInMB, 148 } 149 150 res, err := methods.VslmExtendDisk_Task(ctx, this.c, &req) 151 if err != nil { 152 return nil, err 153 } 154 155 return NewTask(this.c, res.Returnval), nil 156 } 157 158 func (this *GlobalObjectManager) InflateDisk(ctx context.Context, id vim.ID) (*Task, error) { 159 req := types.VslmInflateDisk_Task{ 160 This: this.Reference(), 161 Id: id, 162 } 163 164 res, err := methods.VslmInflateDisk_Task(ctx, this.c, &req) 165 if err != nil { 166 return nil, err 167 } 168 169 return NewTask(this.c, res.Returnval), nil 170 } 171 172 func (this *GlobalObjectManager) Rename(ctx context.Context, id vim.ID, name string) error { 173 req := types.VslmRenameVStorageObject{ 174 This: this.Reference(), 175 Id: id, 176 Name: name, 177 } 178 179 _, err := methods.VslmRenameVStorageObject(ctx, this.c, &req) 180 181 return err 182 } 183 184 func (this *GlobalObjectManager) UpdatePolicy(ct context.Context, id vim.ID, profile []vim.VirtualMachineProfileSpec) ( 185 *Task, error) { 186 req := types.VslmUpdateVstorageObjectPolicy_Task{ 187 This: this.Reference(), 188 Id: id, 189 Profile: profile, 190 } 191 192 res, err := methods.VslmUpdateVstorageObjectPolicy_Task(ct, this.c, &req) 193 194 if err != nil { 195 return nil, err 196 } 197 198 return NewTask(this.c, res.Returnval), nil 199 } 200 201 func (this *GlobalObjectManager) UpdateInfrastructurePolicy(ct context.Context, 202 spec vim.VslmInfrastructureObjectPolicySpec) (*Task, error) { 203 req := types.VslmUpdateVStorageInfrastructureObjectPolicy_Task{ 204 This: this.Reference(), 205 Spec: spec, 206 } 207 208 res, err := methods.VslmUpdateVStorageInfrastructureObjectPolicy_Task(ct, this.c, &req) 209 210 if err != nil { 211 return nil, err 212 } 213 214 return NewTask(this.c, res.Returnval), nil 215 } 216 217 func (this *GlobalObjectManager) RetrieveInfrastructurePolicy(ct context.Context, datastore mo.Reference) ( 218 []vim.VslmInfrastructureObjectPolicy, error) { 219 req := types.VslmRetrieveVStorageInfrastructureObjectPolicy{ 220 This: this.Reference(), 221 Datastore: datastore.Reference(), 222 } 223 224 res, err := methods.VslmRetrieveVStorageInfrastructureObjectPolicy(ct, this.c, &req) 225 if err != nil { 226 return nil, err 227 } 228 229 return res.Returnval, nil 230 } 231 232 func (this *GlobalObjectManager) Delete(ctx context.Context, id vim.ID) (*Task, error) { 233 req := types.VslmDeleteVStorageObject_Task{ 234 This: this.Reference(), 235 Id: id, 236 } 237 238 res, err := methods.VslmDeleteVStorageObject_Task(ctx, this.c, &req) 239 if err != nil { 240 return nil, err 241 } 242 243 return NewTask(this.c, res.Returnval), nil 244 } 245 246 func (this *GlobalObjectManager) Retrieve(ctx context.Context, id vim.ID) (*vim.VStorageObject, error) { 247 req := types.VslmRetrieveVStorageObject{ 248 This: this.Reference(), 249 Id: id, 250 } 251 252 res, err := methods.VslmRetrieveVStorageObject(ctx, this.c, &req) 253 if err != nil { 254 return nil, err 255 } 256 257 return &res.Returnval, nil 258 } 259 260 func (this *GlobalObjectManager) RetrieveState(ct context.Context, id vim.ID) (*vim.VStorageObjectStateInfo, error) { 261 req := types.VslmRetrieveVStorageObjectState{ 262 This: this.Reference(), 263 Id: id, 264 } 265 266 res, err := methods.VslmRetrieveVStorageObjectState(ct, this.c, &req) 267 if err != nil { 268 return nil, err 269 } 270 271 return &res.Returnval, nil 272 } 273 274 func (this *GlobalObjectManager) RetrieveAssociations(ct context.Context, ids []vim.ID) ( 275 []types.VslmVsoVStorageObjectAssociations, error) { 276 req := types.VslmRetrieveVStorageObjectAssociations{ 277 This: this.Reference(), 278 Ids: ids, 279 } 280 281 res, err := methods.VslmRetrieveVStorageObjectAssociations(ct, this.c, &req) 282 if err != nil { 283 return nil, err 284 } 285 286 return res.Returnval, nil 287 } 288 289 func (this *GlobalObjectManager) ListObjectsForSpec(ctx context.Context, query []types.VslmVsoVStorageObjectQuerySpec, 290 maxResult int32) (*types.VslmVsoVStorageObjectQueryResult, error) { 291 req := types.VslmListVStorageObjectForSpec{ 292 This: this.Reference(), 293 Query: query, 294 MaxResult: maxResult, 295 } 296 297 res, err := methods.VslmListVStorageObjectForSpec(ctx, this.c, &req) 298 if err != nil { 299 return nil, err 300 } 301 302 return res.Returnval, nil 303 } 304 305 var DefaultMaxResults = 100 306 307 // List wraps ListObjectsForSpec, using maxResult = DefaultMaxResults 308 // and looping until AllRecordsReturned == true or error is returned. 309 func (this *GlobalObjectManager) List(ctx context.Context, qs ...types.VslmVsoVStorageObjectQuerySpec) (*types.VslmVsoVStorageObjectQueryResult, error) { 310 var res types.VslmVsoVStorageObjectQueryResult 311 312 query := qs 313 314 for { 315 page, err := this.ListObjectsForSpec(ctx, query, int32(DefaultMaxResults)) 316 if err != nil { 317 return nil, err 318 } 319 320 res.Id = append(res.Id, page.Id...) 321 res.QueryResults = append(res.QueryResults, page.QueryResults...) 322 res.AllRecordsReturned = page.AllRecordsReturned 323 324 if page.AllRecordsReturned || len(page.Id) == 0 { 325 break 326 } 327 328 spec := types.VslmVsoVStorageObjectQuerySpec{ 329 QueryField: string(types.VslmVsoVStorageObjectQuerySpecQueryFieldEnumId), 330 QueryOperator: string(types.VslmVsoVStorageObjectQuerySpecQueryOperatorEnumGreaterThan), 331 QueryValue: []string{page.Id[len(page.Id)-1].Id}, 332 } 333 334 query = append(qs, spec) 335 } 336 337 return &res, nil 338 } 339 340 func (this *GlobalObjectManager) Clone(ctx context.Context, id vim.ID, spec vim.VslmCloneSpec) (*Task, error) { 341 req := types.VslmCloneVStorageObject_Task{ 342 This: this.Reference(), 343 Id: id, 344 Spec: spec, 345 } 346 347 res, err := methods.VslmCloneVStorageObject_Task(ctx, this.c, &req) 348 if err != nil { 349 return nil, err 350 } 351 352 return NewTask(this.c, res.Returnval), nil 353 } 354 355 func (this *GlobalObjectManager) Relocate(ct context.Context, id vim.ID, spec vim.VslmRelocateSpec) (*Task, error) { 356 req := types.VslmRelocateVStorageObject_Task{ 357 This: this.Reference(), 358 Id: id, 359 Spec: spec, 360 } 361 362 res, err := methods.VslmRelocateVStorageObject_Task(ct, this.c, &req) 363 364 if err != nil { 365 return nil, err 366 } 367 368 return NewTask(this.c, res.Returnval), nil 369 } 370 371 func (this *GlobalObjectManager) SetControlFlags(ct context.Context, id vim.ID, controlFlags []string) error { 372 req := types.VslmSetVStorageObjectControlFlags{ 373 This: this.Reference(), 374 Id: id, 375 ControlFlags: controlFlags, 376 } 377 378 _, err := methods.VslmSetVStorageObjectControlFlags(ct, this.c, &req) 379 if err != nil { 380 return err 381 } 382 383 return nil 384 } 385 386 func (this *GlobalObjectManager) ClearControlFlags(ct context.Context, id vim.ID) error { 387 req := types.VslmClearVStorageObjectControlFlags{ 388 This: this.Reference(), 389 Id: id, 390 } 391 392 _, err := methods.VslmClearVStorageObjectControlFlags(ct, this.c, &req) 393 394 return err 395 } 396 397 func (this *GlobalObjectManager) AttachTag(ctx context.Context, id vim.ID, category string, tag string) error { 398 req := types.VslmAttachTagToVStorageObject{ 399 This: this.Reference(), 400 Id: id, 401 Category: category, 402 Tag: tag, 403 } 404 405 _, err := methods.VslmAttachTagToVStorageObject(ctx, this.c, &req) 406 407 return err 408 } 409 410 func (this *GlobalObjectManager) DetachTag(ctx context.Context, id vim.ID, category string, tag string) error { 411 req := types.VslmDetachTagFromVStorageObject{ 412 This: this.Reference(), 413 Id: id, 414 Category: category, 415 Tag: tag, 416 } 417 418 _, err := methods.VslmDetachTagFromVStorageObject(ctx, this.c, &req) 419 420 return err 421 } 422 423 func (this *GlobalObjectManager) ListAttachedObjects(ctx context.Context, category string, tag string) ( 424 []vim.ID, error) { 425 req := types.VslmListVStorageObjectsAttachedToTag{ 426 This: this.Reference(), 427 Category: category, 428 Tag: tag, 429 } 430 431 res, err := methods.VslmListVStorageObjectsAttachedToTag(ctx, this.c, &req) 432 if err != nil { 433 return nil, err 434 } 435 436 return res.Returnval, err 437 } 438 439 func (this *GlobalObjectManager) ListAttachedTags(ctx context.Context, id vim.ID) ([]vim.VslmTagEntry, error) { 440 req := types.VslmListTagsAttachedToVStorageObject{ 441 This: this.Reference(), 442 Id: id, 443 } 444 445 res, err := methods.VslmListTagsAttachedToVStorageObject(ctx, this.c, &req) 446 if err != nil { 447 return nil, err 448 } 449 450 return res.Returnval, nil 451 } 452 453 func (this *GlobalObjectManager) ReconcileDatastoreInventory(ctx context.Context, datastore mo.Reference) (*Task, error) { 454 req := &types.VslmReconcileDatastoreInventory_Task{ 455 This: this.Reference(), 456 Datastore: datastore.Reference(), 457 } 458 459 res, err := methods.VslmReconcileDatastoreInventory_Task(ctx, this.c, req) 460 if err != nil { 461 return nil, err 462 } 463 return NewTask(this.c, res.Returnval), nil 464 } 465 466 func (this *GlobalObjectManager) ScheduleReconcileDatastoreInventory(ctx context.Context, datastore mo.Reference) error { 467 req := &types.VslmScheduleReconcileDatastoreInventory{ 468 This: this.Reference(), 469 Datastore: datastore.Reference(), 470 } 471 472 _, err := methods.VslmScheduleReconcileDatastoreInventory(ctx, this.c, req) 473 474 return err 475 } 476 477 func (this *GlobalObjectManager) CreateSnapshot(ctx context.Context, id vim.ID, description string) (*Task, error) { 478 req := types.VslmCreateSnapshot_Task{ 479 This: this.Reference(), 480 Id: id, 481 Description: description, 482 } 483 484 res, err := methods.VslmCreateSnapshot_Task(ctx, this.c, &req) 485 if err != nil { 486 return nil, err 487 } 488 489 return NewTask(this.c, res.Returnval), nil 490 } 491 492 func (this *GlobalObjectManager) DeleteSnapshot(ctx context.Context, id vim.ID, snapshotID vim.ID) (*Task, error) { 493 req := types.VslmDeleteSnapshot_Task{ 494 This: this.Reference(), 495 Id: id, 496 SnapshotId: snapshotID, 497 } 498 499 res, err := methods.VslmDeleteSnapshot_Task(ctx, this.c, &req) 500 if err != nil { 501 return nil, err 502 } 503 504 return NewTask(this.c, res.Returnval), nil 505 } 506 507 func (this *GlobalObjectManager) RetrieveSnapshotInfo(ctx context.Context, id vim.ID) ( 508 []vim.VStorageObjectSnapshotInfoVStorageObjectSnapshot, error) { 509 req := types.VslmRetrieveSnapshotInfo{ 510 This: this.Reference(), 511 Id: id, 512 } 513 514 res, err := methods.VslmRetrieveSnapshotInfo(ctx, this.c, &req) 515 if err != nil { 516 return nil, err 517 } 518 519 return res.Returnval.Snapshots, nil 520 } 521 522 func (this *GlobalObjectManager) CreateDiskFromSnapshot(ctx context.Context, id vim.ID, snapshotId vim.ID, name string, 523 profile []vim.VirtualMachineProfileSpec, crypto *vim.CryptoSpec, 524 path string) (*Task, error) { 525 req := types.VslmCreateDiskFromSnapshot_Task{ 526 This: this.Reference(), 527 Id: id, 528 SnapshotId: snapshotId, 529 Name: name, 530 Profile: profile, 531 Crypto: crypto, 532 Path: path, 533 } 534 535 res, err := methods.VslmCreateDiskFromSnapshot_Task(ctx, this.c, &req) 536 if err != nil { 537 return nil, err 538 } 539 540 return NewTask(this.c, res.Returnval), nil 541 } 542 543 func (this *GlobalObjectManager) Revert(ctx context.Context, id vim.ID, snapshotID vim.ID) (*Task, error) { 544 req := types.VslmRevertVStorageObject_Task{ 545 This: this.Reference(), 546 Id: id, 547 SnapshotId: snapshotID, 548 } 549 550 res, err := methods.VslmRevertVStorageObject_Task(ctx, this.c, &req) 551 if err != nil { 552 return nil, err 553 } 554 555 return NewTask(this.c, res.Returnval), nil 556 } 557 558 func (this *GlobalObjectManager) RetrieveSnapshotDetails(ctx context.Context, id vim.ID, snapshotId vim.ID) ( 559 *vim.VStorageObjectSnapshotDetails, error) { 560 req := types.VslmRetrieveSnapshotDetails{ 561 This: this.Reference(), 562 Id: id, 563 SnapshotId: snapshotId, 564 } 565 566 res, err := methods.VslmRetrieveSnapshotDetails(ctx, this.c, &req) 567 if err != nil { 568 return nil, err 569 } 570 571 return &res.Returnval, nil 572 } 573 574 func (this *GlobalObjectManager) QueryChangedDiskAreas(ctx context.Context, id vim.ID, snapshotId vim.ID, startOffset int64, 575 changeId string) (*vim.DiskChangeInfo, error) { 576 req := types.VslmQueryChangedDiskAreas{ 577 This: this.Reference(), 578 Id: id, 579 SnapshotId: snapshotId, 580 StartOffset: startOffset, 581 ChangeId: changeId, 582 } 583 584 res, err := methods.VslmQueryChangedDiskAreas(ctx, this.c, &req) 585 if err != nil { 586 return nil, err 587 } 588 589 return &res.Returnval, nil 590 } 591 592 func (this *GlobalObjectManager) QueryGlobalCatalogSyncStatus(ct context.Context) ([]types.VslmDatastoreSyncStatus, error) { 593 req := types.VslmQueryGlobalCatalogSyncStatus{ 594 This: this.Reference(), 595 } 596 597 res, err := methods.VslmQueryGlobalCatalogSyncStatus(ct, this.c, &req) 598 if err != nil { 599 return nil, err 600 } 601 602 return res.Returnval, nil 603 } 604 605 func (this *GlobalObjectManager) QueryGlobalCatalogSyncStatusForDatastore(ct context.Context, datastoreURL string) ( 606 *types.VslmDatastoreSyncStatus, error) { 607 req := types.VslmQueryGlobalCatalogSyncStatusForDatastore{ 608 This: this.Reference(), 609 DatastoreURL: datastoreURL, 610 } 611 612 res, err := methods.VslmQueryGlobalCatalogSyncStatusForDatastore(ct, this.c, &req) 613 if err != nil { 614 return nil, err 615 } 616 617 return res.Returnval, nil 618 } 619 620 func (this *GlobalObjectManager) UpdateMetadata(ctx context.Context, id vim.ID, metadata []vim.KeyValue, 621 deleteKeys []string) (*Task, error) { 622 req := &types.VslmUpdateVStorageObjectMetadata_Task{ 623 This: this.Reference(), 624 Id: id, 625 Metadata: metadata, 626 DeleteKeys: deleteKeys, 627 } 628 629 res, err := methods.VslmUpdateVStorageObjectMetadata_Task(ctx, this.c, req) 630 if err != nil { 631 return nil, err 632 } 633 return NewTask(this.c, res.Returnval), nil 634 } 635 636 func (this *GlobalObjectManager) RetrieveMetadata(ct context.Context, id vim.ID, snapshotID *vim.ID, prefix string) ( 637 []vim.KeyValue, error) { 638 req := types.VslmRetrieveVStorageObjectMetadata{ 639 This: this.Reference(), 640 Id: id, 641 SnapshotId: snapshotID, 642 Prefix: prefix, 643 } 644 645 res, err := methods.VslmRetrieveVStorageObjectMetadata(ct, this.c, &req) 646 if err != nil { 647 return nil, err 648 } 649 650 return res.Returnval, nil 651 } 652 653 func (this *GlobalObjectManager) RetrieveMetadataValue(ct context.Context, id vim.ID, snapshotID *vim.ID, key string) ( 654 string, error) { 655 req := types.VslmRetrieveVStorageObjectMetadataValue{ 656 This: this.Reference(), 657 Id: id, 658 SnapshotId: snapshotID, 659 Key: key, 660 } 661 662 res, err := methods.VslmRetrieveVStorageObjectMetadataValue(ct, this.c, &req) 663 if err != nil { 664 return "", err 665 } 666 667 return res.Returnval, nil 668 } 669 670 func (this *GlobalObjectManager) RetrieveObjects(ct context.Context, ids []vim.ID) ([]types.VslmVsoVStorageObjectResult, 671 error) { 672 req := types.VslmRetrieveVStorageObjects{ 673 This: this.Reference(), 674 Ids: ids, 675 } 676 677 res, err := methods.VslmRetrieveVStorageObjects(ct, this.c, &req) 678 if err != nil { 679 return nil, err 680 } 681 682 return res.Returnval, nil 683 } 684 685 func (this *GlobalObjectManager) AttachDisk(ct context.Context, id vim.ID, vm mo.Reference, controllerKey int32, 686 unitNumber *int32) (*Task, error) { 687 req := types.VslmAttachDisk_Task{ 688 This: this.Reference(), 689 Id: id, 690 Vm: vm.Reference(), 691 ControllerKey: controllerKey, 692 UnitNumber: unitNumber, 693 } 694 695 res, err := methods.VslmAttachDisk_Task(ct, this.c, &req) 696 if err != nil { 697 return nil, err 698 } 699 700 return NewTask(this.c, res.Returnval), nil 701 }