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

add secure, protect connect guide link to learning resources #172

Merged
merged 1 commit into from
Nov 19, 2024
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
195 changes: 124 additions & 71 deletions downstream.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,116 +3,169 @@
const fs = require('fs');
const path = require('path');

// Parse command-line arguments
const args = process.argv.slice(2);
const dryRun = args.includes('--dry-run');

// Define file paths
const constantsPath = path.join('src', 'constants', 'links.ts');
const localesPath = path.join('locales');
const localesPath = path.join('locales', 'en', 'plugin__kuadrant-console-plugin.json');
const consoleExtensionsPath = path.join('console-extensions.json');
const localeFile = path.join(localesPath, 'en', 'plugin__kuadrant-console-plugin.json');

const upstreamName = 'Kuadrant';
const downstreamName = 'Connectivity Link';

const upstreamDocumentation = 'https://docs.kuadrant.io';
const upstreamReleaseNotes = 'https://github.com/Kuadrant/kuadrant-operator/releases';

const downstreamDocumentation =
'https://docs.redhat.com/en/documentation/red_hat_connectivity_link/1.0';
const downstreamReleaseNotes =
'https://docs.redhat.com/html-single/release_notes_for_connectivity_link_1.0/index';

const isUpstream = process.argv.includes('--upstream');

const nameToReplace = isUpstream ? downstreamName : upstreamName;
const nameToInsert = isUpstream ? upstreamName : downstreamName;
const docsLinkToReplace = isUpstream ? downstreamDocumentation : upstreamDocumentation;
const docsLinkToInsert = isUpstream ? upstreamDocumentation : downstreamDocumentation;
const releaseNotesToReplace = isUpstream ? downstreamReleaseNotes : upstreamReleaseNotes;
const releaseNotesToInsert = isUpstream ? upstreamReleaseNotes : downstreamReleaseNotes;

