Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/update-docs-and-licenses.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24.2'
go-version-file: 'go.mod'

- name: Update docs & licenses
run: |
Expand Down
114 changes: 114 additions & 0 deletions cli/cmd/api_key_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ package cmd_test
import (
"fmt"
"os"
"os/exec"
"strings"
"time"

. "github.com/onsi/ginkgo/v2"
Expand Down Expand Up @@ -217,4 +219,116 @@ var _ = Describe("API Key Integration Tests", func() {
Expect(err.Error()).To(ContainSubstring("invalid date format"))
})
})

Describe("Old API Key Detection and Warning", func() {
var (
cliPath string
)

BeforeEach(func() {
cliPath = "./oms-cli"

_, err := os.Stat(cliPath)
if err != nil {
Skip("OMS CLI not found at " + cliPath + ", please build it first with 'make build-cli'")
}
})

Context("when using a 22-character old API key format", func() {
It("should detect the old format and attempt to upgrade", func() {
cmd := exec.Command(cliPath, "version")
cmd.Env = append(os.Environ(),
"OMS_PORTAL_API_KEY=fakeapikeywith22charsa", // 22 characters
"OMS_PORTAL_API=http://localhost:3000/api",
)

output, _ := cmd.CombinedOutput()
outputStr := string(output)

Expect(outputStr).To(ContainSubstring("OMS CLI version"))
})
})

Context("when using a new long-format API key", func() {
It("should not show any warning", func() {
cmd := exec.Command(cliPath, "version")
cmd.Env = append(os.Environ(),
"OMS_PORTAL_API_KEY=4hBieJRj2pWeB9qKJ9wQGE3CrcldLnLwP8fz6qutMjkf1n1",
"OMS_PORTAL_API=http://localhost:3000/api",
)

output, _ := cmd.CombinedOutput()
outputStr := string(output)

Expect(outputStr).To(ContainSubstring("OMS CLI version"))
Expect(outputStr).NotTo(ContainSubstring("old API key"))
Expect(outputStr).NotTo(ContainSubstring("Failed to upgrade"))
})
})

Context("when using a 22-character key with list api-keys command", func() {
It("should attempt the upgrade and handle the error gracefully", func() {
cmd := exec.Command(cliPath, "list", "api-keys")
cmd.Env = append(os.Environ(),
"OMS_PORTAL_API_KEY=fakeapikeywith22charsa", // 22 characters (old format)
"OMS_PORTAL_API=http://localhost:3000/api",
)

output, err := cmd.CombinedOutput()
outputStr := string(output)

Expect(err).To(HaveOccurred())

hasWarning := strings.Contains(outputStr, "old API key") ||
strings.Contains(outputStr, "Failed to upgrade") ||
strings.Contains(outputStr, "Unauthorized")

Expect(hasWarning).To(BeTrue(),
"Should contain warning about old key or auth failure. Got: "+outputStr)
})
})

Context("when checking key length detection", func() {
It("should correctly identify 22-character old format", func() {
oldKey := "fakeapikeywith22charsa"
Expect(len(oldKey)).To(Equal(22))
})

It("should correctly identify new long format", func() {
newKey := "4hBieJRj2pWeB9qKJ9wQGE3CrcldLnLwP8fz6qutMjkf1n1"
Expect(len(newKey)).NotTo(Equal(22))
Expect(len(newKey)).To(BeNumerically(">", 22))
})
})
})

Describe("PreRun Hook Execution", func() {
var (
cliPath string
)

BeforeEach(func() {
cliPath = "./oms-cli"

_, err := os.Stat(cliPath)
if err != nil {
Skip("OMS CLI not found at " + cliPath + ", please build it first with 'make build-cli'")
}
})

Context("when running any OMS command", func() {
It("should execute the PreRun hook", func() {
cmd := exec.Command(cliPath, "version")
cmd.Env = append(os.Environ(),
"OMS_PORTAL_API_KEY=valid-key-format-short",
"OMS_PORTAL_API=http://localhost:3000/api",
)

output, _ := cmd.CombinedOutput()
outputStr := string(output)

Expect(outputStr).To(ContainSubstring("OMS CLI version"))
})
})
})
})
104 changes: 104 additions & 0 deletions cli/cmd/cmd_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,18 @@
package cmd_test

