diff --git a/pkg/models/commits.go b/pkg/models/commits.go index 4e444992c..8da51f8e4 100644 --- a/pkg/models/commits.go +++ b/pkg/models/commits.go @@ -4,7 +4,9 @@ package models import ( "errors" + "net/url" + "github.com/redhatinsights/edge-api/config" feature "github.com/redhatinsights/edge-api/unleash/features" log "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -59,17 +61,29 @@ type Commit struct { // Repo is the delivery mechanism of a Commit over HTTP type Repo struct { Model - URL string `json:"RepoURL"` - Status string `json:"RepoStatus"` - PulpURL string `json:"pulp_repo_url"` - PulpStatus string `json:"pulp_repo_status"` + URL string `json:"RepoURL"` // AWS repo URL + Status string `json:"RepoStatus"` // AWS repo upload status + PulpURL string `json:"pulp_repo_url"` // Distribution URL returned from Pulp + PulpStatus string `json:"pulp_repo_status"` // Status of Pulp repo import } -// GetURL is a temporary helper to return the URL of the preferred repo store -// -// this avoids the feature flag everywhere repo.URL is used -// also using GetURL (not URL) to avoid changing the struct used by Gorm -func (r Repo) GetURL() string { +// ContentURL is the URL for internal and Image Builder access to the content in a Pulp repo +func (r Repo) ContentURL() string { + pulpConfig := config.Get().Pulp + + if feature.PulpIntegration.IsEnabled() && r.PulpStatus == RepoStatusSuccess { + parsedURL, _ := url.Parse(r.PulpURL) + parsedConfigContentURL, _ := url.Parse(pulpConfig.ContentURL) + parsedURL.Host = parsedConfigContentURL.Host + + return parsedURL.String() + } + + return r.URL +} + +// DistributionURL is the URL for external access to the content in a Pulp repo +func (r Repo) DistributionURL() string { if feature.PulpIntegration.IsEnabled() && r.PulpStatus == RepoStatusSuccess { return r.PulpURL } diff --git a/pkg/models/commits_test.go b/pkg/models/commits_test.go index ae6427b51..2902a92a2 100644 --- a/pkg/models/commits_test.go +++ b/pkg/models/commits_test.go @@ -2,9 +2,11 @@ package models import ( + "os" "testing" "github.com/bxcodec/faker/v3" + "github.com/redhatinsights/edge-api/config" "github.com/redhatinsights/edge-api/pkg/db" "github.com/stretchr/testify/assert" ) @@ -34,3 +36,65 @@ func TestCommitsBeforeCreate(t *testing.T) { }) } } + +func TestDistributionURL(t *testing.T) { + var awsURL = "https://aws.repo.example.com/repo/is/here" + var pulpURL = "https://pulp.distribution.example.com/api/pulp-content/pulp/repo/is/here" + repo := Repo{ + URL: awsURL, + Status: RepoStatusSuccess, + PulpURL: pulpURL, + PulpStatus: RepoStatusSuccess, + } + + t.Run("return AWS URL", func(t *testing.T) { + defer config.Cleanup() + + os.Unsetenv("FEATURE_PULP_INTEGRATION") + os.Unsetenv("PULP_CONTENT_URL") + + assert.Equal(t, awsURL, repo.DistributionURL()) + }) + + t.Run("return pulp distribution url", func(t *testing.T) { + defer config.Cleanup() + + os.Setenv("FEATURE_PULP_INTEGRATION", "true") + os.Setenv("PULP_CONTENT_URL", "http://internal.repo.example.com:8080") + + assert.Equal(t, pulpURL, repo.DistributionURL()) + }) +} + +func TestContentURL(t *testing.T) { + var awsURL = "https://aws.repo.example.com/repo/is/here" + var pulpURL = "https://pulp.distribution.example.com:3030/api/pulp-content/pulp/repo/is/here" + repo := Repo{ + URL: awsURL, + Status: RepoStatusSuccess, + PulpURL: pulpURL, + PulpStatus: RepoStatusSuccess, + } + + t.Run("return pulp content url", func(t *testing.T) { + defer config.Cleanup() + + os.Setenv("FEATURE_PULP_INTEGRATION", "true") + os.Setenv("PULP_CONTENT_URL", "http://internal.repo.example.com:8080") + + var expectedURL = "https://internal.repo.example.com:8080/api/pulp-content/pulp/repo/is/here" + + assert.Equal(t, expectedURL, repo.ContentURL()) + }) + + t.Run("return aws content url", func(t *testing.T) { + defer config.Cleanup() + + os.Unsetenv("FEATURE_PULP_INTEGRATION") + os.Unsetenv("PULP_CONTENT_URL") + + var expectedURL = "https://aws.repo.example.com/repo/is/here" + + assert.Equal(t, expectedURL, repo.ContentURL()) + }) +} diff --git a/pkg/routes/storage.go b/pkg/routes/storage.go index dc567f763..a336cd1f9 100644 --- a/pkg/routes/storage.go +++ b/pkg/routes/storage.go @@ -517,17 +517,17 @@ func ValidateStorageImage(w http.ResponseWriter, r *http.Request) string { return "" } - if image.Commit.Repo == nil || image.Commit.Repo.GetURL() == "" { + if image.Commit.Repo == nil || image.Commit.Repo.DistributionURL() == "" { logger.Error("image repository does not exist") respondWithAPIError(w, logger, errors.NewNotFound("image repository does not exist")) return "" } - RepoURL, err := url2.Parse(image.Commit.Repo.GetURL()) + RepoURL, err := url2.Parse(image.Commit.Repo.DistributionURL()) if err != nil { logger.WithFields(log.Fields{ "error": err.Error(), - "URL": image.Commit.Repo.GetURL(), + "URL": image.Commit.Repo.DistributionURL(), }).Error("error occurred when parsing repository url") respondWithAPIError(w, logger, errors.NewBadRequest("bad image repository url")) return "" diff --git a/pkg/services/images.go b/pkg/services/images.go index 2a7f65563..b8c118f09 100644 --- a/pkg/services/images.go +++ b/pkg/services/images.go @@ -578,7 +578,7 @@ func (s *ImageService) UpdateImage(image *models.Image, previousImage *models.Im err := errors.NewBadRequest(fmt.Sprintf("Commit repo wasn't found in the database: #%v", image.Commit.ID)) return err } - image.Commit.OSTreeParentCommit = repo.GetURL() + image.Commit.OSTreeParentCommit = repo.ContentURL() } if config.DistributionsRefs[previousSuccessfulImage.Distribution] != config.DistributionsRefs[image.Distribution] { diff --git a/pkg/services/repobuilder.go b/pkg/services/repobuilder.go index ad4dd1c1a..ce01e75aa 100644 --- a/pkg/services/repobuilder.go +++ b/pkg/services/repobuilder.go @@ -350,11 +350,11 @@ func (rb *RepoBuilder) BuildUpdateRepo(id uint) (*models.UpdateTransaction, erro if err != nil { return nil, err } - update.Repo.URL = updateCommit.Repo.GetURL() + update.Repo.URL = updateCommit.Repo.ContentURL() rb.log.WithField("update_transaction", update).Info("UPGRADE: point update to commit repo") } - rb.log.WithField("repo", update.Repo.GetURL()).Info("Update repo URL") + rb.log.WithField("repo", update.Repo.ContentURL()).Info("Update repo URL") update.Repo.Status = models.RepoStatusSuccess if err := db.DB.Omit("Devices.*").Save(&update).Error; err != nil { return nil, err @@ -475,8 +475,8 @@ func (rb *RepoBuilder) ImportRepo(r *models.Repo) (*models.Repo, error) { return nil, fmt.Errorf("error saving status :: %s", result.Error.Error()) } - redactedURL, _ := url.Parse(r.GetURL()) - rb.log.WithField("repo_url", redactedURL.Redacted()).Info("Commit stored in AWS OSTree repo") + logURL, _ := url.Parse(r.DistributionURL()) + rb.log.WithField("repo_url", logURL.Redacted()).Info("Commit stored in AWS OSTree repo") return r, nil } diff --git a/pkg/services/repostore/pulpstore.go b/pkg/services/repostore/pulpstore.go index ec3ba31f0..114784286 100644 --- a/pkg/services/repostore/pulpstore.go +++ b/pkg/services/repostore/pulpstore.go @@ -197,7 +197,7 @@ func fileRepoImport(ctx context.Context, pulpService *pulp.PulpService, sourceUR return artifact, version, nil } -// Import imports an artifact into a Pulp repo and deletes the tarfile artifact +// ostreeRepoImport imports an artifact into a Pulp ostree repo func ostreeRepoImport(ctx context.Context, pulpService *pulp.PulpService, pulpHref string, pulpRepoName string, distBaseURL string, fileRepoArtifact string) (string, error) { @@ -213,16 +213,10 @@ func ostreeRepoImport(ctx context.Context, pulpService *pulp.PulpService, pulpHr } log.WithContext(ctx).WithField("repo_href", *repoImported.PulpHref).Info("Repository imported") - repoURL, err := distributionURL(ctx, pulpService.Domain(), pulpRepoName) - if err != nil { - log.WithContext(ctx).WithField("error", err.Error()).Error("Error getting distibution URL for Pulp repo") - return "", err - } - - parsedURL, _ := url.Parse(repoURL) + parsedURL, _ := url.Parse(distBaseURL) log.WithContext(ctx).WithFields(log.Fields{ "repo_distribution_url": parsedURL.Redacted(), }).Debug("Repo import into Pulp complete") - return repoURL, nil + return distBaseURL, nil } diff --git a/pkg/services/updates.go b/pkg/services/updates.go index ef44dd6c6..ce2803b56 100644 --- a/pkg/services/updates.go +++ b/pkg/services/updates.go @@ -348,7 +348,7 @@ func (s *UpdateService) CreateUpdate(id uint) (*models.UpdateTransaction, error) // NewTemplateRemoteInfo contains the info for the ostree remote file to be written to the system func NewTemplateRemoteInfo(update *models.UpdateTransaction) TemplateRemoteInfo { - updateURL := update.Repo.GetURL() + updateURL := update.Repo.DistributionURL() return TemplateRemoteInfo{ RemoteURL: updateURL, @@ -1016,7 +1016,7 @@ func (s *UpdateService) BuildUpdateTransactions(devicesUpdate *models.DevicesUpd return nil, result.Error } s.log.WithFields(log.Fields{ - "repoURL": repo.GetURL(), + "repoURL": repo.DistributionURL(), "repoID": repo.ID, }).Debug("Getting repo info") }