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

feat: add preferred channel slug #4742

Closed
wants to merge 9 commits into from
Closed
6 changes: 6 additions & 0 deletions cmd/kots/cli/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ func InstallCmd() *cobra.Command {

upstream := pull.RewriteUpstream(args[0])

preferredChannelSlug, err := extractPreferredChannelSlug(upstream)
if err != nil {
return errors.Wrap(err, "failed to extract preferred channel slug")
}

namespace := v.GetString("namespace")

if namespace == "" {
Expand Down Expand Up @@ -252,6 +257,7 @@ func InstallCmd() *cobra.Command {

deployOptions := kotsadmtypes.DeployOptions{
Namespace: namespace,
PreferredChannelSlug: preferredChannelSlug,
Context: v.GetString("context"),
SharedPassword: sharedPassword,
ApplicationMetadata: applicationMetadata.Manifest,
Expand Down
18 changes: 18 additions & 0 deletions cmd/kots/cli/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"

"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/replicatedapp"
"github.com/replicatedhq/kots/pkg/util"
)

Expand Down Expand Up @@ -51,3 +52,20 @@ func splitEndpointAndNamespace(endpoint string) (string, string) {
}
return registryEndpoint, registryNamespace
}

func extractPreferredChannelSlug(upstreamURI string) (string, error) {
u, err := url.ParseRequestURI(upstreamURI)
if err != nil {
return "", errors.Wrap(err, "failed to parse uri")
}

replicatedUpstream, err := replicatedapp.ParseReplicatedURL(u)
if err != nil {
return "", errors.Wrap(err, "failed to parse replicated url")
}

if replicatedUpstream.Channel != nil {
return *replicatedUpstream.Channel, nil
}
return "stable", nil
}
49 changes: 49 additions & 0 deletions cmd/kots/cli/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,52 @@ func Test_getHostFromEndpoint(t *testing.T) {
})
}
}

func Test_extractPreferredChannelSlug(t *testing.T) {
type args struct {
upstreamURI string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
"no channel",
args{
upstreamURI: "replicated://app-slug",
},
"stable", // default channel
false,
},
{
"with channel",
args{
upstreamURI: "replicated://app-slug/channel",
},
"channel",
false,
},
{
"invalid uri",
args{
upstreamURI: "junk",
},
"",
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := extractPreferredChannelSlug(tt.args.upstreamURI)
if (err != nil) != tt.wantErr {
t.Errorf("extractPreferredChannelSlug() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("extractPreferredChannelSlug() = %v, want %v", got, tt.want)
}
})
}
}
5 changes: 2 additions & 3 deletions pkg/airgap/airgap.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/airgap/types"
"github.com/replicatedhq/kots/pkg/archives"
kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types"
kotsadmconfig "github.com/replicatedhq/kots/pkg/kotsadmconfig"
identity "github.com/replicatedhq/kots/pkg/kotsadmidentity"
"github.com/replicatedhq/kots/pkg/kotsutil"
Expand Down Expand Up @@ -197,7 +196,7 @@ func CreateAppFromAirgap(opts CreateAirgapAppOpts) (finalError error) {
}
}

instParams, err := kotsutil.GetInstallationParams(kotsadmtypes.KotsadmConfigMap)
instParams, err := kotsutil.GetInstallationParams()
if err != nil {
return errors.Wrap(err, "failed to get existing kotsadm config map")
}
Expand Down Expand Up @@ -339,7 +338,7 @@ func CreateAppFromAirgap(opts CreateAirgapAppOpts) (finalError error) {
}
}

err = kotsutil.RemoveAppVersionLabelFromInstallationParams(kotsadmtypes.KotsadmConfigMap)
err = kotsutil.RemoveAppVersionLabelFromInstallationParams()
if err != nil {
logger.Error(errors.Wrapf(err, "failed to delete app version label from config"))
}
Expand Down
5 changes: 2 additions & 3 deletions pkg/automation/automation.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
airgaptypes "github.com/replicatedhq/kots/pkg/airgap/types"
"github.com/replicatedhq/kots/pkg/k8sutil"
"github.com/replicatedhq/kots/pkg/kotsadm"
kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types"
kotsadmlicense "github.com/replicatedhq/kots/pkg/kotsadmlicense"
"github.com/replicatedhq/kots/pkg/kotsutil"
kotslicense "github.com/replicatedhq/kots/pkg/license"
Expand Down Expand Up @@ -84,7 +83,7 @@ func AutomateInstall(opts AutomateInstallOptions) error {
}

cleanup := func(licenseSecret *corev1.Secret) {
err = kotsutil.RemoveAppVersionLabelFromInstallationParams(kotsadmtypes.KotsadmConfigMap)
err = kotsutil.RemoveAppVersionLabelFromInstallationParams()
if err != nil {
logger.Error(errors.Wrapf(err, "failed to delete app version label from config"))
}
Expand Down Expand Up @@ -236,7 +235,7 @@ func installLicenseSecret(clientset *kubernetes.Clientset, licenseSecret corev1.
}
}

