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

embedded cluster upgrade modal #4398

Merged
merged 5 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ gosec:

.PHONY: mock
mock:
go get github.com/golang/mock/[email protected]
go install github.com/golang/mock/[email protected]
mockgen -source=pkg/store/store_interface.go -destination=pkg/store/mock/mock.go
mockgen -source=pkg/handlers/interface.go -destination=pkg/handlers/mock/mock.go
mockgen -source=pkg/operator/client/client_interface.go -destination=pkg/operator/client/mock/mock.go
Expand Down
5 changes: 5 additions & 0 deletions pkg/api/handlers/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ type ResponseGitOps struct {
type ResponseCluster struct {
ID string `json:"id"`
Slug string `json:"slug"`
// RequiresUpgrade represents whether the embedded cluster config for the current app
// version is different from the currently deployed embedded cluster config
RequiresUpgrade bool `json:"requiresUpgrade"`
// State represents the current state of the most recently deployed embedded cluster config
State string `json:"state,omitempty"`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a more appropriate place for these response fields? cluster seems like an OK spot, but i know it's not necessarily meant to be for the "embedded cluster" but rather the "kots downstream cluster"

}

type GetPendingAppResponse struct {
Expand Down
33 changes: 33 additions & 0 deletions pkg/handlers/app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package handlers

import (
"context"
"encoding/json"
"fmt"
"net/http"
Expand All @@ -13,8 +14,10 @@ import (
downstreamtypes "github.com/replicatedhq/kots/pkg/api/downstream/types"
"github.com/replicatedhq/kots/pkg/api/handlers/types"
apptypes "github.com/replicatedhq/kots/pkg/app/types"
"github.com/replicatedhq/kots/pkg/embeddedcluster"
"github.com/replicatedhq/kots/pkg/gitops"
"github.com/replicatedhq/kots/pkg/helm"
"github.com/replicatedhq/kots/pkg/k8sutil"
"github.com/replicatedhq/kots/pkg/kotsutil"
"github.com/replicatedhq/kots/pkg/logger"
"github.com/replicatedhq/kots/pkg/operator"
Expand Down Expand Up @@ -314,6 +317,36 @@ func responseAppFromApp(a *apptypes.App) (*types.ResponseApp, error) {
Slug: d.ClusterSlug,
}

clientset, err := k8sutil.GetClientset()
if err != nil {
return nil, errors.Wrap(err, "failed to get clientset")
}

isEmbeddedCluster, err := embeddedcluster.IsEmbeddedCluster(clientset)
if err != nil {
return nil, errors.Wrap(err, "failed to check if cluster is embedded")
}

if isEmbeddedCluster {
embeddedClusterConfig, err := store.GetStore().GetEmbeddedClusterConfigForVersion(a.ID, a.CurrentSequence)
if err != nil {
return nil, errors.Wrap(err, "failed to get embedded cluster config")
}

if embeddedClusterConfig != nil {
cluster.RequiresUpgrade, err = embeddedcluster.RequiresUpgrade(context.TODO(), embeddedClusterConfig.Spec)
if err != nil {
return nil, errors.Wrap(err, "failed to check if cluster requires upgrade")
}

embeddedClusterInstallation, err := embeddedcluster.GetCurrentInstallation(context.TODO())
if err != nil {
return nil, errors.Wrap(err, "failed to get current installation")
}
cluster.State = string(embeddedClusterInstallation.Status.State)
}
}

responseDownstream := types.ResponseDownstream{
Name: d.Name,
Links: links,
Expand Down
32 changes: 32 additions & 0 deletions pkg/store/kotsstore/version_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/blang/semver"
"github.com/mholt/archiver/v3"
"github.com/pkg/errors"
embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster-operator/api/v1beta1"
downstreamtypes "github.com/replicatedhq/kots/pkg/api/downstream/types"
versiontypes "github.com/replicatedhq/kots/pkg/api/version/types"
apptypes "github.com/replicatedhq/kots/pkg/app/types"
Expand Down Expand Up @@ -199,6 +200,37 @@ func (s *KOTSStore) GetTargetKotsVersionForVersion(appID string, sequence int64)
return kotsAppSpec.Spec.TargetKotsVersion, nil
}

func (s *KOTSStore) GetEmbeddedClusterConfigForVersion(appID string, sequence int64) (*embeddedclusterv1beta1.Config, error) {
db := persistence.MustGetDBSession()
query := `select embeddedcluster_config from app_version where app_id = ? and sequence = ?`
rows, err := db.QueryOneParameterized(gorqlite.ParameterizedStatement{
Query: query,
Arguments: []interface{}{appID, sequence},
})
if err != nil {
return nil, fmt.Errorf("failed to query: %v: %v", err, rows.Err)
}
if !rows.Next() {
return nil, nil
}

var embeddedClusterSpecStr gorqlite.NullString
if err := rows.Scan(&embeddedClusterSpecStr); err != nil {
return nil, errors.Wrap(err, "failed to scan")
}

if embeddedClusterSpecStr.String == "" {
return nil, nil
}

embeddedClusterConfig, err := kotsutil.LoadEmbeddedClusterConfigFromBytes([]byte(embeddedClusterSpecStr.String))
if err != nil {
return nil, errors.Wrap(err, "failed to load embedded cluster config from contents")
}

return embeddedClusterConfig, nil
}

// CreateAppVersion takes an unarchived app, makes an archive and then uploads it
// to s3 with the appID and sequence specified
func (s *KOTSStore) CreateAppVersionArchive(appID string, sequence int64, archivePath string) error {
Expand Down
81 changes: 56 additions & 25 deletions pkg/store/mock/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkg/store/store_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"time"

embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster-operator/api/v1beta1"
airgaptypes "github.com/replicatedhq/kots/pkg/airgap/types"
downstreamtypes "github.com/replicatedhq/kots/pkg/api/downstream/types"
versiontypes "github.com/replicatedhq/kots/pkg/api/version/types"
Expand Down Expand Up @@ -199,6 +200,7 @@ type VersionStore interface {
GetNextAppSequence(appID string) (int64, error)
GetCurrentUpdateCursor(appID string, channelID string) (string, error)
HasStrictPreflights(appID string, sequence int64) (bool, error)
GetEmbeddedClusterConfigForVersion(appID string, sequence int64) (*embeddedclusterv1beta1.Config, error)
}

type LicenseStore interface {
Expand Down
Loading
Loading