Kaynağa Gözat

changed assume role logic for capi

Stefan McShane 3 yıl önce
ebeveyn
işleme
0245cf0778

+ 35 - 3
api/server/handlers/project_integration/list_aws.go

@@ -1,6 +1,7 @@
 package project_integration
 
 import (
+	"fmt"
 	"net/http"
 
 	"github.com/porter-dev/porter/api/server/handlers"
@@ -24,18 +25,49 @@ func NewListAWSHandler(
 	}
 }
 
+// ListAWSAssumeRoleLink summarises the responses for AWS assume role chain links.
+// This is only intended for CAPI projects
+type ListAWSAssumeRoleLink struct {
+	// ID is the ID of the assume role chain in the db. UUID as a string
+	ID string `json:"id"`
+	// ARN is the target ARN in an assume role chain
+	ARN string `json:"arn"`
+	// ProjectID is the projec that this link belongs to
+	ProjectID int `json:"project_id"`
+}
+
 func (p *ListAWSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+	ctx := r.Context()
+	project, _ := ctx.Value(types.ProjectScope).(*models.Project)
 
-	awsInts, err := p.Repo().AWSIntegration().ListAWSIntegrationsByProjectID(project.ID)
+	if project.CapiProvisionerEnabled {
+		dblinks, err := p.Repo().AWSAssumeRoleChainer().List(ctx, project.ID)
+		if err != nil {
+			e := fmt.Errorf("unable to find assume role chain links: %w", err)
+			p.HandleAPIError(w, r, apierrors.NewErrInternal(e))
+			return
+		}
+
+		var links []ListAWSAssumeRoleLink
+		for _, link := range dblinks {
+			links = append(links, ListAWSAssumeRoleLink{
+				ID:        link.ID.String(),
+				ARN:       link.TargetARN,
+				ProjectID: link.ProjectID,
+			})
+		}
+		p.WriteResult(w, r, links)
+		w.WriteHeader(http.StatusOK)
+		return
+	}
 
+	awsInts, err := p.Repo().AWSIntegration().ListAWSIntegrationsByProjectID(project.ID)
 	if err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}
 
 	var res types.ListAWSResponse = make([]*types.AWSIntegration, 0)
-
 	for _, awsInt := range awsInts {
 		res = append(res, awsInt.ToAWSIntegrationType())
 	}

+ 15 - 0
internal/repository/aws_assume_role_chain.go

@@ -0,0 +1,15 @@
+package repository
+
+import (
+	"context"
+
+	"github.com/porter-dev/porter/internal/models"
+)
+
+// AWSAssumeRoleChainer represents queries on the aws_assume_role_chain table,
+// which stores all assume role chain hops
+type AWSAssumeRoleChainer interface {
+	// List returns the final hop in an assume role chain, where the ARN accounts
+	// are not owned by Porter
+	List(ctx context.Context, projectID uint) ([]*models.AWSAssumeRoleChain, error)
+}

+ 36 - 0
internal/repository/gorm/aws_assume_role_chain.go

@@ -0,0 +1,36 @@
+package gorm
+
+import (
+	"context"
+	"errors"
+
+	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/repository"
+	"gorm.io/gorm"
+)
+
+// AWSAssumeRoleChain uses gorm.DB for querying the database
+type AWSAssumeRoleChain struct {
+	db *gorm.DB
+}
+
+// NewAPIContractRevisioner creates an APIRevision connection
+func NewAWSAssumeRoleChainer(db *gorm.DB) repository.AWSAssumeRoleChainer {
+	return &AWSAssumeRoleChain{db}
+}
+
+// List returns a list of aws assume role chains where the target arn is not owned by Porter.
+// This allows for only returning the customer ARNs
+func (cr AWSAssumeRoleChain) List(ctx context.Context, projectID uint) ([]*models.AWSAssumeRoleChain, error) {
+	var confs []*models.AWSAssumeRoleChain
+
+	if projectID == 0 {
+		return nil, errors.New("must provide a project ID")
+	}
+	tx := cr.db.Where("project_id = ? and target_arn not like '%arn:aws:iam::108458755588%'", projectID).Find(&confs)
+	if tx.Error != nil {
+		return nil, tx.Error
+	}
+
+	return confs, nil
+}

