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
119 changes: 119 additions & 0 deletions docs/ADRs/009-custom-configuration-file-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# 9. Custom Configuration File Paths

Date: 2025-02-27

## Status

Proposed

## Context

Currently, the Helm Values Manager uses hardcoded file paths for its configuration and lock files:
- Configuration file: `helm-values.json`
- Lock file: `.helm-values.lock`

These paths are defined in the `BaseCommand` class and used across all commands. This approach has several limitations:

1. **Limited Flexibility**: Users cannot manage multiple configurations in the same directory
2. **Naming Constraints**: Organizations may have specific naming conventions that conflict with our hardcoded names
3. **Integration Challenges**: Difficult to integrate with existing systems that might have their own file organization
4. **Location Restrictions**: Configuration files must be in the current working directory

Users have expressed interest in being able to specify custom file paths for their configuration files, which would address these limitations and provide greater flexibility.

## Decision

We will enhance the Helm Values Manager to support custom configuration file paths by:

1. **Adding a `--config-file` option to all commands**:
```python
config_file: str = typer.Option(
"helm-values.json",
"--config-file",
"-c",
help="Path to the configuration file"
)
```

2. **Updating the `BaseCommand` class to accept a config file path**:
```python
def __init__(self, config_file: str = "helm-values.json") -> None:
"""Initialize the base command.

Args:
config_file: Path to the configuration file
"""
self.config_file = config_file
self.lock_file = self._generate_lock_file_path(config_file)
self._lock_fd: Optional[int] = None
```

3. **Generating the lock file name based on the config file path**:
```python
def _generate_lock_file_path(self, config_file: str) -> str:
"""Generate the lock file path based on the config file path.

Args:
config_file: Path to the configuration file

Returns:
str: Path to the lock file
"""
# Expand user home directory if present (e.g., ~/configs)
expanded_path = os.path.expanduser(config_file)
config_path = Path(expanded_path)

# Check if the path is a directory
if config_path.is_dir():
# Use default filename in the specified directory
config_path = config_path / "helm-values.json"

# Create lock file name based on the config file stem (name without extension)
lock_file = f".{config_path.stem}.lock"
return str(config_path.parent / lock_file)
```

4. **Propagating the config file path to all command instances**:
```python
@app.command()
def init(
release_name: str = typer.Option(..., "--release", "-r", help="Name of the Helm release"),
config_file: str = typer.Option("helm-values.json", "--config-file", "-c", help="Path to the configuration file"),
):
"""Initialize a new helm-values configuration."""
command = InitCommand(config_file=config_file)
result = command.execute(release_name=release_name)
echo(result)
```

## Consequences

### Positive

1. **Increased Flexibility**: Users can manage multiple configurations in the same directory
2. **Custom Naming**: Organizations can follow their own naming conventions
3. **Better Integration**: Easier to integrate with existing systems and workflows
4. **Location Freedom**: Configuration files can be placed in any directory

### Negative

1. **API Change**: All command functions need to be updated to accept the new parameter
2. **Complexity**: Slightly more complex code to handle different file paths
3. **Testing**: Additional test cases needed to verify the functionality
4. **Documentation**: Documentation needs to be updated to reflect the new option

### Neutral

1. **Backward Compatibility**: Default values ensure backward compatibility with existing usage
2. **Lock File Naming**: Lock files will be named based on the configuration file name

## Implementation Notes

1. The implementation should be backward compatible, using the current hardcoded paths as defaults
2. All commands should propagate the config file path to their respective command instances
3. Documentation should be updated to reflect the new option
4. Tests should be added to verify the functionality with custom file paths

## Related Issues

