Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to REST endpoints in Core. #33

Merged
merged 2 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 56 additions & 65 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"io"
"net/http"
"path/filepath"
Expand All @@ -48,43 +49,15 @@ const (
ErrNoCoreURL = "no coreURL specified in config"
ErrSomeResendsFailed = "some queued environments failed to be resent from core to builder"

graphQLEndpoint = "/graphql"
resendEndpoint = "/resend-pending-builds"
resendEndpoint = "/resend-pending-builds"
createEndpoint = "/create-environment"
deleteEndpoint = "/delete-environment"
)

type gqlVariables struct {
Name string `json:"name"`
Path string `json:"path"`
Description string `json:"description,omitempty"`
Packages Packages `json:"packages,omitempty"`
}

func newGQLVariables(fullPath, desc string, pkgs Packages) gqlVariables {
return gqlVariables{
Name: filepath.Base(fullPath),
Path: filepath.Dir(fullPath),
Description: desc,
Packages: pkgs,
}
}

type gqlQuery struct {
Variables gqlVariables `json:"variables"`
Query string `json:"query"`
}

// EnvironmentResponse is the kind of return value we get from the core.
type EnvironmentResponse struct {
TypeName string `json:"__typename"`
Message string `json:"message"`
}

// Response represents a response to a GraphQL operation.
type Response struct {
Data struct {
CreateEnvironment *EnvironmentResponse `json:"createEnvironment"`
DeleteEnvironment *EnvironmentResponse `json:"deleteEnvironment"`
} `json:"data"`
Message string `json:"message"`
Error string `json:"error"`
}

// Core is used to interact with a real softpack-core service.
Expand All @@ -111,15 +84,6 @@ func toJSON(thing any) io.Reader {
return &buf
}

func (c *Core) doGQLCoreRequest(graphQLPacket io.Reader) error {
resp, err := c.doCoreRequest(graphQLEndpoint, graphQLPacket)
if err != nil {
return err
}

return handleGQLCoreResponse(resp)
}

func (c *Core) doCoreRequest(endpoint string, content io.Reader) (*http.Response, error) {
req, err := http.NewRequestWithContext(
context.Background(),
Expand All @@ -136,29 +100,6 @@ func (c *Core) doCoreRequest(endpoint string, content io.Reader) (*http.Response
return http.DefaultClient.Do(req)
}

func handleGQLCoreResponse(resp *http.Response) error {
var cr Response

err := json.NewDecoder(resp.Body).Decode(&cr)
if err != nil {
return err
}

if cr.Data.DeleteEnvironment != nil {
if cr.Data.DeleteEnvironment.TypeName != DeleteMutationSuccess {
return internal.Error(cr.Data.DeleteEnvironment.Message)
}
}

if cr.Data.CreateEnvironment != nil {
if cr.Data.CreateEnvironment.TypeName != createMutationSuccess {
return internal.Error(cr.Data.CreateEnvironment.Message)
}
}

return nil
}

// ResendResponse is the response that the core service sends when a resend
// request is sent to it.
type ResendResponse struct {
Expand Down Expand Up @@ -194,3 +135,53 @@ func (c *Core) ResendPendingBuilds() error {

return nil
}

type environmentInput struct {
Name string `json:"name"`
Path string `json:"path"`
Description string `json:"description"`
Packages Packages `json:"packages"`
}

// Create contacts the core to schedule an environment build.
func (c *Core) Create(path, desc string, pkgs Packages) error {
return handleResponse(c.doCoreRequest(createEndpoint, toJSON(environmentInput{
Name: filepath.Base(path),
Path: filepath.Dir(path),
Description: desc,
Packages: pkgs,
})))
}

func handleResponse(resp *http.Response, err error) error {
if err != nil {
return err
}

defer resp.Body.Close()

var r EnvironmentResponse

if err := json.NewDecoder(resp.Body).Decode(&r); err != nil {
return err
}

if r.Error != "" {
return errors.New(r.Error) //nolint:goerr113
}

return nil
}

type deleteEnvironmentInput struct {
Name string `json:"name"`
Path string `json:"path"`
}

// Delete contacts the core to delete an environment.
func (c *Core) Delete(path string) error {
return handleResponse(c.doCoreRequest(deleteEndpoint, toJSON(deleteEnvironmentInput{
Name: filepath.Base(path),
Path: filepath.Dir(path),
})))
}
13 changes: 0 additions & 13 deletions core/core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,6 @@ func TestCore(t *testing.T) {
},
}

Convey("You can create a gqlQuery", func() {
gq := newCreateMutation(path, desc, pkgs)
So(gq, ShouldResemble, &gqlQuery{
Variables: gqlVariables{
Name: "env",
Path: "users/foo",
Description: desc,
Packages: pkgs,
},
Query: createMutationQuery,
})
})

conf, err := config.GetConfig("")
if err != nil || conf.CoreURL == "" || conf.ListenURL == "" {
_, err = New(conf)
Expand Down
58 changes: 0 additions & 58 deletions core/create.go

This file was deleted.

59 changes: 0 additions & 59 deletions core/delete.go

This file was deleted.

17 changes: 7 additions & 10 deletions remove/remove_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestRemove(t *testing.T) {

envPath := filepath.Join(groupsDir, group, env)

var response core.Response
var response core.EnvironmentResponse

mockCore := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
json.NewEncoder(w).Encode(response) //nolint:errcheck
Expand Down Expand Up @@ -88,9 +88,8 @@ func TestRemove(t *testing.T) {
})

Convey("Remove() call fails if environment is not successfully removed from Core", func() {
response.Data.DeleteEnvironment = &core.EnvironmentResponse{
TypeName: "EnvironmentNotFoundError",
Message: "No environment with this name found in this location.",
response = core.EnvironmentResponse{
Error: "No environment with this name found in this location.",
}

err := Remove(conf, s3Mock, envPath, version)
Expand All @@ -104,9 +103,8 @@ func TestRemove(t *testing.T) {
})

Convey("Can use Remove() to delete an existing environment", func() {
response.Data.DeleteEnvironment = &core.EnvironmentResponse{
TypeName: core.DeleteMutationSuccess,
Message: "Successfully deleted the environment",
response = core.EnvironmentResponse{
Message: "Successfully deleted the environment",
}

modulePath := filepath.Join(conf.Module.ModuleInstallDir, groupsDir, group, env)
Expand All @@ -124,9 +122,8 @@ func TestRemove(t *testing.T) {
})

Convey("Remove() only deletes the environment matching the version specified", func() {
response.Data.DeleteEnvironment = &core.EnvironmentResponse{
TypeName: core.DeleteMutationSuccess,
Message: "Successfully deleted the environment",
response = core.EnvironmentResponse{
Message: "Successfully deleted the environment",
}

newVersion := genRandString(4)
Expand Down
Loading