Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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 go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/charmbracelet/glamour v0.7.0
github.com/charmbracelet/lipgloss v0.11.0
github.com/client9/gospell v0.0.0-20160306015952-90dfc71015df
github.com/confluentinc/ccloud-sdk-go-v1-public v0.0.0-20250521223017-0e8f6f971b52
github.com/confluentinc/ccloud-sdk-go-v1-public v0.0.0-20251024191705-f32f6cebfdd1
github.com/confluentinc/ccloud-sdk-go-v2/ai v0.1.0
github.com/confluentinc/ccloud-sdk-go-v2/apikeys v0.4.0
github.com/confluentinc/ccloud-sdk-go-v2/billing v0.3.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/compose-spec/compose-go/v2 v2.1.3 h1:bD67uqLuL/XgkAK6ir3xZvNLFPxPScEi1KW7R5esrLE=
github.com/compose-spec/compose-go/v2 v2.1.3/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
github.com/confluentinc/ccloud-sdk-go-v1-public v0.0.0-20250521223017-0e8f6f971b52 h1:19qEGhkbZa5fopKCe0VPIV+Sasby4Pv10z9ZaktwWso=
github.com/confluentinc/ccloud-sdk-go-v1-public v0.0.0-20250521223017-0e8f6f971b52/go.mod h1:62EMf+5uFEt1BJ2q8WMrUoI9VUSxAbDnmZCGRt/MbA0=
github.com/confluentinc/ccloud-sdk-go-v1-public v0.0.0-20251024191705-f32f6cebfdd1 h1:mXLlTii+xqGk9wNtAoPnrJsvR1bwuaEmWD4TuUoTYfw=
github.com/confluentinc/ccloud-sdk-go-v1-public v0.0.0-20251024191705-f32f6cebfdd1/go.mod h1:62EMf+5uFEt1BJ2q8WMrUoI9VUSxAbDnmZCGRt/MbA0=
github.com/confluentinc/ccloud-sdk-go-v2/ai v0.1.0 h1:zSF4OQUJXWH2JeAo9rsq13ibk+JFdzITGR8S7cFMpzw=
github.com/confluentinc/ccloud-sdk-go-v2/ai v0.1.0/go.mod h1:DoxqzzF3JzvJr3fWkvCiOHFlE0GoYpozWxFZ1Ud9ntA=
github.com/confluentinc/ccloud-sdk-go-v2/apikeys v0.4.0 h1:8fWyLwMuy8ec0MVF5Avd54UvbIxhDFhZzanHBVwgxdw=
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/run_requirements_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var (

regularOrgContextState = &config.ContextState{Auth: &config.AuthConfig{Organization: testserver.RegularOrg}}
endOfFreeTrialSuspendedOrgContextState = &config.ContextState{Auth: &config.AuthConfig{Organization: testserver.SuspendedOrg(ccloudv1.SuspensionEventType_SUSPENSION_EVENT_END_OF_FREE_TRIAL)}}
pauseTrialSuspendedOrgContextState = &config.ContextState{Auth: &config.AuthConfig{Organization: testserver.SuspendedOrg(ccloudv1.SuspensionEventType_SUSPENSION_EVENT_PAUSE_TRIAL)}}
normalSuspendedOrgContextState = &config.ContextState{Auth: &config.AuthConfig{Organization: testserver.SuspendedOrg(ccloudv1.SuspensionEventType_SUSPENSION_EVENT_CUSTOMER_INITIATED_ORG_DEACTIVATION)}}

cloudCfg = func(contextState *config.ContextState) *config.Config {
Expand Down Expand Up @@ -89,6 +90,7 @@ func TestErrIfMissingRunRequirement_Error(t *testing.T) {
}{
{RequireCloudLogin, onPremCfg, config.RequireCloudLoginErr},
{RequireCloudLogin, cloudCfg(endOfFreeTrialSuspendedOrgContextState), config.RequireCloudLoginFreeTrialEndedOrgUnsuspendedErr},
{RequireCloudLogin, cloudCfg(pauseTrialSuspendedOrgContextState), config.RequireCloudLoginPauseTrialOrgUnsuspendedErr},
{RequireCloudLogin, cloudCfg(normalSuspendedOrgContextState), config.RequireCloudLoginOrgUnsuspendedErr},
{RequireCloudLoginAllowFreeTrialEnded, onPremCfg, config.RequireCloudLoginErr},
{RequireCloudLoginAllowFreeTrialEnded, cloudCfg(normalSuspendedOrgContextState), config.RequireCloudLoginOrgUnsuspendedErr},
Expand Down
10 changes: 10 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ var (
ErrorMsg: "you must unsuspend your organization to use this command",
SuggestionsMsg: errors.EndOfFreeTrialSuggestions,
}
RequireCloudLoginPauseTrialOrgUnsuspendedErr = &errors.RunRequirementError{
ErrorMsg: "you must resume your organization to use this command",
SuggestionsMsg: errors.PauseTrialSuggestions,
}
RequireCloudLoginOrOnPremErr = &errors.RunRequirementError{
ErrorMsg: "you must log in to use this command",
SuggestionsMsg: "Log in with `confluent login`.\n" + signupSuggestion,
Expand Down Expand Up @@ -669,6 +673,8 @@ func (c *Config) CheckIsCloudLogin() error {
if c.isContextStatePresent() && c.isOrgSuspended() {
if c.isLoginBlockedByOrgSuspension() {
return RequireCloudLoginOrgUnsuspendedErr
} else if c.isOrgPauseTrialSuspension() {
return RequireCloudLoginPauseTrialOrgUnsuspendedErr
} else {
return RequireCloudLoginFreeTrialEndedOrgUnsuspendedErr
}
Expand Down Expand Up @@ -794,6 +800,10 @@ func (c *Config) isLoginBlockedByOrgSuspension() bool {
return utils.IsLoginBlockedByOrgSuspension(c.Context().GetSuspensionStatus())
}

func (c *Config) isOrgPauseTrialSuspension() bool {
return utils.IsOrgPauseTrialSuspended(c.Context().GetSuspensionStatus())
}

// Parse `--context` flag value into config struct
// Call ParseFlagsIntoContext which handles environment and cluster flags
func (c *Config) ParseFlagsIntoConfig(cmd *cobra.Command) error {
Expand Down
1 change: 1 addition & 0 deletions pkg/errors/error_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const (
ByokKeyNotFoundSuggestions = "Ensure the self-managed key exists and has not been deleted, or register a new key via `confluent byok register`."
EndOfFreeTrialErrorMsg = `organization "%s" has been suspended because your free trial has ended`
EndOfFreeTrialSuggestions = "To continue using Confluent Cloud, please enter a credit card with `confluent billing payment update` or claim a promo code with `confluent billing promo add`. To enter payment via the UI, please go to https://confluent.cloud/login."
PauseTrialSuggestions = "To continue using Confluent Cloud, resume your paused organization at https://confluent.cloud/login."
EnsureCpSixPlusSuggestions = "Ensure that you are running against MDS with CP 6.0+."
ExactlyOneSetErrorMsg = "exactly one of %v must be set"
ListResourceSuggestions = "List available %s with `%s list`."
Expand Down
9 changes: 8 additions & 1 deletion pkg/utils/org_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ func IsOrgEndOfFreeTrialSuspended(suspensionStatus *ccloudv1.SuspensionStatus) b
return IsOrgSuspended(suspensionStatus) && eventType == ccloudv1.SuspensionEventType_SUSPENSION_EVENT_END_OF_FREE_TRIAL
}

func IsOrgPauseTrialSuspended(suspensionStatus *ccloudv1.SuspensionStatus) bool {
eventType := suspensionStatus.GetEventType()
return IsOrgSuspended(suspensionStatus) && eventType == ccloudv1.SuspensionEventType_SUSPENSION_EVENT_PAUSE_TRIAL
}

func IsLoginBlockedByOrgSuspension(suspensionStatus *ccloudv1.SuspensionStatus) bool {
eventType := suspensionStatus.GetEventType()
return IsOrgSuspended(suspensionStatus) && eventType != ccloudv1.SuspensionEventType_SUSPENSION_EVENT_END_OF_FREE_TRIAL
return IsOrgSuspended(suspensionStatus) &&
eventType != ccloudv1.SuspensionEventType_SUSPENSION_EVENT_END_OF_FREE_TRIAL &&
eventType != ccloudv1.SuspensionEventType_SUSPENSION_EVENT_PAUSE_TRIAL
}
104 changes: 104 additions & 0 deletions pkg/utils/org_utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package utils

import (
"testing"

ccloudv1 "github.com/confluentinc/ccloud-sdk-go-v1-public"
"github.com/stretchr/testify/require"
)

func TestIsOrgPauseTrialSuspended(t *testing.T) {
tests := []struct {
name string
suspensionStatus *ccloudv1.SuspensionStatus
expected bool
}{
{
name: "PAUSE_TRIAL event should be pause trial",
suspensionStatus: &ccloudv1.SuspensionStatus{
Status: ccloudv1.SuspensionStatusType_SUSPENSION_COMPLETED,
EventType: ccloudv1.SuspensionEventType_SUSPENSION_EVENT_PAUSE_TRIAL,
},
expected: true,
},
{
name: "END_OF_FREE_TRIAL event should not be pause trial",
suspensionStatus: &ccloudv1.SuspensionStatus{
Status: ccloudv1.SuspensionStatusType_SUSPENSION_COMPLETED,
EventType: ccloudv1.SuspensionEventType_SUSPENSION_EVENT_END_OF_FREE_TRIAL,
},
expected: false,
},
{
name: "CUSTOMER_INITIATED_ORG_DEACTIVATION should not be pause trial",
suspensionStatus: &ccloudv1.SuspensionStatus{
Status: ccloudv1.SuspensionStatusType_SUSPENSION_COMPLETED,
EventType: ccloudv1.SuspensionEventType_SUSPENSION_EVENT_CUSTOMER_INITIATED_ORG_DEACTIVATION,
},
expected: false,
},
{
name: "Not suspended should not be pause trial",
suspensionStatus: &ccloudv1.SuspensionStatus{
Status: ccloudv1.SuspensionStatusType_SUSPENSION_UNKNOWN,
EventType: ccloudv1.SuspensionEventType_SUSPENSION_EVENT_PAUSE_TRIAL,
},
expected: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := IsOrgPauseTrialSuspended(tt.suspensionStatus)
require.Equal(t, tt.expected, result)
})
}
}

func TestIsLoginBlockedByOrgSuspension(t *testing.T) {
tests := []struct {
name string
suspensionStatus *ccloudv1.SuspensionStatus
expected bool
}{
{
name: "PAUSE_TRIAL should not block login",
suspensionStatus: &ccloudv1.SuspensionStatus{
Status: ccloudv1.SuspensionStatusType_SUSPENSION_COMPLETED,
EventType: ccloudv1.SuspensionEventType_SUSPENSION_EVENT_PAUSE_TRIAL,
},
expected: false,
},
{
name: "END_OF_FREE_TRIAL should not block login",
suspensionStatus: &ccloudv1.SuspensionStatus{
Status: ccloudv1.SuspensionStatusType_SUSPENSION_COMPLETED,
EventType: ccloudv1.SuspensionEventType_SUSPENSION_EVENT_END_OF_FREE_TRIAL,
},
expected: false,
},
{
name: "CUSTOMER_INITIATED_ORG_DEACTIVATION should block login",
suspensionStatus: &ccloudv1.SuspensionStatus{
Status: ccloudv1.SuspensionStatusType_SUSPENSION_COMPLETED,
EventType: ccloudv1.SuspensionEventType_SUSPENSION_EVENT_CUSTOMER_INITIATED_ORG_DEACTIVATION,
},
expected: true,
},
{
name: "Not suspended should not block login",
suspensionStatus: &ccloudv1.SuspensionStatus{
Status: ccloudv1.SuspensionStatusType_SUSPENSION_UNKNOWN,
EventType: ccloudv1.SuspensionEventType_SUSPENSION_EVENT_CUSTOMER_INITIATED_ORG_DEACTIVATION,
},
expected: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := IsLoginBlockedByOrgSuspension(tt.suspensionStatus)
require.Equal(t, tt.expected, result)
})
}
}