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

atmos read/write storage interface #865

Merged
merged 32 commits into from
Dec 18, 2024
Merged

atmos read/write storage interface #865

merged 32 commits into from
Dec 18, 2024

Conversation

mcalhoun
Copy link
Member

@mcalhoun mcalhoun commented Dec 17, 2024

what

Add the concept of atmos stores to the app. This PR adds only the read side of stores. The write side will be implemented in a separate PR.

why

Atmos stores allow values to be written to an external store (i.e., AWS SSM Param Store) after apply-time and read from at plan/before apply time.

Stores are pluggable and configurable and multiple may be enabled at the same time (i.e. for prod/non-prod, east/west, etc).

The initial set of stores we are implementing as part of this PR are:

AWS SSM Parameter Store

Summary by CodeRabbit

  • New Features

    • Introduced a new Store interface with methods for storing and retrieving data.
    • Added support for AWS SSM Parameter Store and an in-memory store implementation.
    • New event hooks for Terraform operations, enhancing extensibility.
    • Enhanced CLI configuration with store management capabilities.
    • Added constants for Atmos YAML functions to improve maintainability.
  • Bug Fixes

    • Improved error handling across various functions and methods.
  • Documentation

    • Updated documentation to reflect new functionalities and configurations.
  • Tests

    • Added unit tests for the new store implementations and their methods.

@mcalhoun mcalhoun changed the base branch from main to chore/refactor-checkatmosconfig December 17, 2024 19:55
Copy link

mergify bot commented Dec 17, 2024

💥 This pull request now has conflicts. Could you fix it @mcalhoun? 🙏

@mergify mergify bot added the conflict This PR has conflicts label Dec 17, 2024
@mcalhoun mcalhoun self-assigned this Dec 17, 2024
@mcalhoun mcalhoun requested a review from aknysh December 17, 2024 20:35
@mcalhoun mcalhoun removed the triage Needs triage label Dec 17, 2024
@mcalhoun mcalhoun marked this pull request as ready for review December 17, 2024 20:35
@mcalhoun mcalhoun requested a review from a team as a code owner December 17, 2024 20:35
Copy link
Contributor

coderabbitai bot commented Dec 17, 2024

Warning

Rate limit exceeded

@mcalhoun has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 4 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 1defdce and 8023ddc.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (18)
  • go.mod (4 hunks)
  • internal/exec/yaml_func_exec.go (1 hunks)
  • internal/exec/yaml_func_store.go (1 hunks)
  • internal/exec/yaml_func_template.go (1 hunks)
  • internal/exec/yaml_func_terraform_output.go (1 hunks)
  • internal/exec/yaml_func_utils.go (2 hunks)
  • pkg/config/config.go (1 hunks)
  • pkg/config/utils.go (2 hunks)
  • pkg/hooks/hooks.go (1 hunks)
  • pkg/schema/schema.go (3 hunks)
  • pkg/store/aws_ssm_param_store.go (1 hunks)
  • pkg/store/aws_ssm_param_store_test.go (1 hunks)
  • pkg/store/config.go (1 hunks)
  • pkg/store/in_memory_store.go (1 hunks)
  • pkg/store/in_memory_store_test.go (1 hunks)
  • pkg/store/registry.go (1 hunks)
  • pkg/store/store.go (1 hunks)
  • pkg/utils/yaml_utils.go (1 hunks)
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough

Walkthrough

This pull request introduces significant enhancements to the Atmos configuration management system, focusing on store functionality, configuration handling, and dependency management. The changes include adding new store implementations (AWS SSM Parameter Store and In-Memory Store), updating dependency versions, and refactoring various utility functions to support more flexible configuration processing. The modifications aim to improve the system's extensibility and configuration management capabilities.

Changes

