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
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Alert, Link, SxProps, Theme, Typography } from "@mui/material";
import { FormattedMessage } from "react-intl";
import { ReactNode } from "react-markdown/lib/react-markdown";
import { DOCS_AWS_CREDENTIALS_ACCESS_KEYS, DOCS_FINOPS_AUTHENTICATION_TYPE_MIGRATION } from "urls";
import { SPACING_2 } from "utils/layouts";

const ParagraphHelper = ({ messageId, link, sx }: { messageId: string; link?: string; sx?: SxProps<Theme> }) => (
<Typography sx={sx}>
<FormattedMessage
id={messageId}
values={{
link: (chunks: ReactNode[]) => {
const linkText = chunks.length > 0 ? chunks : link;
return (
<Link data-test-id="documentation_link" href={link} target="_blank" rel="noopener">
{linkText}
</Link>
);
},
strong: (chunks: ReactNode) => <strong>{chunks}</strong>,
break: <br />
}}
/>
</Typography>
);

const AwsAuthenticationTypeAlert = ({ authenticationType }: { authenticationType: string }) => {
const getAlert = (authenticationType: string) => {
switch (authenticationType) {
case "assumedRole":
return (
<>
<ParagraphHelper sx={{ marginBottom: SPACING_2 }} messageId="awsAuthenticationTypeAlert:assumedRoleP1" />
<ParagraphHelper sx={{ marginBottom: SPACING_2 }} messageId="awsAuthenticationTypeAlert:assumedRoleP2" />
<ParagraphHelper messageId="awsAuthenticationTypeAlert:assumedRoleP3" />
</>
);
case "assumedRoleLinked":
return (
<>
<ParagraphHelper sx={{ marginBottom: SPACING_2 }} messageId="awsAuthenticationTypeAlert:assumedRoleP1" />
<ParagraphHelper messageId="awsAuthenticationTypeAlert:assumedRoleP2" />
</>
);
case "accessKeyLinked":
case "accessKey":
return (
<>
<ParagraphHelper
sx={{ marginBottom: SPACING_2 }}
messageId="awsAuthenticationTypeAlert:accessKeyP1"
link={DOCS_FINOPS_AUTHENTICATION_TYPE_MIGRATION}
/>
<ParagraphHelper messageId="awsAuthenticationTypeAlert:accessKeyP2" link={DOCS_AWS_CREDENTIALS_ACCESS_KEYS} />
</>
);

default:
return <></>;
}
};

return (
<Alert severity="warning" sx={{ mt: 1, mb: 1 }}>
{getAlert(authenticationType)}
</Alert>
);
};

export default AwsAuthenticationTypeAlert;
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
AUTHENTICATION_TYPES,
AuthenticationTypeSelector
} from "components/forms/ConnectCloudAccountForm/FormElements/AwsConnectionForm";
import AwsAuthenticationTypeAlert from "./AwsAuthenticationTypeAlert";
import AwsDescription from "./AwsDescription";

