Skip to content

Commit da618ee

Browse files
authored
fix(cloud): fix to default org flow (#7860)
The previous implementation didn't prevent migrated single-tenant users from selecting another org than the one their project ID belongs to, leading to confusing behaviour. Here, if a project ID is present, we ensure that the organization ID belonging to it (if any) is always used, and is automatically written into the project config on disk.
1 parent 6aaa139 commit da618ee

File tree

4 files changed

+547
-66
lines changed

4 files changed

+547
-66
lines changed

core/src/cloud/api/api.ts

Lines changed: 76 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,72 @@ import { styles } from "../../logger/styles.js"
3838

3939
const refreshThreshold = 10 // Threshold (in seconds) subtracted to jwt validity when checking if a refresh is needed
4040

41+
/**
42+
* Resolves the organization ID for a legacy project, or returns the provided one if none is found by the API.
43+
*/
44+
async function resolveOrganizationIdForLegacyProject({
45+
cloudDomain,
46+
authToken,
47+
legacyProjectId,
48+
organizationId,
49+
log,
50+
__trpcClientOverrideForTesting,
51+
}: {
52+
cloudDomain: string
53+
authToken: string
54+
legacyProjectId: string
55+
organizationId: string | undefined
56+
log: Log
57+
__trpcClientOverrideForTesting?: ApiTrpcClient
58+
}): Promise<string | undefined> {
59+
log.debug({ msg: `Legacy project ID found, resolving organization ID from project ID` })
60+
try {
61+
const resolvedOrgId = await GardenCloudApi.getDefaultOrganizationIdForLegacyProject(
62+
cloudDomain,
63+
authToken,
64+
legacyProjectId,
65+
__trpcClientOverrideForTesting
66+
)
67+
68+
if (resolvedOrgId) {
69+
log.debug({ msg: `Resolved organization ID: ${resolvedOrgId}` })
70+
71+
// Check for conflict and log if org ID is being updated
72+
if (organizationId && organizationId !== resolvedOrgId) {
73+
log.info({
74+
msg:
75+
dedent`
76+
Organization ID mismatch detected. The configured organizationId (${organizationId}) differs from the organization associated with the legacy project ID (${resolvedOrgId}).
77+
78+
Using ${resolvedOrgId} from the legacy project ID. Your project configuration will be updated automatically.
79+
` + "\n",
80+
})
81+
} else if (!organizationId) {
82+
log.warn({
83+
msg:
84+
dedent`
85+
Organization ID resolved from legacy project ID. Your project configuration will be updated to include the organization ID and comment out the legacy fields (project ID and domain).
86+
87+
Recommended configuration:
88+
89+
${styles.command(`organizationId: ${resolvedOrgId}`)}
90+
# id: ${legacyProjectId} # Legacy field, no longer needed
91+
` + "\n",
92+
})
93+
}
94+
95+
return resolvedOrgId
96+
} else {
97+
log.debug({ msg: `Could not resolve organization ID from project ID` })
98+
return organizationId
99+
}
100+
} catch (error) {
101+
log.warn({ msg: `Failed to resolve organization ID from project ID: ${error}` })
102+
// Fall back to provided organizationId if resolution fails
103+
return organizationId
104+
}
105+
}
106+
41107
export type GardenCloudApiFactory = (params: GardenCloudApiFactoryParams) => Promise<GardenCloudApi | undefined>
42108

43109
export class GardenCloudError extends GardenError {
@@ -206,34 +272,16 @@ export class GardenCloudApi {
206272
}
207273
}
208274

209-
// Resolve organization ID if not provided but legacy project ID is available
210-
if (!organizationId && legacyProjectId) {
211-
cloudFactoryLog.debug({ msg: `No organization ID provided, attempting to resolve from project ID` })
212-
try {
213-
organizationId = await GardenCloudApi.getDefaultOrganizationIdForLegacyProject(
214-
cloudDomain,
215-
authToken,
216-
legacyProjectId,
217-
__trpcClientOverrideForTesting
218-
)
219-
if (organizationId) {
220-
cloudFactoryLog.debug({ msg: `Resolved organization ID: ${organizationId}` })
221-
cloudFactoryLog.warn({
222-
msg:
223-
dedent`
224-
Organization ID resolved from project ID. Please update your project configuration to specify the organization ID.
225-
226-
Add the following to your project configuration to avoid this message in the future:
227-
228-
${styles.command(`organizationId: ${organizationId}`)}
229-
` + "\n",
230-
})
231-
} else {
232-
cloudFactoryLog.debug({ msg: `Could not resolve organization ID from project ID` })
233-
}
234-
} catch (error) {
235-
cloudFactoryLog.warn({ msg: `Failed to resolve organization ID from project ID: ${error}` })
236-
}
275+
// Resolve organization ID from legacy project ID if available (always takes precedence)
276+
if (legacyProjectId) {
277+
organizationId = await resolveOrganizationIdForLegacyProject({
278+
cloudDomain,
279+
authToken,
280+
legacyProjectId,
281+
organizationId,
282+
log: cloudFactoryLog,
283+
__trpcClientOverrideForTesting,
284+
})
237285
}
238286

239287
if (!organizationId) {

0 commit comments

Comments
 (0)