File Change Summary
go.mod Updated dependencies, added new packages like AWS SDK, Charmbracelet log
internal/exec/* Refactored YAML function processing, removed cliConfig from several function signatures
pkg/config/* Added store configuration processing, enhanced configuration handling
pkg/store/* Introduced new store implementations (SSM, In-Memory), added store registry and configuration
pkg/schema/schema.go Added new fields for stores and hooks configuration
pkg/hooks/hooks.go Defined new hook types and structures for event management
pkg/utils/yaml_utils.go Added constants for YAML function tags

Suggested Labels

minor

Possibly related PRs

Suggested reviewers

  • osterman
  • aknysh

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or @auto-summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @auto-title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (18)
pkg/store/aws_ssm_param_store.go (2)

31-31: Correct the function comment to match 'NewSSMStore'.

The comment on line 31 incorrectly refers to 'NewInMemoryStore'. It should be 'NewSSMStore' to reflect the actual function.

Apply this diff to fix the issue:

-// NewInMemoryStore initializes a new MemoryStore.
+// NewSSMStore initializes a new SSMStore.

50-50: Pass context from the caller instead of using 'context.TODO()'.

Using 'context.TODO()' is a placeholder. It's better to accept a context parameter in your methods to support cancellation and timeouts.

Apply this diff to implement the suggestion:

- func (s *SSMStore) Set(key string, value interface{}) error {
+ func (s *SSMStore) Set(ctx context.Context, key string, value interface{}) error {

  ...

- func (s *SSMStore) Get(key string) (interface{}, error) {
+ func (s *SSMStore) Get(ctx context.Context, key string) (interface{}, error) {

  ...

-	ctx := context.TODO()

Note: This change will require updating any callers of these methods to pass a context.

Also applies to: 75-75

pkg/store/store.go (1)

6-6: Clarify or remove the comment regarding default values.

The comment // Default values if it doesn't exist? seems like a placeholder or reminder. Consider removing it or providing additional context.

Apply this diff to fix the issue:

pkg/hooks/hooks.go (2)

12-16: Consider future extensibility for Command type.

The Command type is well-positioned for future expansion beyond store operations.

Consider documenting potential future command types in comments to guide future development.


18-28: Enhance documentation for Hook struct fields.

While the structure is solid, the field documentation could be more descriptive.

Consider enhancing the comments:

 type Hook struct {
-	Events  []string `yaml:"events"`
-	Command string   `yaml:"command"`
+	// Events defines when this hook should be triggered
+	Events []string `yaml:"events"`
+	// Command specifies the type of operation to perform (e.g., "store")
+	Command string `yaml:"command"`

 	// Dynamic command-specific properties

 	// store command
-	Name   string                 `yaml:"name,omitempty"`   // for store command
-	Values map[string]interface{} `yaml:"values,omitempty"` // for store command
+	// Name identifies the store to use for this operation
+	Name string `yaml:"name,omitempty"`
+	// Values contains the key-value pairs to be stored
+	Values map[string]interface{} `yaml:"values,omitempty"`
 }
pkg/store/registry.go (1)

7-36: Consider using constants for store types.

The store initialization logic is solid, but string literals for store types could be replaced with constants.

Consider adding constants:

+const (
+	StoreTypeSSM      = "aws-ssm-parameter-store"
+	StoreTypeInMemory = "in-memory"
+)

 func NewStoreRegistry(config *StoresConfig) (StoreRegistry, error) {
 	registry := make(StoreRegistry)
 	for key, storeConfig := range *config {
 		switch storeConfig.Type {
-		case "aws-ssm-parameter-store":
+		case StoreTypeSSM:
 			var opts SSMStoreOptions
 			if err := parseOptions(storeConfig.Options, &opts); err != nil {
 				return nil, fmt.Errorf("failed to parse SSM store options: %w", err)
 			}

 			store, err := NewSSMStore(opts)
 			if err != nil {
 				return nil, err
 			}
 			registry[key] = store

-		case "in-memory":
+		case StoreTypeInMemory:
internal/exec/yaml_func_exec.go (1)

Line range hint 1-36: Consider consistent parameter passing.

The function still uses cliConfig for logging and shell execution but removes it from getStringAfterTag. This creates an inconsistent pattern.

Consider either:

  1. Removing cliConfig entirely and using a different logging mechanism
  2. Maintaining consistency by keeping cliConfig in getStringAfterTag
pkg/store/in_memory_store.go (2)

17-20: Document the options parameter usage

The constructor accepts an options parameter but doesn't use it. If it's for future extensibility or interface consistency, please document this intention.

-// NewInMemoryStore initializes a new MemoryStore.
+// NewInMemoryStore initializes a new MemoryStore.
+// The options parameter is reserved for future extensibility but is currently unused.
 func NewInMemoryStore(options map[string]interface{}) (Store, error) {

22-28: Consider adding input validation

The Set method could benefit from basic input validation to prevent edge cases:

 func (m *InMemoryStore) Set(key string, value interface{}) error {
+	if key == "" {
+		return fmt.Errorf("key cannot be empty")
+	}
+	if value == nil {
+		return fmt.Errorf("value cannot be nil")
+	}
 	m.mu.Lock()
 	defer m.mu.Unlock()
 	m.data[key] = value
 	return nil
 }
internal/exec/yaml_func_store.go (2)

12-12: Add function documentation

Please add documentation describing the function's purpose, parameters, and return value.

+// processTagStore processes store tags in YAML configuration, retrieving values from the specified store.
+// Parameters:
+//   - cliConfig: The CLI configuration containing store definitions
+//   - input: The raw input string containing the store tag
+//   - currentStack: The current stack being processed
+// Returns: The value retrieved from the store or exits on error
 func processTagStore(cliConfig schema.CliConfiguration, input string, currentStack string) any {

21-24: Consider more flexible parameter parsing

The current implementation requires exactly 2 space-separated parameters. Consider:

  1. Supporting quoted values for keys with spaces
  2. Using a more robust parsing mechanism
-	parts := strings.Split(str, " ")
-	if len(parts) != 2 {
+	const expectedParts = 2
+	parts := strings.Fields(str)
+	if len(parts) != expectedParts {
pkg/store/in_memory_store_test.go (2)

18-64: Consider adding concurrent access tests

The test coverage for Set operations is thorough, but since this is a store that might be accessed concurrently, we should add tests to verify thread safety.

Here's a suggested concurrent test:

func TestMemoryStoreConcurrentAccess(t *testing.T) {
    store := &InMemoryStore{
        data: make(map[string]interface{}),
    }
    
    const goroutines = 10
    var wg sync.WaitGroup
    wg.Add(goroutines)
    
    for i := 0; i < goroutines; i++ {
        go func(id int) {
            defer wg.Done()
            key := fmt.Sprintf("key-%d", id)
            value := fmt.Sprintf("value-%d", id)
            
            if err := store.Set(key, value); err != nil {
                t.Errorf("Set() error = %v", err)
            }
            
            got, err := store.Get(key)
            if err != nil {
                t.Errorf("Get() error = %v", err)
            }
            if got != value {
                t.Errorf("Get() = %v, want %v", got, value)
            }
        }(i)
    }
    
    wg.Wait()
}

66-108: Consider adding type assertion tests

The Get operation tests could be enhanced to verify behavior with different value types and type assertions.

Add these test cases:

 tests := []struct {
     name      string
     key       string
     want      interface{}
     wantError bool
 }{
+    {
+        name:      "integer value",
+        key:       "int-key",
+        want:      42,
+        wantError: false,
+    },
+    {
+        name:      "map value",
+        key:       "map-key",
+        want:      map[string]string{"foo": "bar"},
+        wantError: false,
+    },
internal/exec/yaml_func_terraform_output.go (2)

Line range hint 34-44: Consider enhancing error message for stack parameter

When using the current stack as default, the trace message is helpful but we could make it more visible for debugging.

-		u.LogTrace(cliConfig, fmt.Sprintf("Atmos YAML function `%s` is called with two parameters 'component' and 'output'. "+
-			"Using the current stack '%s' as the 'stack' parameter", input, currentStack))
+		u.LogDebug(cliConfig, fmt.Sprintf("Atmos YAML function `%s` is using current stack '%s' as default", 
+			input, currentStack))

Line range hint 52-63: Consider adding cache expiration mechanism

The cache implementation using sync.Map is thread-safe, but consider adding a cache expiration mechanism to prevent stale data.

Consider implementing a cache wrapper with TTL support or using a caching library that provides this functionality out of the box.

pkg/store/aws_ssm_param_store_test.go (2)

36-93: Consider adding more edge cases to the test suite.

While the current test cases cover the basic scenarios well, consider adding tests for:

  • Empty key validation
  • Maximum key length validation
  • Special characters in parameter names
  • Different parameter types (SecureString, StringList)

95-148: Add test cases for common SSM Get scenarios.

Consider adding test cases for:

  • Parameter not found (ParameterNotFound error)
  • Decryption failure for SecureString parameters
  • Invalid parameter version
pkg/config/utils.go (1)

491-502: LGTM! Consider enhancing error logging.

The implementation is clean and focused. However, when the store registry creation fails, it might be helpful to log the error before returning it.

 func processStoreConfig(cliConfig *schema.CliConfiguration) error {
     log.Debug("processStoreConfig", "cliConfig.StoresConfig", fmt.Sprintf("%v", cliConfig.StoresConfig))
 
     storeRegistry, err := store.NewStoreRegistry(&cliConfig.StoresConfig)
     if err != nil {
+        log.Error("failed to create store registry", "error", err)
         return err
     }
     cliConfig.Stores = storeRegistry
 
     return nil
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c4fe769 and e7a432a.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (18)
  • go.mod (3 hunks)
  • internal/exec/yaml_func_exec.go (1 hunks)
  • internal/exec/yaml_func_store.go (1 hunks)
  • internal/exec/yaml_func_template.go (1 hunks)
  • internal/exec/yaml_func_terraform_output.go (1 hunks)
  • internal/exec/yaml_func_utils.go (2 hunks)
  • pkg/config/config.go (1 hunks)
  • pkg/config/utils.go (2 hunks)
  • pkg/hooks/hooks.go (1 hunks)
  • pkg/schema/schema.go (3 hunks)
  • pkg/store/aws_ssm_param_store.go (1 hunks)
  • pkg/store/aws_ssm_param_store_test.go (1 hunks)
  • pkg/store/config.go (1 hunks)
  • pkg/store/in_memory_store.go (1 hunks)
  • pkg/store/in_memory_store_test.go (1 hunks)
  • pkg/store/registry.go (1 hunks)
  • pkg/store/store.go (1 hunks)
  • pkg/utils/yaml_utils.go (1 hunks)
🧰 Additional context used
📓 Learnings (1)
internal/exec/yaml_func_terraform_output.go (1)
Learnt from: aknysh
PR: cloudposse/atmos#863
File: internal/exec/yaml_func_terraform_output.go:34-38
Timestamp: 2024-12-17T07:08:41.288Z
Learning: In the `processTagTerraformOutput` function within `internal/exec/yaml_func_terraform_output.go`, parameters are separated by spaces and do not contain spaces. Therefore, using `strings.Fields()` for parsing is acceptable, and there's no need to handle parameters with spaces.
🔇 Additional comments (17)
pkg/store/config.go (1)

1-14: Looks good!

The configuration structures are well-defined, and the code is clear.

internal/exec/yaml_func_template.go (1)

19-19: Change reflects the updated function signature appropriately.

The update to remove cliConfig from the getStringAfterTag call aligns with the modified function signature.

pkg/hooks/hooks.go (1)

3-10: LGTM! Well-defined hook points for Terraform operations.

The hook types provide clear integration points for store operations before and after critical Terraform operations.

pkg/store/registry.go (1)

5-5: LGTM! Clean registry type definition.

The StoreRegistry type provides a simple but effective way to manage multiple stores.

internal/exec/yaml_func_exec.go (1)

19-19: Verify impact of removing cliConfig parameter.

The removal of cliConfig from getStringAfterTag while retaining it in other function calls seems inconsistent.

Let's check other usages of getStringAfterTag:

pkg/store/in_memory_store.go (2)

8-16: Strong foundation for the store implementation!

The InMemoryStore implementation follows Go best practices with:

  • Thread-safe data storage using sync.RWMutex
  • Clear interface compliance check
  • Good encapsulation of internal state

30-39: Solid Get implementation!

The Get method is well-implemented with:

  • Proper read lock usage
  • Clear error handling
  • Descriptive error messages
internal/exec/yaml_func_utils.go (2)

64-75: Clean switch statement refactoring!

The switch statement improves code readability and maintainability. The default case properly handles unsupported YAML types.


Line range hint 79-89: Clean utility function implementation!

The getStringAfterTag function is well-focused and handles its single responsibility effectively.

pkg/utils/yaml_utils.go (2)

11-17: Well structured constants for YAML functions!

The introduction of these constants aligns perfectly with the store functionality objectives and follows good coding practices by eliminating magic strings.


21-24: Clean transition to using constant references!

The update to use constants in AtmosYamlTags array improves maintainability and reduces the risk of typos.

internal/exec/yaml_func_terraform_output.go (1)

24-24: Verify tag constant usage

The function now uses the constant from config package, which is good. However, let's verify this constant is properly defined.

✅ Verification successful

Tag constant is properly defined and imported

The constant AtmosYamlFuncTerraformOutput is correctly defined in the config package and properly imported in the file. The usage is consistent with the codebase standards.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the terraform output tag constant is properly defined
# Test: Search for the constant definition
rg -A 1 "AtmosYamlFuncTerraformOutput.*=.*\"!terraform.output\""

Length of output: 263


Script:

#!/bin/bash
# Check if the constant is imported correctly from config package
rg -A 2 "import.*\".*config\".*" internal/exec/yaml_func_terraform_output.go

Length of output: 76


Script:

#!/bin/bash
# Let's check all imports in the file
rg "^import \(" -A 10 internal/exec/yaml_func_terraform_output.go

Length of output: 239

pkg/store/aws_ssm_param_store_test.go (1)

15-34: LGTM! Well-structured mock implementation.

The mock implementation follows best practices with proper error handling and type assertions.

pkg/config/config.go (1)

249-254: LGTM! Verify store configuration processing.

The integration of store configuration processing is clean and follows existing patterns.

✅ Verification successful

Store configuration processing implementation is properly integrated

The implementation is well-structured and follows a clean design:

  • Processes store configuration through a dedicated function in pkg/config/utils.go
  • Creates a store registry using the configuration from StoresConfig
  • Properly documented in schema with clear purpose for hooks and yaml parsing
  • Uses appropriate error handling and logging
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify store configuration processing implementation
# Test: Search for store configuration processing implementation
ast-grep --pattern 'func processStoreConfig($config *schema.CliConfiguration) error {
  $$$
}'

Length of output: 96


Script:

#!/bin/bash
# Let's try a broader search for processStoreConfig function
rg "func processStoreConfig" -A 5

# Also search for any references to store configuration
rg "processStoreConfig" -A 2

# Let's also check for store-related configuration structures
rg "type.*Store.*Config" -A 3

Length of output: 1891

pkg/schema/schema.go (3)

3-3: Well-structured store integration!

The store-related fields are well-integrated into the configuration structure with clear documentation explaining the runtime-only nature of the Stores field.

Also applies to: 20-21, 34-37


204-204: LGTM! Consistent with existing patterns.

The ComponentHooksSection field follows the established pattern of using AtmosSectionMapType for component sections.


488-488: LGTM! Maintains consistency with base component structure.

The BaseComponentHooks field aligns with the existing pattern of base component configuration fields.

pkg/store/aws_ssm_param_store.go Outdated Show resolved Hide resolved
internal/exec/yaml_func_store.go Show resolved Hide resolved
go.mod Outdated Show resolved Hide resolved
Copy link

mergify bot commented Dec 18, 2024

💥 This pull request now has conflicts. Could you fix it @mcalhoun? 🙏

@mergify mergify bot added the conflict This PR has conflicts label Dec 18, 2024
@mergify mergify bot removed the conflict This PR has conflicts label Dec 18, 2024
@mcalhoun
Copy link
Member Author

@coderabbitai full review

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (4)
go.mod (3)

19-19: New logging library.

This new library (github.com/charmbracelet/log) can simplify structured logging. Confirm that it is applied consistently across the codebase for a cohesive logging experience.


92-95: Expanded AWS SSO and STS dependencies.

Since SSO and STS logic can introduce complexities in cross-account or session-based operations, confirm that the updated versions do not break any current usage patterns.


132-132: Minimal feedback on go-logfmt/logfmt addition.

No issues here. If you integrate this formatting approach, consider standardizing logs to maintain consistent style across the project.

pkg/store/aws_ssm_param_store.go (1)

62-69: Parameter writing.

Overwriting existing keys simplifies usage. If you anticipate needing a "merge" or "append" approach, consider future extension here.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e7a432a and 8023ddc.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (2)
  • go.mod (4 hunks)
  • pkg/store/aws_ssm_param_store.go (1 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/store/aws_ssm_param_store.go

1-1: : # github.com/cloudposse/atmos/pkg/store [github.com/cloudposse/atmos/pkg/store.test]
pkg/store/aws_ssm_param_store_test.go:53:17: cannot use true (untyped bool constant) as *bool value in struct literal
pkg/store/aws_ssm_param_store_test.go:109:22: cannot use true (untyped bool constant) as *bool value in struct literal

(typecheck)

🔇 Additional comments (20)
go.mod (5)

10-12: Added AWS SDK dependencies look aligned with PR objectives.

These additions for AWS SDK v2 and its SSM module align with the introduction of the new AWS SSM store functionality. Be mindful to keep them up-to-date to take advantage of any relevant bug fixes or enhancements.


80-81: Updated AWS credentials and IMDS dependencies.

These updates appear necessary for supporting the new store functionality. If possible, confirm that references to the credentials constructor or IMDS usage follow the updated methods and type signatures introduced in these versions.


83-85: Keep an eye on internal config changes.

The internal configsources, endpoints, and INI modules are central to AWS configuration resolution. Verify that existing unit tests cover edge cases like missing or malformed config files.


87-89: Internal S3-related modules updated.

While these changes likely come in indirectly, ensure that the presigned URL usage is tested so that your code references remain compatible with the updated library.


251-251: golang.org/x/exp updated.

This experimental package can be a moving target. Validate that your code is not reliant on APIs that may change or break in future releases.

pkg/store/aws_ssm_param_store.go (15)

1-2: New package declaration looks good.

This package is well-named to target AWS SSM Parameter Store. No immediate concerns noted.

🧰 Tools
🪛 golangci-lint (1.62.2)

1-1: : # github.com/cloudposse/atmos/pkg/store [github.com/cloudposse/atmos/pkg/store.test]
pkg/store/aws_ssm_param_store_test.go:53:17: cannot use true (untyped bool constant) as *bool value in struct literal
pkg/store/aws_ssm_param_store_test.go:109:22: cannot use true (untyped bool constant) as *bool value in struct literal

(typecheck)


3-6: Imports appear valid and minimal.

These imports cover the AWS SDK and standard Go libraries for context and formatting. Good job keeping them concise.


7-11: AWS and SSM references.

The chosen modules from the AWS SDK are exactly what you need to support SSM. Great alignment with your PR objectives.


13-16: SSMStore struct.

The struct definition is clear, focusing only on what’s needed for the SSM client. This keeps the store abstraction straightforward.


18-20: Region specified in SSMStoreOptions.

Mapping the region in the struct is good. This fosters explicit user configuration and reduces mistakes from default region assumptions.


22-24: Store interface satisfaction.

Declaring the interface conformance is neat and ensures that the store pattern is standardized throughout the codebase.


25-29: Interface for SSMClient.

By introducing SSMClient as an interface, it’s easier to mock AWS interactions for testing. This design choice is flexible.


31-32: NewSSMStore constructor.

Straightforward name. The function returns the store interface, which is a good factory pattern.


35-39: Robust AWS config loading.

Appropriately handling errors from config loading ensures the application fails fast if AWS credentials or config are missing.


41-45: Enforcement of a non-empty region.

Requiring a region is a good design choice. Minimizes runtime confusion by failing early if misconfigured.


47-50: SSM client creation.

Constructing the SSM client from the validated config is straightforward and robust. Nice approach.


52-60: Set method enforces string value.

The design ensures type consistency in SSM parameters. However, be sure to note in your docs that only string values are supported.


70-72: Error contextualization.

Appending the key name in the error message helps with debugging. Nicely done.


77-88: Get method with decryption.

Allowing secure parameter decryption is essential for handling secrets. Great that you return an error if retrieval fails instead of ignoring it.


90-91: Returning string data.

Returning the parameter value as a string is consistent with the approach used in the Set method.

@mcalhoun mcalhoun merged commit 05606ad into main Dec 18, 2024
28 of 29 checks passed
@mcalhoun mcalhoun deleted the feature/add-hooks-config branch December 18, 2024 17:36
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Dec 18, 2024
Listener430 pushed a commit that referenced this pull request Dec 18, 2024
@mcalhoun mcalhoun restored the feature/add-hooks-config branch December 18, 2024 19:11
Copy link

These changes were released in v1.131.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-release Do not create a new release (wait for additional code changes)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant