Skip to content

Commit

Permalink
feat: splits remote endpoint retrieval from deployment.
Browse files Browse the repository at this point in the history
  • Loading branch information
outofcoffee committed Jan 15, 2023
1 parent 5800e20 commit 5413c4f
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 25 deletions.
6 changes: 5 additions & 1 deletion cmd/remote_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,13 @@ func remoteDeploy(dir string) {
}
logger.Infof("deploying workspace '%s' to %s remote", active.Name, active.RemoteType)

endpoint, err := (*r).Deploy()
err = (*r).Deploy()
if err != nil {
logger.Fatalf("failed to deploy workspace: %s", err)
}
endpoint, err := (*r).GetEndpoint()
if err != nil {
logger.Fatalf("failed to get remote details: %s", err)
}
logger.Infof("deployed workspace '%s'\nBase URL: %s\nSpec: %s\nStatus: %s", active.Name, endpoint.BaseUrl, endpoint.SpecUrl, endpoint.StatusUrl)
}
13 changes: 12 additions & 1 deletion cmd/remote_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"gatehill.io/imposter/remote"
"github.com/spf13/cobra"
"os"
"strings"
"time"
)

Expand Down Expand Up @@ -61,5 +62,15 @@ func showRemoteStatus(dir string) {
} else {
lastModified = "never"
}
logger.Infof("Workspace '%s' remote status: %s\nLast modified: %s", active.Name, status.Status, lastModified)
msg := fmt.Sprintf("Workspace '%s' remote status: %s\nLast modified: %s", active.Name, status.Status, lastModified)

