add remaining org/proj/user initial sync

This commit is contained in:
Mike Mason
2023-07-11 21:32:30 +00:00
parent 80fb879ef6
commit 11fe8f8f2a
15 changed files with 215 additions and 34 deletions

View File

@@ -3,10 +3,11 @@ package metal
import (
"context"
"go.equinixmetal.net/infra9-metal-bridge/internal/metal/models"
provider "go.equinixmetal.net/infra9-metal-bridge/internal/metal/providers"
"go.infratographer.com/x/gidx"
"go.uber.org/zap"
"go.equinixmetal.net/infra9-metal-bridge/internal/metal/models"
provider "go.equinixmetal.net/infra9-metal-bridge/internal/metal/providers"
)
// Client is the Equinix Metal API Client struct.
@@ -28,6 +29,14 @@ func (c *Client) GetUserDetails(ctx context.Context, id gidx.PrefixedID) (*model
return c.provider.GetUserDetails(ctx, id)
}
func (c *Client) GetUserOrganizationRole(ctx context.Context, userID, orgID gidx.PrefixedID) (string, error) {
return c.provider.GetUserOrganizationRole(ctx, userID, orgID)
}
func (c *Client) GetUserProjectRole(ctx context.Context, userID, projID gidx.PrefixedID) (string, error) {
return c.provider.GetUserProjectRole(ctx, userID, projID)
}
// New creates a new Client.
func New(options ...Option) (*Client, error) {
client := new(Client)

View File

@@ -0,0 +1,27 @@
package emapi
import (
"net/url"
"strings"
)
// idOrLinkID returns the id if not empty, otherwise it plucks the last subpath from the link.
// An empty string is returned if nothing is defined or an error occurs.
func idOrLinkID(id, link string) string {
if id != "" || link == "" {
return id
}
url, err := url.Parse(link)
if err != nil {
return ""
}
parts := strings.Split(strings.TrimRight(url.Path, "/"), "/")
if len(parts) != 0 {
return parts[len(parts)-1]
}
return ""
}

View File

@@ -48,12 +48,18 @@ type Organization struct {
}
func (o *Organization) ToDetails() *models.OrganizationDetails {
if o == nil || o.ID == "" {
var id string
if o != nil {
id = idOrLinkID(o.ID, o.HREF)
}
if id == "" {
return nil
}
details := &models.OrganizationDetails{
ID: o.ID,
ID: id,
Name: o.Name,
Projects: o.Projects.ToDetails(),
}
@@ -66,7 +72,7 @@ func (o *Organization) ToDetails() *models.OrganizationDetails {
func (c *Client) getOrganizationWithMemberships(ctx context.Context, id string) (*Organization, error) {
var org Organization
_, err := c.DoRequest(ctx, http.MethodGet, organizationsPath+"/"+id+"?include=memberships.user,projects.memberships.user", nil, &org)
_, err := c.DoRequest(ctx, http.MethodGet, organizationsPath+"/"+id+"?include=memberships.user", nil, &org)
if err != nil {
return nil, fmt.Errorf("error loading organization: %w", err)
}

View File

@@ -48,12 +48,18 @@ type Project struct {
}
func (p *Project) ToDetails() *models.ProjectDetails {
if p == nil || p.ID == "" {
var id string
if p != nil {
id = idOrLinkID(p.ID, p.HREF)
}
if id == "" {
return nil
}
details := &models.ProjectDetails{
ID: p.ID,
ID: id,
Name: p.Name,
Organization: p.Organization.ToDetails(),
}
@@ -63,19 +69,19 @@ func (p *Project) ToDetails() *models.ProjectDetails {
return details
}
func (c *Client) getProject(ctx context.Context, id string) (*Project, error) {
func (c *Client) getProjectWithMemberships(ctx context.Context, id string) (*Project, error) {
var project Project
_, err := c.DoRequest(ctx, http.MethodGet, c.baseURL.JoinPath(projectsPath, id).String(), nil, &project)
_, err := c.DoRequest(ctx, http.MethodGet, projectsPath+"/"+id+"?include=memberships.user", nil, &project)
if err != nil {
return nil, fmt.Errorf("error loading project: %w", err)
return nil, fmt.Errorf("error loading organization: %w", err)
}
return &project, nil
}
func (c *Client) GetProjectDetails(ctx context.Context, id gidx.PrefixedID) (*models.ProjectDetails, error) {
project, err := c.getProject(ctx, id.String()[gidx.PrefixPartLength+1:])
project, err := c.getProjectWithMemberships(ctx, id.String()[gidx.PrefixPartLength+1:])
if err != nil {
return nil, err
}

View File

@@ -47,12 +47,18 @@ type User struct {
}
func (u *User) ToDetails() *models.UserDetails {
if u.ID == "" {
var id string
if u != nil {
id = idOrLinkID(u.ID, u.HREF)
}
if id == "" {
return nil
}
return &models.UserDetails{
ID: u.ID,
ID: id,
FullName: u.FullName,
Organizations: nil,
Projects: u.Projects.ToDetails(),
@@ -62,9 +68,9 @@ func (u *User) ToDetails() *models.UserDetails {
func (c *Client) getUser(ctx context.Context, id string) (*User, error) {
var user User
_, err := c.DoRequest(ctx, http.MethodGet, c.baseURL.JoinPath(usersPath, id).String(), nil, &user)
_, err := c.DoRequest(ctx, http.MethodGet, usersPath+"/"+id, nil, &user)
if err != nil {
return nil, fmt.Errorf("error loading user: %w", err)
return nil, fmt.Errorf("error loading organization: %w", err)
}
return &user, nil
@@ -78,3 +84,11 @@ func (c *Client) GetUserDetails(ctx context.Context, id gidx.PrefixedID) (*model
return user.ToDetails(), nil
}
func (c *Client) GetUserOrganizationRole(ctx context.Context, userID, orgID gidx.PrefixedID) (string, error) {
return "collaborator", nil
}
func (c *Client) GetUserProjectRole(ctx context.Context, userID, projectID gidx.PrefixedID) (string, error) {
return "collaborator", nil
}

View File

@@ -3,10 +3,19 @@ package emgql
import (
"context"
"go.equinixmetal.net/infra9-metal-bridge/internal/metal/models"
"go.infratographer.com/x/gidx"
"go.equinixmetal.net/infra9-metal-bridge/internal/metal/models"
)
func (c *Client) GetUserDetails(ctx context.Context, id gidx.PrefixedID) (*models.UserDetails, error) {
return nil, nil
}
func (c *Client) GetUserOrganizationRole(ctx context.Context, userID, orgID gidx.PrefixedID) (string, error) {
return "collaborator", nil
}
func (c *Client) GetUserProjectRole(ctx context.Context, userID, projID gidx.PrefixedID) (string, error) {
return "collaborator", nil
}

View File

@@ -3,12 +3,15 @@ package provider
import (
"context"
"go.equinixmetal.net/infra9-metal-bridge/internal/metal/models"
"go.infratographer.com/x/gidx"
"go.equinixmetal.net/infra9-metal-bridge/internal/metal/models"
)
type Provider interface {
GetOrganizationDetails(ctx context.Context, id gidx.PrefixedID) (*models.OrganizationDetails, error)
GetProjectDetails(ctx context.Context, id gidx.PrefixedID) (*models.ProjectDetails, error)
GetUserDetails(ctx context.Context, id gidx.PrefixedID) (*models.UserDetails, error)
GetUserOrganizationRole(ctx context.Context, userID, orgID gidx.PrefixedID) (string, error)
GetUserProjectRole(ctx context.Context, userID, projID gidx.PrefixedID) (string, error)
}