Skip to content

Commit

Permalink
store reported secrets in FM DB
Browse files Browse the repository at this point in the history
  • Loading branch information
johannes94 committed Aug 2, 2023
1 parent 14d6d5f commit 50bb47a
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 6 deletions.
17 changes: 15 additions & 2 deletions internal/dinosaur/pkg/api/dbapi/central_request_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ type CentralRequest struct {
RoutesCreated bool `json:"routes_created"`
// Namespace is the namespace of the provisioned central instance.
// We store this in the database to ensure that old centrals whose namespace contained "owner-<central-id>" information will continue to work.
Namespace string `json:"namespace"`
RoutesCreationID string `json:"routes_creation_id"`

// Secrets stores the encrypted secrets reported for a central tenant
Secrets api.JSON `json:"secrets"`
Namespace string `json:"namespace"`
RoutesCreationID string `json:"routes_creation_id"`
// DeletionTimestamp stores the timestamp of the DELETE api call for the resource.
DeletionTimestamp *time.Time `json:"deletionTimestamp"`

Expand Down Expand Up @@ -158,6 +161,16 @@ func (k *CentralRequest) SetRoutes(routes []DataPlaneCentralRoute) error {
return nil
}

// SetSecrets sets CentralRequest.Secret field by converting secrets to api.JSON
func (k *CentralRequest) SetSecrets(secrets map[string]string) error {
r, err := json.Marshal(secrets)
if err != nil {
return fmt.Errorf("marshalling routes into JSON: %w", err)
}
k.Secrets = r
return nil
}

// GetUIHost returns host for CLI/GUI/API connections
func (k *CentralRequest) GetUIHost() string {
if k.Host == "" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type DataPlaneCentralStatus struct {
Conditions []DataPlaneCentralStatusCondition
// Going to ignore the rest of fields (like capacity and versions) for now, until when they are needed
Routes []DataPlaneCentralRoute
Secrets map[string]string
CentralVersion string
CentralOperatorVersion string
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package migrations

// Migrations should NEVER use types from other packages. Types can change
// and then migrations run on a _new_ database will fail or behave unexpectedly.
// Instead of importing types, always re-create the type in the migration, as
// is done here, even though the same type is defined in pkg/api

import (
"github.com/go-gormigrate/gormigrate/v2"
"github.com/stackrox/acs-fleet-manager/pkg/api"
"github.com/stackrox/acs-fleet-manager/pkg/db"
"gorm.io/gorm"

"time"
)

func addSecretFieldToCentralRequests() *gormigrate.Migration {
type CentralRequest struct {
db.Model
Region string `json:"region"`
ClusterID string `json:"cluster_id" gorm:"index"`
CloudProvider string `json:"cloud_provider"`
MultiAZ bool `json:"multi_az"`
Name string `json:"name" gorm:"index"`
Status string `json:"status" gorm:"index"`
SubscriptionID string `json:"subscription_id"`
Owner string `json:"owner" gorm:"index"`
OwnerAccountID string `json:"owner_account_id"`
OwnerUserID string `json:"owner_user_id"`
Host string `json:"host"`
OrganisationID string `json:"organisation_id" gorm:"index"`
FailedReason string `json:"failed_reason"`
PlacementID string `json:"placement_id"`
DesiredCentralVersion string `json:"desired_central_version"`
ActualCentralVersion string `json:"actual_central_version"`
DesiredCentralOperatorVersion string `json:"desired_central_operator_version"`
ActualCentralOperatorVersion string `json:"actual_central_operator_version"`
CentralUpgrading bool `json:"central_upgrading"`
CentralOperatorUpgrading bool `json:"central_operator_upgrading"`
InstanceType string `json:"instance_type"`
QuotaType string `json:"quota_type"`
Routes api.JSON `json:"routes"`
Secrets api.JSON `json:"secrets"`
RoutesCreated bool `json:"routes_created"`
Namespace string `json:"namespace"`
RoutesCreationID string `json:"routes_creation_id"`
DeletionTimestamp *time.Time `json:"deletionTimestamp"`
Central api.JSON `json:"central"`
Scanner api.JSON `json:"scanner"`
OperatorImage string `json:"operator_image"`
}
migrationID := "20230802000000"

return &gormigrate.Migration{
ID: migrationID,
Migrate: func(tx *gorm.DB) error {
return addColumnIfNotExists(tx, &CentralRequest{}, "secrets")
},
Rollback: func(tx *gorm.DB) error {
return nil
},
}
}
2 changes: 2 additions & 0 deletions internal/dinosaur/pkg/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package migrations

import (
"fmt"

"github.com/go-gormigrate/gormigrate/v2"
"github.com/stackrox/acs-fleet-manager/pkg/db"
"gorm.io/gorm"
Expand Down Expand Up @@ -46,6 +47,7 @@ func getMigrations() []*gormigrate.Migration {
addForceReconcileToCentralRequest(),
addOperatorImageFields(),
removeAvailableOperatorField(),
addSecretFieldToCentralRequests(),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ func ConvertDataPlaneDinosaurStatus(status map[string]private.DataPlaneCentralSt
})
}
}

res = append(res, &dbapi.DataPlaneCentralStatus{
CentralClusterID: k,
Conditions: c,
Routes: routes,
Secrets: v.Secrets, // pragma: allowlist secret
})
}

Expand Down
35 changes: 31 additions & 4 deletions internal/dinosaur/pkg/services/data_plane_dinosaur.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (d *dataPlaneCentralService) UpdateDataPlaneCentralService(ctx context.Cont
case statusReady:
// Only store the routes (and create them) when the Dinosaurs are ready, as by the time they are ready,
// the routes should definitely be there.
e = d.persistCentralRoutes(dinosaur, ks, cluster)
e = d.persistCentralValues(dinosaur, ks, cluster)
if e == nil {
e = d.setCentralClusterReady(dinosaur)
}
Expand Down Expand Up @@ -217,7 +217,23 @@ func (d *dataPlaneCentralService) checkCentralRequestCurrentStatus(centralReques
return matchStatus, nil
}

func (d *dataPlaneCentralService) persistCentralRoutes(centralRequest *dbapi.CentralRequest, centralStatus *dbapi.DataPlaneCentralStatus, cluster *api.Cluster) *serviceError.ServiceError {
func (d *dataPlaneCentralService) persistCentralValues(centralRequest *dbapi.CentralRequest, centralStatus *dbapi.DataPlaneCentralStatus, cluster *api.Cluster) *serviceError.ServiceError {
if err := d.addRoutesToRequest(centralRequest, centralStatus, cluster); err != nil {
return err
}

if err := d.addSecretsToRequest(centralRequest, centralStatus, cluster); err != nil {
return err
}

if err := d.dinosaurService.Update(centralRequest); err != nil {
return serviceError.NewWithCause(err.Code, err, "failed to update routes for central cluster %s", centralRequest.ID)
}

return nil
}

func (d *dataPlaneCentralService) addRoutesToRequest(centralRequest *dbapi.CentralRequest, centralStatus *dbapi.DataPlaneCentralStatus, cluster *api.Cluster) *serviceError.ServiceError {
if centralRequest.Routes != nil {
logger.Logger.V(10).Infof("skip persisting routes for Central %s as they are already stored", centralRequest.ID)
return nil
Expand All @@ -238,9 +254,20 @@ func (d *dataPlaneCentralService) persistCentralRoutes(centralRequest *dbapi.Cen
return serviceError.NewWithCause(serviceError.ErrorGeneral, err, "failed to set routes for central %s", centralRequest.ID)
}

if err := d.dinosaurService.Update(centralRequest); err != nil {
return serviceError.NewWithCause(err.Code, err, "failed to update routes for central cluster %s", centralRequest.ID)
return nil
}

func (d *dataPlaneCentralService) addSecretsToRequest(centralRequest *dbapi.CentralRequest, centralStatus *dbapi.DataPlaneCentralStatus, cluster *api.Cluster) *serviceError.ServiceError {
if centralRequest.Secrets != nil { // pragma: allowlist secret
logger.Logger.V(10).Infof("skip persisting secrets for Central %s as they are already stored", centralRequest.ID)
return nil
}
logger.Logger.Infof("store secret information for central %s", centralRequest.ID)

if err := centralRequest.SetSecrets(centralStatus.Secrets); err != nil {
return serviceError.NewWithCause(serviceError.ErrorGeneral, err, "failed to set secrets for central %s", centralRequest.ID)
}

return nil
}

Expand Down

0 comments on commit 50bb47a

Please sign in to comment.