소스 검색

add image repo uri to release object

Alexander Belanger 5 년 전
부모
커밋
56def68736

+ 10 - 5
internal/models/release.go

@@ -10,11 +10,16 @@ import (
 type Release struct {
 	gorm.Model
 
-	WebhookToken    string          `json:"webhook_token" gorm:"unique"`
-	ClusterID       uint            `json:"cluster_id"`
-	ProjectID       uint            `json:"project_id"`
-	Name            string          `json:"name"`
-	Namespace       string          `json:"namespace"`
+	WebhookToken string `json:"webhook_token" gorm:"unique"`
+	ClusterID    uint   `json:"cluster_id"`
+	ProjectID    uint   `json:"project_id"`
+	Name         string `json:"name"`
+	Namespace    string `json:"namespace"`
+
+	// The complete image repository uri to pull from. This is also stored in GitActionConfig,
+	// but this should be used for the source of truth going forward.
+	ImageRepoURI string `json:"image_repo_uri,omitempty"`
+
 	GitActionConfig GitActionConfig `json:"git_action_config"`
 }
 

+ 15 - 0
internal/repository/gorm/release.go

@@ -34,6 +34,21 @@ func (repo *ReleaseRepository) ReadRelease(clusterID uint, name, namespace strin
 	return release, nil
 }
 
+// ReadRelease finds a single release based on their unique name and namespace pair.
+func (repo *ReleaseRepository) ListReleasesByImageRepoURI(clusterID uint, imageRepoURI string) ([]*models.Release, error) {
+	releases := make([]*models.Release, 0)
+
+	if imageRepoURI == "" {
+		return releases, nil
+	}
+
+	if err := repo.db.Preload("GitActionConfig").Where("cluster_id = ?", clusterID).Where("image_repo_uri = ?", imageRepoURI).Find(&releases).Error; err != nil {
+		return nil, err
+	}
+
+	return releases, nil
+}
+
 // ReadReleaseByWebhookToken finds a single release based on their unique webhook token.
 func (repo *ReleaseRepository) ReadReleaseByWebhookToken(token string) (*models.Release, error) {
 	release := &models.Release{}

+ 58 - 0
internal/repository/gorm/release_test.go

@@ -1,8 +1,10 @@
 package gorm_test
 
 import (
+	"fmt"
 	"testing"
 
+	"github.com/go-test/deep"
 	"github.com/porter-dev/porter/internal/models"
 	orm "gorm.io/gorm"
 )
@@ -55,6 +57,62 @@ func TestCreateRelease(t *testing.T) {
 	}
 }
 
+func TestListReleasesByImageRepoURI(t *testing.T) {
+	tester := &tester{
+		dbFileName: "./porter_list_releases.db",
+	}
+
+	setupTestEnv(tester, t)
+	defer cleanup(tester, t)
+
+	imageRepoURIs := []string{
+		"uri1",
+		"uri2",
+		"uri3",
+		"uri1",
+		"uri1",
+	}
+
+	releases := make([]*models.Release, 0)
+
+	for i, uri := range imageRepoURIs {
+		release := &models.Release{
+			Name:         fmt.Sprintf("denver-meister-dakota-%d", i),
+			Namespace:    "default",
+			ProjectID:    1,
+			ClusterID:    1,
+			WebhookToken: fmt.Sprintf("abcdefgh-%d", i),
+			ImageRepoURI: uri,
+		}
+
+		release, err := tester.repo.Release.CreateRelease(release)
+
+		if err != nil {
+			t.Fatalf("%v\n", err)
+		}
+
+		if uri == "uri1" {
+			releases = append(releases, release)
+		}
+	}
+
+	resReleases, err := tester.repo.Release.ListReleasesByImageRepoURI(1, "uri1")
+
+	if err != nil {
+		t.Fatalf("%v\n", err)
+	}
+
+	// make sure resulting arrays match
+	if len(resReleases) != 3 {
+		t.Fatalf("length of resulting release list not 3")
+	}
+
+	if diff := deep.Equal(releases, resReleases); diff != nil {
+		t.Errorf("release entry not equal:")
+		t.Error(diff)
+	}
+}
+
 func TestDeleteRelease(t *testing.T) {
 	tester := &tester{
 		dbFileName: "./porter_delete_release.db",

+ 1 - 0
internal/repository/release.go

@@ -12,6 +12,7 @@ type ReleaseRepository interface {
 	CreateRelease(release *models.Release) (*models.Release, error)
 	ReadRelease(clusterID uint, name, namespace string) (*models.Release, error)
 	ReadReleaseByWebhookToken(token string) (*models.Release, error)
+	ListReleasesByImageRepoURI(clusterID uint, imageRepoURI string) ([]*models.Release, error)
 	UpdateRelease(release *models.Release) (*models.Release, error)
 	DeleteRelease(release *models.Release) (*models.Release, error)
 }

+ 11 - 1
server/api/deploy_handler.go

@@ -2,6 +2,7 @@ package api
 
 import (
 	"encoding/json"
+	"fmt"
 	"net/http"
 	"net/url"
 	"strconv"
@@ -105,7 +106,7 @@ func (app *App) HandleDeployTemplate(w http.ResponseWriter, r *http.Request) {
 		Registries: registries,
 	}
 
-	_, err = agent.InstallChart(conf, app.DOConf)
+	rel, err := agent.InstallChart(conf, app.DOConf)
 
 	if err != nil {
 		app.sendExternalError(err, http.StatusInternalServerError, HTTPError{
@@ -124,12 +125,21 @@ func (app *App) HandleDeployTemplate(w http.ResponseWriter, r *http.Request) {
 	}
 
 	// create release with webhook token in db
+	repository := rel.Config["image"].(map[string]interface{})["repository"]
+	repoStr, ok := repository.(string)
+
+	if !ok {
+		app.handleErrorInternal(fmt.Errorf("Could not find field repository in config"), w)
+		return
+	}
+
 	release := &models.Release{
 		ClusterID:    form.ReleaseForm.Form.Cluster.ID,
 		ProjectID:    form.ReleaseForm.Form.Cluster.ProjectID,
 		Namespace:    form.ReleaseForm.Form.Namespace,
 		Name:         form.ChartTemplateForm.Name,
 		WebhookToken: token,
+		ImageRepoURI: repoStr,
 	}
 
 	_, err = app.Repo.Release.CreateRelease(release)

+ 10 - 0
server/api/git_action_handler.go

@@ -187,5 +187,15 @@ func (app *App) createGitActionFromForm(
 
 	app.Logger.Info().Msgf("New git action created: %d", ga.ID)
 
+	// update the release in the db with the image repo uri
+	release.ImageRepoURI = gitAction.ImageRepoURI
+
+	_, err = app.Repo.Release.UpdateRelease(release)
+
+	if err != nil {
+		app.handleErrorDataWrite(err, w)
+		return nil
+	}
+
 	return ga.Externalize()
 }

+ 36 - 0
server/api/release_handler.go

@@ -783,6 +783,24 @@ func (app *App) HandleUpgradeRelease(w http.ResponseWriter, r *http.Request) {
 		release, err := app.Repo.Release.ReadRelease(uint(clusterID), name, rel.Namespace)
 
 		if release != nil {
+			// update image repo uri if changed
+			repository := rel.Config["image"].(map[string]interface{})["repository"]
+			repoStr, ok := repository.(string)
+
+			if !ok {
+				app.handleErrorInternal(fmt.Errorf("Could not find field repository in config"), w)
+				return
+			}
+
+			if repoStr != release.ImageRepoURI {
+				release, err = app.Repo.Release.UpdateRelease(release)
+
+				if err != nil {
+					app.handleErrorInternal(err, w)
+					return
+				}
+			}
+
 			gitAction := release.GitActionConfig
 
 			if gitAction.ID != 0 {
@@ -1034,6 +1052,24 @@ func (app *App) HandleRollbackRelease(w http.ResponseWriter, r *http.Request) {
 		release, err := app.Repo.Release.ReadRelease(uint(clusterID), name, rel.Namespace)
 
 		if release != nil {
+			// update image repo uri if changed
+			repository := rel.Config["image"].(map[string]interface{})["repository"]
+			repoStr, ok := repository.(string)
+
+			if !ok {
+				app.handleErrorInternal(fmt.Errorf("Could not find field repository in config"), w)
+				return
+			}
+
+			if repoStr != release.ImageRepoURI {
+				release, err = app.Repo.Release.UpdateRelease(release)
+
+				if err != nil {
+					app.handleErrorInternal(err, w)
+					return
+				}
+			}
+
 			gitAction := release.GitActionConfig
 
 			if gitAction.ID != 0 {