github.com/vmware/govmomi@v0.37.1/pbm/client.go (about)

     1  /*
     2  Copyright (c) 2017 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 pbm
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  
    23  	"github.com/vmware/govmomi/pbm/methods"
    24  	"github.com/vmware/govmomi/pbm/types"
    25  	"github.com/vmware/govmomi/vim25"
    26  	"github.com/vmware/govmomi/vim25/soap"
    27  	vim "github.com/vmware/govmomi/vim25/types"
    28  )
    29  
    30  const (
    31  	Namespace = "pbm"
    32  	Path      = "/pbm"
    33  )
    34  
    35  var (
    36  	ServiceInstance = vim.ManagedObjectReference{
    37  		Type:  "PbmServiceInstance",
    38  		Value: "ServiceInstance",
    39  	}
    40  )
    41  
    42  type Client struct {
    43  	*soap.Client
    44  
    45  	ServiceContent types.PbmServiceInstanceContent
    46  
    47  	RoundTripper soap.RoundTripper
    48  }
    49  
    50  func NewClient(ctx context.Context, c *vim25.Client) (*Client, error) {
    51  	sc := c.Client.NewServiceClient(Path, Namespace)
    52  
    53  	req := types.PbmRetrieveServiceContent{
    54  		This: ServiceInstance,
    55  	}
    56  
    57  	res, err := methods.PbmRetrieveServiceContent(ctx, sc, &req)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  
    62  	return &Client{sc, res.Returnval, sc}, nil
    63  }
    64  
    65  // RoundTrip dispatches to the RoundTripper field.
    66  func (c *Client) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
    67  	return c.RoundTripper.RoundTrip(ctx, req, res)
    68  }
    69  
    70  func (c *Client) QueryProfile(ctx context.Context, rtype types.PbmProfileResourceType, category string) ([]types.PbmProfileId, error) {
    71  	req := types.PbmQueryProfile{
    72  		This:            c.ServiceContent.ProfileManager,
    73  		ResourceType:    rtype,
    74  		ProfileCategory: category,
    75  	}
    76  
    77  	res, err := methods.PbmQueryProfile(ctx, c, &req)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	return res.Returnval, nil
    83  }
    84  
    85  func (c *Client) RetrieveContent(ctx context.Context, ids []types.PbmProfileId) ([]types.BasePbmProfile, error) {
    86  	req := types.PbmRetrieveContent{
    87  		This:       c.ServiceContent.ProfileManager,
    88  		ProfileIds: ids,
    89  	}
    90  
    91  	res, err := methods.PbmRetrieveContent(ctx, c, &req)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	return res.Returnval, nil
    97  }
    98  
    99  type PlacementCompatibilityResult []types.PbmPlacementCompatibilityResult
   100  
   101  func (c *Client) CheckRequirements(ctx context.Context, hubs []types.PbmPlacementHub, ref *types.PbmServerObjectRef, preq []types.BasePbmPlacementRequirement) (PlacementCompatibilityResult, error) {
   102  	req := types.PbmCheckRequirements{
   103  		This:                        c.ServiceContent.PlacementSolver,
   104  		HubsToSearch:                hubs,
   105  		PlacementSubjectRef:         ref,
   106  		PlacementSubjectRequirement: preq,
   107  	}
   108  
   109  	res, err := methods.PbmCheckRequirements(ctx, c, &req)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  
   114  	return res.Returnval, nil
   115  }
   116  
   117  func (l PlacementCompatibilityResult) CompatibleDatastores() []types.PbmPlacementHub {
   118  	var compatibleDatastores []types.PbmPlacementHub
   119  
   120  	for _, res := range l {
   121  		if len(res.Error) == 0 {
   122  			compatibleDatastores = append(compatibleDatastores, res.Hub)
   123  		}
   124  	}
   125  	return compatibleDatastores
   126  }
   127  
   128  func (l PlacementCompatibilityResult) NonCompatibleDatastores() []types.PbmPlacementHub {
   129  	var nonCompatibleDatastores []types.PbmPlacementHub
   130  
   131  	for _, res := range l {
   132  		if len(res.Error) > 0 {
   133  			nonCompatibleDatastores = append(nonCompatibleDatastores, res.Hub)
   134  		}
   135  	}
   136  	return nonCompatibleDatastores
   137  }
   138  
   139  func (c *Client) CreateProfile(ctx context.Context, capabilityProfileCreateSpec types.PbmCapabilityProfileCreateSpec) (*types.PbmProfileId, error) {
   140  	req := types.PbmCreate{
   141  		This:       c.ServiceContent.ProfileManager,
   142  		CreateSpec: capabilityProfileCreateSpec,
   143  	}
   144  
   145  	res, err := methods.PbmCreate(ctx, c, &req)
   146  	if err != nil {
   147  		return nil, err
   148  	}
   149  
   150  	return &res.Returnval, nil
   151  }
   152  
   153  func (c *Client) UpdateProfile(ctx context.Context, id types.PbmProfileId, updateSpec types.PbmCapabilityProfileUpdateSpec) error {
   154  	req := types.PbmUpdate{
   155  		This:       c.ServiceContent.ProfileManager,
   156  		ProfileId:  id,
   157  		UpdateSpec: updateSpec,
   158  	}
   159  
   160  	_, err := methods.PbmUpdate(ctx, c, &req)
   161  	if err != nil {
   162  		return err
   163  	}
   164  
   165  	return nil
   166  }
   167  
   168  func (c *Client) DeleteProfile(ctx context.Context, ids []types.PbmProfileId) ([]types.PbmProfileOperationOutcome, error) {
   169  	req := types.PbmDelete{
   170  		This:      c.ServiceContent.ProfileManager,
   171  		ProfileId: ids,
   172  	}
   173  
   174  	res, err := methods.PbmDelete(ctx, c, &req)
   175  	if err != nil {
   176  		return nil, err
   177  	}
   178  
   179  	return res.Returnval, nil
   180  }
   181  
   182  func (c *Client) QueryAssociatedEntity(ctx context.Context, id types.PbmProfileId, entityType string) ([]types.PbmServerObjectRef, error) {
   183  	req := types.PbmQueryAssociatedEntity{
   184  		This:       c.ServiceContent.ProfileManager,
   185  		Profile:    id,
   186  		EntityType: entityType,
   187  	}
   188  
   189  	res, err := methods.PbmQueryAssociatedEntity(ctx, c, &req)
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  
   194  	return res.Returnval, nil
   195  }
   196  
   197  func (c *Client) QueryAssociatedEntities(ctx context.Context, ids []types.PbmProfileId) ([]types.PbmQueryProfileResult, error) {
   198  	req := types.PbmQueryAssociatedEntities{
   199  		This:     c.ServiceContent.ProfileManager,
   200  		Profiles: ids,
   201  	}
   202  
   203  	res, err := methods.PbmQueryAssociatedEntities(ctx, c, &req)
   204  	if err != nil {
   205  		return nil, err
   206  	}
   207  
   208  	return res.Returnval, nil
   209  }
   210  
   211  func (c *Client) ProfileIDByName(ctx context.Context, profileName string) (string, error) {
   212  	resourceType := types.PbmProfileResourceType{
   213  		ResourceType: string(types.PbmProfileResourceTypeEnumSTORAGE),
   214  	}
   215  	category := types.PbmProfileCategoryEnumREQUIREMENT
   216  	ids, err := c.QueryProfile(ctx, resourceType, string(category))
   217  	if err != nil {
   218  		return "", err
   219  	}
   220  
   221  	profiles, err := c.RetrieveContent(ctx, ids)
   222  	if err != nil {
   223  		return "", err
   224  	}
   225  
   226  	for i := range profiles {
   227  		profile := profiles[i].GetPbmProfile()
   228  		if profile.Name == profileName {
   229  			return profile.ProfileId.UniqueId, nil
   230  		}
   231  	}
   232  	return "", fmt.Errorf("no pbm profile found with name: %q", profileName)
   233  }
   234  
   235  func (c *Client) FetchCapabilityMetadata(ctx context.Context, rtype *types.PbmProfileResourceType, vendorUuid string) ([]types.PbmCapabilityMetadataPerCategory, error) {
   236  	req := types.PbmFetchCapabilityMetadata{
   237  		This:         c.ServiceContent.ProfileManager,
   238  		ResourceType: rtype,
   239  		VendorUuid:   vendorUuid,
   240  	}
   241  
   242  	res, err := methods.PbmFetchCapabilityMetadata(ctx, c, &req)
   243  	if err != nil {
   244  		return nil, err
   245  	}
   246  
   247  	return res.Returnval, nil
   248  }
   249  
   250  func (c *Client) FetchComplianceResult(ctx context.Context, entities []types.PbmServerObjectRef) ([]types.PbmComplianceResult, error) {
   251  	req := types.PbmFetchComplianceResult{
   252  		This:     c.ServiceContent.ComplianceManager,
   253  		Entities: entities,
   254  	}
   255  
   256  	res, err := methods.PbmFetchComplianceResult(ctx, c, &req)
   257  	if err != nil {
   258  		return nil, err
   259  	}
   260  
   261  	return res.Returnval, nil
   262  }
   263  
   264  // GetProfileNameByID gets storage profile name by ID
   265  func (c *Client) GetProfileNameByID(ctx context.Context, profileID string) (string, error) {
   266  	resourceType := types.PbmProfileResourceType{
   267  		ResourceType: string(types.PbmProfileResourceTypeEnumSTORAGE),
   268  	}
   269  	category := types.PbmProfileCategoryEnumREQUIREMENT
   270  	ids, err := c.QueryProfile(ctx, resourceType, string(category))
   271  	if err != nil {
   272  		return "", err
   273  	}
   274  
   275  	profiles, err := c.RetrieveContent(ctx, ids)
   276  	if err != nil {
   277  		return "", err
   278  	}
   279  
   280  	for i := range profiles {
   281  		profile := profiles[i].GetPbmProfile()
   282  		if profile.ProfileId.UniqueId == profileID {
   283  			return profile.Name, nil
   284  		}
   285  	}
   286  	return "", fmt.Errorf("no pbm profile found with id: %q", profileID)
   287  }
   288  
   289  func (c *Client) QueryAssociatedProfile(ctx context.Context, entity types.PbmServerObjectRef) ([]types.PbmProfileId, error) {
   290  	req := types.PbmQueryAssociatedProfile{
   291  		This:   c.ServiceContent.ProfileManager,
   292  		Entity: entity,
   293  	}
   294  
   295  	res, err := methods.PbmQueryAssociatedProfile(ctx, c, &req)
   296  	if err != nil {
   297  		return nil, err
   298  	}
   299  
   300  	return res.Returnval, nil
   301  }
   302  
   303  func (c *Client) QueryAssociatedProfiles(ctx context.Context, entities []types.PbmServerObjectRef) ([]types.PbmQueryProfileResult, error) {
   304  	req := types.PbmQueryAssociatedProfiles{
   305  		This:     c.ServiceContent.ProfileManager,
   306  		Entities: entities,
   307  	}
   308  
   309  	res, err := methods.PbmQueryAssociatedProfiles(ctx, c, &req)
   310  	if err != nil {
   311  		return nil, err
   312  	}
   313  
   314  	return res.Returnval, nil
   315  }