if strings.ToUpper(status.Status) == "ACTIVE" {
endpoint, err := (*r).GetEndpoint()
if err != nil {
logger.Warnf("failed to get remote details: %s", err)
} else {
msg += fmt.Sprintf("\nBase URL: %s\nSpec: %s\nStatus: %s", endpoint.BaseUrl, endpoint.SpecUrl, endpoint.StatusUrl)
}
}
logger.Info(msg)
}
63 changes: 50 additions & 13 deletions remote/awslambda/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@ import (

var defaultIamRoleName = "ImposterLambdaExecutionRole"

func (m LambdaRemote) Deploy() (*remote.EndpointDetails, error) {
if m.Config[configKeyRegion] == "" {
return nil, fmt.Errorf("region cannot be null")
func (m LambdaRemote) Deploy() error {
region, sess, svc, err := m.initAws()
if err != nil {
return err
}

region, sess := m.startAwsSession()

roleName := stringutil.GetFirstNonEmpty(m.Config[configKeyIamRoleName], defaultIamRoleName)

roleArn, err := ensureIamRole(sess, roleName)
Expand All @@ -41,22 +40,46 @@ func (m LambdaRemote) Deploy() (*remote.EndpointDetails, error) {
logger.Fatal(err)
}

svc := lambda.New(sess)

funcName := m.getFunctionName()
funcArn, err := ensureFunctionExists(svc, region, funcName, roleArn, m.getMemorySize(), zipContents)
if err != nil {
return nil, err
return err
}
functionUrl, err := ensureUrlConfigured(svc, funcArn)
_, err = ensureUrlConfigured(svc, funcArn)
if err != nil {
return nil, err
return err
}

permitAnonAccess := m.Config[configKeyAnonAccess] == "true"
err = configureUrlAccess(svc, funcArn, permitAnonAccess)
if err != nil {
return err
}
return nil
}

func (m LambdaRemote) GetEndpoint() (*remote.EndpointDetails, error) {
_, _, svc, err := m.initAws()
if err != nil {
return nil, err
}

var funcArn string
funcExists, err := checkFunctionExists(svc, m.getFunctionName())
if err != nil {
return nil, err
} else {
funcArn = *funcExists.Configuration.FunctionArn
logger.Tracef("function ARN: %s", funcArn)
}

var functionUrl string
getUrlResult, err := checkFunctionUrlConfig(svc, funcArn)
if err != nil {
return nil, err
} else {
functionUrl = *getUrlResult.FunctionUrl
logger.Tracef("function URL: %s", functionUrl)
}

details := &remote.EndpointDetails{
Expand All @@ -69,6 +92,15 @@ func (m LambdaRemote) Deploy() (*remote.EndpointDetails, error) {
return details, nil
}

func (m LambdaRemote) initAws() (region string, sess *awssession.Session, svc *lambda.Lambda, err error) {
if m.Config[configKeyRegion] == "" {
return "", nil, nil, fmt.Errorf("region cannot be null")
}
region, sess = m.startAwsSession()
svc = lambda.New(sess)
return region, sess, svc, nil
}

func configureUrlAccess(svc *lambda.Lambda, funcArn string, anonAccess bool) error {
const statementId = "PermitAnonymousAccessToFunctionUrl"
if anonAccess {
Expand Down Expand Up @@ -240,9 +272,7 @@ func ensureUrlConfigured(svc *lambda.Lambda, funcArn string) (string, error) {
logger.Debugf("configuring URL for function: %s", funcArn)

var functionUrl string
getUrlResult, err := svc.GetFunctionUrlConfig(&lambda.GetFunctionUrlConfigInput{
FunctionName: aws.String(funcArn),
})
getUrlResult, err := checkFunctionUrlConfig(svc, funcArn)
if err != nil {
if awsErr, ok := err.(awserr.Error); ok {
if awsErr.Code() == lambda.ErrCodeResourceNotFoundException {
Expand All @@ -269,6 +299,13 @@ func ensureUrlConfigured(svc *lambda.Lambda, funcArn string) (string, error) {
return functionUrl, nil
}

func checkFunctionUrlConfig(svc *lambda.Lambda, funcArn string) (*lambda.GetFunctionUrlConfigOutput, error) {
getUrlResult, err := svc.GetFunctionUrlConfig(&lambda.GetFunctionUrlConfigInput{
FunctionName: aws.String(funcArn),
})
return getUrlResult, err
}

func (m LambdaRemote) getAwsRegion() string {
if defaultRegion, ok := os.LookupEnv("AWS_DEFAULT_REGION"); ok {
return defaultRegion
Expand Down
21 changes: 12 additions & 9 deletions remote/cloudmocks/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,43 @@ type getEndpointResponse struct {
SpecUrl string `json:"specUrl"`
}

func (m CloudMocksRemote) Deploy() (*remote.EndpointDetails, error) {
func (m CloudMocksRemote) Deploy() error {
if m.Config[configKeyUrl] == "" {
return nil, fmt.Errorf("URL cannot be null")
return fmt.Errorf("URL cannot be null")
} else if token, _ := m.getObfuscatedToken(); token == "" {
return nil, fmt.Errorf("auth token cannot be null")
return fmt.Errorf("auth token cannot be null")
}

err := m.ensureMockExists()
if err != nil {
return nil, err
return err
}

err = m.setMockState("DRAFT")
if err != nil {
return nil, err
return err
}

err = m.syncFiles(m.Dir)
if err != nil {
return nil, err
return err
}

err = m.setMockState("LIVE")
if err != nil {
return nil, err
return err
}
if success := m.waitForStatus("ACTIVE", make(chan bool)); !success {
return nil, fmt.Errorf("timed out waiting for mock to reach active status")
return fmt.Errorf("timed out waiting for mock to reach active status")
}
return nil
}

func (m CloudMocksRemote) GetEndpoint() (*remote.EndpointDetails, error) {
endpoint, err := m.getEndpoint()
if err != nil {
return nil, err
}

details := &remote.EndpointDetails{
BaseUrl: endpoint.BaseUrl,
SpecUrl: endpoint.SpecUrl,
Expand Down
3 changes: 2 additions & 1 deletion remote/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ type Remote interface {
GetType() string
GetConfig() (*map[string]string, error)
SetConfigValue(key string, value string) error
Deploy() (*EndpointDetails, error)
Deploy() error
GetStatus() (*Status, error)
GetConfigKeys() []string
GetEndpoint() (*EndpointDetails, error)
}

type EndpointDetails struct {
Expand Down

0 comments on commit 5413c4f

Please sign in to comment.