-
Notifications
You must be signed in to change notification settings - Fork 4
✨ Implement addon. #2
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
Conversation
WalkthroughA new action-based framework is introduced for an addon, supporting "import," "fetch," and "generate" operations. The implementation includes new action types, a base action context, and provider integrations for Cloud Foundry and Helm. The main routine is refactored to use the new action model with SSH agent initialization. Supporting modules and dependencies are updated, and new directories are established for templates and assets. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Main
participant ActionFactory
participant Action
participant Provider
participant Addon
participant Helm
User->>Main: Start program
Main->>ActionFactory: NewAction(Data.Action)
ActionFactory->>Action: Instantiate Fetch/Import/Generate
Main->>Action: Run(Data)
alt Fetch
Action->>Action: setApplication()
Action->>Provider: Fetch Manifest
Provider->>Addon: Create Manifest
else Import
Action->>Action: setPlatform()
Action->>Provider: Find Applications (Filter)
loop For each application found
Provider->>Addon: Create Application
end
else Generate
Action->>Action: setApplication()
Action->>Action: selectIdentity()
Action->>Addon: Get Generators
loop For each generator
Action->>Action: fetchTemplates()
Action->>Helm: Generate Files
Action->>Addon: Write Asset Files
end
Action->>Addon: Commit Asset Repository
end
Action->>Main: Return result
Estimated code review effort3 (~45 minutes) Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Signed-off-by: Jeff Ortel <[email protected]>
Signed-off-by: Jeff Ortel <[email protected]>
Signed-off-by: Jeff Ortel <[email protected]>
Signed-off-by: Jeff Ortel <[email protected]>
Signed-off-by: Jeff Ortel <[email protected]>
Signed-off-by: Jeff Ortel <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 18
🧹 Nitpick comments (7)
cmd/fetch.go (1)
52-54: Use consistent logging prefix format.The success message lacks the
[Fetch]prefix used elsewhere in the method.addon.Activity( - "Manifest (id=%d) created.", + "[Fetch] Manifest (id=%d) created.", manifest.ID)cmd/main.go (1)
58-63: Consider SSH agent cleanup for better resource management.The SSH agent is started but never explicitly stopped, which could lead to resource leaks in long-running processes.
// // SSH agent := ssh.Agent{} err = agent.Start() if err != nil { return } +defer agent.Stop()Note: Verify that the
ssh.Agenttype has aStop()method available.cmd/helm/generator.go (1)
12-14: Consider using package-level functions instead of empty struct.The Generator struct is empty and could be replaced with package-level functions for better simplicity.
-// Generator is a helm generator. -type Generator struct { -} - -// Generate generates assets. +// Generate generates assets using Helm. // Returns a list of files (content). -func (g *Generator) Generate(templateDir string, values api.Map) (files Files, err error) { +func Generate(templateDir string, values api.Map) (files Files, err error) {cmd/generate.go (2)
13-13: Consider using a more specific type alias name.The type alias
Filesis too generic and could conflict with other packages. Consider a more specific name likeGeneratedFilesorAssetFiles.-type Files = map[string]string +type GeneratedFiles = map[string]string
175-178: Validate directory permissions.The function creates directories with 0755 permissions, which might be too permissive. Consider using more restrictive permissions.
- err = os.MkdirAll(templateDir, 0755) + err = os.MkdirAll(templateDir, 0750)cmd/cloudfoundry/provider.go (2)
69-71: Handle type assertion failure explicitly.The type assertion failure is silently ignored. Consider logging or returning an error for unexpected types.
appRef, cast := ref.(cfp.AppReference) if !cast { + addon.Log.Error(fmt.Errorf("unexpected application reference type: %T", ref), "Failed to cast application reference") continue }
123-131: Optimize space matching logic.The current implementation has O(n) complexity for each match. Consider using a map for O(1) lookups when dealing with many spaces.
func (f *Filter) MatchSpace(name string) (match bool) { + if len(f.Spaces) == 0 { + return true // No filter means match all + } for _, s := range f.Spaces { match = s == name if match { break } } return }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (8)
cmd/action.go(1 hunks)cmd/cloudfoundry/provider.go(1 hunks)cmd/fetch.go(1 hunks)cmd/generate.go(1 hunks)cmd/helm/generator.go(1 hunks)cmd/import.go(1 hunks)cmd/main.go(2 hunks)go.mod(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
cmd/fetch.go (3)
cmd/action.go (1)
BaseAction(30-33)cmd/main.go (1)
Data(27-35)cmd/cloudfoundry/provider.go (1)
Provider(15-18)
cmd/main.go (2)
cmd/action.go (2)
Action(10-12)NewAction(15-27)cmd/cloudfoundry/provider.go (1)
Filter(117-120)
cmd/helm/generator.go (1)
cmd/generate.go (2)
Generate(16-18)Files(13-13)
cmd/action.go (4)
cmd/main.go (1)
Data(27-35)cmd/fetch.go (1)
Fetch(9-11)cmd/import.go (1)
Import(9-11)cmd/generate.go (1)
Generate(16-18)
cmd/generate.go (4)
cmd/action.go (1)
BaseAction(30-33)cmd/main.go (3)
Data(27-35)AssetDir(16-16)TemplateDir(15-15)cmd/fetch.go (1)
Fetch(9-11)cmd/helm/generator.go (2)
Generator(13-14)Files(10-10)
🪛 golangci-lint (1.64.8)
cmd/action.go
6-6: could not import github.com/konveyor/tackle2-hub/api (-: # github.com/konveyor/tackle2-hub/api
/tmp/go/.go-mod-cache/github.com/jortel/[email protected]/api/error.go:174:25: undefined: sqlite3.Error
/tmp/go/.go-mod-cache/github.com/jortel/[email protected]/api/error.go:177:17: undefined: sqlite3.ErrConstraintUnique
/tmp/go/.go-mod-cache/github.com/jortel/[email protected]/api/error.go:178:13: undefined: sqlite3.ErrConstraintPrimaryKey)
(typecheck)
🔇 Additional comments (5)
cmd/main.go (1)
65-75: LGTM! Clean action-based architecture implementation.The refactoring to use the action framework is well-implemented with proper error handling and clean separation of concerns.
cmd/helm/generator.go (1)
18-30: LGTM! Clean wrapper implementation with proper error handling.The Generate method provides a clean interface to the external Helm provider with appropriate error handling.
cmd/action.go (2)
77-91: LGTM! Well-implemented identity selection method.The selectIdentity method is well-structured with proper error handling and clear logic flow.
6-6: No action required – SQLite3 dependencies are correctly specified
I’ve verified in go.mod and viago list -m allthat:
- github.com/mattn/go-sqlite3 v1.14.17 and gorm.io/driver/sqlite v1.5.2 are present
- The
replacedirectives point tackle2-hub (and addon) to the jortel forks- There are no version conflicts or missing dependencies
The import
"github.com/konveyor/tackle2-hub/api"remains valid under the module replace rule.
go.mod (1)
3-5: Confirmed: Go 1.23.9 and toolchain go1.23.10 are valid releases
Both versions are listed on the official Go download page and correspond to existing patch releases. No changes required.
- go.mod line 3:
go 1.23.9is a supported module Go version.- go.mod line 4:
toolchain go1.23.10correctly specifies the available Go 1.23.10 release.
| addon.Activity( | ||
| "[Fetch] Using platform (id=%d): %s", | ||
| a.platform.ID, | ||
| a.platform.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing setPlatform() call causes potential runtime panic.
The code logs platform information but never calls setPlatform() to populate the platform context. This will likely cause a runtime panic when accessing a.platform.ID and a.platform.Name.
addon.Activity(
"[Fetch] Fetch manifest for application (id=%d): %s",
a.application.ID,
a.application.Name)
+err = a.setPlatform()
+if err != nil {
+ return
+}
addon.Activity(
"[Fetch] Using platform (id=%d): %s",
a.platform.ID,
a.platform.Name)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| addon.Activity( | |
| "[Fetch] Using platform (id=%d): %s", | |
| a.platform.ID, | |
| a.platform.Name) | |
| addon.Activity( | |
| "[Fetch] Fetch manifest for application (id=%d): %s", | |
| a.application.ID, | |
| a.application.Name) | |
| err = a.setPlatform() | |
| if err != nil { | |
| return | |
| } | |
| addon.Activity( | |
| "[Fetch] Using platform (id=%d): %s", | |
| a.platform.ID, | |
| a.platform.Name) |
🤖 Prompt for AI Agents
In cmd/fetch.go around lines 23 to 26, the code logs platform details using
a.platform.ID and a.platform.Name without first calling setPlatform(), which can
cause a runtime panic due to uninitialized platform data. To fix this, ensure
that setPlatform() is called before accessing a.platform fields to properly
initialize the platform context and avoid nil pointer dereference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setApplication() will set the a.platform as needed with the platform associated with the application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
@jortel Thank you for the clarification! Let me verify the implementation to understand the behavior better.
🐰
╭─────╮
│ ◔ ◔ │
│ ⌄ │ curious about the code details!
╰─────╯
🏁 Script executed:
#!/bin/bash
# Find the setApplication method implementation
ast-grep --pattern 'func ($_ *BaseAction) setApplication() error {
$$$
}'
Length of output: 77
🏁 Script executed:
#!/bin/bash
# Search for setApplication method with ripgrep
rg "setApplication" -A 10 -B 2
# Also search for setPlatform to understand the relationship
rg "setPlatform" -A 10 -B 2
Length of output: 2629
🏁 Script executed:
#!/bin/bash
# Read the action.go file to see the BaseAction methods
cat cmd/action.go
Length of output: 1746
@jortel You're absolutely right! I can see from the setApplication() implementation that it does indeed set both the application and the platform:
// setApplication fetches and sets `application` referenced by the task.
// The associated `platform` will be set when as appropriate.
func (r *BaseAction) setApplication() (err error) {
// ... error handling ...
app, err := addon.Task.Application()
if err == nil {
r.application = *app
} else {
return
}
if app.Platform == nil {
return
}
p, err := addon.Platform.Get(app.Platform.ID)
if err == nil {
r.platform = *p // Platform is set here!
}
return
}The method first fetches the application, then checks if the application has an associated platform, and if so, fetches and sets the platform. The comment even explicitly states "The associated platform will be set when as appropriate."
Thank you for the correction! The original suggestion to add setPlatform() was indeed unnecessary.
🐰
╭─────╮
│ ◔ ◔ │
│ ⌄ │ grateful for the clarification!
╰─────╯
🧬 Code Graph Analysis Results
Relevant snippets for understanding setApplication() and platform association in cmd/fetch.go:
File: cmd/action.go
Lines: 30-33
BaseAction struct {
application api.Application
platform api.Platform
}This snippet defines the BaseAction struct which holds the application and platform fields. Since Fetch embeds BaseAction, these fields are accessible in Fetch. The setApplication() method likely sets these fields, including a.platform as mentioned in the user comment.
File: cmd/cloudfoundry/provider.go
Lines: 15-18
Provider struct {
URL string
Identity *api.Identity
}Defines the Provider struct used in Fetch.Run() to fetch manifests from a platform. The Provider is initialized with the platform URL and optionally an identity. This is relevant because a.platform is used to create this provider, so understanding the platform structure and its usage is helpful.
File: cmd/main.go
Lines: 27-35
Data struct {
// Action
// - import
// - fetch
// - generate
Action string `json:"action"`
// Filter applications.
Filter api.Map `json:"filter"`
}Defines the Data struct passed into Fetch.Run(). While not directly related to setApplication(), it provides context on the input data structure for the action.
These snippets provide context on the application and platform fields in Fetch, the Provider struct that uses platform info, and the input data structure. The actual setApplication() method implementation is not included here but would be part of the same or related files to see how a.platform is set based on the application.
✏️ Learnings added
Learnt from: jortel
PR: konveyor/tackle2-addon-platform#2
File: cmd/fetch.go:23-26
Timestamp: 2025-07-06T19:09:45.429Z
Learning: In the cmd/fetch.go file, the setApplication() method on BaseAction will automatically set the a.platform field with the platform associated with the application, so there's no need to call setPlatform() separately.
Learnt from: jortel
PR: konveyor/tackle2-addon-platform#2
File: cmd/fetch.go:23-26
Timestamp: 2025-07-06T19:09:45.429Z
Learning: In the BaseAction struct, the setApplication() method automatically sets both the application and platform fields. When called, it first fetches the application, then checks if the application has an associated platform (app.Platform != nil), and if so, fetches the platform using addon.Platform.Get(app.Platform.ID) and sets r.platform = *p. This means there's no need to call setPlatform() separately when setApplication() is used.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
| // client returns a cloudfoundry client. | ||
| func (p *Provider) client(spaces ...string) (client *cfp.CloudFoundryProvider, err error) { | ||
| options := []cf.Option{ | ||
| cf.SkipTLSValidation(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make TLS validation configurable.
TLS validation is always skipped, which is a security risk. This should be configurable based on the environment.
- options := []cf.Option{
- cf.SkipTLSValidation(),
- }
+ options := []cf.Option{}
+ // Only skip TLS validation if explicitly configured
+ if p.Identity != nil && p.Identity.Settings != nil {
+ if skipTLS, ok := p.Identity.Settings["skipTLS"].(bool); ok && skipTLS {
+ options = append(options, cf.SkipTLSValidation())
+ }
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| cf.SkipTLSValidation(), | |
| options := []cf.Option{} | |
| // Only skip TLS validation if explicitly configured | |
| if p.Identity != nil && p.Identity.Settings != nil { | |
| if skipTLS, ok := p.Identity.Settings["skipTLS"].(bool); ok && skipTLS { | |
| options = append(options, cf.SkipTLSValidation()) | |
| } | |
| } |
🤖 Prompt for AI Agents
In cmd/cloudfoundry/provider.go at line 86, TLS validation is currently always
skipped by calling cf.SkipTLSValidation(), which poses a security risk. Modify
the code to make TLS validation configurable by introducing a configuration
option or environment variable that controls whether TLS validation is skipped
or enforced. Use this configuration to conditionally call cf.SkipTLSValidation()
only when skipping TLS validation is explicitly enabled.
| if application.Coordinates == nil { | ||
| return | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add nil check for application coordinates.
The method returns silently when coordinates are nil. Consider returning an error to make the failure explicit.
if application.Coordinates == nil {
+ err = fmt.Errorf("application coordinates not defined")
return
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if application.Coordinates == nil { | |
| return | |
| } | |
| if application.Coordinates == nil { | |
| err = fmt.Errorf("application coordinates not defined") | |
| return | |
| } |
🤖 Prompt for AI Agents
In cmd/cloudfoundry/provider.go around lines 22 to 24, the code currently
returns silently if application.Coordinates is nil. Modify this to return an
explicit error indicating that the coordinates are nil, so the failure is clear
to the caller. Update the function signature if needed to support returning an
error and ensure the error message clearly states the issue with missing
coordinates.
cmd/cloudfoundry/provider.go
Outdated
| user := "admin" | ||
| password := "dtuqBCRms14buxCnCVy2J7g2n8GVHs" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove hardcoded credentials.
Hardcoded credentials pose a serious security risk and should never be committed to source control.
- user := "admin"
- password := "dtuqBCRms14buxCnCVy2J7g2n8GVHs"
+ user := os.Getenv("CF_TEST_USER")
+ password := os.Getenv("CF_TEST_PASSWORD")
+ if user == "" || password == "" {
+ err = fmt.Errorf("CF_TEST_USER and CF_TEST_PASSWORD environment variables must be set")
+ return
+ }🤖 Prompt for AI Agents
In cmd/cloudfoundry/provider.go at lines 185 to 186, remove the hardcoded
credentials for user and password. Instead, retrieve these values securely from
environment variables or a secure secrets management system to avoid exposing
sensitive information in the source code.
| func (f *Filter) MatchName(name string) (match bool) { | ||
| for _, pattern := range f.Names { | ||
| match, _ = filepath.Match(pattern, name) | ||
| if match { | ||
| break | ||
| } | ||
| } | ||
| return | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for glob pattern matching.
The error from filepath.Match is ignored, which could hide invalid patterns. Also, empty filter should match all.
func (f *Filter) MatchName(name string) (match bool) {
+ if len(f.Names) == 0 {
+ return true // No filter means match all
+ }
for _, pattern := range f.Names {
- match, _ = filepath.Match(pattern, name)
+ var err error
+ match, err = filepath.Match(pattern, name)
+ if err != nil {
+ addon.Log.Error(err, "Invalid glob pattern", "pattern", pattern)
+ continue
+ }
if match {
break
}
}
return
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func (f *Filter) MatchName(name string) (match bool) { | |
| for _, pattern := range f.Names { | |
| match, _ = filepath.Match(pattern, name) | |
| if match { | |
| break | |
| } | |
| } | |
| return | |
| } | |
| func (f *Filter) MatchName(name string) (match bool) { | |
| if len(f.Names) == 0 { | |
| return true // No filter means match all | |
| } | |
| for _, pattern := range f.Names { | |
| var err error | |
| match, err = filepath.Match(pattern, name) | |
| if err != nil { | |
| addon.Log.Error(err, "Invalid glob pattern", "pattern", pattern) | |
| continue | |
| } | |
| if match { | |
| break | |
| } | |
| } | |
| return | |
| } |
🤖 Prompt for AI Agents
In cmd/cloudfoundry/provider.go around lines 135 to 143, the error returned by
filepath.Match is currently ignored, which can hide invalid glob patterns.
Modify the MatchName function to check and handle the error from filepath.Match
properly, for example by logging or returning it. Additionally, update the
function so that if the filter list f.Names is empty, it returns true to match
all names.
Signed-off-by: Jeff Ortel <[email protected]>
Signed-off-by: Jeff Ortel <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (3)
cmd/cloudfoundry/provider.go (3)
24-26: Add nil check for application coordinates.The method returns silently when coordinates are nil. Consider returning an error to make the failure explicit.
if application.Coordinates == nil { + err = fmt.Errorf("application coordinates not defined") return }
87-88: Make TLS validation configurable.TLS validation is always skipped, which is a security risk. This should be configurable based on the environment.
- options := []cf.Option{ - cf.SkipTLSValidation(), - } + options := []cf.Option{} + // Only skip TLS validation if explicitly configured + if p.Identity != nil && p.Identity.Settings != nil { + if skipTLS, ok := p.Identity.Settings["skipTLS"].(bool); ok && skipTLS { + options = append(options, cf.SkipTLSValidation()) + } + }
135-150: Handle empty filter to match all names.Similar to
MatchSpace, when the Names slice is empty, the method should match all names instead of returning false.func (f *Filter) MatchName(name string) (match bool) { + if len(f.Names) == 0 { + return true // No filter means match all + } var err error for _, pattern := range f.Names { match, err = filepath.Match(pattern, name) if err != nil { addon.Log.Error(err, "Invalid glob pattern", "pattern", pattern) continue } if match { break } } return }
🧹 Nitpick comments (1)
cmd/helm/generator.go (1)
8-8: Consider removing duplicate type alias.The
Filestype alias is already defined incmd/generate.go(line 13). Having duplicate type definitions can lead to maintenance issues and confusion.Consider either:
- Removing this duplicate and importing the type from the generate package
- Moving the type definition to a shared location if it's used across multiple packages
-type Files = map[string]stringAnd import it from the generate package:
import ( hp "github.com/konveyor/asset-generation/pkg/providers/generators/helm" "github.com/konveyor/tackle2-hub/api" "path/to/generate" // adjust path as needed )Then use
generate.Filesinstead ofFiles.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
cmd/cloudfoundry/provider.go(1 hunks)cmd/helm/generator.go(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
cmd/helm/generator.go (1)
cmd/generate.go (2)
Generate(16-18)Files(13-13)
🪛 golangci-lint (1.64.8)
cmd/cloudfoundry/provider.go
9-9: could not import github.com/konveyor/tackle2-hub/api (-: # github.com/konveyor/tackle2-hub/api
/tmp/go/.go-mod-cache/github.com/jortel/[email protected]/api/error.go:174:25: undefined: sqlite3.Error
/tmp/go/.go-mod-cache/github.com/jortel/[email protected]/api/error.go:177:17: undefined: sqlite3.ErrConstraintUnique
/tmp/go/.go-mod-cache/github.com/jortel/[email protected]/api/error.go:178:13: undefined: sqlite3.ErrConstraintPrimaryKey)
(typecheck)
cmd/helm/generator.go
5-5: could not import github.com/konveyor/tackle2-hub/api (-: # github.com/konveyor/tackle2-hub/api
/tmp/go/.go-mod-cache/github.com/jortel/[email protected]/api/error.go:174:25: undefined: sqlite3.Error
/tmp/go/.go-mod-cache/github.com/jortel/[email protected]/api/error.go:177:17: undefined: sqlite3.ErrConstraintUnique
/tmp/go/.go-mod-cache/github.com/jortel/[email protected]/api/error.go:178:13: undefined: sqlite3.ErrConstraintPrimaryKey)
(typecheck)
🔇 Additional comments (1)
cmd/helm/generator.go (1)
5-5: Verify replaced tackle2-hub dependencyIt looks like your
go.modrequiresgithub.zerozr99.workers.dev/konveyor/tackle2-hub v0.7.0-alpha…but then immediately replaces it with the jortel fork (v0.0.0-20250705181441-9c08d48947e5). That means:
- All imports of
github.com/konveyor/tackle2-hub/apiresolve github.com/jortel/tackle2-hub/api- The forked version may have reorganized or removed the
apipackage or its sqlite3 code- Undefined sqlite3 symbols usually point to missing CGO support or a moved/deleted package in the fork
Please verify:
- The jortel/tackle2-hub module at the replaced version still exposes
apiand its sqlite3-backed types.- If CGO is required, that your build environment has
CGO_ENABLED=1(or adjust to a pure-Go driver).- If the fork dropped or relocated sqlite3 code, either bump to a version that includes it or update your imports accordingly.
| func (g *Generator) Generate(templateDir string, values api.Map) (files Files, err error) { | ||
| files = make(Files) | ||
| config := hp.Config{ | ||
| ChartPath: templateDir, | ||
| Values: values, | ||
| } | ||
| provider := hp.New(config) | ||
| files, err = provider.Generate() | ||
| if err != nil { | ||
| return | ||
| } | ||
| return | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation for robustness.
The Generate method doesn't validate its inputs, which could lead to runtime errors or unexpected behavior when called with invalid parameters.
Add input validation to improve robustness:
func (g *Generator) Generate(templateDir string, values api.Map) (files Files, err error) {
+ if templateDir == "" {
+ return nil, fmt.Errorf("templateDir cannot be empty")
+ }
+ if values == nil {
+ values = make(api.Map)
+ }
+
files = make(Files)
config := hp.Config{
ChartPath: templateDir,
Values: values,
}
provider := hp.New(config)
files, err = provider.Generate()
if err != nil {
return
}
return
}Don't forget to add the fmt import:
import (
+ "fmt"
hp "github.com/konveyor/asset-generation/pkg/providers/generators/helm"
"github.com/konveyor/tackle2-hub/api"
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func (g *Generator) Generate(templateDir string, values api.Map) (files Files, err error) { | |
| files = make(Files) | |
| config := hp.Config{ | |
| ChartPath: templateDir, | |
| Values: values, | |
| } | |
| provider := hp.New(config) | |
| files, err = provider.Generate() | |
| if err != nil { | |
| return | |
| } | |
| return | |
| } | |
| --- a/cmd/helm/generator.go | |
| +++ b/cmd/helm/generator.go | |
| @@ -1,7 +1,8 @@ | |
| -import ( | |
| +import ( | |
| + "fmt" | |
| hp "github.com/konveyor/asset-generation/pkg/providers/generators/helm" | |
| "github.com/konveyor/tackle2-hub/api" | |
| ) | |
| @@ -16,6 +17,11 @@ func (g *Generator) Generate(templateDir string, values api.Map) (files Files, err error) { | |
| + if templateDir == "" { | |
| + return nil, fmt.Errorf("templateDir cannot be empty") | |
| + } | |
| + if values == nil { | |
| + values = make(api.Map) | |
| + } | |
| + | |
| files = make(Files) | |
| config := hp.Config{ | |
| ChartPath: templateDir, |
🤖 Prompt for AI Agents
In cmd/helm/generator.go around lines 16 to 28, the Generate method lacks input
validation, risking runtime errors with invalid parameters. Add checks to ensure
templateDir is not empty and values is not nil before proceeding. If validation
fails, return an appropriate error. Also, add the "fmt" import to support error
formatting.
| // MatchSpace returns true when the application name matches the filter. | ||
| func (f *Filter) MatchSpace(name string) (match bool) { | ||
| for _, s := range f.Spaces { | ||
| match = s == name | ||
| if match { | ||
| break | ||
| } | ||
| } | ||
| return | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Handle empty filter to match all spaces.
When the Spaces slice is empty, the method returns false instead of matching all spaces. This may not be the intended behavior.
func (f *Filter) MatchSpace(name string) (match bool) {
+ if len(f.Spaces) == 0 {
+ return true // No filter means match all
+ }
for _, s := range f.Spaces {
match = s == name
if match {
break
}
}
return
}🤖 Prompt for AI Agents
In cmd/cloudfoundry/provider.go around lines 124 to 133, the MatchSpace method
currently returns false when the Spaces slice is empty, but it should match all
spaces in that case. Modify the method to first check if the Spaces slice is
empty and return true immediately to indicate a match for all spaces. Otherwise,
proceed with the existing loop to check for a matching space name.
aufi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with not blocking comment above.
go.mod
Outdated
| gopkg.in/yaml.v3 v3.0.1 | ||
| ) | ||
|
|
||
| replace github.com/konveyor/tackle2-hub => github.com/jortel/tackle2-hub v0.0.0-20250705181441-9c08d48947e5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check if deps could be redirected to konveyor org.
Signed-off-by: Jeff Ortel <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (3)
cmd/generate.go (3)
39-41: Fix typo in error message.The error message contains a grammatical error and should return an error instead of just logging.
- addon.Failed("[Gen] not asset repository defined.") - return + err = fmt.Errorf("no asset repository defined for application %s (id=%d)", a.application.Name, a.application.ID) + addon.Failed("[Gen] %v", err) + return
211-212: Add missing error handling after Generator.Get.The error from
addon.Generator.Getis not being checked, which could lead to nil pointer dereferences.for _, ref = range p.Generators { gen, err = addon.Generator.Get(ref.ID) + if err != nil { + return + } + if gen != nil { + list = append(list, gen) + } - list = append(list, gen) }
132-147: Add explicit file permissions and path validation.The file creation uses default permissions and doesn't validate the path for security concerns.
func (a *Generate) writeAsset(assetPath, content string) (err error) { + // Validate path to prevent directory traversal + if filepath.IsAbs(assetPath) || strings.Contains(assetPath, "..") { + return fmt.Errorf("invalid asset path: %s", assetPath) + } - f, err := os.Create(assetPath) + f, err := os.OpenFile(assetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { return }
🧹 Nitpick comments (1)
cmd/import.go (1)
37-37: Consider avoiding variable shadowing.The
errvariable declared in the loop shadows the outererrvariable, which could lead to confusion.- for _, app := range applications { - err := addon.Application.Create(&app) - if err != nil { + for _, app := range applications { + if createErr := addon.Application.Create(&app); createErr != nil { addon.Errorf( "warn", "[Import] Application: %s, create failed: %s", app.Name, - err.Error()) + createErr.Error()) continue }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (4)
cmd/fetch.go(1 hunks)cmd/generate.go(1 hunks)cmd/import.go(1 hunks)go.mod(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- cmd/fetch.go
- go.mod
🧰 Additional context used
🧠 Learnings (2)
cmd/import.go (3)
Learnt from: jortel
PR: konveyor/tackle2-addon-platform#2
File: cmd/fetch.go:23-26
Timestamp: 2025-07-06T19:09:45.429Z
Learning: In the cmd/fetch.go file, the setApplication() method on BaseAction will automatically set the a.platform field with the platform associated with the application, so there's no need to call setPlatform() separately.
Learnt from: jortel
PR: konveyor/tackle2-addon-platform#2
File: cmd/fetch.go:23-26
Timestamp: 2025-07-06T19:09:45.429Z
Learning: In the BaseAction struct, the setApplication() method automatically sets both the application and platform fields. When called, it first fetches the application, then checks if the application has an associated platform (app.Platform != nil), and if so, fetches the platform using addon.Platform.Get(app.Platform.ID) and sets r.platform = *p. This means there's no need to call setPlatform() separately when setApplication() is used.
Learnt from: jortel
PR: konveyor/tackle2-addon-platform#2
File: cmd/import.go:48-61
Timestamp: 2025-07-06T19:06:20.294Z
Learning: In the tackle2-addon framework, the `addon.Errorf` function automatically appends errors to a list, providing built-in error collection functionality. Manual error collection in loops is typically not necessary when using `addon.Errorf`.
cmd/generate.go (1)
Learnt from: jortel
PR: konveyor/tackle2-addon-platform#2
File: cmd/import.go:48-61
Timestamp: 2025-07-06T19:06:20.294Z
Learning: In the tackle2-addon framework, the `addon.Errorf` function automatically appends errors to a list, providing built-in error collection functionality. Manual error collection in loops is typically not necessary when using `addon.Errorf`.
🧬 Code Graph Analysis (2)
cmd/import.go (3)
cmd/action.go (1)
BaseAction(30-33)cmd/main.go (1)
Data(27-35)cmd/cloudfoundry/provider.go (2)
Filter(119-122)Provider(17-20)
cmd/generate.go (4)
cmd/action.go (1)
BaseAction(30-33)cmd/main.go (3)
Data(27-35)AssetDir(16-16)TemplateDir(15-15)cmd/fetch.go (1)
Fetch(11-13)cmd/helm/generator.go (2)
Generator(11-12)Files(8-8)
🔇 Additional comments (3)
cmd/import.go (2)
26-32: LGTM! Switch statement properly handles platform kinds.The switch statement now correctly handles the "cloudfoundry" case and returns an appropriate error for unsupported platform kinds. This addresses the previous concern about only having a default case.
36-49: LGTM! Error handling follows the addon framework pattern.The error handling in the application creation loop correctly uses
addon.Errorffor warnings and continues processing remaining applications, which aligns with the addon framework's built-in error collection functionality.cmd/generate.go (1)
106-115: LGTM! Switch statement properly handles generator kinds.The switch statement now correctly handles the "helm" case and returns an appropriate error for unsupported generator kinds, addressing the previous concern.
Signed-off-by: Jeff Ortel <[email protected]>
Signed-off-by: Jeff Ortel <[email protected]>
Signed-off-by: Jeff Ortel <[email protected]>
Signed-off-by: Jeff Ortel <[email protected]>
The platform addon provides for multiple kinds of platform related tasks:
Requires:
Examples:
Archetype:
Generator:
Platform:
Fetch:
Import:
Generate:
Summary by CodeRabbit
Summary by CodeRabbit
New Features
Improvements
Chores