diff --git a/internal/services/gateway/api/api.go b/internal/services/gateway/api/api.go index 1e65b03..97378c9 100644 --- a/internal/services/gateway/api/api.go +++ b/internal/services/gateway/api/api.go @@ -15,6 +15,7 @@ package api import ( + "encoding/json" "net/http" "net/url" @@ -24,12 +25,33 @@ import ( "github.com/sorintlab/agola/internal/util" ) +type ErrorResponse struct { + Message string `json:"message"` +} + +func ErrorResponseFromError(err error) *ErrorResponse { + if util.IsErrBadRequest(err) { + return &ErrorResponse{Message: err.Error()} + } + + // on generic error return an generic message to not leak the real error + return &ErrorResponse{Message: "internal server error"} +} + func httpError(w http.ResponseWriter, err error) bool { if err != nil { + response := ErrorResponseFromError(err) + resj, merr := json.Marshal(response) + if merr != nil { + w.WriteHeader(http.StatusInternalServerError) + return true + } if util.IsErrBadRequest(err) { - http.Error(w, err.Error(), http.StatusBadRequest) + w.WriteHeader(http.StatusBadRequest) + w.Write(resj) } else { - http.Error(w, "", http.StatusInternalServerError) + w.WriteHeader(http.StatusInternalServerError) + w.Write(resj) } return true } @@ -37,6 +59,24 @@ func httpError(w http.ResponseWriter, err error) bool { return false } +func httpResponse(w http.ResponseWriter, code int, res interface{}) error { + w.Header().Set("Content-Type", "application/json") + + if res != nil { + resj, err := json.Marshal(res) + if err != nil { + httpError(w, err) + return err + } + w.WriteHeader(code) + _, err = w.Write(resj) + return err + } + + w.WriteHeader(code) + return nil +} + func GetConfigTypeRef(r *http.Request) (types.ConfigType, string, error) { vars := mux.Vars(r) projectRef, err := url.PathUnescape(vars["projectref"]) diff --git a/internal/services/gateway/api/oauth2.go b/internal/services/gateway/api/oauth2.go index 235897a..1532462 100644 --- a/internal/services/gateway/api/oauth2.go +++ b/internal/services/gateway/api/oauth2.go @@ -15,7 +15,6 @@ package api import ( - "encoding/json" "net/http" csapi "github.com/sorintlab/agola/internal/services/configstore/api" @@ -78,13 +77,11 @@ func (h *OAuth2CallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request response = &RegisterUserResponse{} } - resp := RemoteSourceAuthResult{ + res := RemoteSourceAuthResult{ RequestType: string(cresp.RequestType), Response: response, } - if err := json.NewEncoder(w).Encode(resp); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } diff --git a/internal/services/gateway/api/org.go b/internal/services/gateway/api/org.go index 68eebd9..20afa16 100644 --- a/internal/services/gateway/api/org.go +++ b/internal/services/gateway/api/org.go @@ -15,18 +15,16 @@ package api import ( - "context" "encoding/json" "net/http" "strconv" csapi "github.com/sorintlab/agola/internal/services/configstore/api" + "github.com/sorintlab/agola/internal/services/gateway/command" "github.com/sorintlab/agola/internal/services/types" - "github.com/sorintlab/agola/internal/util" "go.uber.org/zap" "github.com/gorilla/mux" - "github.com/pkg/errors" ) type CreateOrgRequest struct { @@ -34,12 +32,12 @@ type CreateOrgRequest struct { } type CreateOrgHandler struct { - log *zap.SugaredLogger - configstoreClient *csapi.Client + log *zap.SugaredLogger + ch *command.CommandHandler } -func NewCreateOrgHandler(logger *zap.Logger, configstoreClient *csapi.Client) *CreateOrgHandler { - return &CreateOrgHandler{log: logger.Sugar(), configstoreClient: configstoreClient} +func NewCreateOrgHandler(logger *zap.Logger, ch *command.CommandHandler) *CreateOrgHandler { + return &CreateOrgHandler{log: logger.Sugar(), ch: ch} } func (h *CreateOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -52,39 +50,20 @@ func (h *CreateOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - org, err := h.createOrg(ctx, &req) - if err != nil { - h.log.Errorf("err: %+v", err) - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - if err := json.NewEncoder(w).Encode(org); err != nil { - h.log.Errorf("err: %+v", err) - httpError(w, err) - return - } - -} - -func (h *CreateOrgHandler) createOrg(ctx context.Context, req *CreateOrgRequest) (*OrgResponse, error) { - if !util.ValidateName(req.Name) { - return nil, errors.Errorf("invalid org name %q", req.Name) - } - - u := &types.Organization{ + creq := &command.CreateOrgRequest{ Name: req.Name, } - h.log.Infof("creating org") - u, _, err := h.configstoreClient.CreateOrg(ctx, u) - if err != nil { - return nil, errors.Wrapf(err, "failed to create org") + org, err := h.ch.CreateOrg(ctx, creq) + if httpError(w, err) { + h.log.Errorf("err: %+v", err) + return } - h.log.Infof("org %s created, ID: %s", u.Name, u.ID) - res := createOrgResponse(u) - return res, nil + res := createOrgResponse(org) + if err := httpResponse(w, http.StatusCreated, res); err != nil { + h.log.Errorf("err: %+v", err) + } } type DeleteOrgHandler struct { @@ -111,43 +90,9 @@ func (h *DeleteOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { httpError(w, err) return } -} -type CurrentOrgHandler struct { - log *zap.SugaredLogger - configstoreClient *csapi.Client -} - -func NewCurrentOrgHandler(logger *zap.Logger, configstoreClient *csapi.Client) *CurrentOrgHandler { - return &CurrentOrgHandler{log: logger.Sugar(), configstoreClient: configstoreClient} -} - -func (h *CurrentOrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - orgIDVal := ctx.Value("orgid") - if orgIDVal == nil { - http.Error(w, "", http.StatusBadRequest) - return - } - orgID := orgIDVal.(string) - - org, resp, err := h.configstoreClient.GetOrg(ctx, orgID) - if err != nil { - if resp != nil && resp.StatusCode == http.StatusNotFound { - http.Error(w, err.Error(), http.StatusNotFound) - return - } + if err := httpResponse(w, http.StatusNoContent, nil); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return - } - - res := createOrgResponse(org) - if err := json.NewEncoder(w).Encode(res); err != nil { - h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -177,10 +122,8 @@ func (h *OrgHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } res := createOrgResponse(org) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -210,26 +153,20 @@ func (h *OrgByNameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } res := createOrgResponse(org) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } -type OrgsResponse struct { - Orgs []*OrgResponse `json:"orgs"` -} - type OrgResponse struct { ID string `json:"id"` Name string `json:"name"` } -func createOrgResponse(r *types.Organization) *OrgResponse { +func createOrgResponse(o *types.Organization) *OrgResponse { org := &OrgResponse{ - ID: r.ID, - Name: r.Name, + ID: o.ID, + Name: o.Name, } return org } @@ -287,13 +224,7 @@ func (h *OrgsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { for i, p := range csorgs { orgs[i] = createOrgResponse(p) } - orgsResponse := &OrgsResponse{ - Orgs: orgs, - } - - if err := json.NewEncoder(w).Encode(orgsResponse); err != nil { + if err := httpResponse(w, http.StatusOK, orgs); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } diff --git a/internal/services/gateway/api/project.go b/internal/services/gateway/api/project.go index 89939aa..dfc26fa 100644 --- a/internal/services/gateway/api/project.go +++ b/internal/services/gateway/api/project.go @@ -75,17 +75,14 @@ func (h *CreateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) } project, err := h.ch.CreateProject(ctx, creq) - if err != nil { + if httpError(w, err) { h.log.Errorf("err: %+v", err) - http.Error(w, err.Error(), http.StatusBadRequest) return } res := createProjectResponse(project) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -110,10 +107,12 @@ func (h *ProjectReconfigHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques } if err := h.ch.ReconfigProject(ctx, projectRef); err != nil { - h.log.Errorf("err: %+v", err) httpError(w, err) return } + if err := httpResponse(w, http.StatusNoContent, nil); err != nil { + h.log.Errorf("err: %+v", err) + } } type DeleteProjectHandler struct { @@ -155,6 +154,10 @@ func (h *DeleteProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) httpError(w, err) return } + + if err := httpResponse(w, http.StatusNoContent, nil); err != nil { + h.log.Errorf("err: %+v", err) + } } type ProjectHandler struct { @@ -187,10 +190,8 @@ func (h *ProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } res := createProjectResponse(project) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } diff --git a/internal/services/gateway/api/projectgroup.go b/internal/services/gateway/api/projectgroup.go index 274c667..086f508 100644 --- a/internal/services/gateway/api/projectgroup.go +++ b/internal/services/gateway/api/projectgroup.go @@ -74,10 +74,9 @@ func (h *CreateProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Req return } - if err := json.NewEncoder(w).Encode(projectGroup); err != nil { + res := createProjectGroupResponse(projectGroup) + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -111,10 +110,8 @@ func (h *ProjectGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) } res := createProjectGroupResponse(projectGroup) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -152,10 +149,8 @@ func (h *ProjectGroupProjectsHandler) ServeHTTP(w http.ResponseWriter, r *http.R projects[i] = createProjectResponse(p) } - if err := json.NewEncoder(w).Encode(projects); err != nil { + if err := httpResponse(w, http.StatusOK, projects); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -193,10 +188,8 @@ func (h *ProjectGroupSubgroupsHandler) ServeHTTP(w http.ResponseWriter, r *http. subgroups[i] = createProjectGroupResponse(g) } - if err := json.NewEncoder(w).Encode(subgroups); err != nil { + if err := httpResponse(w, http.StatusOK, subgroups); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } diff --git a/internal/services/gateway/api/remotesource.go b/internal/services/gateway/api/remotesource.go index d5457c0..a8c061f 100644 --- a/internal/services/gateway/api/remotesource.go +++ b/internal/services/gateway/api/remotesource.go @@ -65,12 +65,9 @@ func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req } res := createRemoteSourceResponse(rs) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } - } func (h *CreateRemoteSourceHandler) createRemoteSource(ctx context.Context, req *CreateRemoteSourceRequest) (*types.RemoteSource, error) { @@ -165,10 +162,8 @@ func (h *RemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) } res := createRemoteSourceResponse(rs) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -226,9 +221,7 @@ func (h *RemoteSourcesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) remoteSources[i] = createRemoteSourceResponse(rs) } - if err := json.NewEncoder(w).Encode(remoteSources); err != nil { + if err := httpResponse(w, http.StatusOK, remoteSources); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } diff --git a/internal/services/gateway/api/run.go b/internal/services/gateway/api/run.go index 9f9419b..11a331b 100644 --- a/internal/services/gateway/api/run.go +++ b/internal/services/gateway/api/run.go @@ -213,10 +213,8 @@ func (h *RunHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } res := createRunResponse(runResp.Run, runResp.RunConfig) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -257,11 +255,8 @@ func (h *RuntaskHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { rct := rc.Tasks[rt.ID] res := createRunTaskResponse(rt, rct) - - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -353,11 +348,8 @@ func (h *RunsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { for i, r := range runsResp.Runs { runs[i] = createRunsResponse(r) } - - if err := json.NewEncoder(w).Encode(runs); err != nil { + if err := httpResponse(w, http.StatusOK, runs); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } diff --git a/internal/services/gateway/api/secret.go b/internal/services/gateway/api/secret.go index 8d023cf..bf22cd7 100644 --- a/internal/services/gateway/api/secret.go +++ b/internal/services/gateway/api/secret.go @@ -78,10 +78,8 @@ func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { secrets[i] = createSecretResponse(s) } - if err := json.NewEncoder(w).Encode(secrets); err != nil { + if err := httpResponse(w, http.StatusOK, secrets); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -148,11 +146,8 @@ func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) h.log.Infof("secret %s created, ID: %s", s.Name, s.ID) res := createSecretResponse(s) - - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -193,4 +188,7 @@ func (h *DeleteSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) httpError(w, err) return } + if err := httpResponse(w, http.StatusNoContent, nil); err != nil { + h.log.Errorf("err: %+v", err) + } } diff --git a/internal/services/gateway/api/user.go b/internal/services/gateway/api/user.go index fb8ee90..b2dc26d 100644 --- a/internal/services/gateway/api/user.go +++ b/internal/services/gateway/api/user.go @@ -64,11 +64,8 @@ func (h *CreateUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } res := createUserResponse(u) - - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -129,10 +126,8 @@ func (h *CurrentUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } res := createUserResponse(user) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -162,10 +157,8 @@ func (h *UserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } res := createUserResponse(user) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -195,10 +188,8 @@ func (h *UserByNameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } res := createUserResponse(user) - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusOK, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -276,10 +267,8 @@ func (h *UsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { users[i] = createUserResponse(p) } - if err := json.NewEncoder(w).Encode(users); err != nil { + if err := httpResponse(w, http.StatusOK, users); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -315,19 +304,16 @@ func (h *CreateUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) return } - resp, err := h.createUserLA(ctx, userName, req) + res, err := h.createUserLA(ctx, userName, req) if err != nil { h.log.Errorf("err: %+v", err) http.Error(w, err.Error(), http.StatusBadRequest) return } - if err := json.NewEncoder(w).Encode(resp); err != nil { + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } - } func (h *CreateUserLAHandler) createUserLA(ctx context.Context, userName string, req *CreateUserLARequest) (*CreateUserLAResponse, error) { @@ -376,6 +362,10 @@ func (h *DeleteUserLAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) httpError(w, err) return } + + if err := httpResponse(w, http.StatusNoContent, nil); err != nil { + h.log.Errorf("err: %+v", err) + } } type CreateUserTokenRequest struct { @@ -418,13 +408,12 @@ func (h *CreateUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques return } - resp := &CreateUserTokenResponse{ + res := &CreateUserTokenResponse{ Token: token, } - if err := json.NewEncoder(w).Encode(resp); err != nil { + + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -450,6 +439,10 @@ func (h *DeleteUserTokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques httpError(w, err) return } + + if err := httpResponse(w, http.StatusNoContent, nil); err != nil { + h.log.Errorf("err: %+v", err) + } } type RegisterUserRequest struct { @@ -480,17 +473,15 @@ func (h *RegisterUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) return } - resp, err := h.registerUser(ctx, req) + res, err := h.registerUser(ctx, req) if err != nil { h.log.Errorf("err: %+v", err) http.Error(w, err.Error(), http.StatusBadRequest) return } - if err := json.NewEncoder(w).Encode(resp); err != nil { + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -540,19 +531,16 @@ func (h *AuthorizeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - resp, err := h.authorize(ctx, req) + res, err := h.authorize(ctx, req) if err != nil { h.log.Errorf("err: %+v", err) http.Error(w, err.Error(), http.StatusBadRequest) return } - if err := json.NewEncoder(w).Encode(resp); err != nil { + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } - } func (h *AuthorizeHandler) authorize(ctx context.Context, req *LoginUserRequest) (*AuthorizeResponse, error) { @@ -609,23 +597,19 @@ func (h *LoginUserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - resp, err := h.loginUser(ctx, req) + res, err := h.loginUser(ctx, req) if err != nil { h.log.Errorf("err: %+v", err) http.Error(w, err.Error(), http.StatusBadRequest) return } - if err := json.NewEncoder(w).Encode(resp); err != nil { + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } - } func (h *LoginUserHandler) loginUser(ctx context.Context, req *LoginUserRequest) (*LoginUserResponse, error) { - creq := &command.LoginUserRequest{ RemoteSourceName: req.RemoteSourceName, } @@ -648,8 +632,3 @@ func (h *LoginUserHandler) loginUser(ctx context.Context, req *LoginUserRequest) } return resp, nil } - -type RemoteSourceAuthResponse struct { - Oauth2Redirect string `json:"oauth_2_redirect"` - Response interface{} `json:"response"` -} diff --git a/internal/services/gateway/api/variable.go b/internal/services/gateway/api/variable.go index ea35cfa..d797b9c 100644 --- a/internal/services/gateway/api/variable.go +++ b/internal/services/gateway/api/variable.go @@ -132,10 +132,8 @@ func (h *VariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { variables[i] = createVariableResponse(v, cssecrets) } - if err := json.NewEncoder(w).Encode(variables); err != nil { + if err := httpResponse(w, http.StatusOK, variables); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -218,11 +216,8 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request h.log.Infof("variable %s created, ID: %s", v.Name, v.ID) res := createVariableResponse(v, cssecrets) - - if err := json.NewEncoder(w).Encode(res); err != nil { + if err := httpResponse(w, http.StatusCreated, res); err != nil { h.log.Errorf("err: %+v", err) - httpError(w, err) - return } } @@ -264,4 +259,7 @@ func (h *DeleteVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request httpError(w, err) return } + if err := httpResponse(w, http.StatusNoContent, nil); err != nil { + h.log.Errorf("err: %+v", err) + } } diff --git a/internal/services/gateway/command/org.go b/internal/services/gateway/command/org.go new file mode 100644 index 0000000..367ba6a --- /dev/null +++ b/internal/services/gateway/command/org.go @@ -0,0 +1,50 @@ +// Copyright 2019 Sorint.lab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied +// See the License for the specific language governing permissions and +// limitations under the License. + +package command + +import ( + "context" + + "github.com/sorintlab/agola/internal/services/types" + "github.com/sorintlab/agola/internal/util" + + "github.com/pkg/errors" +) + +type CreateOrgRequest struct { + Name string +} + +func (c *CommandHandler) CreateOrg(ctx context.Context, req *CreateOrgRequest) (*types.Organization, error) { + if req.Name == "" { + return nil, util.NewErrBadRequest(errors.Errorf("organization name required")) + } + if !util.ValidateName(req.Name) { + return nil, errors.Errorf("invalid organization name %q", req.Name) + } + + org := &types.Organization{ + Name: req.Name, + } + + c.log.Infof("creating organization") + org, _, err := c.configstoreClient.CreateOrg(ctx, org) + if err != nil { + return nil, errors.Wrapf(err, "failed to create organization") + } + c.log.Infof("organization %s created, ID: %s", org.Name, org.ID) + + return org, nil +} diff --git a/internal/services/gateway/gateway.go b/internal/services/gateway/gateway.go index 6699eea..d828023 100644 --- a/internal/services/gateway/gateway.go +++ b/internal/services/gateway/gateway.go @@ -184,7 +184,7 @@ func (g *Gateway) Run(ctx context.Context) error { orgHandler := api.NewOrgHandler(logger, g.configstoreClient) orgByNameHandler := api.NewOrgByNameHandler(logger, g.configstoreClient) orgsHandler := api.NewOrgsHandler(logger, g.configstoreClient) - createOrgHandler := api.NewCreateOrgHandler(logger, g.configstoreClient) + createOrgHandler := api.NewCreateOrgHandler(logger, g.ch) deleteOrgHandler := api.NewDeleteOrgHandler(logger, g.configstoreClient) runHandler := api.NewRunHandler(logger, g.runserviceClient)