function updateJsonValues(filePath, searchValue, replaceValue) {
// Replacement mappings
const replacements = {
// Direct string replacements for links.ts
[constantsPath]: {
type: 'simple',
mappings: {
// Order matters: specific URLs first to prevent partial matches
'https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/secure-protect-connect-single-multi-cluster/':
'https://docs.redhat.com/en/documentation/red_hat_connectivity_link/1.0/html-single/configuring_and_deploying_gateway_policies_with_connectivity_link/index',
'https://docs.kuadrant.io/latest/kuadrant-operator/doc/observability/examples/':
'https://docs.redhat.com/en/documentation/red_hat_connectivity_link/1.0/html-single/connectivity_link_observability_guide/index',
'https://docs.kuadrant.io':
'https://docs.redhat.com/en/documentation/red_hat_connectivity_link/1.0/',
'https://github.com/Kuadrant/kuadrant-operator/releases':
'https://docs.redhat.com/en/documentation/red_hat_connectivity_link/1.0/html-single/release_notes_for_connectivity_link_1.0/index',
Kuadrant: 'Connectivity Link',
},
},

// Regex-based replacements for console-extensions.json
[consoleExtensionsPath]: {
type: 'regex',
patterns: [
{
search: /%plugin__kuadrant-console-plugin~Kuadrant%/g,
replace: 'Connectivity Link',
},
],
},

// Value-only replacements for plugin__kuadrant-console-plugin.json
[localesPath]: {
type: 'value',
replaceValue: 'Connectivity Link', // Replace "Kuadrant" with "Connectivity Link" in values only
},
};

function replaceSimpleStrings(filePath, mappings) {
try {
const content = fs.readFileSync(filePath, 'utf-8');
const jsonContent = JSON.parse(content);

let updated = false;
let content = fs.readFileSync(filePath, 'utf-8');
let updatedContent = content;
let changesMade = false;

Object.keys(jsonContent).forEach((key) => {
if (jsonContent[key].includes(searchValue)) {
jsonContent[key] = jsonContent[key].replace(new RegExp(searchValue, 'g'), replaceValue);
updated = true;
Object.entries(mappings).forEach(([search, replace]) => {
if (content.includes(search)) {
console.log(`Replacing '${search}' with '${replace}' in ${filePath}`);
updatedContent = updatedContent.split(search).join(replace);
changesMade = true;
}
});

if (updated) {
fs.writeFileSync(filePath, JSON.stringify(jsonContent, null, 2));
console.log(`Updated values in ${filePath}`);
if (changesMade) {
if (!dryRun) {
fs.writeFileSync(filePath, updatedContent, 'utf-8');
console.log(`Updated content in ${filePath}`);
} else {
console.log(`[Dry Run] Would update content in ${filePath}`);
}
} else {
console.log(`No changes made to ${filePath}`);
}
} catch (error) {
console.error(`Failed to update ${filePath}: ${error}`);
console.error(`Failed to update ${filePath}: ${error.message}`);
}
}

function updateFileContent(filePath, replacements) {
function replaceWithRegex(filePath, patterns) {
try {
let content = fs.readFileSync(filePath, 'utf-8');
let updatedContent = content;
let changesMade = false;

replacements.forEach(({ searchValue, replaceValue }) => {
updatedContent = updatedContent.replace(new RegExp(searchValue, 'g'), replaceValue);
patterns.forEach(({ search, replace }) => {
if (search.test(updatedContent)) {
console.log(`Applying regex replacement: ${search} -> ${replace} in ${filePath}`);
updatedContent = updatedContent.replace(search, replace);
changesMade = true;
}
});

if (content !== updatedContent) {
fs.writeFileSync(filePath, updatedContent);
console.log(`Updated content in ${filePath}`);
if (changesMade) {
if (!dryRun) {
// Validate JSON integrity
JSON.parse(updatedContent); // Throws if invalid
fs.writeFileSync(filePath, updatedContent, 'utf-8');
console.log(`Updated JSON content in ${filePath}`);
} else {
console.log(`[Dry Run] Would update JSON content in ${filePath}`);
}
} else {
console.log(`No changes made to ${filePath}`);
}
} catch (error) {
console.error(`Failed to update ${filePath}: ${error}`);
console.error(`Failed to update ${filePath}: ${error.message}`);
}
}

function traverseAndReplace(obj, replaceValue) {
if (typeof obj === 'string') {
return obj.includes('Kuadrant') ? obj.split('Kuadrant').join(replaceValue) : obj;
} else if (Array.isArray(obj)) {
return obj.map((item) => traverseAndReplace(item, replaceValue));
} else if (typeof obj === 'object' && obj !== null) {
const newObj = {};
Object.entries(obj).forEach(([key, value]) => {
newObj[key] = traverseAndReplace(value, replaceValue);
});
return newObj;
} else {
return obj;
}
}

function updateConsoleExtensions(filePath, searchValue, replaceValue) {
function replaceValuesInJson(filePath, replaceValue) {
try {
const content = fs.readFileSync(filePath, 'utf-8');
const jsonContent = JSON.parse(content);
const jsonData = JSON.parse(content);

let updated = false;
const updatedJsonData = traverseAndReplace(jsonData, replaceValue);

jsonContent.forEach((item) => {
if (item.properties && item.properties.name === searchValue) {
item.properties.name = replaceValue;
updated = true;
if (JSON.stringify(jsonData) !== JSON.stringify(updatedJsonData)) {
if (!dryRun) {
const updatedContentStr = JSON.stringify(updatedJsonData, null, 2);
fs.writeFileSync(filePath, updatedContentStr, 'utf-8');
console.log(`Updated JSON content in ${filePath}`);
} else {
console.log(`[Dry Run] Would update JSON content in ${filePath}`);
}
});

if (updated) {
fs.writeFileSync(filePath, JSON.stringify(jsonContent, null, 2));
console.log(`Updated console extensions in ${filePath}`);
} else {
console.log(`No changes made to ${filePath}`);
}
} catch (error) {
console.error(`Failed to update ${filePath}: ${error}`);
console.error(`Failed to update ${filePath}: ${error.message}`);
}
}

console.log(`Updating locale files to ${isUpstream ? 'upstream' : 'downstream'}...`);
updateJsonValues(localeFile, nameToReplace, nameToInsert);

console.log(`Updating constants.links.ts to ${isUpstream ? 'upstream' : 'downstream'}...`);

updateFileContent(constantsPath, [
{ searchValue: docsLinkToReplace, replaceValue: docsLinkToInsert },
{ searchValue: releaseNotesToReplace, replaceValue: releaseNotesToInsert },
]);
if (dryRun) {
console.log('Running in Dry-Run mode. No files will be modified.');
}

console.log(`Updating console-extensions.json to ${isUpstream ? 'upstream' : 'downstream'}...`);
updateConsoleExtensions(
consoleExtensionsPath,
`%plugin__kuadrant-console-plugin~${nameToReplace}%`,
nameToInsert,
);
Object.entries(replacements).forEach(([filePath, rules]) => {
switch (rules.type) {
case 'simple':
replaceSimpleStrings(filePath, rules.mappings);
break;
case 'regex':
replaceWithRegex(filePath, rules.patterns);
break;
case 'value':
replaceValuesInJson(filePath, rules.replaceValue);
break;
default:
console.warn(`Unknown replacement type for ${filePath}`);
}
});

console.log('Update complete!');
console.log('Downstream replacement update complete!');
1 change: 1 addition & 0 deletions locales/en/plugin__kuadrant-console-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"Collapse Getting Started": "Collapse Getting Started",
"Configure via": "Configure via",
"Configured Limits": "Configured Limits",
"Configuring and deploying Gateway policies with Kuadrant": "Configuring and deploying Gateway policies with Kuadrant",
"Create": "Create",
"Create AuthPolicy": "Create AuthPolicy",
"Create DNS Policy": "Create DNS Policy",
Expand Down
11 changes: 11 additions & 0 deletions src/components/KuadrantOverviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,17 @@ const KuadrantOverviewPage: React.FC = () => {
{t('View Documentation')} <ExternalLinkAltIcon />
</Text>
</StackItem>
<StackItem>
<Text
component="a"
href={EXTERNAL_LINKS.secureConnectProtect}
className="kuadrant-dashboard-resource-link"
target="_blank"
>
{t('Configuring and deploying Gateway policies with Kuadrant')}{' '}
<ExternalLinkAltIcon />
</Text>
</StackItem>
</Stack>
</FlexItem>
<Divider orientation={{ default: 'vertical' }} />
Expand Down
4 changes: 2 additions & 2 deletions src/constants/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export const EXTERNAL_LINKS = {
// TODO: Update these when available for real
documentation: 'https://docs.kuadrant.io',
releaseNotes: 'https://github.com/Kuadrant/kuadrant-operator/releases',
quickStarts:
'https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/secure-protect-connect/',
secureConnectProtect:
'https://docs.kuadrant.io/latest/kuadrant-operator/doc/user-guides/secure-protect-connect-single-multi-cluster/',
highlights: 'https://kuadrant.io/blog/',
blog: 'https://kuadrant.io/blog/',
};
Loading