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 }