feat(x2a): change the project to be source-technology agnostic#2953
feat(x2a): change the project to be source-technology agnostic#2953mareklibra wants to merge 3 commits intoredhat-developer:mainfrom
Conversation
Changed Packages
|
1be7a8b to
a2241b1
Compare
a2241b1 to
7930e25
Compare
| @@ -1,2 +1,2 @@ | |||
| name,description,abbreviation,ownedByGroup,sourceRepoUrl,sourceRepoBranch,targetRepoUrl,targetRepoBranch | |||
| my-examples,Convert chef-examples to Ansible,mex,,https://github.com/x2ansible/chef-examples,main,https://github.com/my-converted-projects/my-examples,target | |||
| my-examples,Convert legacy config to Ansible,mex,,https://github.com/x2ansible/config-examples,main,https://github.com/my-converted-projects/my-examples,target | |||
There was a problem hiding this comment.
we should decide on a standard way for this. legacy config? legacy infra code? legacy sources?
| /** | ||
| * @public | ||
| */ | ||
| export type SourceTechnology = 'chef' | 'puppet' | 'salt' | 'legacy-ansible'; |
| "enum": [ | ||
| "chef", | ||
| "puppet", | ||
| "salt", | ||
| "legacy-ansible" |
| enum: | ||
| - chef | ||
| - puppet | ||
| - salt | ||
| - legacy-ansible |
| # Strip git tokens from files before committing to prevent secret leaks. | ||
| # The x2a tool may embed SOURCE_REPO_TOKEN in generated files (e.g., Policyfile.lock.json) | ||
| # when Chef resolves cookbook sources using authenticated URLs. | ||
| # when the source tool resolves dependencies using authenticated URLs. |
There was a problem hiding this comment.
what is the "source tool"?
| # Usage: app.py init [OPTIONS] USER_REQUIREMENTS | ||
| # --source-dir DIRECTORY Source directory to analyze | ||
| USER_REQ="${USER_PROMPT:-Analyze the Chef cookbooks and create a migration plan}" | ||
| USER_REQ="${USER_PROMPT:-Analyze the source configuration and create a migration plan}" |
There was a problem hiding this comment.
source configurations? legacy config? see my comment above
| /** | ||
| * @public | ||
| */ | ||
| export type SourceTechnology = 'chef' | 'puppet' | 'salt' | 'legacy-ansible'; |
| chef: ['chef'], | ||
| puppet: ['puppet'], | ||
| salt: ['salt', 'saltstack'], | ||
| 'legacy-ansible': ['legacy-ansible', 'ansible'], |
| type: string | ||
| enum: | ||
| - chef | ||
| - puppet |
There was a problem hiding this comment.
I would nto add yet chef or salt, it's not yet created
7930e25 to
7f0b32b
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2953 +/- ##
==========================================
+ Coverage 57.12% 60.72% +3.59%
==========================================
Files 2065 2066 +1
Lines 63363 63751 +388
Branches 16624 16631 +7
==========================================
+ Hits 36199 38713 +2514
+ Misses 25495 23537 -1958
+ Partials 1669 1501 -168
*This pull request uses carry forward flags. Click here to find out more. Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
|
|
||
| 1. Open the Backstage instance and navigate to `/create`. | ||
| 2. Select the **Chef-to-Ansible Conversion Project** template (`chef-conversion-project-template`). | ||
| 2. Select the **Legacy-to-Ansible Conversion Project** template (`x2a-conversion-project-template`). |
There was a problem hiding this comment.
Older versions of Ansible? Legacy sounds like we're understimated what it's doing.
There was a problem hiding this comment.
It was -to-.
But I missed that in the second round of rename, changing to Infrastructure Conversion Project now.
| web-app,wapp,https://github.com/myorg/web-app-chef,main,https://github.com/myorg/web-app-ansible,main,Convert web app cookbook,team-platform | ||
| db-setup,dbset,gitlab.com?owner=myorg&repo=db-chef,develop,gitlab.com?owner=myorg&repo=db-ansible,main,, | ||
| cache-svc,cache,bitbucket.org?workspace=myws&project=x2a&repo=cache-chef,main,,main,Cache service conversion, | ||
| web-app,wapp,https://github.com/myorg/web-app-legacy,main,https://github.com/myorg/web-app-ansible,main,Convert web app configuration,team-platform |
There was a problem hiding this comment.
I would keep here the chef example to be honest, add a bit more "clear" context
There was a problem hiding this comment.
makes sense, reverting
| title: Chef-to-Ansible Conversion Project | ||
| description: Initiate a conversion of a Chef cookbook or directory into a new Ansible Playbook repository. | ||
| name: x2a-conversion-project-template | ||
| title: Legacy-to-Ansible Conversion Project |
There was a problem hiding this comment.
Infraestructure conversion project?
| /** | ||
| * @public | ||
| */ | ||
| export type SourceTechnology = 'chef' | 'legacy-ansible' | 'powershell'; |
There was a problem hiding this comment.
I would use Ansible as we used in the types in the Input agent: https://github.com/x2ansible/x2a-convertor/blob/main/src/types/technology.py#L4
There was a problem hiding this comment.
ok, changing to ansible.
ansible is easier for using but our flow is about conversion older version to a newer one.
| ? [ | ||
| { | ||
| name: 'SOURCE_TECHNOLOGY', | ||
| value: params.sourceTechnology, |
There was a problem hiding this comment.
Be aware that you're using legacy-ansible, and we using ansible on input agents, the thing will break here.
There was a problem hiding this comment.
saying this, why this line is currently working is a totally unknown to me
rhdh-plugins/workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh
Lines 421 to 426 in 0b28051
| cd /app | ||
| echo "Working directory: $(pwd)" | ||
|
|
||
| if [ -z "${SOURCE_TECHNOLOGY:-}" ]; then |
There was a problem hiding this comment.
We can do one line here on the default no?
There was a problem hiding this comment.
The idea is to log that we are using something unknown to simplify debugging.
Having the logging and setting of the default as a one-liner would be more cryptic.
| -H "Authorization: Bearer ${TOKEN}" \ | ||
| -d '{ | ||
| "name": "My Chef Migration", | ||
| "name": "My Legacy Project Migration", |
There was a problem hiding this comment.
my source automation project
| * | ||
| * @public | ||
| */ | ||
| export const SOURCE_TECHNOLOGY_ALIASES: Record<SourceTechnology, string[]> = { |
There was a problem hiding this comment.
this should be a few ValueObjects to be honest and an Enum on technology, it's going to be much cleaner and easy to follow in the future.
https://martinfowler.com/bliki/ValueObject.html
There was a problem hiding this comment.
There are always more to achieve something.
IMHO, the Value Objects would bring more boilerplate here and provide no/limited benefits.
We do not have any rich logic to be encapsulated with the data, just one function for simple alias-to-canonical comparison. It's easy to maintain this way.
If we encapsulate this by value objects, we would need to write more dummy code when adding a new technology. And still maintaining a sort of an array for the desired canonical mapping.
There was a problem hiding this comment.
Ok, for me this is simpler, has a pourpose, and can be simpler to understand and add in the future:
abstract class SourceTechnology {
abstract readonly canonical: string;
abstract readonly aliases: ReadonlySet<string>;
matches(raw: string): boolean {
return this.aliases.has(raw.trim().toLocaleLowerCase('en-US'));
}
toString(): string {
return this.canonical;
}
}
class ChefTechnology extends SourceTechnology {
readonly canonical = 'chef';
readonly aliases = new Set(['chef']);
}
class AnsibleTechnology extends SourceTechnology {
readonly canonical = 'ansible';
readonly aliases = new Set(['ansible', 'legacy-ansible']);
}
class PowerShellTechnology extends SourceTechnology {
readonly canonical = 'powershell';
readonly aliases = new Set(['powershell', 'powershell-dsc', 'dsc']);
}
```
And after, we can have a registry like that:
```
class SourceTechnologyRegistry {
private readonly technologies: ReadonlyMap<string, SourceTechnology>;
constructor(technologies: SourceTechnology[]) {
// Pre-build the alias → technology map at construction time
const map = new Map<string, SourceTechnology>();
for (const tech of technologies) {
for (const alias of tech.aliases) {
if (map.has(alias)) {
throw new Error(
`Duplicate alias "${alias}" registered by "${tech.canonical}" and "${map.get(alias)!.canonical}"`
);
}
map.set(alias, tech);
}
}
this.technologies = map;
}
normalize(raw: string | undefined): SourceTechnology | undefined {
if (!raw) return undefined;
return this.technologies.get(raw.trim().toLocaleLowerCase('en-US'));
}
has(raw: string): boolean {
return this.normalize(raw) !== undefined;
}
all(): SourceTechnology[] {
return [...new Set(this.technologies.values())];
}
canonicals(): string[] {
return this.all().map(t => t.canonical);
}
findByCanonical(canonical: string): SourceTechnology | undefined {
return this.all().find(t => t.canonical === canonical);
}
}
```
that for me, it's simpler, and can be compose one thing on top of another.
Rephrasing all texts from being Chef-oriented to more generic variants. There is explicit mapping from free-form agentic findings to a new SourceTechnology enum (normalizeSourceTechnology.ts). Signed-off-by: Marek Libra <marek.libra@gmail.com>
7f0b32b to
48710fd
Compare
|



Fixes: FLPATH-3431
Rephrasing all texts from being Chef-oriented to more generic variants.
There is newly explicit mapping from free-form agentic findings to the new
SourceTechnologyenum (normalizeSourceTechnology.ts). This became the input for thex2a-convertorparameter.