+ 5 - 0
internal/repository/gorm/repository.go

@@ -50,6 +50,7 @@ type GormRepository struct {
 	stack                     repository.StackRepository
 	monitor                   repository.MonitorTestResultRepository
 	apiContractRevisions      repository.APIContractRevisioner
+	awsAssumeRoleChainer      repository.AWSAssumeRoleChainer
 }
 
 func (t *GormRepository) User() repository.UserRepository {
@@ -222,6 +223,9 @@ func (t *GormRepository) MonitorTestResult() repository.MonitorTestResultReposit
 func (t *GormRepository) APIContractRevisioner() repository.APIContractRevisioner {
 	return t.apiContractRevisions
 }
+func (t *GormRepository) AWSAssumeRoleChainer() repository.AWSAssumeRoleChainer {
+	return t.awsAssumeRoleChainer
+}
 
 // NewRepository returns a Repository which persists users in memory
 // and accepts a parameter that can trigger read/write errors
@@ -270,5 +274,6 @@ func NewRepository(db *gorm.DB, key *[32]byte, storageBackend credentials.Creden
 		stack:                     NewStackRepository(db),
 		monitor:                   NewMonitorTestResultRepository(db),
 		apiContractRevisions:      NewAPIContractRevisioner(db),
+		awsAssumeRoleChainer:      NewAWSAssumeRoleChainer(db),
 	}
 }

+ 1 - 0
internal/repository/repository.go

@@ -44,4 +44,5 @@ type Repository interface {
 	Stack() StackRepository
 	MonitorTestResult() MonitorTestResultRepository
 	APIContractRevisioner() APIContractRevisioner
+	AWSAssumeRoleChainer() AWSAssumeRoleChainer
 }

+ 22 - 0
internal/repository/test/aws_assume_role_chain.go

@@ -0,0 +1,22 @@
+package test
+
+import (
+	"context"
+	"errors"
+
+	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/repository"
+)
+
+// AWSAssumeRoleChain uses gorm.DB for querying the database
+type AWSAssumeRoleChain struct{}
+
+// NewAWSAssumeRoleChainer creates an AWSAssumeRoleChain connection
+func NewAWSAssumeRoleChainer() repository.AWSAssumeRoleChainer {
+	return &AWSAssumeRoleChain{}
+}
+
+// List returns a list of aws assume role chains for a given project, removing any chain links owned by Porter
+func (cr AWSAssumeRoleChain) List(ctx context.Context, projectID uint) ([]*models.AWSAssumeRoleChain, error) {
+	return nil, errors.New("not implemented")
+}

+ 5 - 0
internal/repository/test/repository.go

@@ -48,6 +48,7 @@ type TestRepository struct {
 	stack                     repository.StackRepository
 	monitor                   repository.MonitorTestResultRepository
 	apiContractRevision       repository.APIContractRevisioner
+	awsAssumeRoleChainer      repository.AWSAssumeRoleChainer
 }
 
 func (t *TestRepository) User() repository.UserRepository {
@@ -220,6 +221,9 @@ func (t *TestRepository) MonitorTestResult() repository.MonitorTestResultReposit
 func (t *TestRepository) APIContractRevisioner() repository.APIContractRevisioner {
 	return t.apiContractRevision
 }
+func (t *TestRepository) AWSAssumeRoleChainer() repository.AWSAssumeRoleChainer {
+	return t.awsAssumeRoleChainer
+}
 
 // NewRepository returns a Repository which persists users in memory
 // and accepts a parameter that can trigger read/write errors
@@ -268,5 +272,6 @@ func NewRepository(canQuery bool, failingMethods ...string) repository.Repositor
 		stack:                     NewStackRepository(),
 		monitor:                   NewMonitorTestResultRepository(canQuery),
 		apiContractRevision:       NewAPIContractRevisioner(),
+		awsAssumeRoleChainer:      NewAWSAssumeRoleChainer(),
 	}
 }