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

add deployment templates, begin add deployment #30

Closed
wants to merge 4 commits into from
Closed
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
47 changes: 46 additions & 1 deletion momentum-backend/git-client/git-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
git "gopkg.in/src-d/go-git.v4"
)

func PullRepoTo(url string, username string, password string, location string) error {
func CloneRepoTo(url string, username string, password string, location string) error {
_, err := git.PlainClone(location, false, &git.CloneOptions{
URL: url,
Progress: os.Stdout,
Expand All @@ -15,3 +15,48 @@ func PullRepoTo(url string, username string, password string, location string) e

return err
}

func PullRepo(location string) error {

repo, err := git.PlainOpen(location)
if err != nil {
return err
}

worktree, err := repo.Worktree()
if err != nil {
return err
}

err = worktree.Pull(&git.PullOptions{RemoteName: "origin"})
if err != nil && err.Error() != "already up-to-date" {
// TODO is there a more elegant solution?
return err
}
return nil
}

func CommitAllChangesAndPush(location string, commitMsg string) error {

repo, err := git.PlainOpen(location)
if err != nil {
return err
}

worktree, err := repo.Worktree()
if err != nil {
return err
}

_, err = worktree.Add(location)
if err != nil {
return err
}

_, err = worktree.Commit(commitMsg, &git.CommitOptions{})
if err != nil {
return err
}

return nil
}
6 changes: 5 additions & 1 deletion momentum-backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"github.com/pocketbase/pocketbase/plugins/migratecmd"
)

const ENABLE_CLEANUP = true

func defaultPublicDir() string {
if strings.HasPrefix(os.Args[0], os.TempDir()) {
// most likely ran with go run
Expand Down Expand Up @@ -72,7 +74,9 @@ func main() {

app.OnAfterBootstrap().Add(func(e *core.BootstrapEvent) error {

testCleanUp(app.Dao().Clone())
if ENABLE_CLEANUP {
testCleanUp(app.Dao().Clone())
}

dispatcher := momentumcore.NewDispatcher(momentumConfig, app)

Expand Down
48 changes: 43 additions & 5 deletions momentum-backend/momentum-core/momentum-config/config.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package momentumconfig

import (
"errors"
utils "momentum/momentum-core/momentum-utils"
"os"
)

type MomentumConfig struct {
dataDir string
validationTmpDir string
dataDir string
validationTmpDir string
templatesDir string
deploymentTemplateFilePath string
deploymentTemplateFolderPath string
}

func (m *MomentumConfig) DataDir() string {
Expand All @@ -18,6 +22,31 @@ func (m *MomentumConfig) ValidationTmpDir() string {
return m.validationTmpDir
}

func (m *MomentumConfig) TemplateDir() string {
return m.templatesDir
}

func (m *MomentumConfig) DeploymentTemplateFolderPath() string {
return m.deploymentTemplateFolderPath
}

func (m *MomentumConfig) DeploymentTemplateFilePath() string {
return m.deploymentTemplateFilePath
}

func (m *MomentumConfig) checkMandatoryTemplates() error {

if !utils.FileExists(m.DeploymentTemplateFolderPath()) {
return errors.New("provide mandatory template for deployment folders at " + m.DeploymentTemplateFolderPath())
}

if !utils.FileExists(m.DeploymentTemplateFilePath()) {
return errors.New("provide mandatory template for deployment files at " + m.DeploymentTemplateFilePath())
}

return nil
}

func InitializeMomentumCore() (*MomentumConfig, error) {

usrHome, err := os.UserHomeDir()
Expand All @@ -28,22 +57,31 @@ func InitializeMomentumCore() (*MomentumConfig, error) {
momentumDir := utils.BuildPath(usrHome, ".momentum")
dataDir := utils.BuildPath(momentumDir, "data")
validationTmpDir := utils.BuildPath(momentumDir, "validation")
templatesDir := utils.BuildPath(momentumDir, "templates")

createPathIfNotPresent(dataDir, momentumDir)
createPathIfNotPresent(validationTmpDir, momentumDir)

config := new(MomentumConfig)

config.dataDir = dataDir

config.validationTmpDir = validationTmpDir

config.templatesDir = templatesDir
config.deploymentTemplateFolderPath = utils.BuildPath(templatesDir, "deployments", "deploymentName")
config.deploymentTemplateFilePath = utils.BuildPath(templatesDir, "deployments", "deploymentName.yaml")

err = config.checkMandatoryTemplates()

return config, err
}

func createPathIfNotPresent(path string, momentumDir string) {
func createPathIfNotPresent(path string, parentDir string) {

if !utils.FileExists(path) {
if !utils.FileExists(momentumDir) {
utils.DirCreate(momentumDir)
if !utils.FileExists(parentDir) {
utils.DirCreate(parentDir)
}
utils.DirCreate(path)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func NewApplicationController(appService *services.ApplicationService, repoServi

func (ac *ApplicationController) AddRepositoryToApplications(repoAddedEvent *RepositoryAddedEvent) error {

repositoryRecord, err := ac.repositoryService.FindForName(repoAddedEvent.RepositoryName)
repositoryRecord, err := ac.repositoryService.FindByName(repoAddedEvent.RepositoryName)
if err != nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,106 @@
package momentumcontrollers

import (
"errors"
"fmt"
gitclient "momentum/git-client"
kustomizeclient "momentum/kustomize-client"
config "momentum/momentum-core/momentum-config"
model "momentum/momentum-core/momentum-model"
services "momentum/momentum-core/momentum-services"
utils "momentum/momentum-core/momentum-utils"

"github.com/pocketbase/pocketbase/models"
)

type DeploymentController struct {
deploymentService *services.DeploymentService
repositoryService *services.RepositoryService
deploymentService *services.DeploymentService
stageService *services.StageService
applicationService *services.ApplicationService
repositoryService *services.RepositoryService
keyValueService *services.KeyValueService
kustomizeValidator *kustomizeclient.KustomizationValidationService
}

func NewDeploymentController(deploymentService *services.DeploymentService, repositoryService *services.RepositoryService) *DeploymentController {
func NewDeploymentController(
deploymentService *services.DeploymentService,
stageService *services.StageService,
applicationService *services.ApplicationService,
repositoryService *services.RepositoryService,
keyValueService *services.KeyValueService,
kustomizeValidator *kustomizeclient.KustomizationValidationService) *DeploymentController {

deploymentController := new(DeploymentController)
deploymentController.deploymentService = deploymentService
deploymentController.repositoryService = repositoryService
deploymentController.applicationService = applicationService
deploymentController.stageService = stageService
deploymentController.keyValueService = keyValueService
deploymentController.kustomizeValidator = kustomizeValidator

return deploymentController
}

func (dc *DeploymentController) AddDeployment(record *models.Record, conf *config.MomentumConfig) error {
func (dc *DeploymentController) AddDeployment(deploymentRecord *models.Record, conf *config.MomentumConfig) error {

fmt.Println("Adding deployment...")

deploymentWithoutId, err := model.ToDeployment(deploymentRecord)
if err != nil {
fmt.Println("error mapping record to model:", err.Error())
return err
}

stagesSorted, isStagelessDeployment, err := dc.stageService.GetStagesSortedTopDownById(deploymentWithoutId.ParentStageId())
if err != nil {
fmt.Println("Loading stages failed:", err.Error())
return err
}

app, err := dc.applicationService.GetById(stagesSorted[0].ParentApplicationId())
if err != nil {
fmt.Println("Loading app failed:", err.Error())
return err
}

repo, err := dc.repositoryService.GetById(app.ParentRepositoryId())
if err != nil {
fmt.Println("Loading repo failed:", err.Error())
return err
}

gitPath := utils.BuildPath(conf.DataDir(), repo.Name())
err = gitclient.PullRepo(gitPath)
if err != nil {
fmt.Println("updating repository failed:", err.Error())
return err
}

err = dc.deploymentService.CreateDeployment(deploymentWithoutId, stagesSorted, app, repo, isStagelessDeployment)
if err != nil {
fmt.Println("creating deployment failed:", err.Error())
return err
}

// TODO sync files (key values etc)
// use keyValueService -> Use pattern with channel...

valid, err := dc.kustomizeValidator.Validate(repo.Name())
if err != nil {
fmt.Println("validation has errors. manual actions required", err.Error())
return err
}

if !valid {
fmt.Println("validation failed. manual actions required")
return errors.New("kustomize validation failed and manual actions are required now")
}

commitMsg := "added deployment " + deploymentWithoutId.Name()
err = gitclient.CommitAllChangesAndPush(gitPath, commitMsg)
if err != nil {
fmt.Println("failed committing and pushing changes, manual actions required:", err.Error())
}

return nil
}
Expand All @@ -38,7 +117,7 @@ func (dc *DeploymentController) DeleteDeployment(record *models.Record, conf *co

func (dc *DeploymentController) AddRepositoryToDeployments(repositoryAddedEvent *RepositoryAddedEvent) error {

repositoryRecord, err := dc.repositoryService.FindForName(repositoryAddedEvent.RepositoryName)
repositoryRecord, err := dc.repositoryService.FindByName(repositoryAddedEvent.RepositoryName)
if err != nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (rc *RepositoryController) AddRepository(record *models.Record, conf *confi

fmt.Println("Cloning repo to:", path)

err := gitclient.PullRepoTo(repoUrl, "", "", path)
err := gitclient.CloneRepoTo(repoUrl, "", "", path)
if err != nil {
return err
}
Expand Down
9 changes: 6 additions & 3 deletions momentum-backend/momentum-core/momentum-dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ func NewDispatcher(config *conf.MomentumConfig, pb *pocketbase.PocketBase) *Mome
dispatcher := new(MomentumDispatcher)
dispatcher.Config = config

templateService := services.NewTemplateService()
keyValueService := services.NewKeyValueService(pb.Dao())
deploymentService := services.NewDeploymentService(pb.Dao(), keyValueService)
deploymentService := services.NewDeploymentService(pb.Dao(), config, keyValueService, templateService)
stageService := services.NewStageService(pb.Dao(), deploymentService, keyValueService)
appService := services.NewApplicationService(pb.Dao(), stageService)
repoService := services.NewRepositoryService(pb.Dao(), appService)
Expand All @@ -56,7 +57,7 @@ func NewDispatcher(config *conf.MomentumConfig, pb *pocketbase.PocketBase) *Mome
dispatcher.RepositoryController = controllers.NewRepositoryController(repoSyncService, repoService, REPOSITORY_ADDED_EVENT_CHANNEL, dispatcher.kustomizeValidator)
dispatcher.ApplicationsController = controllers.NewApplicationController(appService, repoService)
dispatcher.StagesController = controllers.NewStageController(stageService)
dispatcher.DeploymentController = controllers.NewDeploymentController(deploymentService, repoService)
dispatcher.DeploymentController = controllers.NewDeploymentController(deploymentService, stageService, appService, repoService, keyValueService, dispatcher.kustomizeValidator)

dispatcher.CreateRules = dispatcher.setupCreateRules()
dispatcher.UpdateRules = dispatcher.setupUpdateRules()
Expand All @@ -72,10 +73,12 @@ func NewDispatcher(config *conf.MomentumConfig, pb *pocketbase.PocketBase) *Mome
func (d *MomentumDispatcher) DispatchCreate(recordEvent *core.RecordCreateEvent) error {

for _, rule := range d.CreateRules {
fmt.Println("Rule:", rule.tableName)
fmt.Println("Rule:", rule.tableName, "(record: "+recordEvent.Record.TableName()+")")
if rule.tableName == recordEvent.Record.TableName() {
fmt.Println("Rule match")
err := rule.action(recordEvent.Record, d.Config)
if err != nil {
fmt.Println("Dispatch failed:", err.Error())
return err
}
}
Expand Down
18 changes: 17 additions & 1 deletion momentum-backend/momentum-core/momentum-model/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type IApplication interface {

type Application struct {
IApplication
Model

name string
parentRepositoryId string
Expand All @@ -47,7 +48,14 @@ func ToApplication(record *models.Record) (IApplication, error) {
app := new(Application)
app.SetId(record.Id)
app.name = record.GetString(TABLE_APPLICATIONS_FIELD_NAME)
app.stageIds = record.Get(TABLE_APPLICATIONS_FIELD_STAGES).([]string)

ids, ok := record.Get(TABLE_APPLICATIONS_FIELD_STAGES).([]string)
if ok {
app.stageIds = ids
} else {
app.stageIds = []string{}
}

app.helmRepositoryUrl = record.GetString(TABLE_APPLICATIONS_FIELD_HELMREPO)
app.parentRepositoryId = record.GetString(TABLE_APPLICATIONS_FIELD_PARENTREPOSITORY)

Expand All @@ -68,6 +76,14 @@ func ToApplicationRecord(app IApplication, recordInstance *models.Record) (*mode
return recordInstance, nil
}

func (a *Application) Id() string {
return a.id
}

func (a *Application) SetId(id string) {
a.id = id
}

func (a *Application) Name() string {
return a.name
}
Expand Down
Loading