Skip to content
This repository has been archived by the owner on May 6, 2021. It is now read-only.

Commit

Permalink
Check for environment existence before creating env-pipeline
Browse files Browse the repository at this point in the history
This PR will add the feature of checking whther the environment
exist or not before creating a environment pipeline

Adds the environment service in serviceFactory

To check it will make a request to env service and get all
the environment in a space. Then conver them into
map[envId]envName and then traverse all the env-pipeline
creation request and check the respective environment
exists or not in map. In case it does not exist, throws error.

Adds test for the change and little bit refactoring.

Fixes #93
and openshiftio/openshift.io#4566
  • Loading branch information
piyush-garg authored and chmouel committed Dec 11, 2018
1 parent 4f519ef commit 55247b6
Show file tree
Hide file tree
Showing 11 changed files with 247 additions and 27 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ migration/sqlbindata.go
environment/generated/
auth/client
application/wit/witservice
application/env/envservice
12 changes: 10 additions & 2 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ required = [
"github.com/goadesign/goa/encoding/form",
"github.com/goadesign/goa/goagen",
"github.com/goadesign/goa/goagen/codegen",
"github.com/fabric8-services/fabric8-env/design",
"github.com/goadesign/goa/goagen/gen_app",
"github.com/goadesign/goa/goagen/gen_controller",
"github.com/goadesign/goa/goagen/gen_swagger",
Expand Down Expand Up @@ -66,3 +67,7 @@ ignored = [
[[constraint]]
name = "github.com/fabric8-services/fabric8-wit"
revision = "b59d0dc8ae9b2bfea1fb5dc6ff3552c42b735756"

[[constraint]]
name = "github.com/fabric8-services/fabric8-env"
revision = "f81e3120df92f20cca3c06d98d03e2e83cd15862"
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ clean-generated:
-rm -rf ./swagger/
-rm -f ./migration/sqlbindata.go
-rm -rf application/wit/witservice
-rm -rf application/env/envservice

CLEAN_TARGETS += clean-vendor
.PHONY: clean-vendor
Expand Down Expand Up @@ -315,6 +316,7 @@ app/controllers.go: $(DESIGNS) $(GOAGEN_BIN) $(VENDOR_DIR)
$(GOAGEN_BIN) controller -d ${PACKAGE_NAME}/${DESIGN_DIR} -o controller/ --pkg controller --app-pkg ${PACKAGE_NAME}/app
$(GOAGEN_BIN) swagger -d ${PACKAGE_NAME}/${DESIGN_DIR}
$(GOAGEN_BIN) client -d github.com/fabric8-services/fabric8-wit/design --notool --pkg witservice -o application/wit
$(GOAGEN_BIN) client -d github.com/fabric8-services/fabric8-env/design --notool --pkg envservice -o application/env
$(GOAGEN_BIN) gen -d ${PACKAGE_NAME}/${DESIGN_DIR} --pkg-path=github.com/fabric8-services/fabric8-common/goasupport/status --out app
$(GOAGEN_BIN) gen -d ${PACKAGE_NAME}/${DESIGN_DIR} \
--pkg-path=github.com/fabric8-services/fabric8-common/goasupport/jsonapi_errors_helpers --out app
Expand Down
102 changes: 102 additions & 0 deletions application/env/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package env

import (
"context"
"github.com/fabric8-services/fabric8-build/application/env/envservice"
"github.com/fabric8-services/fabric8-build/application/rest"
"github.com/fabric8-services/fabric8-build/configuration"
commonerr "github.com/fabric8-services/fabric8-common/errors"
"github.com/fabric8-services/fabric8-common/goasupport"
guuid "github.com/goadesign/goa/uuid"
"github.com/pkg/errors"
"github.com/prometheus/common/log"
"net/http"
"net/url"
)

type Environment struct {
ID guuid.UUID
Name string
}

type ENVService interface {
GetEnvList(ctx context.Context, spaceID string) (envs []Environment, e error)
}

type ENVServiceImpl struct {
Config configuration.Config
doer rest.HttpDoer
}

// GetEnvList talks to the ENV service and return the list of env's in a given space
func (s *ENVServiceImpl) GetEnvList(ctx context.Context, spaceID string) (envs []Environment, e error) {
remoteENVService, err := s.createClientWithContextSigner(ctx)
if err != nil {
return nil, err
}

spaceIDUUID, err := guuid.FromString(spaceID)
if err != nil {
return nil, err
}

res, err := remoteENVService.ListEnvironment(ctx, envservice.ListEnvironmentPath(spaceIDUUID))
if err != nil {
return nil, err
}

defer rest.CloseResponse(res)
if res.StatusCode != http.StatusOK {
bodyString := rest.ReadBody(res.Body)
log.Error(ctx, map[string]interface{}{
"spaceId": spaceID,
"response_status": res.Status,
"response_body": bodyString,
}, "unable to get env list from ENV Service")
if res.StatusCode == 401 {
return nil, commonerr.NewUnauthorizedError("Not Authorized")
} else {
return nil, errors.Errorf("unable to get env list from ENV Service. Response status: %s. Response body: %s", res.Status, bodyString)
}
}

envList, err := remoteENVService.DecodeEnvironmentsList(res)
if err != nil {
return nil, err
}

for _, env := range envList.Data {
envs = append(envs, Environment{
ID: *env.ID,
Name: *env.Attributes.Name,
})
}
return envs, nil
}

// createClientWithContextSigner creates with a signer based on current context
func (s *ENVServiceImpl) createClientWithContextSigner(ctx context.Context) (*envservice.Client, error) {
c, err := s.createClient()
if err != nil {
return nil, err
}

c.SetJWTSigner(goasupport.NewForwardSigner(ctx))
return c, nil
}

func (s *ENVServiceImpl) createClient() (*envservice.Client, error) {
envURL, e := s.Config.GetEnvServiceURL()
if e != nil {
return nil, e
}
u, err := url.Parse(envURL)
if err != nil {
return nil, err
}

c := envservice.New(s.doer)
c.Host = u.Host
c.Scheme = u.Scheme
return c, nil
}
8 changes: 8 additions & 0 deletions application/services.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package application

import (
"github.com/fabric8-services/fabric8-build/application/env"
"github.com/fabric8-services/fabric8-build/application/wit"
"github.com/fabric8-services/fabric8-build/configuration"
)

type ServiceFactory interface {
WITService() wit.WITService
ENVService() env.ENVService
}

type serviceFactoryImpl struct {
Expand All @@ -19,6 +21,12 @@ func (s serviceFactoryImpl) WITService() wit.WITService {
}
}

func (s serviceFactoryImpl) ENVService() env.ENVService {
return &env.ENVServiceImpl{
Config: *s.Config,
}
}

func NewServiceFactory(config *configuration.Config) ServiceFactory {
return serviceFactoryImpl{
Config: config,
Expand Down
8 changes: 4 additions & 4 deletions application/wit/wit.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import (
"github.com/fabric8-services/fabric8-common/goasupport"
"github.com/pkg/errors"

"github.com/goadesign/goa/uuid"
guuid "github.com/goadesign/goa/uuid"
"github.com/prometheus/common/log"
)

type Space struct {
ID uuid.UUID
OwnerID uuid.UUID
ID guuid.UUID
OwnerID guuid.UUID
Name string
Description string
}
Expand All @@ -39,7 +39,7 @@ func (s *WITServiceImpl) GetSpace(ctx context.Context, spaceID string) (space *S
return nil, err
}

spaceIDUUID, err := uuid.FromString(spaceID)
spaceIDUUID, err := guuid.FromString(spaceID)
if err != nil {
return nil, err
}
Expand Down
3 changes: 3 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ metrics.http.address: ""
# Auth
auth.url: ""

# Env
env.url: ""

#------------------------
# Postgres configuration
#------------------------
Expand Down
6 changes: 6 additions & 0 deletions configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (
// External f8 services
varAuthURL = "auth.url"
varWITURL = "wit.url"
varEnvURL = "env.url"

// Postgres
varPostgresHost = "postgres.host"
Expand Down Expand Up @@ -135,6 +136,11 @@ func (c *Config) GetAuthServiceURL() string {
return "http://localhost:8089"
}

// GetEnvServiceUrl returns Env Service URL
func (c *Config) GetEnvServiceURL() (string, error) {
return c.v.GetString(varEnvURL), nil
}

// GetEnvironment returns the current environment application is deployed in
// like 'production', 'prod-preview', 'local', etc as the value of environment variable
// `F8_ENVIRONMENT` is set.
Expand Down
50 changes: 37 additions & 13 deletions controller/pipeline_environments.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ package controller

import (
"context"

"fmt"
"github.com/fabric8-services/fabric8-build/app"
"github.com/fabric8-services/fabric8-build/application"
"github.com/fabric8-services/fabric8-build/application/env"
"github.com/fabric8-services/fabric8-build/build"
"github.com/fabric8-services/fabric8-common/errors"
"github.com/fabric8-services/fabric8-common/httpsupport"
"github.com/fabric8-services/fabric8-common/token"
"github.com/goadesign/goa"
guuid "github.com/goadesign/goa/uuid"
errs "github.com/pkg/errors"
"github.com/prometheus/common/log"
)
Expand All @@ -30,16 +32,6 @@ func NewPipelineEnvironmentController(service *goa.Service, db application.DB, s
}
}

func checkAndConvertEnvironment(envs []*app.EnvironmentAttributes) (ret []build.Environment, err error) {
//TODO: check environemnts here
for _, env := range envs {
ret = append(ret, build.Environment{
EnvironmentID: env.EnvUUID,
})
}
return
}

// Create runs the create action.
func (c *PipelineEnvironmentController) Create(ctx *app.CreatePipelineEnvironmentsContext) error {
tokenMgr, err := token.ReadManagerFromContext(ctx)
Expand All @@ -62,9 +54,9 @@ func (c *PipelineEnvironmentController) Create(ctx *app.CreatePipelineEnvironmen
return app.JSONErrorResponse(ctx, err)
}

newEnvs, err := checkAndConvertEnvironment(reqPpl.Environments)
newEnvs, err := c.checkEnvironmentExistAndConvert(ctx, spaceID.String(), reqPpl.Environments)
if err != nil {
return app.JSONErrorResponse(ctx, err)
return app.JSONErrorResponse(ctx, errors.NewNotFoundError("environment", err.Error()))
}

var ppl *build.Pipeline
Expand Down Expand Up @@ -140,6 +132,7 @@ func (c *PipelineEnvironmentController) Show(ctx *app.ShowPipelineEnvironmentsCo
return ctx.OK(res)
}

// This will check whether the given space exist or not
func (c *PipelineEnvironmentController) checkSpaceExist(ctx context.Context, spaceID string) error {
// TODO(chmouel): Make sure we have the rights for that space
// TODO(chmouel): Better error reporting when NOTFound
Expand All @@ -149,3 +142,34 @@ func (c *PipelineEnvironmentController) checkSpaceExist(ctx context.Context, spa
}
return nil
}

// This will check whether the env's exit and then convert to build.Environment List
func (c *PipelineEnvironmentController) checkEnvironmentExistAndConvert(ctx *app.CreatePipelineEnvironmentsContext, spaceID string, envs []*app.EnvironmentAttributes) ([]build.Environment, error) {
envList, err := c.svcFactory.ENVService().GetEnvList(ctx, spaceID)
if err != nil {
return nil, errs.Wrapf(err, "failed to get env list for space id: %s from env service", spaceID)
}
envUUIDList := convertToEnvUidList(envList)
var environments []build.Environment
for _, env := range envs {
envId, _ := guuid.FromString(env.EnvUUID.String())
envName := envUUIDList[envId]
if envName == "" {
return nil, errors.NewNotFoundError("environment", env.EnvUUID.String()) //errs.Wrapf(err, "Env %s for space id: %s does not exist", envId, spaceID)
}
environments = append(environments, build.Environment{
EnvironmentID: env.EnvUUID,
})
}
return environments, nil
}

// This will convert the list of env into map[envId]envName
// this will help to check whether env exist or not
func convertToEnvUidList(envList []env.Environment) map[guuid.UUID]string {
var envMap = make(map[guuid.UUID]string)
for _, env := range envList {
envMap[env.ID] = env.Name
}
return envMap
}
Loading

0 comments on commit 55247b6

Please sign in to comment.