diff --git a/controller/agentController/config.go b/controller/agentController/config.go index 175c2444..b44a6245 100644 --- a/controller/agentController/config.go +++ b/controller/agentController/config.go @@ -1,5 +1,6 @@ package agentController type Config struct { + ZId string IdentityPath string } diff --git a/controller/agentEnroll.go b/controller/agentEnroll.go new file mode 100644 index 00000000..525dc248 --- /dev/null +++ b/controller/agentEnroll.go @@ -0,0 +1,77 @@ +package controller + +import ( + "github.com/go-openapi/runtime/middleware" + "github.com/openziti/zrok/controller/zrokEdgeSdk" + "github.com/openziti/zrok/rest_model_zrok" + "github.com/openziti/zrok/rest_server_zrok/operations/agent" + "github.com/sirupsen/logrus" +) + +type agentEnrollHandler struct{} + +func newAgentEnrollHandler() *agentEnrollHandler { + return &agentEnrollHandler{} +} + +func (h *agentEnrollHandler) Handle(params agent.EnrollParams, principal *rest_model_zrok.Principal) middleware.Responder { + // start transaction early, if it fails, don't bother creating ziti resources + trx, err := str.Begin() + if err != nil { + logrus.Errorf("error starting transaction for '%v': %v", principal.Email, err) + return agent.NewEnrollInternalServerError() + } + defer trx.Rollback() + + env, err := str.FindEnvironmentForAccount(params.Body.EnvZID, int(principal.ID), trx) + if err != nil { + logrus.Errorf("error finding environment '%v' for '%v': %v", params.Body.EnvZID, principal.Email, err) + return agent.NewEnrollUnauthorized() + } + + if _, err := str.FindAgentEnrollmentForEnvironment(env.Id, trx); err == nil { + logrus.Errorf("environment '%v' (%v) is already enrolled!", params.Body.EnvZID, principal.Email) + return agent.NewEnrollBadRequest() + } + + client, err := zrokEdgeSdk.Client(cfg.Ziti) + if err != nil { + logrus.Errorf("error getting ziti client for '%v': %v", principal.Email, err) + return agent.NewEnrollInternalServerError() + } + + token, err := CreateToken() + if err != nil { + logrus.Errorf("error creating agent enrollment token for '%v': %v", principal.Email, err) + return agent.NewEnrollInternalServerError() + } + logrus.Infof("enrollment token: %v", token) + + zId, err := zrokEdgeSdk.CreateService(token, nil, map[string]interface{}{"zrokEnvZId": env.ZId}, client) + if err != nil { + logrus.Errorf("error creating agent remoting service for '%v' (%v): %v", env.ZId, principal.Email, err) + return agent.NewEnrollInternalServerError() + } + + if err := zrokEdgeSdk.CreateServicePolicyBind(env.ZId+"-"+token+"-bind", zId, env.ZId, zrokEdgeSdk.ZrokAgentRemoteTags(token, env.ZId).SubTags, client); err != nil { + logrus.Errorf("error creating agent remoting bind policy for '%v' (%v): %v", env.ZId, principal.Email, err.Error()) + return agent.NewEnrollInternalServerError() + } + + if err := zrokEdgeSdk.CreateServicePolicyDial(env.ZId+"-"+token+"-dial", zId, []string{cfg.AgentController.ZId}, zrokEdgeSdk.ZrokAgentRemoteTags(token, env.ZId).SubTags, client); err != nil { + logrus.Errorf("error creating agent remoting dial policy for '%v' (%v): %v", env.ZId, principal.Email, err.Error()) + return agent.NewEnrollInternalServerError() + } + + if err := zrokEdgeSdk.CreateShareServiceEdgeRouterPolicy(env.ZId, token, zId, client); err != nil { + logrus.Errorf("error creating agent remoting serp for '%v' (%v): %v", env.ZId, principal.Email, err) + return agent.NewEnrollInternalServerError() + } + + if err := trx.Commit(); err != nil { + logrus.Errorf("error committing agent enrollment record for '%v' (%v): %v", env.ZId, principal.Email, err) + return agent.NewEnrollInternalServerError() + } + + return agent.NewEnrollOK().WithPayload(&agent.EnrollOKBody{Token: token}) +} diff --git a/controller/agentPing.go b/controller/agentPing.go index 4ec0fab1..27b6994b 100644 --- a/controller/agentPing.go +++ b/controller/agentPing.go @@ -5,22 +5,19 @@ import ( "github.com/go-openapi/runtime/middleware" "github.com/openziti/zrok/agent/agentGrpc" "github.com/openziti/zrok/controller/agentController" - "github.com/openziti/zrok/controller/config" "github.com/openziti/zrok/rest_model_zrok" "github.com/openziti/zrok/rest_server_zrok/operations/agent" "github.com/sirupsen/logrus" ) -type agentPingHandler struct { - cfg *config.Config -} +type agentPingHandler struct{} -func newAgentPingHandler(cfg *config.Config) *agentPingHandler { - return &agentPingHandler{cfg: cfg} +func newAgentPingHandler() *agentPingHandler { + return &agentPingHandler{} } func (h *agentPingHandler) Handle(params agent.PingParams, principal *rest_model_zrok.Principal) middleware.Responder { - acli, aconn, err := agentController.NewAgentClient(params.Body.EnvZID, h.cfg.AgentController) + acli, aconn, err := agentController.NewAgentClient(params.Body.EnvZID, cfg.AgentController) if err != nil { logrus.Errorf("error creating agent client for '%v' (%v): %v", params.Body.EnvZID, principal.Email, err) return agent.NewPingInternalServerError() diff --git a/controller/controller.go b/controller/controller.go index 60f2c7a7..a2d8a25a 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -66,7 +66,8 @@ func Run(inCfg *config.Config) error { api.AdminRemoveOrganizationMemberHandler = newRemoveOrganizationMemberHandler() api.AdminUpdateFrontendHandler = newUpdateFrontendHandler() if cfg.AgentController != nil { - api.AgentPingHandler = newAgentPingHandler(cfg) + api.AgentEnrollHandler = newAgentEnrollHandler() + api.AgentPingHandler = newAgentPingHandler() } api.EnvironmentEnableHandler = newEnableHandler() api.EnvironmentDisableHandler = newDisableHandler() diff --git a/controller/zrokEdgeSdk/service.go b/controller/zrokEdgeSdk/service.go index d6d3f9ed..3873c269 100644 --- a/controller/zrokEdgeSdk/service.go +++ b/controller/zrokEdgeSdk/service.go @@ -41,7 +41,7 @@ func CreateShareService(envZId, shrToken, cfgZId string, edge *rest_management_a return shrZId, nil } -func CreateService(name string, cfgZIds []string, addlTags map[string]interface{}, edge *rest_management_api_client.ZitiEdgeManagement) (shrZId string, err error) { +func CreateService(name string, cfgZIds []string, addlTags map[string]interface{}, edge *rest_management_api_client.ZitiEdgeManagement) (zId string, err error) { encryptionRequired := true svc := &rest_model.ServiceCreate{ EncryptionRequired: &encryptionRequired, diff --git a/controller/zrokEdgeSdk/tags.go b/controller/zrokEdgeSdk/tags.go index f03958d2..a4e8c410 100644 --- a/controller/zrokEdgeSdk/tags.go +++ b/controller/zrokEdgeSdk/tags.go @@ -19,6 +19,13 @@ func ZrokShareTags(shrToken string) *rest_model.Tags { return tags } +func ZrokAgentRemoteTags(enrollmentToken, envZId string) *rest_model.Tags { + tags := ZrokTags() + tags.SubTags["zrokAgentRemote"] = enrollmentToken + tags.SubTags["zrokEnvZId"] = envZId + return tags +} + func MergeTags(tags *rest_model.Tags, addl map[string]interface{}) *rest_model.Tags { for k, v := range addl { tags.SubTags[k] = v