- GitHub Issue [#17](https://github.com/Zipstack/helm-values-manager/issues/17): Support for custom configuration file paths
86 changes: 86 additions & 0 deletions docs/ADRs/010-configuration-update-and-merge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# ADR-010: Configuration Update and Merge

Date: 2025-02-27

## Status

Proposed

## Context

Chart owners may update their configuration schema over time, adding new configuration paths, modifying metadata, or removing obsolete paths. Users who have already configured their deployments need a way to incorporate these updates without losing their existing configurations.

Currently, the Helm Values Manager does not provide a mechanism to update an existing configuration with changes from a new version. This leads to several challenges:

1. Users must manually identify and apply changes between configuration versions
2. There's a risk of missing new required configuration paths
3. Users may lose their existing values when updating to a new configuration
4. Conflicts between user customizations and chart owner updates are difficult to resolve

A structured approach to configuration updates would improve the user experience and reduce the risk of configuration errors.

## Decision

We will implement a configuration update and merge feature that allows users to incorporate changes from a new configuration file while preserving their existing values and deployments.

The feature will:

1. Compare the current configuration with the new one to identify:
- Added configuration paths
- Removed configuration paths
- Modified metadata (description, required, sensitive flags)
- Potential conflicts

2. Provide multiple merge strategies:
- "Smart" (default): Preserve user values while adopting new metadata and paths
- "Theirs": Prefer the new configuration but keep existing values where possible
- "Ours": Prefer the existing configuration but add new paths

3. Validate the merged configuration to ensure it meets all requirements
- Identify missing required values
- Ensure all paths have valid values for their environments

4. Provide clear reporting of changes and required actions

This will be implemented as a new `update-config` command in the CLI.

## Consequences

### Positive

- Users can easily update their configurations when chart owners release updates
- Existing user values are preserved during updates
- New required configurations are clearly identified
- The risk of missing important configuration changes is reduced
- The update process becomes more transparent and less error-prone

### Negative

- Adds complexity to the codebase
- May require additional schema versioning to handle major changes
- Conflict resolution might still require manual intervention in complex cases

### Neutral

- Users will need to learn a new command and its options
- May need to adjust the configuration schema to better support versioning and updates

## Implementation Notes

The implementation will require:

1. A new `UpdateConfigCommand` class that extends `BaseCommand`
2. Configuration comparison logic to identify differences
3. Merge strategies to combine configurations
4. Validation to ensure the merged configuration is valid
5. Reporting to communicate changes and required actions

The command will be exposed through the CLI as:

```
helm values update-config [source-file] [--strategy=smart|theirs|ours] [--report-only]
```

## Related Issues

- GitHub Issue [#19](https://github.com/Zipstack/helm-values-manager/issues/19): Configuration Update and Merge Feature
32 changes: 16 additions & 16 deletions docs/ADRs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ This directory contains Architecture Decision Records (ADRs) for the Helm Values
## What is an ADR?
An Architecture Decision Record (ADR) is a document that captures an important architectural decision made along with its context and consequences.

## Creating New ADRs

For new ADRs, use the [ADR template](adr-template.md) as a starting point.

## ADR Index

### [ADR-001: Helm Values Manager as a Helm Plugin](001-helm-values-manager.md)
Expand Down Expand Up @@ -61,20 +65,16 @@ An Architecture Decision Record (ADR) is a document that captures an important a
- **Decision**: Remove registry in favor of direct command instantiation
- **Impact**: Simplifies code and aligns better with Typer's design

## ADR Template
For new ADRs, use this template:
```markdown
# ADR-NNN: Title

## Status
[Proposed | Accepted | Deprecated | Superseded]

## Context
What is the issue that we're seeing that is motivating this decision or change?

## Decision
What is the change that we're proposing and/or doing?
### [ADR-009: Custom Configuration File Paths](009-custom-configuration-file-paths.md)
- **Status**: Proposed
- **Context**: Limited flexibility with hardcoded configuration file paths
- **Decision**: Add support for custom configuration file paths
- **Impact**: Increases flexibility and improves integration capabilities
- **Dependencies**: ADR-001

## Consequences
What becomes easier or more difficult to do because of this change?
```
### [ADR-010: Configuration Update and Merge](010-configuration-update-and-merge.md)
- **Status**: Proposed
- **Context**: Need to incorporate chart owner configuration updates without losing user customizations
- **Decision**: Implement configuration comparison and smart merging with multiple strategies
- **Impact**: Simplifies configuration updates and reduces risk of missing required changes
- **Dependencies**: ADR-001
37 changes: 37 additions & 0 deletions docs/ADRs/adr-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# ADR-NNN: Title

Date: YYYY-MM-DD

## Status

[Proposed | Accepted | Deprecated | Superseded]

## Context

What is the issue that we're seeing that is motivating this decision or change?

## Decision

What is the change that we're proposing and/or doing?

## Consequences

### Positive

What becomes easier because of this change?

### Negative

What becomes more difficult because of this change?

### Neutral

What other effects does this change have?

## Implementation Notes

Additional notes on implementation details, if applicable.

## Related Issues

- GitHub Issue #[TBD]: Related issue title
8 changes: 4 additions & 4 deletions docs/Development/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@
- [x] Add empty config initialization
- [x] Add config file creation
- [x] Add schema template generation
- [ ] Implement add-value-config command
- [ ] Add basic path validation
- [ ] Add metadata validation
- [ ] Add config update
- [x] Implement add-value-config command
- [x] Add basic path validation
- [x] Add metadata validation
- [x] Add config update
- [ ] Implement add-deployment command
- [ ] Add basic deployment validation
- [ ] Add backend validation
Expand Down
34 changes: 34 additions & 0 deletions helm_values_manager/cli.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
"""Command line interface for the helm-values-manager plugin."""

from typing import Optional

import typer

from helm_values_manager.commands.add_value_config_command import AddValueConfigCommand
from helm_values_manager.commands.init_command import InitCommand
from helm_values_manager.utils.logger import HelmLogger

Expand Down Expand Up @@ -42,5 +45,36 @@ def init(
raise typer.Exit(code=1) from e


@app.command("add-value-config")
def add_value_config(
path: str = typer.Option(..., "--path", "-p", help="Configuration path (e.g., 'app.replicas')"),
description: Optional[str] = typer.Option(
None, "--description", "-d", help="Description of what this configuration does"
),
required: bool = typer.Option(False, "--required", "-r", help="Whether this configuration is required"),
sensitive: bool = typer.Option(
False,
"--sensitive",
"-s",
help="Whether this configuration contains sensitive data (coming in v0.2.0)",
hidden=True, # Hide from help text until v0.2.0
),
):
"""Add a new value configuration with metadata."""
try:
command = AddValueConfigCommand()

# Add warning for sensitive flag until it's fully implemented
if sensitive:
HelmLogger.warning("Sensitive value support will be available in version 0.2.0. Flag will be ignored.")
sensitive = False # Ignore the flag for now

result = command.execute(path=path, description=description, required=required, sensitive=sensitive)
typer.echo(result)
except Exception as e:
HelmLogger.error("Failed to add value config: %s", str(e))
raise typer.Exit(code=1) from e


if __name__ == "__main__":
app(prog_name=COMMAND_INFO)
Loading