import (
"bytes"
"encoding/json"
"io"
"net/http"
"os"
"testing"

"github.com/codesphere-cloud/oms/cli/cmd"
"github.com/codesphere-cloud/oms/internal/env"
"github.com/codesphere-cloud/oms/internal/portal"
"github.com/stretchr/testify/mock"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
Expand All @@ -14,3 +24,97 @@ func TestCmd(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Cmd Suite")
}

var _ = Describe("RootCmd", func() {
var (
mockEnv *env.MockEnv
mockHttpClient *portal.MockHttpClient
)

BeforeEach(func() {
mockEnv = env.NewMockEnv(GinkgoT())
mockHttpClient = portal.NewMockHttpClient(GinkgoT())
})

AfterEach(func() {
mockEnv.AssertExpectations(GinkgoT())
mockHttpClient.AssertExpectations(GinkgoT())
})

Describe("PreRun hook with old API key", func() {
Context("when API key is 22 characters (old format)", func() {
It("attempts to upgrade the key via GetApiKeyByHeader", func() {
oldKey := "fakeapikeywith22charsa" // 22 characters
keyId := "test-key-id-12345"
expectedNewKey := keyId + oldKey

Expect(os.Setenv("OMS_PORTAL_API_KEY", oldKey)).NotTo(HaveOccurred())
Expect(os.Setenv("OMS_PORTAL_API", "http://test-portal.com/api")).NotTo(HaveOccurred())

mockEnv.EXPECT().GetOmsPortalApi().Return("http://test-portal.com/api")

mockHttpClient.EXPECT().Do(mock.Anything).RunAndReturn(
func(req *http.Request) (*http.Response, error) {
Expect(req.Header.Get("X-API-Key")).To(Equal(oldKey))
Expect(req.URL.Path).To(ContainSubstring("/key"))

response := map[string]string{
"keyId": keyId,
}
body, _ := json.Marshal(response)
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewReader(body)),
}, nil
})

portalClient := &portal.PortalClient{
Env: mockEnv,
HttpClient: mockHttpClient,
}

result, err := portalClient.GetApiKeyByHeader(oldKey)
Expect(err).NotTo(HaveOccurred())
Expect(result).To(Equal(expectedNewKey))

Expect(os.Unsetenv("OMS_PORTAL_API_KEY")).NotTo(HaveOccurred())
Expect(os.Unsetenv("OMS_PORTAL_API")).NotTo(HaveOccurred())
})
})

Context("when API key is not 22 characters (new format)", func() {
It("does not attempt to upgrade the key", func() {
newKey := "new-long-api-key-format-very-long-string"

Expect(os.Setenv("OMS_PORTAL_API_KEY", newKey)).NotTo(HaveOccurred())
Expect(os.Setenv("OMS_PORTAL_API", "http://test-portal.com/api")).NotTo(HaveOccurred())

Expect(len(newKey)).NotTo(Equal(22))

Expect(os.Unsetenv("OMS_PORTAL_API_KEY")).NotTo(HaveOccurred())
Expect(os.Unsetenv("OMS_PORTAL_API")).NotTo(HaveOccurred())
})
})

Context("when API key is empty", func() {
It("does not attempt to upgrade", func() {
Expect(os.Setenv("OMS_PORTAL_API_KEY", "")).NotTo(HaveOccurred())
Expect(os.Setenv("OMS_PORTAL_API", "http://test-portal.com/api")).NotTo(HaveOccurred())

Expect(len(os.Getenv("OMS_PORTAL_API_KEY"))).To(Equal(0))

Expect(os.Unsetenv("OMS_PORTAL_API_KEY")).NotTo(HaveOccurred())
Expect(os.Unsetenv("OMS_PORTAL_API")).NotTo(HaveOccurred())
})
})
})

Describe("GetRootCmd", func() {
It("returns a valid root command", func() {
rootCmd := cmd.GetRootCmd()
Expect(rootCmd).NotTo(BeNil())
Expect(rootCmd.Use).To(Equal("oms"))
Expect(rootCmd.Short).To(Equal("Codesphere Operations Management System (OMS)"))
})
})
})
27 changes: 27 additions & 0 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
package cmd

import (
"fmt"
"log"
"os"

"github.com/codesphere-cloud/cs-go/pkg/io"
"github.com/codesphere-cloud/oms/internal/portal"
"github.com/spf13/cobra"
)

Expand All @@ -25,6 +27,31 @@ func GetRootCmd() *cobra.Command {

This command can be used to run common tasks related to managing codesphere installations,
like downloading new versions.`),
PersistentPreRun: func(cmd *cobra.Command, args []string) {
apiKey := os.Getenv("OMS_PORTAL_API_KEY")

if len(apiKey) == 22 {
fmt.Fprintf(os.Stderr, "Warning: You used an old API key format.\n")
fmt.Fprintf(os.Stderr, "Attempting to upgrade to the new format...\n\n")

portalClient := portal.NewPortalClient()
newApiKey, err := portalClient.GetApiKeyByHeader(apiKey)

if err != nil {
fmt.Fprintf(os.Stderr, "Error: Failed to upgrade old API key: %v\n", err)
return
}

if err := os.Setenv("OMS_PORTAL_API_KEY", newApiKey); err != nil {
fmt.Fprintf(os.Stderr, "Error: Failed to set environment variable: %v\n", err)
return
}
opts.OmsPortalApiKey = newApiKey

fmt.Fprintf(os.Stderr, "Please update your environment variable:\n\n")
fmt.Fprintf(os.Stderr, " export OMS_PORTAL_API_KEY='%s'\n\n", newApiKey)
}
},
}
// General commands
AddVersionCmd(rootCmd)
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ like downloading new versions.
* [oms-cli update](oms-cli_update.md) - Update OMS related resources
* [oms-cli version](oms-cli_version.md) - Print version

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ like downloading new versions.
* [oms-cli update](oms-cli_update.md) - Update OMS related resources
* [oms-cli version](oms-cli_version.md) - Print version

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_beta.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ Be aware that that usage and behavior may change as the features are developed.
* [oms-cli](oms-cli.md) - Codesphere Operations Management System (OMS)
* [oms-cli beta extend](oms-cli_beta_extend.md) - Extend Codesphere ressources such as base images.

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_beta_extend.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ Extend Codesphere ressources such as base images to customize them for your need
* [oms-cli beta](oms-cli_beta.md) - Commands for early testing
* [oms-cli beta extend baseimage](oms-cli_beta_extend_baseimage.md) - Extend Codesphere's workspace base image for customization

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_beta_extend_baseimage.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ oms-cli beta extend baseimage [flags]

* [oms-cli beta extend](oms-cli_beta_extend.md) - Extend Codesphere ressources such as base images.

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_download.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ e.g. available Codesphere packages
* [oms-cli](oms-cli.md) - Codesphere Operations Management System (OMS)
* [oms-cli download package](oms-cli_download_package.md) - Download a codesphere package

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_download_package.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ $ oms-cli download package --version codesphere-v1.55.0 --file installer-lite.ta

* [oms-cli download](oms-cli_download.md) - Download resources available through OMS

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_install.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ Coming soon: Install Codesphere and other components like Ceph and PostgreSQL.
* [oms-cli](oms-cli.md) - Codesphere Operations Management System (OMS)
* [oms-cli install codesphere](oms-cli_install_codesphere.md) - Install a Codesphere instance

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_install_codesphere.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ oms-cli install codesphere [flags]

* [oms-cli install](oms-cli_install.md) - Coming soon: Install Codesphere and other components

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_licenses.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ oms-cli licenses [flags]

* [oms-cli](oms-cli.md) - Codesphere Operations Management System (OMS)

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ eg. available Codesphere packages
* [oms-cli list api-keys](oms-cli_list_api-keys.md) - List API keys
* [oms-cli list packages](oms-cli_list_packages.md) - List available packages

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_list_api-keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ oms-cli list api-keys [flags]

* [oms-cli list](oms-cli_list.md) - List resources available through OMS

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_list_packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ oms-cli list packages [flags]

* [oms-cli list](oms-cli_list.md) - List resources available through OMS

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_register.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ oms-cli register [flags]

* [oms-cli](oms-cli.md) - Codesphere Operations Management System (OMS)

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_revoke.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ eg. api keys.
* [oms-cli](oms-cli.md) - Codesphere Operations Management System (OMS)
* [oms-cli revoke api-key](oms-cli_revoke_api-key.md) - Revoke an API key

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_revoke_api-key.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ oms-cli revoke api-key [flags]

* [oms-cli revoke](oms-cli_revoke.md) - Revoke resources available through OMS

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
2 changes: 1 addition & 1 deletion docs/oms-cli_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ oms-cli update [flags]
* [oms-cli update oms](oms-cli_update_oms.md) - Update the OMS CLI
* [oms-cli update package](oms-cli_update_package.md) - Download a codesphere package

###### Auto generated by spf13/cobra on 23-Oct-2025
###### Auto generated by spf13/cobra on 27-Oct-2025
Loading