instParams, err := kotsutil.GetInstallationParams(kotsadmtypes.KotsadmConfigMap)
instParams, err := kotsutil.GetInstallationParams()
if err != nil {
return errors.Wrap(err, "failed to get existing kotsadm config map")
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/handlers/garbage_collect_images.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/k8sutil"
kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types"
"github.com/replicatedhq/kots/pkg/kotsutil"
"github.com/replicatedhq/kots/pkg/kurl"
"github.com/replicatedhq/kots/pkg/logger"
Expand All @@ -33,7 +32,7 @@ func (h *Handler) GarbageCollectImages(w http.ResponseWriter, r *http.Request) {
return
}

installParams, err := kotsutil.GetInstallationParams(kotsadmtypes.KotsadmConfigMap)
installParams, err := kotsutil.GetInstallationParams()
if err != nil {
response.Error = "failed to get app registry info"
logger.Error(errors.Wrap(err, response.Error))
Expand Down
9 changes: 4 additions & 5 deletions pkg/handlers/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
apptypes "github.com/replicatedhq/kots/pkg/app/types"
"github.com/replicatedhq/kots/pkg/k8sutil"
"github.com/replicatedhq/kots/pkg/kotsadm"
kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types"
kotsadmlicense "github.com/replicatedhq/kots/pkg/kotsadmlicense"
"github.com/replicatedhq/kots/pkg/kotsutil"
kotslicense "github.com/replicatedhq/kots/pkg/license"
Expand Down Expand Up @@ -323,7 +322,7 @@ func (h *Handler) UploadNewLicense(w http.ResponseWriter, r *http.Request) {
}
}

installationParams, err := kotsutil.GetInstallationParams(kotsadmtypes.KotsadmConfigMap)
installationParams, err := kotsutil.GetInstallationParams()
if err != nil {
logger.Error(err)
uploadLicenseResponse.Error = err.Error()
Expand Down Expand Up @@ -362,7 +361,7 @@ func (h *Handler) UploadNewLicense(w http.ResponseWriter, r *http.Request) {
return
}

err = kotsutil.RemoveAppVersionLabelFromInstallationParams(kotsadmtypes.KotsadmConfigMap)
err = kotsutil.RemoveAppVersionLabelFromInstallationParams()
if err != nil {
logger.Error(err)
uploadLicenseResponse.Error = err.Error()
Expand Down Expand Up @@ -418,7 +417,7 @@ func (h *Handler) ResumeInstallOnline(w http.ResponseWriter, r *http.Request) {
return
}

installationParams, err := kotsutil.GetInstallationParams(kotsadmtypes.KotsadmConfigMap)
installationParams, err := kotsutil.GetInstallationParams()
if err != nil {
logger.Error(err)
resumeInstallOnlineResponse.Error = err.Error()
Expand Down Expand Up @@ -465,7 +464,7 @@ func (h *Handler) ResumeInstallOnline(w http.ResponseWriter, r *http.Request) {
return
}

err = kotsutil.RemoveAppVersionLabelFromInstallationParams(kotsadmtypes.KotsadmConfigMap)
err = kotsutil.RemoveAppVersionLabelFromInstallationParams()
if err != nil {
logger.Error(err)
resumeInstallOnlineResponse.Error = err.Error()
Expand Down
1 change: 1 addition & 0 deletions pkg/kotsadm/objects/configmaps_objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

func KotsadmConfigMap(deployOptions types.DeployOptions) *corev1.ConfigMap {
data := map[string]string{
"preferred-channel-slug": fmt.Sprintf("%v", deployOptions.PreferredChannelSlug),
"kots-install-id": fmt.Sprintf("%v", deployOptions.InstallID),
"initial-app-images-pushed": fmt.Sprintf("%v", deployOptions.AppImagesPushed),
"skip-preflights": fmt.Sprintf("%v", deployOptions.SkipPreflights),
Expand Down
1 change: 1 addition & 0 deletions pkg/kotsadm/types/deployoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

type DeployOptions struct {
Namespace string
PreferredChannelSlug string
Context string
SharedPassword string
SharedPasswordBcrypt string
Expand Down
3 changes: 1 addition & 2 deletions pkg/kotsadm/updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/buildversion"
"github.com/replicatedhq/kots/pkg/k8sutil"
kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types"
"github.com/replicatedhq/kots/pkg/kotsutil"
"github.com/replicatedhq/kots/pkg/logger"
"github.com/replicatedhq/kots/pkg/rand"
Expand Down Expand Up @@ -104,7 +103,7 @@ func UpdateToVersion(newVersion string) error {
return errors.Wrap(err, "failed to get kots options from cluster")
}

installationParams, err := kotsutil.GetInstallationParams(kotsadmtypes.KotsadmConfigMap)
installationParams, err := kotsutil.GetInstallationParams()
if err != nil {
return errors.Wrap(err, "failed to get installation params")
}
Expand Down
11 changes: 7 additions & 4 deletions pkg/kotsutil/kots.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/replicatedhq/kots/pkg/crypto"
registrytypes "github.com/replicatedhq/kots/pkg/docker/registry/types"
"github.com/replicatedhq/kots/pkg/k8sutil"
kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types"
"github.com/replicatedhq/kots/pkg/kurl"
"github.com/replicatedhq/kots/pkg/logger"
"github.com/replicatedhq/kots/pkg/util"
Expand Down Expand Up @@ -1139,9 +1140,10 @@ type InstallationParams struct {
WaitDuration time.Duration
WithMinio bool
AppVersionLabel string
PreferredChannelSlug string
}

func GetInstallationParams(configMapName string) (InstallationParams, error) {
func GetInstallationParams() (InstallationParams, error) {
autoConfig := InstallationParams{}

clientset, err := k8sutil.GetClientset()
Expand All @@ -1154,7 +1156,7 @@ func GetInstallationParams(configMapName string) (InstallationParams, error) {
return autoConfig, errors.Wrap(err, "failed to check if cluster is kurl")
}

kotsadmConfigMap, err := clientset.CoreV1().ConfigMaps(util.PodNamespace).Get(context.TODO(), configMapName, metav1.GetOptions{})
kotsadmConfigMap, err := clientset.CoreV1().ConfigMaps(util.PodNamespace).Get(context.TODO(), kotsadmtypes.KotsadmConfigMap, metav1.GetOptions{})
if err != nil {
if kuberneteserrors.IsNotFound(err) {
return autoConfig, nil
Expand All @@ -1174,6 +1176,7 @@ func GetInstallationParams(configMapName string) (InstallationParams, error) {
autoConfig.WaitDuration, _ = time.ParseDuration(kotsadmConfigMap.Data["wait-duration"])
autoConfig.WithMinio, _ = strconv.ParseBool(kotsadmConfigMap.Data["with-minio"])
autoConfig.AppVersionLabel = kotsadmConfigMap.Data["app-version-label"]
autoConfig.PreferredChannelSlug = kotsadmConfigMap.Data["preferred-channel-slug"]

if enableImageDeletion, ok := kotsadmConfigMap.Data["enable-image-deletion"]; ok {
autoConfig.EnableImageDeletion, _ = strconv.ParseBool(enableImageDeletion)
Expand Down Expand Up @@ -1310,13 +1313,13 @@ func IsKotsAutoUpgradeSupported(app *kotsv1beta1.Application) bool {
return false
}

func RemoveAppVersionLabelFromInstallationParams(configMapName string) error {
func RemoveAppVersionLabelFromInstallationParams() error {
clientset, err := k8sutil.GetClientset()
if err != nil {
return errors.Wrap(err, "failed to get k8s clientset")
}

kotsadmConfigMap, err := clientset.CoreV1().ConfigMaps(util.PodNamespace).Get(context.TODO(), configMapName, metav1.GetOptions{})
kotsadmConfigMap, err := clientset.CoreV1().ConfigMaps(util.PodNamespace).Get(context.TODO(), kotsadmtypes.KotsadmConfigMap, metav1.GetOptions{})
if err != nil {
if kuberneteserrors.IsNotFound(err) {
return nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/registry/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func shouldGarbageCollectImages(isKurl bool, embeddedRegistryHost string, instal
}

func DeleteUnusedImages(appID string, ignoreRollback bool) error {
installParams, err := kotsutil.GetInstallationParams(kotsadmtypes.KotsadmConfigMap)
installParams, err := kotsutil.GetInstallationParams()
if err != nil {
return errors.Wrap(err, "failed to get app registry info")
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/replicatedapp/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/pkg/errors"
apptypes "github.com/replicatedhq/kots/pkg/app/types"
"github.com/replicatedhq/kots/pkg/kotsutil"
"github.com/replicatedhq/kots/pkg/logger"
"github.com/replicatedhq/kots/pkg/persistence"
"github.com/replicatedhq/kots/pkg/reporting"
Expand Down Expand Up @@ -43,6 +44,13 @@ type LicenseData struct {
func GetLatestLicense(license *kotsv1beta1.License) (*LicenseData, error) {
url := fmt.Sprintf("%s/license/%s", license.Spec.Endpoint, license.Spec.AppSlug)

installParams, err := kotsutil.GetInstallationParams()
if err != nil {
logger.Warnf("failed to get preferred channel slug from installation params: %v", err)
} else if installParams.PreferredChannelSlug != "" {
url = fmt.Sprintf("%s/%s", url, installParams.PreferredChannelSlug)
}

licenseData, err := getLicenseFromAPI(url, license.Spec.LicenseID)
if err != nil {
return nil, errors.Wrap(err, "failed to get license from api")
Expand Down
Loading