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

Replace isTeam with new flags #39794

Merged
merged 38 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
da44be3
Add new flags to modules
mcbattirola Mar 21, 2024
9bca525
Add deprecated comments to isTeam
mcbattirola Mar 22, 2024
b6da55f
Make support flag an enum
mcbattirola Mar 22, 2024
cd25989
Add a TODO instead of deprecating flag right away
mcbattirola Mar 22, 2024
ed38ae5
Merge branch 'master' into mcbattirola/remove-team--new-flags
mcbattirola Mar 22, 2024
c8e7f63
Add gogoproto.jsontag to new fields
mcbattirola Mar 22, 2024
a2c8be6
remove meaning from enum zero value
mcbattirola Mar 22, 2024
e31bc6d
Reuse proto.SupportType instead of suping
mcbattirola Mar 22, 2024
3de00cd
Replace isTeam for new flags in web app
mcbattirola Mar 22, 2024
fefc4fb
Update proto file: rename enum 0 value to unspecified;fix json tag ca…
mcbattirola Mar 22, 2024
cfc7296
Reuse proto file instead of aliasing it
mcbattirola Mar 22, 2024
05bd479
Merge branch 'mcbattirola/remove-team--new-flags' into mcbattirola/re…
mcbattirola Mar 22, 2024
b50c46f
undo removing method by accident
mcbattirola Mar 22, 2024
b6c13c3
Add MobileDeviceManagement field to web config struct
mcbattirola Mar 22, 2024
1bc8bf7
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Mar 25, 2024
2dcf627
Improve comments
mcbattirola Mar 25, 2024
4cf1030
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 18, 2024
ff6393d
Merge branch 'master' of github.com:gravitational/teleport into mcbat…
mcbattirola Apr 18, 2024
f1d73a9
Fix tests
mcbattirola Apr 18, 2024
292c628
Merge branch 'mcbattirola/remove-team--use-new-flags' of github.com:g…
mcbattirola Apr 18, 2024
efc7d40
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 18, 2024
ae218c9
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 19, 2024
126dce2
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 19, 2024
97f25bc
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 22, 2024
34ef90a
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 25, 2024
c65190d
Simplify lockedFeatures object
mcbattirola Apr 25, 2024
7ca4457
Include JoinActiveSessions in the web config object
mcbattirola Apr 25, 2024
2bde5a4
Remove more instances of isTeam
mcbattirola Apr 25, 2024
1b6a7f2
Apply suggestions from code review - improve comments
mcbattirola Apr 25, 2024
380bff8
Use consistent comments to remove isTeam
mcbattirola Apr 25, 2024
53afcb0
Update godocs comments
mcbattirola Apr 26, 2024
abca9af
Revert removign `isTeam` from stories it still should
mcbattirola Apr 26, 2024
28946dd
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 26, 2024
1c6427a
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 29, 2024
ae0d473
Fix godoc typo
mcbattirola Apr 29, 2024
480e891
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 29, 2024
f68ed2f
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 29, 2024
c49e8fd
Merge branch 'master' into mcbattirola/remove-team--use-new-flags
mcbattirola Apr 30, 2024
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
21 changes: 21 additions & 0 deletions api/client/webclient/webconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,34 @@ type WebConfig struct {
// CustomTheme is a string that represents the name of the custom theme that the WebUI should use.
CustomTheme string `json:"customTheme"`
// IsTeam is true if [Features.ProductType] = Team
// Prefer checking the cluster features over this flag, as this will be removed.
mcbattirola marked this conversation as resolved.
Show resolved Hide resolved
IsTeam bool `json:"isTeam"`
// IsIGSEnabled is true if [Features.IdentityGovernance] = true
IsIGSEnabled bool `json:"isIgsEnabled"`
// featureLimits define limits for features.
// Typically used with feature teasers if feature is not enabled for the
// product type eg: Team product contains teasers to upgrade to Enterprise.
FeatureLimits FeatureLimits `json:"featureLimits"`
// Questionnaire indicates whether cluster users should get an onboarding questionnaire
Questionnaire bool `json:"questionnaire"`
// indicates if the cluster billing & lifecycle is managed via Stripe
mcbattirola marked this conversation as resolved.
Show resolved Hide resolved
IsStripeManaged bool `json:"isStripeManaged"`
// ExternalAuditStorage indicates whether the EAS feature is enabled in the cluster.
ExternalAuditStorage bool `json:"externalAuditStorage"`
// PremiumSupport indicates if the customer has premium support
PremiumSupport bool `json:"premiumSupport"`
// JoinActiveSessions indicates whether joining active sessions via web UI is enabled
JoinActiveSessions bool `json:"joinActiveSessions"`
// AccessRequests enables access requests
AccessRequests bool `json:"accessRequests"`
// TrustedDevices enables trusted devices pages
TrustedDevices bool `json:"trustedDevices"`
// OIDC enables the OIDC integration flow
OIDC bool `json:"oidc"`
// SAML enables the SAML integration flow
SAML bool `json:"saml"`
// MobileDeviceManagement enables adding Jamf plugin
MobileDeviceManagement bool `json:"mobileDeviceManagement"`
mcbattirola marked this conversation as resolved.
Show resolved Hide resolved
}