const CostAndUsageReport = () => (
Expand All @@ -36,9 +37,9 @@ const getAwsAuthType = (config) => {
const AwsCredentials = ({ config }) => {
const currentAuthType = getAwsAuthType(config);
const [authenticationType, setAuthenticationType] = useState<string>(currentAuthType);
const getAwsInputs = (config) => {
const fullAuthenticationType: string = authenticationType + (config.linked ? "Linked" : "");

const fullAuthenticationType: string = authenticationType + (config.linked ? "Linked" : "");
const getAwsInputs = (config) => {
switch (fullAuthenticationType) {
case "assumedRole":
case "assumedRoleLinked":
Expand All @@ -63,8 +64,13 @@ const AwsCredentials = ({ config }) => {
};
return (
<>
<AuthenticationTypeSelector authenticationType={authenticationType} setAuthenticationType={setAuthenticationType} />
<AwsDescription config={config} authenticationType={authenticationType} />
{currentAuthType === AUTHENTICATION_TYPES.ACCESS_KEY && (
<>
<AuthenticationTypeSelector authenticationType={authenticationType} setAuthenticationType={setAuthenticationType} />
<AwsAuthenticationTypeAlert authenticationType={fullAuthenticationType} />
</>
)}
<AwsDescription authenticationType={fullAuthenticationType} />
{getAwsInputs(config)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,95 +1,57 @@
import { Typography } from "@mui/material";
import { ReactNode } from "react";
import { Link, SxProps, Theme, Typography } from "@mui/material";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
import { intl } from "translations/react-intl-config";
import {
DOCS_HYSTAX_AWS_LINKED_DISCOVER_RESOURCES,
DOCS_HYSTAX_CONNECT_AWS_ROOT,
DOCS_HYSTAX_MIGRATE_FROM_CUR_TO_DATA_EXPORTS_CUR_2_0
} from "urls";
import { DOCS_FINOPS_AWS_DATA_SOURCE, DOCS_FINOPS_AWS_DATA_SOURCE_MIGRATE_CUR_2_0 } from "urls";
import { SPACING_2 } from "utils/layouts";

const AwsDescription = ({ config, authenticationType }) => {
const getAwsDescription = (config) => {
if (authenticationType === "assumedRole") {
if (config.linked) {
const ParagraphHelper = ({ messageId, link, sx }: { messageId: string; link?: string; sx?: SxProps<Theme> }) => (
<Typography sx={sx}>
<FormattedMessage
id={messageId}
values={{
link: (chunks: ReactNode[]) => {
const linkText = chunks.length > 0 ? chunks : link;
return (
<Link data-test-id="documentation_link" href={link} target="_blank" rel="noopener">
{linkText}
</Link>
);
}
}}
/>
</Typography>
);

const AwsDescription = ({ authenticationType }: { authenticationType: string }) => {
const getAwsDescription = (authenticationType: string) => {
switch (authenticationType) {
case "assumedRoleLinked":
case "accessKeyLinked":
return (
<ParagraphHelper
messageId="awsDataSourceUpdateDescriptionP1"
link={DOCS_FINOPS_AWS_DATA_SOURCE}
sx={{ marginBottom: SPACING_2 }}
/>
);
case "assumedRole":
case "accessKey":
return (
<Typography sx={{ marginBottom: SPACING_2 }}>
<FormattedMessage
id="createAwsAssumedRoleLinkedDescription"
values={{ action: intl.formatMessage({ id: "save" }) }}
<>
<ParagraphHelper messageId="awsDataSourceUpdateDescriptionP1" link={DOCS_FINOPS_AWS_DATA_SOURCE} />
<ParagraphHelper
messageId="awsDataSourceUpdateDescriptionP2"
link={DOCS_FINOPS_AWS_DATA_SOURCE_MIGRATE_CUR_2_0}
sx={{ marginBottom: SPACING_2 }}
/>
</Typography>
</>
);
}

return (
<Typography sx={{ marginBottom: SPACING_2 }}>
<FormattedMessage id="createAwsAssumedRoleDescription" values={{ action: intl.formatMessage({ id: "save" }) }} />
</Typography>
);
default:
return <></>;
}

if (config.linked) {
return (
<Typography gutterBottom>
<FormattedMessage
id="createAwsLinkedDocumentationReference3"
values={{
discoverResourcesLink: (chunks) => (
<Link
data-test-id="link_iam_user"
href={DOCS_HYSTAX_AWS_LINKED_DISCOVER_RESOURCES}
target="_blank"
rel="noopener"
>
{chunks}
</Link>
)
}}
/>
</Typography>
);
}

return (
<Typography gutterBottom component="div">
<div>
<FormattedMessage
id="createAwsRootDocumentationReference"
values={{
link: (chunks) => (
<Link data-test-id="link_guide" href={DOCS_HYSTAX_CONNECT_AWS_ROOT} target="_blank" rel="noopener">
{chunks}
</Link>
),
strong: (chunks) => <strong>{chunks}</strong>
}}
/>
</div>
<div>
<FormattedMessage
id="migrateToCur2.0"
values={{
link: (chunks) => (
<Link
data-test-id="link_guide"
href={DOCS_HYSTAX_MIGRATE_FROM_CUR_TO_DATA_EXPORTS_CUR_2_0}
target="_blank"
rel="noopener"
>
{chunks}
</Link>
),
strong: (chunks) => <strong>{chunks}</strong>
}}
/>
</div>
</Typography>
);
};

return <>{getAwsDescription(config)}</>;
return <>{getAwsDescription(authenticationType)}</>;
};

export default AwsDescription;
Original file line number Diff line number Diff line change
Expand Up @@ -524,8 +524,6 @@ const UpdateDataSourceCredentialsForm = ({

const { handleSubmit } = methods;

const isAssumedRole = Boolean(config?.assume_role_account_id && config?.assume_role_name);

return (
<FormProvider {...methods}>
<form
Expand All @@ -536,7 +534,7 @@ const UpdateDataSourceCredentialsForm = ({
>
<Description type={type} config={config} />
<CredentialInputs type={type} config={config} />
{!isAssumedRole && <UpdateCredentialsWarning type={type} />}
<UpdateCredentialsWarning type={type} />
<FormButtonsWrapper>
<ButtonLoader
dataTestId="btn_update_data_source_credentials"
Expand Down
9 changes: 8 additions & 1 deletion ngui/ui/src/translations/en-US/appOverride.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@
"awsAccountId": "AWS account ID",
"awsAccountType": "AWS account type",
"awsAssumedRoleName": "Assumed role name",
"awsAuthenticationTypeAlert:accessKeyP1": "Access keys are a set of permanent credentials. This authentication type is <link>not recommended</link> by SoftwareOne or AWS - use an <strong>assumed role</strong> where possible.",
"awsAuthenticationTypeAlert:accessKeyP2": "<link>More information</link>",
"awsAuthenticationTypeAlert:assumedRoleP1": "Switching from an access key to an assumed role is permanent. After you make this change, you can’t switch back to using an access key for this data source.",
"awsAuthenticationTypeAlert:assumedRoleP2": "If you later want to use an access key again, you’ll need to delete this data source and recreate it with access key credentials. This will delete all existing data for this data source and require a full reimport of the resource and billing data.",
"awsAuthenticationTypeAlert:assumedRoleP3": "This will also affect all the billing data of any member account data sources linked to this management account.",
"awsDataSourceUpdateDescriptionP1": "For detailed information on how to add and manage AWS data sources, refer to our <link>documentation</link>.",
"awsDataSourceUpdateDescriptionP2": "To switch from legacy cost and usage reports to cost and usage reports 2.0, <link>follow these steps</link>.",
"awsDataSourcesBackdropMessage": "To get real data, please connect an AWS data source.",
"awsDataSourcesContactManagerBackdropMessage": "Please contact your organization manager to connect an AWS data source to get real data.",
"awsLinked": "AWS linked",
Expand Down Expand Up @@ -370,7 +377,7 @@
"createAlibabaDocumentationReference": "Please provide programmatic credentials for a RAM user with a ReadOnlyAccess permission attached. <link>Read this guide</link> for more details.",
"createAnomalyDetectionPolicyTitle": "Create anomaly detection policy",
"createAutomaticAssignmentRuleBackdropMessage": "Please add an assignment rule to let FinOps For Cloud automatically assign newly discovered resources to a pool.",
"createAwsAssumedRoleDescription": "Connection through Assumed Role provides the most modern and secure way to connect FinOps for Cloud to your AWS account. Please fill the fields below with the necessary information, then click the \"Show Role\" button to get the Assumed Role definition. Once you create the corresponding Role in the AWS Account you're connecting, click the {action} button.",
"createAwsAssumedRoleDescription": "Connection through Assumed Role provides the most modern and secure way to connect FinOps for Cloud to your AWS account. Please fill the fields below with the necessary information, then click the {action} button.",
"createAwsAssumedRoleLinkedDescription": "Connection through Assumed Role provides the most modern and secure way to connect FinOps for Cloud to your AWS account. Please fill the fields below with the necessary information, then click the {action} button.",
"createAwsDefaultAssumedRoleDDocumentationReference1": "<warning>SoftwareOne recommends using the Assume Role method to provide access to your AWS account. For more information, please see AWS documentation. <link>View documentation</link></warning>",
"createAwsDefaultAssumedRoleDDocumentationReference2": "Please provide programmatic credentials for an IAM user with access to resource and billing data.",
Expand Down
5 changes: 5 additions & 0 deletions ngui/ui/src/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,11 @@ export const DOCS_HYSTAX_SLACK_INTEGRATION = `${DOCS_HYSTAX_OPTSCALE}integration
export const DOCS_HYSTAX_GOOGLE_CALENDAR_INTEGRATION = `${DOCS_HYSTAX_OPTSCALE}integrations.html#google-calendar`;
export const DOCS_HYSTAX_CONNECT_ALIBABA_CLOUD = dataSourceConnectionDocUrl("e2e_alibaba.html");

export const DOCS_FINOPS_AUTHENTICATION_TYPE_MIGRATION = `${DOCS_HYSTAX_OPTSCALE}system/data-sources/amazon-web-services#aws-organizations`;
export const DOCS_FINOPS_AWS_DATA_SOURCE = `${DOCS_HYSTAX_OPTSCALE}system/data-sources/amazon-web-services`;
export const DOCS_FINOPS_AWS_DATA_SOURCE_MIGRATE_CUR_2_0 = `${DOCS_HYSTAX_OPTSCALE}system/data-sources/amazon-web-services/migrate-from-legacy-cur-to-cur-2.0`;
export const DOCS_AWS_CREDENTIALS_ACCESS_KEYS = `https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html`;

// Hystax open source links
export const GITHUB_HYSTAX_K8S_COST_METRICS_COLLECTOR =
"https://github.com/hystax/helm-charts/tree/main/charts/kube-cost-metrics-collector";
Expand Down