graphql testin'
This commit is contained in:
3
.envrc
Normal file
3
.envrc
Normal file
@@ -0,0 +1,3 @@
|
||||
source_url "https://raw.githubusercontent.com/cachix/devenv/d1f7b48e35e6dee421cfd0f51481d17f77586997/direnvrc" "sha256-YBzqskFZxmNb3kYVoKD9ZixoPXJh1C9ZvTLGFRkauZ0="
|
||||
|
||||
use devenv
|
||||
156
devenv.lock
Normal file
156
devenv.lock
Normal file
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"nodes": {
|
||||
"devenv": {
|
||||
"locked": {
|
||||
"dir": "src/modules",
|
||||
"lastModified": 1690391043,
|
||||
"narHash": "sha256-8x5DkOaejES6C2JYX2A3riebbJHGFHBmJ+LwxXUIIVw=",
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"rev": "05240861ef3ae1bbe65b1acc88e2fad7dd24a84b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"dir": "src/modules",
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1673956053,
|
||||
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1685518550,
|
||||
"narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1660459072,
|
||||
"narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1690327932,
|
||||
"narHash": "sha256-Fv7PYZxN4eo0K6zXhHG/vOc+e2iuqQ5ywDrh0yeRjP0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a9b47d85504bdd199e90846622c76aa0bfeabfac",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1685801374,
|
||||
"narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-23.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1689668210,
|
||||
"narHash": "sha256-XAATwDkaUxH958yXLs1lcEOmU6pSEIkatY3qjqk8X0E=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "eb433bff05b285258be76513add6f6c57b441775",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"devenv": "devenv",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
5
devenv.nix
Normal file
5
devenv.nix
Normal file
@@ -0,0 +1,5 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
languages.go.enable = true;
|
||||
}
|
||||
3
devenv.yaml
Normal file
3
devenv.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
inputs:
|
||||
nixpkgs:
|
||||
url: github:NixOS/nixpkgs/nixpkgs-unstable
|
||||
@@ -1,6 +1,11 @@
|
||||
package emgql
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -50,3 +55,41 @@ func New(options ...Option) (*Client, error) {
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *Client) graphquery(ctx context.Context, q string, vars map[string]string) (io.ReadCloser, error) {
|
||||
qObj := struct {
|
||||
Query string `json:"query"`
|
||||
Variables map[string]string `json:"variables"`
|
||||
}{
|
||||
Query: q,
|
||||
Variables: vars,
|
||||
}
|
||||
|
||||
res, err := json.Marshal(qObj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal request object: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL.String(), bytes.NewBuffer(res))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build post request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Add("content-type", "application/json")
|
||||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to make post request: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
b, err2 := io.ReadAll(resp.Body)
|
||||
if err2 != nil {
|
||||
return nil, fmt.Errorf("got unexpected response code [%d]: unable to parse request body: %v", resp.StatusCode, err)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("got unexpected response code [%d]: %s", resp.StatusCode, string(b))
|
||||
}
|
||||
return resp.Body, nil
|
||||
|
||||
}
|
||||
|
||||
85
internal/metal/providers/emgql/mapping.go
Normal file
85
internal/metal/providers/emgql/mapping.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package emgql
|
||||
|
||||
import "go.equinixmetal.net/infra9-metal-bridge/internal/metal/models"
|
||||
|
||||
type organization struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Projects []project `json:"projects"`
|
||||
Users []user `json:"users"`
|
||||
}
|
||||
|
||||
func (o organization) ToOrganizationDetails() models.OrganizationDetails {
|
||||
orgDetails := models.OrganizationDetails{
|
||||
ID: o.ID,
|
||||
Name: o.Name,
|
||||
}
|
||||
|
||||
memberships := []*models.Membership[models.OrganizationDetails]{}
|
||||
for _, u := range o.Users {
|
||||
m := u.ToOrganizationMembership()
|
||||
memberships = append(memberships, &m)
|
||||
}
|
||||
|
||||
pDetails := []*models.ProjectDetails{}
|
||||
for _, p := range o.Projects {
|
||||
details := p.ToProjectDetails()
|
||||
details.Organization = &orgDetails
|
||||
pDetails = append(pDetails, &details)
|
||||
}
|
||||
|
||||
orgDetails.Memberships = memberships
|
||||
orgDetails.Projects = pDetails
|
||||
|
||||
return orgDetails
|
||||
|
||||
}
|
||||
|
||||
type project struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Users []user `json:"users"`
|
||||
Organization struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"organization"`
|
||||
}
|
||||
|
||||
func (p project) ToProjectDetails() models.ProjectDetails {
|
||||
memberships := []*models.Membership[models.ProjectDetails]{}
|
||||
for _, u := range p.Users {
|
||||
m := u.ToProjectMembership()
|
||||
memberships = append(memberships, &m)
|
||||
}
|
||||
|
||||
return models.ProjectDetails{
|
||||
ID: p.ID,
|
||||
Name: p.Name,
|
||||
Memberships: memberships,
|
||||
Organization: &models.OrganizationDetails{
|
||||
ID: p.Organization.ID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type user struct {
|
||||
ID string `json:"id"`
|
||||
Roles []string `json:"roles"`
|
||||
}
|
||||
|
||||
func (u user) ToOrganizationMembership() models.Membership[models.OrganizationDetails] {
|
||||
return models.Membership[models.OrganizationDetails]{
|
||||
User: &models.UserDetails{
|
||||
ID: u.ID,
|
||||
},
|
||||
Roles: u.Roles,
|
||||
}
|
||||
}
|
||||
|
||||
func (u user) ToProjectMembership() models.Membership[models.ProjectDetails] {
|
||||
return models.Membership[models.ProjectDetails]{
|
||||
User: &models.UserDetails{
|
||||
ID: u.ID,
|
||||
},
|
||||
Roles: u.Roles,
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@ package emgql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"go.infratographer.com/x/gidx"
|
||||
|
||||
@@ -10,5 +13,56 @@ import (
|
||||
|
||||
// GetOrganizationDetails fetches the organization id provided with its memberships.
|
||||
func (c *Client) GetOrganizationDetails(ctx context.Context, id gidx.PrefixedID) (*models.OrganizationDetails, error) {
|
||||
return nil, nil
|
||||
q := `
|
||||
query ($orgId: OrgId!){
|
||||
organization(id: $orgId) {
|
||||
id
|
||||
name
|
||||
users {
|
||||
id
|
||||
roles
|
||||
}
|
||||
projects {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
variables := map[string]string{
|
||||
"orgId": id.String(),
|
||||
}
|
||||
|
||||
res, err := c.graphquery(ctx, q, variables)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("emgql: error loading organization details: %w", err)
|
||||
}
|
||||
|
||||
org, err := organizationFromResponse(res)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("emgql: failed to parse response: %w", err)
|
||||
}
|
||||
|
||||
out := org.ToOrganizationDetails()
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func organizationFromResponse(r io.ReadCloser) (organization, error) {
|
||||
out := struct {
|
||||
Data struct {
|
||||
Organization organization `json:"organization"`
|
||||
} `json:"data"`
|
||||
}{}
|
||||
|
||||
body, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return out.Data.Organization, fmt.Errorf("emgql: %w", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &out)
|
||||
if err != nil {
|
||||
return out.Data.Organization, fmt.Errorf("emgql: %w", err)
|
||||
}
|
||||
|
||||
return out.Data.Organization, nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ package emgql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"go.infratographer.com/x/gidx"
|
||||
|
||||
@@ -10,5 +13,55 @@ import (
|
||||
|
||||
// GetProjectDetails fetchs the provided project id with membership information.
|
||||
func (c *Client) GetProjectDetails(ctx context.Context, id gidx.PrefixedID) (*models.ProjectDetails, error) {
|
||||
return nil, nil
|
||||
q := `
|
||||
query ($projectId: ProjectId!){
|
||||
project(id: $projectId) {
|
||||
id
|
||||
name
|
||||
users {
|
||||
id
|
||||
roles
|
||||
}
|
||||
organization {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
variables := map[string]string{
|
||||
"projectId": id.String(),
|
||||
}
|
||||
|
||||
res, err := c.graphquery(ctx, q, variables)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading project details: %w", err)
|
||||
}
|
||||
|
||||
prj, err := projectFromResponse(res)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse response: %w", err)
|
||||
}
|
||||
|
||||
out := prj.ToProjectDetails()
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func projectFromResponse(r io.ReadCloser) (project, error) {
|
||||
out := struct {
|
||||
Data struct {
|
||||
Project project `json:"project"`
|
||||
} `json:"data"`
|
||||
}{}
|
||||
|
||||
body, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return out.Data.Project, fmt.Errorf("emgql: %w", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &out)
|
||||
if err != nil {
|
||||
return out.Data.Project, fmt.Errorf("emgql: %w", err)
|
||||
}
|
||||
|
||||
return out.Data.Project, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user