// featureLimits define limits for features.
Expand Down
2 changes: 1 addition & 1 deletion lib/httplib/httpheaders.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ var indexCSPStringCache *cspCache = newCSPCache()

func getIndexContentSecurityPolicyString(cfg proto.Features, urlPath string) string {
// Check for result with this cfg and urlPath in cache
withStripe := cfg.GetProductType() == proto.ProductType_PRODUCT_TYPE_TEAM
withStripe := cfg.GetIsStripeManaged()
key := fmt.Sprintf("%v-%v", withStripe, urlPath)
if cspString, ok := indexCSPStringCache.get(key); ok {
return cspString
Expand Down
8 changes: 4 additions & 4 deletions lib/httplib/httplib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ func TestSetIndexContentSecurityPolicy(t *testing.T) {
},
},
{
name: "for cloud based usage, Team product (with stripe, no wasm)",
features: proto.Features{Cloud: true, IsUsageBased: true, ProductType: proto.ProductType_PRODUCT_TYPE_TEAM},
name: "for cloud based usage, Stripe managed product (with stripe, no wasm)",
features: proto.Features{Cloud: true, IsUsageBased: true, IsStripeManaged: true},
urlPath: "/web/index.js",
expectedCspVals: map[string]string{
"default-src": "'self'",
Expand Down Expand Up @@ -346,8 +346,8 @@ func TestSetIndexContentSecurityPolicy(t *testing.T) {
},
},
{
name: "for cloud based usage & desktop session, Team product (with stripe, with wasm)",
features: proto.Features{Cloud: true, IsUsageBased: true, ProductType: proto.ProductType_PRODUCT_TYPE_TEAM},
name: "for cloud based usage & desktop session, Stripe managed product (with stripe, with wasm)",
features: proto.Features{Cloud: true, IsUsageBased: true, IsStripeManaged: true},
urlPath: "/web/cluster/:clusterId/desktops/:desktopName/:username",
expectedCspVals: map[string]string{
"default-src": "'self'",
Expand Down
2 changes: 1 addition & 1 deletion lib/integrations/externalauditstorage/configurator.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func NewDraftConfigurator(ctx context.Context, ecaSvc ExternalAuditStorageGetter

func newConfigurator(ctx context.Context, spec *externalauditstorage.ExternalAuditStorageSpec, integrationSvc services.IntegrationsGetter, alertService ClusterAlertService, optFns ...func(*Options)) (*Configurator, error) {
// ExternalAuditStorage is only available in Cloud Enterprise
if !modules.GetModules().Features().Cloud || modules.GetModules().Features().IsTeam() {
if !modules.GetModules().Features().Cloud || !modules.GetModules().Features().ExternalAuditStorage {
return &Configurator{isUsed: false}, nil
}

Expand Down
20 changes: 10 additions & 10 deletions lib/integrations/externalauditstorage/configurator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ func TestConfiguratorIsUsed(t *testing.T) {
name: "cloud enterprise without config",
modules: &modules.TestModules{
TestFeatures: modules.Features{
Cloud: true,
IsUsageBasedBilling: false,
Cloud: true,
ExternalAuditStorage: true,
},
},
wantIsUsed: false,
Expand All @@ -112,8 +112,8 @@ func TestConfiguratorIsUsed(t *testing.T) {
name: "cloud enterprise with only draft",
modules: &modules.TestModules{
TestFeatures: modules.Features{
Cloud: true,
IsUsageBasedBilling: false,
Cloud: true,
ExternalAuditStorage: true,
},
},
// Just create draft, External Audit Storage should be disabled, it's
Expand All @@ -129,8 +129,8 @@ func TestConfiguratorIsUsed(t *testing.T) {
name: "cloud enterprise with cluster config",
modules: &modules.TestModules{
TestFeatures: modules.Features{
Cloud: true,
IsUsageBasedBilling: false,
Cloud: true,
ExternalAuditStorage: true,
},
},
// Create draft and promote it to cluster.
Expand Down Expand Up @@ -178,8 +178,8 @@ func TestCredentialsCache(t *testing.T) {

modules.SetTestModules(t, &modules.TestModules{
TestFeatures: modules.Features{
Cloud: true,
IsUsageBasedBilling: false,
Cloud: true,
ExternalAuditStorage: true,
},
})

Expand Down Expand Up @@ -316,8 +316,8 @@ func TestDraftConfigurator(t *testing.T) {

modules.SetTestModules(t, &modules.TestModules{
TestFeatures: modules.Features{
Cloud: true,
IsUsageBasedBilling: false,
Cloud: true,
ExternalAuditStorage: true,
},
})

Expand Down
2 changes: 1 addition & 1 deletion lib/modules/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func (f Features) IGSEnabled() bool {
return f.IdentityGovernanceSecurity
}

// TODO(mcbattirola): Deprecate IsTeam once it's unused.
// TODO(mcbattirola): remove isTeam when it is no longer used
func (f Features) IsTeam() bool {
return f.ProductType == ProductTypeTeam
}
Expand Down
3 changes: 2 additions & 1 deletion lib/service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,8 @@ func TestAthenaAuditLogSetup(t *testing.T) {
ctx := context.Background()
modules.SetTestModules(t, &modules.TestModules{
TestFeatures: modules.Features{
Cloud: true,
Cloud: true,
ExternalAuditStorage: true,
},
})

Expand Down
16 changes: 15 additions & 1 deletion lib/web/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -1694,6 +1694,9 @@ func (h *Handler) getWebConfig(w http.ResponseWriter, r *http.Request, p httprou
h.log.WithError(err).Error("Cannot read target version")
}

// TODO(mcbattirola): remove isTeam when it is no longer used
isTeam := clusterFeatures.GetProductType() == proto.ProductType_PRODUCT_TYPE_TEAM
mcbattirola marked this conversation as resolved.
Show resolved Hide resolved

webCfg := webclient.WebConfig{
Auth: authSettings,
CanJoinSessions: canJoinSessions,
Expand All @@ -1708,13 +1711,24 @@ func (h *Handler) getWebConfig(w http.ResponseWriter, r *http.Request, p httprou
AssistEnabled: assistEnabled,
HideInaccessibleFeatures: clusterFeatures.GetFeatureHiding(),
CustomTheme: clusterFeatures.GetCustomTheme(),
IsTeam: clusterFeatures.GetProductType() == proto.ProductType_PRODUCT_TYPE_TEAM,
IsIGSEnabled: clusterFeatures.GetIdentityGovernance(),
FeatureLimits: webclient.FeatureLimits{
AccessListCreateLimit: int(clusterFeatures.GetAccessList().GetCreateLimit()),
AccessMonitoringMaxReportRangeLimit: int(clusterFeatures.GetAccessMonitoring().GetMaxReportRangeLimit()),
AccessRequestMonthlyRequestLimit: int(clusterFeatures.GetAccessRequests().GetMonthlyRequestLimit()),
},
Questionnaire: clusterFeatures.GetQuestionnaire(),
IsStripeManaged: clusterFeatures.GetIsStripeManaged(),
ExternalAuditStorage: clusterFeatures.GetExternalAuditStorage(),
PremiumSupport: clusterFeatures.GetSupportType() == proto.SupportType_SUPPORT_TYPE_PREMIUM,
AccessRequests: clusterFeatures.GetAccessRequests().MonthlyRequestLimit > 0,
TrustedDevices: clusterFeatures.GetDeviceTrust().GetEnabled(),
OIDC: clusterFeatures.GetOIDC(),
SAML: clusterFeatures.GetSAML(),
MobileDeviceManagement: clusterFeatures.GetMobileDeviceManagement(),
JoinActiveSessions: clusterFeatures.GetJoinActiveSessions(),
// TODO(mcbattirola): remove isTeam when it is no longer used
IsTeam: isTeam,
}

resource, err := h.cfg.ProxyClient.GetClusterName()
Expand Down
22 changes: 15 additions & 7 deletions lib/web/apiserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4497,11 +4497,12 @@ func TestGetWebConfig(t *testing.T) {
PrivateKeyPolicy: keys.PrivateKeyPolicyNone,
MOTD: MOTD,
},
CanJoinSessions: true,
ProxyClusterName: env.server.ClusterName(),
IsCloud: false,
AssistEnabled: false,
AutomaticUpgrades: false,
CanJoinSessions: true,
ProxyClusterName: env.server.ClusterName(),
IsCloud: false,
AssistEnabled: false,
AutomaticUpgrades: false,
JoinActiveSessions: true,
}

// Make a request.
Expand Down Expand Up @@ -4551,6 +4552,7 @@ func TestGetWebConfig(t *testing.T) {
expectedCfg.AutomaticUpgrades = true
expectedCfg.AutomaticUpgradesTargetVersion = "v" + teleport.Version
expectedCfg.AssistEnabled = false
expectedCfg.JoinActiveSessions = false

// request and verify enabled features are enabled.
re, err = clt.Get(ctx, endpoint, nil)
Expand Down Expand Up @@ -4603,6 +4605,9 @@ func TestGetWebConfig_IGSFeatureLimits(t *testing.T) {
AccessMonitoring: modules.AccessMonitoringFeature{
MaxReportRangeLimit: 10,
},
IsUsageBasedBilling: true,
IsStripeManaged: true,
Questionnaire: true,
},
})

Expand All @@ -4619,8 +4624,11 @@ func TestGetWebConfig_IGSFeatureLimits(t *testing.T) {
AccessListCreateLimit: 5,
AccessMonitoringMaxReportRangeLimit: 10,
},
IsTeam: true,
IsIGSEnabled: true,
IsTeam: true,
IsIGSEnabled: true,
IsStripeManaged: true,
Questionnaire: true,
IsUsageBasedBilling: true,
}

// Make a request.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function IntegrationTiles({
hasIntegrationAccess?: boolean;
hasExternalAuditStorage?: boolean;
}) {
const isCloudEnterprise = cfg.isCloud && !cfg.isTeam;
const externalAuditStorageEnabled = cfg.externalAuditStorage;
const isOnpremEnterprise = cfg.isEnterprise && !cfg.isCloud;

return (
Expand Down Expand Up @@ -76,7 +76,7 @@ export function IntegrationTiles({
</IntegrationTile>
{!isOnpremEnterprise && (
<IntegrationTile
disabled={!hasExternalAuditStorage || !isCloudEnterprise}
disabled={!hasExternalAuditStorage || !externalAuditStorageEnabled}
as={hasExternalAuditStorage ? Link : null}
to={
hasExternalAuditStorage
Expand All @@ -93,7 +93,7 @@ export function IntegrationTiles({
<Text>AWS External Audit Storage</Text>
{renderExternalAuditStorageBadge(
hasExternalAuditStorage,
isCloudEnterprise
externalAuditStorageEnabled
)}
</IntegrationTile>
)}
Expand Down
1 change: 0 additions & 1 deletion web/packages/teleport/src/Sessions/Sessions.story.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ test('loaded', () => {
});

test('active sessions CTA', () => {
cfg.isTeam = true;
cfg.isEnterprise = true;
const { container } = render(<ActiveSessionsCTA />);
expect(container.firstChild).toMatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ exports[`active sessions CTA 1`] = `
<a
class="c10"
height="36px"
href="https://goteleport.com/r/upgrade-team?e_4.4.0-dev&utm_campaign=CTA_ACTIVE_SESSIONS"
href="https://goteleport.com/r/upgrade-igs?e_4.4.0-dev&utm_campaign=CTA_ACTIVE_SESSIONS"
mcbattirola marked this conversation as resolved.
Show resolved Hide resolved
kind="primary"
rel="noreferrer"
style="text-transform: none;"
Expand Down
3 changes: 2 additions & 1 deletion web/packages/teleport/src/Sessions/useSessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { context, trace } from '@opentelemetry/api';
import { Session } from 'teleport/services/session';

import Ctx from 'teleport/teleportContext';
import cfg from 'teleport/config';

const tracer = trace.getTracer('userSessions');

Expand Down Expand Up @@ -57,6 +58,6 @@ export default function useSessions(ctx: Ctx, clusterId: string) {
sessions,
// moderated is available with any enterprise editions
showModeratedSessionsCTA: !ctx.isEnterprise,
showActiveSessionsCTA: ctx.lockedFeatures.activeSessions,
showActiveSessionsCTA: !cfg.joinActiveSessions,
};
}
2 changes: 1 addition & 1 deletion web/packages/teleport/src/Support/Support.story.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ test('support Enterprise', () => {

test('support Enterprise with CTA', () => {
cfg.isEnterprise = true;
cfg.isTeam = true;
cfg.premiumSupport = true;
const { container } = render(
<MemoryRouter>
<SupportEnterpriseWithCTA />
Expand Down
2 changes: 1 addition & 1 deletion web/packages/teleport/src/Support/Support.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function SupportContainer({ children }: { children?: React.ReactNode }) {
const cluster = ctx.storeUser.state.cluster;

// showCTA returns the premium support value for enterprise customers and true for OSS users
const showCTA = cfg.isEnterprise ? ctx.lockedFeatures.premiumSupport : true;
const showCTA = cfg.isEnterprise ? !cfg.premiumSupport : true;

return (
<Support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,7 @@ exports[`support Enterprise with CTA 1`] = `
</a>
<a
class="c13"
href="https://goteleport.com/r/upgrade-team?e_4.4.0-dev&utm_campaign=CTA_PREMIUM_SUPPORT"
href="https://goteleport.com/r/upgrade-igs?e_4.4.0-dev&utm_campaign=CTA_PREMIUM_SUPPORT"
mcbattirola marked this conversation as resolved.
Show resolved Hide resolved
kind="primary"
rel="noreferrer"
style="text-transform: none;"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,12 @@ import { CtaEvent, userEventService } from 'teleport/services/userEvent';

import { ButtonLockedFeature } from './ButtonLockedFeature';

const defaultIsTeamFlag = cfg.isTeam;
const defaultIsEnterpriseFlag = cfg.isEnterprise;

describe('buttonLockedFeature', () => {
afterEach(() => {
jest.resetAllMocks();

cfg.isTeam = defaultIsTeamFlag;
cfg.isEnterprise = defaultIsEnterpriseFlag;
});

Expand All @@ -59,35 +57,8 @@ describe('buttonLockedFeature', () => {
expect(screen.queryByTestId('locked-icon')).not.toBeInTheDocument();
});

test('it has upgrade-team href for Team Plan', () => {
const version = ctx.storeUser.state.cluster.authVersion;
cfg.isTeam = true;
cfg.isEnterprise = true;

renderWithContext(
<ButtonLockedFeature noIcon={true}>text</ButtonLockedFeature>
);
expect(screen.getByText('text').closest('a')).toHaveAttribute(
'href',
`https://goteleport.com/r/upgrade-team?e_${version}&utm_campaign=CTA_UNSPECIFIED`
);

renderWithContext(
<ButtonLockedFeature noIcon={true} event={CtaEvent.CTA_ACCESS_REQUESTS}>
othertext
</ButtonLockedFeature>
);
expect(screen.getByText('othertext').closest('a')).toHaveAttribute(
'href',
`https://goteleport.com/r/upgrade-team?e_${version}&utm_campaign=${
CtaEvent[CtaEvent.CTA_ACCESS_REQUESTS]
}`
);
});

test('it has upgrade-community href for community edition', () => {
const version = ctx.storeUser.state.cluster.authVersion;
cfg.isTeam = false;
cfg.isEnterprise = false;
renderWithContext(
<ButtonLockedFeature noIcon={true}>text</ButtonLockedFeature>,
Expand Down Expand Up @@ -118,7 +89,6 @@ describe('buttonLockedFeature', () => {

test('it has upgrade-igs href for Enterprise + IGS Plan', () => {
const version = ctx.storeUser.state.cluster.authVersion;
cfg.isTeam = false;
cfg.isEnterprise = true;

renderWithContext(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('externalAuditStorageCta', () => {
});

cfg.isCloud = isCloud;
ctx.lockedFeatures.externalCloudAudit = lockedFeature;
cfg.externalAuditStorage = lockedFeature;

jest
.spyOn(storageService, 'getExternalAuditStorageCtaDisabled')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { ButtonLockedFeature } from '../ButtonLockedFeature';
export const ExternalAuditStorageCta = () => {
const [showCta, setShowCta] = useState<boolean>(false);
const ctx = useTeleport();
const featureEnabled = !ctx.lockedFeatures.externalCloudAudit;
const featureEnabled = !cfg.externalAuditStorage;
const userHasAccess = ctx.getFeatureFlags().enrollIntegrationsOrPlugins;

useEffect(() => {
Expand Down
Loading
Loading