Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
14 changes: 7 additions & 7 deletions cli/cmd/app_hostname_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,23 +187,23 @@ func extractHostnameStrings(merged *types.KotsAppCustomHostnames) map[string]str
// printHostnamesTable prints hostnames in a table format
func printHostnamesTable(w *tabwriter.Writer, hostnames map[string]string) error {
fmt.Fprintln(w, "TYPE\tHOSTNAME")

if registry, ok := hostnames["registry"]; ok && registry != "" {
fmt.Fprintf(w, "Registry\t%s\n", registry)
}

if proxy, ok := hostnames["proxy"]; ok && proxy != "" {
fmt.Fprintf(w, "Proxy\t%s\n", proxy)
}

if downloadPortal, ok := hostnames["downloadPortal"]; ok && downloadPortal != "" {
fmt.Fprintf(w, "Download Portal\t%s\n", downloadPortal)
}

if replicatedApp, ok := hostnames["replicatedApp"]; ok && replicatedApp != "" {
fmt.Fprintf(w, "Replicated App\t%s\n", replicatedApp)
}

w.Flush()
return nil
}
Expand All @@ -215,11 +215,11 @@ func mergeHostnames(defaults *types.DefaultHostnames, custom *types.KotsAppCusto
if custom == nil && defaults == nil {
return &types.KotsAppCustomHostnames{}
}

if custom == nil {
custom = &types.KotsAppCustomHostnames{}
}

if defaults == nil {
return custom
}
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/cluster_upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (r *runners) upgradeCluster(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("cluster id or name is required")
}

clusterID, err := r.getClusterIDFromArg(args[0])
if err != nil {
return errors.Wrap(err, "get cluster id from arg")
Expand Down
2 changes: 0 additions & 2 deletions cli/cmd/image_extraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ func TestExtractImagesFromConfig_ChartWithRequiredValues_NoHelmChartManifest(t *
// This tests only the discovery layer behavior
}


func TestExtractImagesFromConfig_NonMatchingHelmChart_FailsToRender(t *testing.T) {
// Test that HelmChart manifest must match chart name:version exactly
chartPath := getAbsTestDataPath(t, filepath.Join("testdata", "image-extraction", "non-matching-helmchart-test", "chart"))
Expand Down Expand Up @@ -275,7 +274,6 @@ func TestExtractImagesFromConfig_NoManifests_ReturnsError(t *testing.T) {
// This tests only the discovery layer behavior (which is now lenient)
}


func TestExtractImagesFromConfig_EmptyBuilder_FailsToRender(t *testing.T) {
// Test that HelmChart manifest with empty builder section doesn't provide values
chartPath := getAbsTestDataPath(t, filepath.Join("testdata", "image-extraction", "empty-builder-test", "chart"))
Expand Down
4 changes: 2 additions & 2 deletions cli/cmd/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -730,8 +730,8 @@ func (r *runners) calculateOverallSummary(output *JSONLintOutput) LintSummary {
// This eliminates duplication across chart, preflight, and support bundle display functions.
func (r *runners) displayLintResults(
sectionTitle string,
itemName string, // e.g., "chart", "preflight spec", "support bundle spec"
pluralName string, // e.g., "charts", "preflight specs", "support bundle specs"
itemName string, // e.g., "chart", "preflight spec", "support bundle spec"
pluralName string, // e.g., "charts", "preflight specs", "support bundle specs"
results []LintableResult,
) error {
if len(results) == 0 {
Expand Down
20 changes: 10 additions & 10 deletions cli/cmd/lint_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ type PreflightLintResult struct {

// SupportBundleLintResults contains all Support Bundle spec lint results
type SupportBundleLintResults struct {
Enabled bool `json:"enabled"`
Enabled bool `json:"enabled"`
Specs []SupportBundleLintResult `json:"specs"`
}

Expand Down Expand Up @@ -144,21 +144,21 @@ type LintableResult interface {
}

// Implement LintableResult interface for ChartLintResult
func (c ChartLintResult) GetPath() string { return c.Path }
func (c ChartLintResult) GetSuccess() bool { return c.Success }
func (c ChartLintResult) GetMessages() []LintMessage { return c.Messages }
func (c ChartLintResult) GetPath() string { return c.Path }
func (c ChartLintResult) GetSuccess() bool { return c.Success }
func (c ChartLintResult) GetMessages() []LintMessage { return c.Messages }
func (c ChartLintResult) GetSummary() ResourceSummary { return c.Summary }

// Implement LintableResult interface for PreflightLintResult
func (p PreflightLintResult) GetPath() string { return p.Path }
func (p PreflightLintResult) GetSuccess() bool { return p.Success }
func (p PreflightLintResult) GetMessages() []LintMessage { return p.Messages }
func (p PreflightLintResult) GetPath() string { return p.Path }
func (p PreflightLintResult) GetSuccess() bool { return p.Success }
func (p PreflightLintResult) GetMessages() []LintMessage { return p.Messages }
func (p PreflightLintResult) GetSummary() ResourceSummary { return p.Summary }

// Implement LintableResult interface for SupportBundleLintResult
func (s SupportBundleLintResult) GetPath() string { return s.Path }
func (s SupportBundleLintResult) GetSuccess() bool { return s.Success }
func (s SupportBundleLintResult) GetMessages() []LintMessage { return s.Messages }
func (s SupportBundleLintResult) GetPath() string { return s.Path }
func (s SupportBundleLintResult) GetSuccess() bool { return s.Success }
func (s SupportBundleLintResult) GetMessages() []LintMessage { return s.Messages }
func (s SupportBundleLintResult) GetSummary() ResourceSummary { return s.Summary }

// Helper functions to convert between types
Expand Down
16 changes: 8 additions & 8 deletions cli/cmd/release_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ func (r *runners) InitReleaseCreate(parent *cobra.Command) error {
savedAppID := r.appID
savedAppSlug := r.appSlug
savedAppType := r.appType

r.appID = ""
r.appSlug = ""
r.appType = ""

// Call parent prerun (will setup APIs but skip app resolution since app is empty)
if originalPreRun != nil {
if err := originalPreRun(cmd, args); err != nil {
Expand All @@ -115,7 +115,7 @@ func (r *runners) InitReleaseCreate(parent *cobra.Command) error {
return err
}
}

// Keep app cleared - we'll load from config in releaseCreate
return nil
}
Expand Down Expand Up @@ -891,31 +891,31 @@ func (r *runners) validateAppFromConfig(config *tools.Config) error {
// This handles cases where user passes appId and config has appSlug (or vice versa)
// as long as they refer to the same app
cliMatchesConfig := false

// Check if CLI appID matches config appId
if r.appID != "" && configAppId != "" && r.appID == configAppId {
cliMatchesConfig = true
}

// Check if CLI appSlug matches config appSlug
if r.appSlug != "" && configAppSlug != "" && r.appSlug == configAppSlug {
cliMatchesConfig = true
}

// Check if CLI appID matches config appSlug (or vice versa)
// We need to resolve this via API to check if they're the same app
if r.appID != "" && configAppSlug != "" && !cliMatchesConfig {
// The appID from CLI might be the ID for the slug in config
// We'll allow this and let the API resolve it
cliMatchesConfig = true
}

if r.appSlug != "" && configAppId != "" && !cliMatchesConfig {
// The appSlug from CLI might be the slug for the ID in config
// We'll allow this and let the API resolve it
cliMatchesConfig = true
}

// If we couldn't match, show error with both values
if !cliMatchesConfig {
configValue := configAppSlug
Expand Down
42 changes: 21 additions & 21 deletions cli/cmd/release_download.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ replicated release download --channel Unstable

# Download to directory (KOTS only with sequence)
replicated release download 1 --dest ./manifests`,
Args: cobra.MaximumNArgs(1),
Args: cobra.MaximumNArgs(1),
}
parent.AddCommand(cmd)

// Similar to release create, handle config-based flow in PreRunE
cmd.PreRunE = func(cmd *cobra.Command, args []string) error {
// Check if --app flag was explicitly provided by the user
appFlagProvided := cmd.Flags().Changed("app")

// Check if we should use config-based flow (no --app flag was provided)
// Note: Parent's PersistentPreRunE runs BEFORE our PreRunE, so appID/appSlug
// Note: Parent's PersistentPreRunE runs BEFORE our PreRunE, so appID/appSlug
// may already be set from cache/env even if user didn't provide --app flag
usingConfigFlow := false
if !appFlagProvided {
Expand All @@ -69,28 +69,28 @@ replicated release download 1 --dest ./manifests`,
}
}
}

if usingConfigFlow {
// The parent's PersistentPreRunE already ran and may have set wrong app from cache
// We need to override it with the app from config and re-resolve

// Clear the wrong app state that parent set
r.appID = ""
r.appType = ""
// r.appSlug is already set from config above

// Resolve the app using the correct profile's API
if err := r.resolveAppTypeForDownload(); err != nil {
return errors.Wrap(err, "resolve app type from config")
}

return nil
}

// Normal flow - --app flag was provided, parent prerun already handled it
return nil
}

cmd.RunE = r.releaseDownload
cmd.Flags().StringVarP(&r.args.releaseDownloadDest, "dest", "d", "", "File or directory to which release should be downloaded. Auto-generated if not specified.")
cmd.Flags().StringVarP(&r.args.releaseDownloadChannel, "channel", "c", "", "Download the current release from this channel (case sensitive)")
Expand All @@ -110,25 +110,25 @@ func (r *runners) releaseDownload(command *cobra.Command, args []string) error {
// Determine sequence to download
var seq int64
var err error

if r.args.releaseDownloadChannel != "" {
// Download from channel
if len(args) > 0 {
return errors.New("cannot specify both sequence and --channel flag")
}

log.ActionWithSpinner("Finding channel %q", r.args.releaseDownloadChannel)
channel, err := r.api.GetChannelByName(r.appID, r.appType, r.args.releaseDownloadChannel)
if err != nil {
log.FinishSpinnerWithError()
return errors.Wrapf(err, "get channel %q", r.args.releaseDownloadChannel)
}

if channel.ReleaseSequence == 0 {
log.FinishSpinnerWithError()
return errors.Errorf("channel %q has no releases", r.args.releaseDownloadChannel)
}

seq = channel.ReleaseSequence
log.FinishSpinner()
log.ActionWithoutSpinner("Channel %q is at sequence %d", r.args.releaseDownloadChannel, seq)
Expand All @@ -146,19 +146,19 @@ func (r *runners) releaseDownload(command *cobra.Command, args []string) error {
log.FinishSpinnerWithError()
return errors.Wrap(err, "list channels to find latest release")
}

var latestSeq int64
for _, channel := range channels {
if channel.ReleaseSequence > latestSeq {
latestSeq = channel.ReleaseSequence
}
}

if latestSeq == 0 {
log.FinishSpinnerWithError()
return errors.New("no releases found")
}

seq = latestSeq
log.FinishSpinner()
log.ActionWithoutSpinner("Latest release is sequence %d", seq)
Expand All @@ -167,7 +167,7 @@ func (r *runners) releaseDownload(command *cobra.Command, args []string) error {
// Determine destination and whether to save as file or directory
dest := r.args.releaseDownloadDest
saveAsFile := false

if dest == "" {
// Auto-generate filename for .tgz
dest = r.generateDownloadFilename()
Expand Down Expand Up @@ -247,7 +247,7 @@ func (r *runners) generateDownloadFilename() string {
if base == "" {
base = r.appID
}

filename := fmt.Sprintf("%s.tgz", base)
if _, err := os.Stat(filename); err == nil {
// File exists, try with incrementing number
Expand All @@ -258,7 +258,7 @@ func (r *runners) generateDownloadFilename() string {
}
}
}

return filename
}

Expand All @@ -273,7 +273,7 @@ func (r *runners) downloadReleaseArchive(seq int64, dest string) error {
// The release config is base64 encoded JSON, we need to get the raw archive
// For now, we'll use the kotsrelease.Save to a temp dir then tar it up
// TODO: Look for a direct archive download endpoint

tempDir, err := os.MkdirTemp("", "replicated-download-*")
if err != nil {
return errors.Wrap(err, "create temp directory")
Expand Down
4 changes: 1 addition & 3 deletions cli/cmd/release_image_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func (r *runners) releaseImageLS(cmd *cobra.Command, args []string) error {

// Extract and clean up image names
images := make([]string, 0)

for _, image := range targetRelease.AirgapBundleImages {
// Remove registry prefixes and clean up image names
var cleanProxyDomain string
Expand Down Expand Up @@ -207,5 +207,3 @@ func findTargetRelease(releases []*types.ChannelRelease, requestedVersion string

return targetRelease, nil
}


8 changes: 4 additions & 4 deletions cli/cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ func Version() *cobra.Command {
Long: `Print the current version and exit`,
RunE: func(cmd *cobra.Command, args []string) error {
currentVersion := version.Version()

// For version command, do a synchronous update check
updateChecker, err := version.NewUpdateChecker(currentVersion, "replicatedhq/replicated/cli")
updateChecker, err := version.NewUpdateChecker(currentVersion, "replicatedhq/replicated/cli")
if err == nil {
// If we're in a development build or unknown version, still try to get latest
// version info but don't compare versions
Expand All @@ -32,7 +32,7 @@ func Version() *cobra.Command {
version.SaveUpdateCache(currentVersion, updateInfo)
}
}

// Now get the (potentially updated) build info
build := version.GetBuild()

Expand Down Expand Up @@ -68,4 +68,4 @@ func Version() *cobra.Command {
cmd.AddCommand(versionUpgradeCmd())

return cmd
}
}
8 changes: 4 additions & 4 deletions cli/print/channel_images.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
func ChannelImages(w *tabwriter.Writer, images []string) error {
// Sort images for consistent output
sort.Strings(images)

// Print header
fmt.Fprintln(w, "IMAGE")

// Print each image
for _, image := range images {
fmt.Fprintln(w, image)
}

return w.Flush()
}
}
2 changes: 1 addition & 1 deletion cli/print/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var clustersTmplTableNoHeader = template.Must(template.New("clusters").Funcs(clu

// Wide table formatting
var clustersTmplWideHeaderSrc = `ID NAME DISTRIBUTION VERSION STATUS LAST SCHEDULING STATUS NETWORK CREATED EXPIRES COST TOTAL NODES NODEGROUPS TAGS`
var clustersTmplWideRowSrc = `{{ range . -}}
var clustersTmplWideRowSrc = `{{ range . -}}
{{ .ID }} {{ padding .Name 27 }} {{ padding .KubernetesDistribution 12 }} {{ padding .KubernetesVersion 10 }} {{ padding (printf "%s" .Status) 12 }} {{ if .LastSchedulingStatus }}{{ padding .LastSchedulingStatus 29 }}{{ else }}{{ padding "-" 29 }}{{ end }} {{ if .Network }}{{ padding (printf "%.8s" .Network) 8 }}{{else}}{{ padding "-" 8 }}{{end}} {{ padding (printf "%s" (localeTime .CreatedAt)) 30 }} {{if .ExpiresAt.IsZero}}{{ padding "-" 30 }}{{else}}{{ padding (printf "%s" (localeTime .ExpiresAt)) 30 }}{{end}} {{ padding (CreditsToDollarsDisplay .EstimatedCost) 11 }} {{$nodecount:=0}}{{ range $index, $ng := .NodeGroups}}{{$nodecount = add $nodecount $ng.NodeCount}}{{ end }}{{ padding (printf "%d" $nodecount) 11 }} {{ len .NodeGroups}} {{ if eq (len .Tags) 0 }}{{ padding "-" 11 }}{{ else }}{{ range $index, $tag := .Tags }}{{if $index}}, {{end}}{{ $tag.Key }}={{ $tag.Value }}{{ end }}{{ end }}
{{ end }}`
var clustersTmplWideSrc = fmt.Sprintln(clustersTmplWideHeaderSrc) + clustersTmplWideRowSrc
Expand Down
Loading
Loading