github.com/vmware/govmomi@v0.51.0/ssoadmin/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 ssoadmin 6 7 import ( 8 "context" 9 "fmt" 10 "math" 11 "path" 12 "reflect" 13 "strings" 14 15 "github.com/vmware/govmomi/internal" 16 "github.com/vmware/govmomi/lookup" 17 ltypes "github.com/vmware/govmomi/lookup/types" 18 "github.com/vmware/govmomi/ssoadmin/methods" 19 "github.com/vmware/govmomi/ssoadmin/types" 20 "github.com/vmware/govmomi/vim25" 21 "github.com/vmware/govmomi/vim25/soap" 22 vim "github.com/vmware/govmomi/vim25/types" 23 ) 24 25 const ( 26 Namespace = "sso" 27 Version = "version2" 28 basePath = "/sso-adminserver" 29 Path = basePath + vim25.Path 30 SystemPath = basePath + "/system-sdk" 31 ) 32 33 var ( 34 ServiceInstance = vim.ManagedObjectReference{ 35 Type: "SsoAdminServiceInstance", 36 Value: "SsoAdminServiceInstance", 37 } 38 ) 39 40 type Client struct { 41 *soap.Client 42 43 RoundTripper soap.RoundTripper 44 ServiceContent types.AdminServiceContent 45 GroupCheck types.GroupcheckServiceContent 46 Domain string 47 Limit int32 48 } 49 50 func init() { 51 // Fault types are not in the ssoadmin.wsdl 52 vim.Add("SsoFaultNotAuthenticated", reflect.TypeOf((*vim.NotAuthenticated)(nil)).Elem()) 53 vim.Add("SsoFaultNoPermission", reflect.TypeOf((*vim.NoPermission)(nil)).Elem()) 54 vim.Add("SsoFaultInvalidCredentials", reflect.TypeOf((*vim.InvalidLogin)(nil)).Elem()) 55 vim.Add("SsoAdminFaultDuplicateSolutionCertificateFaultFault", reflect.TypeOf((*vim.InvalidArgument)(nil)).Elem()) 56 } 57 58 func getEndpointURL(ctx context.Context, c *vim25.Client) string { 59 // Services running on vCenter can bypass lookup service using the 60 // system-sdk path. This avoids the need to lookup the system domain. 61 if useSidecar := internal.UsingEnvoySidecar(c); useSidecar { 62 return fmt.Sprintf("http://%s%s", c.URL().Host, SystemPath) 63 } 64 return getEndpointURLFromLookupService(ctx, c) 65 } 66 67 func getEndpointURLFromLookupService(ctx context.Context, c *vim25.Client) string { 68 filter := <ypes.LookupServiceRegistrationFilter{ 69 ServiceType: <ypes.LookupServiceRegistrationServiceType{ 70 Product: "com.vmware.cis", 71 Type: "cs.identity", 72 }, 73 EndpointType: <ypes.LookupServiceRegistrationEndpointType{ 74 Protocol: "vmomi", 75 Type: "com.vmware.cis.cs.identity.admin", 76 }, 77 } 78 79 return lookup.EndpointURL(ctx, c, Path, filter) 80 } 81 82 func NewClient(ctx context.Context, c *vim25.Client) (*Client, error) { 83 url := getEndpointURL(ctx, c) 84 sc := c.NewServiceClient(url, Namespace) 85 sc.Version = Version 86 87 admin := &Client{ 88 Client: sc, 89 RoundTripper: sc, 90 Domain: "vsphere.local", // Default 91 Limit: math.MaxInt32, 92 } 93 if url != Path && !internal.UsingEnvoySidecar(c) { 94 admin.Domain = path.Base(url) 95 } 96 97 { 98 req := types.SsoAdminServiceInstance{ 99 This: ServiceInstance, 100 } 101 102 res, err := methods.SsoAdminServiceInstance(ctx, admin, &req) 103 if err != nil { 104 return nil, err 105 } 106 107 admin.ServiceContent = res.Returnval 108 } 109 110 { 111 req := types.SsoGroupcheckServiceInstance{ 112 This: vim.ManagedObjectReference{ 113 Type: "SsoGroupcheckServiceInstance", Value: "ServiceInstance", 114 }, 115 } 116 117 res, err := methods.SsoGroupcheckServiceInstance(ctx, admin, &req) 118 if err != nil { 119 return nil, err 120 } 121 122 admin.GroupCheck = res.Returnval 123 } 124 125 return admin, nil 126 } 127 128 // RoundTrip dispatches to the RoundTripper field. 129 func (c *Client) RoundTrip(ctx context.Context, req, res soap.HasFault) error { 130 // Drop any operationID header, not used by ssoadmin 131 ctx = context.WithValue(ctx, vim.ID{}, "") 132 return c.RoundTripper.RoundTrip(ctx, req, res) 133 } 134 135 func (c *Client) parseID(name string) types.PrincipalId { 136 p := strings.SplitN(name, "@", 2) 137 id := types.PrincipalId{Name: p[0]} 138 if len(p) == 2 { 139 id.Domain = p[1] 140 } else { 141 id.Domain = c.Domain 142 } 143 return id 144 } 145 146 func (c *Client) CreateSolutionUser(ctx context.Context, name string, details types.AdminSolutionDetails) error { 147 req := types.CreateLocalSolutionUser{ 148 This: c.ServiceContent.PrincipalManagementService, 149 UserName: name, 150 UserDetails: details, 151 } 152 153 _, err := methods.CreateLocalSolutionUser(ctx, c, &req) 154 return err 155 } 156 157 func (c *Client) UpdateLocalPasswordPolicy(ctx context.Context, policy types.AdminPasswordPolicy) error { 158 req := types.UpdateLocalPasswordPolicy{ 159 This: c.ServiceContent.PasswordPolicyService, 160 Policy: policy, 161 } 162 163 _, err := methods.UpdateLocalPasswordPolicy(ctx, c, &req) 164 return err 165 } 166 167 func (c *Client) UpdateSolutionUser(ctx context.Context, name string, details types.AdminSolutionDetails) error { 168 req := types.UpdateLocalSolutionUserDetails{ 169 This: c.ServiceContent.PrincipalManagementService, 170 UserName: name, 171 UserDetails: details, 172 } 173 174 _, err := methods.UpdateLocalSolutionUserDetails(ctx, c, &req) 175 return err 176 } 177 178 func (c *Client) DeletePrincipal(ctx context.Context, name string) error { 179 req := types.DeleteLocalPrincipal{ 180 This: c.ServiceContent.PrincipalManagementService, 181 PrincipalName: name, 182 } 183 184 _, err := methods.DeleteLocalPrincipal(ctx, c, &req) 185 return err 186 } 187 188 func (c *Client) AddUsersToGroup(ctx context.Context, groupName string, userIDs ...types.PrincipalId) error { 189 req := types.AddUsersToLocalGroup{ 190 This: c.ServiceContent.PrincipalManagementService, 191 GroupName: groupName, 192 UserIds: userIDs, 193 } 194 195 _, err := methods.AddUsersToLocalGroup(ctx, c, &req) 196 return err 197 } 198 199 func (c *Client) RemoveUsersFromGroup(ctx context.Context, groupName string, userIDs ...types.PrincipalId) error { 200 req := types.RemovePrincipalsFromLocalGroup{ 201 This: c.ServiceContent.PrincipalManagementService, 202 GroupName: groupName, 203 PrincipalsIds: userIDs, 204 } 205 206 _, err := methods.RemovePrincipalsFromLocalGroup(ctx, c, &req) 207 return err 208 } 209 210 func (c *Client) AddGroupsToGroup(ctx context.Context, groupName string, groupIDs ...types.PrincipalId) error { 211 req := types.AddGroupsToLocalGroup{ 212 This: c.ServiceContent.PrincipalManagementService, 213 GroupName: groupName, 214 GroupIds: groupIDs, 215 } 216 217 _, err := methods.AddGroupsToLocalGroup(ctx, c, &req) 218 return err 219 } 220 221 func (c *Client) CreateGroup(ctx context.Context, name string, details types.AdminGroupDetails) error { 222 req := types.CreateLocalGroup{ 223 This: c.ServiceContent.PrincipalManagementService, 224 GroupName: name, 225 GroupDetails: details, 226 } 227 228 _, err := methods.CreateLocalGroup(ctx, c, &req) 229 return err 230 } 231 232 func (c *Client) UpdateGroup(ctx context.Context, name string, details types.AdminGroupDetails) error { 233 req := types.UpdateLocalGroupDetails{ 234 This: c.ServiceContent.PrincipalManagementService, 235 GroupName: name, 236 GroupDetails: details, 237 } 238 239 _, err := methods.UpdateLocalGroupDetails(ctx, c, &req) 240 return err 241 } 242 243 func (c *Client) CreatePersonUser(ctx context.Context, name string, details types.AdminPersonDetails, password string) error { 244 req := types.CreateLocalPersonUser{ 245 This: c.ServiceContent.PrincipalManagementService, 246 UserName: name, 247 UserDetails: details, 248 Password: password, 249 } 250 251 _, err := methods.CreateLocalPersonUser(ctx, c, &req) 252 return err 253 } 254 255 func (c *Client) UpdatePersonUser(ctx context.Context, name string, details types.AdminPersonDetails) error { 256 req := types.UpdateLocalPersonUserDetails{ 257 This: c.ServiceContent.PrincipalManagementService, 258 UserName: name, 259 UserDetails: details, 260 } 261 262 _, err := methods.UpdateLocalPersonUserDetails(ctx, c, &req) 263 return err 264 } 265 266 func (c *Client) ResetPersonPassword(ctx context.Context, name string, password string) error { 267 req := types.ResetLocalPersonUserPassword{ 268 This: c.ServiceContent.PrincipalManagementService, 269 UserName: name, 270 NewPassword: password, 271 } 272 273 _, err := methods.ResetLocalPersonUserPassword(ctx, c, &req) 274 return err 275 } 276 277 func (c *Client) FindSolutionUser(ctx context.Context, name string) (*types.AdminSolutionUser, error) { 278 req := types.FindSolutionUser{ 279 This: c.ServiceContent.PrincipalDiscoveryService, 280 UserName: name, 281 } 282 283 res, err := methods.FindSolutionUser(ctx, c, &req) 284 if err != nil { 285 return nil, err 286 } 287 288 return res.Returnval, nil 289 } 290 291 func (c *Client) FindPersonUser(ctx context.Context, name string) (*types.AdminPersonUser, error) { 292 req := types.FindPersonUser{ 293 This: c.ServiceContent.PrincipalDiscoveryService, 294 UserId: c.parseID(name), 295 } 296 297 res, err := methods.FindPersonUser(ctx, c, &req) 298 if err != nil { 299 return nil, err 300 } 301 302 return res.Returnval, nil 303 } 304 305 func (c *Client) FindUser(ctx context.Context, name string) (*types.AdminUser, error) { 306 req := types.FindUser{ 307 This: c.ServiceContent.PrincipalDiscoveryService, 308 UserId: c.parseID(name), 309 } 310 311 res, err := methods.FindUser(ctx, c, &req) 312 if err != nil { 313 return nil, err 314 } 315 316 return res.Returnval, nil 317 } 318 319 func (c *Client) FindSolutionUsers(ctx context.Context, search string) ([]types.AdminSolutionUser, error) { 320 req := types.FindSolutionUsers{ 321 This: c.ServiceContent.PrincipalDiscoveryService, 322 SearchString: search, 323 Limit: c.Limit, 324 } 325 326 res, err := methods.FindSolutionUsers(ctx, c, &req) 327 if err != nil { 328 return nil, err 329 } 330 331 return res.Returnval, nil 332 } 333 334 func (c *Client) FindPersonUsers(ctx context.Context, search string) ([]types.AdminPersonUser, error) { 335 req := types.FindPersonUsers{ 336 This: c.ServiceContent.PrincipalDiscoveryService, 337 Criteria: types.AdminPrincipalDiscoveryServiceSearchCriteria{ 338 Domain: c.Domain, 339 SearchString: search, 340 }, 341 Limit: c.Limit, 342 } 343 344 res, err := methods.FindPersonUsers(ctx, c, &req) 345 if err != nil { 346 return nil, err 347 } 348 349 return res.Returnval, nil 350 } 351 352 func (c *Client) FindGroup(ctx context.Context, name string) (*types.AdminGroup, error) { 353 req := types.FindGroup{ 354 This: c.ServiceContent.PrincipalDiscoveryService, 355 GroupId: c.parseID(name), 356 } 357 358 res, err := methods.FindGroup(ctx, c, &req) 359 if err != nil { 360 return nil, err 361 } 362 363 return res.Returnval, nil 364 } 365 366 func (c *Client) FindGroups(ctx context.Context, search string) ([]types.AdminGroup, error) { 367 req := types.FindGroups{ 368 This: c.ServiceContent.PrincipalDiscoveryService, 369 Criteria: types.AdminPrincipalDiscoveryServiceSearchCriteria{ 370 Domain: c.Domain, 371 SearchString: search, 372 }, 373 Limit: c.Limit, 374 } 375 376 res, err := methods.FindGroups(ctx, c, &req) 377 if err != nil { 378 return nil, err 379 } 380 381 return res.Returnval, nil 382 } 383 384 func (c *Client) FindUsersInGroup(ctx context.Context, name string, search string) ([]types.AdminUser, error) { 385 req := types.FindUsersInGroup{ 386 This: c.ServiceContent.PrincipalDiscoveryService, 387 GroupId: c.parseID(name), 388 SearchString: search, 389 Limit: c.Limit, 390 } 391 392 res, err := methods.FindUsersInGroup(ctx, c, &req) 393 if err != nil { 394 return nil, err 395 } 396 397 return res.Returnval, nil 398 } 399 400 func (c *Client) FindGroupsInGroup(ctx context.Context, name string, search string) ([]types.AdminGroup, error) { 401 req := types.FindGroupsInGroup{ 402 This: c.ServiceContent.PrincipalDiscoveryService, 403 GroupId: c.parseID(name), 404 SearchString: search, 405 Limit: c.Limit, 406 } 407 408 res, err := methods.FindGroupsInGroup(ctx, c, &req) 409 if err != nil { 410 return nil, err 411 } 412 413 return res.Returnval, nil 414 } 415 416 func (c *Client) FindParentGroups(ctx context.Context, id types.PrincipalId, groups ...types.PrincipalId) ([]types.PrincipalId, error) { 417 if len(groups) == 0 { 418 req := types.FindAllParentGroups{ 419 This: c.GroupCheck.GroupCheckService, 420 UserId: id, 421 } 422 res, err := methods.FindAllParentGroups(ctx, c, &req) 423 if err != nil { 424 return nil, err 425 } 426 return res.Returnval, nil 427 } 428 429 return nil, nil 430 } 431 432 func (c *Client) GetLocalPasswordPolicy(ctx context.Context) (*types.AdminPasswordPolicy, error) { 433 req := types.GetLocalPasswordPolicy{ 434 This: c.ServiceContent.PasswordPolicyService, 435 } 436 437 res, err := methods.GetLocalPasswordPolicy(ctx, c, &req) 438 if err != nil { 439 return nil, err 440 } 441 442 return &res.Returnval, nil 443 } 444 445 func (c *Client) Login(ctx context.Context) error { 446 req := types.Login{ 447 This: c.ServiceContent.SessionManager, 448 } 449 450 _, err := methods.Login(ctx, c, &req) 451 return err 452 } 453 454 func (c *Client) Logout(ctx context.Context) error { 455 req := types.Logout{ 456 This: c.ServiceContent.SessionManager, 457 } 458 459 _, err := methods.Logout(ctx, c, &req) 460 return err 461 } 462 463 func (c *Client) SetRole(ctx context.Context, id types.PrincipalId, role string) (bool, error) { 464 req := types.SetRole{ 465 This: c.ServiceContent.RoleManagementService, 466 UserId: id, 467 Role: role, 468 } 469 470 res, err := methods.SetRole(ctx, c, &req) 471 if err != nil { 472 return false, err 473 } 474 475 return res.Returnval, nil 476 } 477 478 func (c *Client) GrantWSTrustRole(ctx context.Context, id types.PrincipalId, role string) (bool, error) { 479 req := types.GrantWSTrustRole{ 480 This: c.ServiceContent.RoleManagementService, 481 UserId: id, 482 Role: role, 483 } 484 485 res, err := methods.GrantWSTrustRole(ctx, c, &req) 486 if err != nil { 487 return false, err 488 } 489 490 return res.Returnval, nil 491 } 492 493 func (c *Client) RevokeWSTrustRole(ctx context.Context, id types.PrincipalId, role string) (bool, error) { 494 req := types.RevokeWSTrustRole{ 495 This: c.ServiceContent.RoleManagementService, 496 UserId: id, 497 Role: role, 498 } 499 500 res, err := methods.RevokeWSTrustRole(ctx, c, &req) 501 if err != nil { 502 return false, err 503 } 504 505 return res.Returnval, nil 506 } 507 508 func (c *Client) IdentitySources(ctx context.Context) (*types.IdentitySources, error) { 509 req := types.Get{ 510 This: c.ServiceContent.IdentitySourceManagementService, 511 } 512 513 res, err := methods.Get(ctx, c, &req) 514 if err != nil { 515 return nil, err 516 } 517 518 return &res.Returnval, nil 519 } 520 521 func (c *Client) GetDefaultDomains(ctx context.Context) ([]string, error) { 522 req := types.GetDefaultDomains{ 523 This: c.ServiceContent.IdentitySourceManagementService, 524 } 525 526 res, err := methods.GetDefaultDomains(ctx, c, &req) 527 if err != nil { 528 return nil, err 529 } 530 531 return res.Returnval, nil 532 } 533 534 func (c *Client) SetDefaultDomains(ctx context.Context, domain string) error { 535 req := types.SetDefaultDomains{ 536 This: c.ServiceContent.IdentitySourceManagementService, 537 DomainNames: domain, 538 } 539 540 _, err := methods.SetDefaultDomains(ctx, c, &req) 541 return err 542 } 543 544 func (c *Client) RegisterLdap(ctx context.Context, stype string, name string, alias string, details types.LdapIdentitySourceDetails, auth types.SsoAdminIdentitySourceManagementServiceAuthenticationCredentails) error { 545 req := types.RegisterLdap{ 546 This: c.ServiceContent.IdentitySourceManagementService, 547 ServerType: stype, 548 DomainName: name, 549 DomainAlias: alias, 550 Details: details, 551 AuthenticationType: "password", 552 AuthnCredentials: &auth, 553 } 554 555 _, err := methods.RegisterLdap(ctx, c, &req) 556 return err 557 } 558 559 func (c *Client) UpdateLdap(ctx context.Context, name string, details types.LdapIdentitySourceDetails) error { 560 req := types.UpdateLdap{ 561 This: c.ServiceContent.IdentitySourceManagementService, 562 DomainName: name, 563 Details: details, 564 } 565 566 _, err := methods.UpdateLdap(ctx, c, &req) 567 return err 568 } 569 570 func (c *Client) UpdateLdapAuthnType(ctx context.Context, name string, auth types.SsoAdminIdentitySourceManagementServiceAuthenticationCredentails) error { 571 req := types.UpdateLdapAuthnType{ 572 This: c.ServiceContent.IdentitySourceManagementService, 573 DomainName: name, 574 AuthenticationType: "password", 575 AuthnCredentials: &auth, 576 } 577 578 _, err := methods.UpdateLdapAuthnType(ctx, c, &req) 579 return err 580 } 581 582 func (c *Client) GetTrustedCertificates(ctx context.Context) ([]string, error) { 583 req := types.GetTrustedCertificates{ 584 This: c.ServiceContent.ConfigurationManagementService, 585 } 586 587 res, err := methods.GetTrustedCertificates(ctx, c, &req) 588 if err != nil { 589 return nil, err 590 } 591 592 return res.Returnval, nil 593 }