train-k8s-container-mitre 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.expeditor/buildkite/coverage.sh +46 -0
  3. data/.expeditor/buildkite/run_linux_tests.sh +16 -0
  4. data/.expeditor/config.yml +61 -0
  5. data/.expeditor/coverage.pipeline.yml +19 -0
  6. data/.expeditor/update_version.sh +12 -0
  7. data/.expeditor/verify.pipeline.yml +44 -0
  8. data/.rspec +4 -0
  9. data/.rubocop.yml +57 -0
  10. data/CHANGELOG.md +158 -0
  11. data/CODE_OF_CONDUCT.md +13 -0
  12. data/CONTRIBUTING.md +161 -0
  13. data/DEVELOPMENT.md +315 -0
  14. data/Gemfile +23 -0
  15. data/LICENSE.md +9 -0
  16. data/NOTICE.md +9 -0
  17. data/README.md +237 -0
  18. data/Rakefile +37 -0
  19. data/SECURITY.md +100 -0
  20. data/VERSION +1 -0
  21. data/cliff.toml +80 -0
  22. data/docs/README.md +1 -0
  23. data/lib/train-k8s-container/ansi_sanitizer.rb +31 -0
  24. data/lib/train-k8s-container/connection.rb +102 -0
  25. data/lib/train-k8s-container/errors.rb +22 -0
  26. data/lib/train-k8s-container/kubectl_command_builder.rb +87 -0
  27. data/lib/train-k8s-container/kubectl_exec_client.rb +176 -0
  28. data/lib/train-k8s-container/kubernetes_name_validator.rb +44 -0
  29. data/lib/train-k8s-container/platform.rb +93 -0
  30. data/lib/train-k8s-container/pty_session.rb +156 -0
  31. data/lib/train-k8s-container/result_processor.rb +94 -0
  32. data/lib/train-k8s-container/retry_handler.rb +35 -0
  33. data/lib/train-k8s-container/session_manager.rb +95 -0
  34. data/lib/train-k8s-container/shell_detector.rb +198 -0
  35. data/lib/train-k8s-container/transport.rb +30 -0
  36. data/lib/train-k8s-container/version.rb +7 -0
  37. data/lib/train-k8s-container.rb +12 -0
  38. data/sonar-project.properties +17 -0
  39. data/train-k8s-container.gemspec +49 -0
  40. metadata +107 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d3fb5eed626b5b0237f0b191baf0a6d9044c41c768a1fcf144e28163bb53e489
4
+ data.tar.gz: 33208b23e20238d127a60db0e7165a6a4aa405a31b59ed66a80472d467755647
5
+ SHA512:
6
+ metadata.gz: b5bd3221b2ca510b600c75994a777fa37eccec5fc4b208f0f1f03bac2f6f849a3bfcef4bef4d4c5fdc9d8abc35927430772cea1b64f20d848fc81f90944251be
7
+ data.tar.gz: 9b1c7f1b4b4f96f87ab6eeeaad58f5f22a70476c3c659b5dae02f4b6b6e210ed67cef01809674c91d4b76c8e81593b66bdd2cd6607eba5015aec8ae4645dcb57
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+
3
+ echo "--- This is the coverage pipeline for train-k8s-container"
4
+
5
+ # Fetch tokens from vault ASAP so that long-running tests don't cause our vault token to expire
6
+ echo "--- installing vault"
7
+ export VAULT_VERSION=1.13.0
8
+ export VAULT_HOME=$HOME/vault
9
+ curl --create-dirs -sSLo $VAULT_HOME/vault.zip https://releases.hashicorp.com/vault/$VAULT_VERSION/vault_${VAULT_VERSION}_linux_amd64.zip
10
+ unzip -o $VAULT_HOME/vault.zip -d $VAULT_HOME
11
+
12
+ if [ -n "${CI_ENABLE_COVERAGE:-}" ]; then
13
+ echo "--- fetching Sonar token from vault"
14
+ # TODO: Update the path to the key within the key-value store `secret/trains-k8s-container/sonar` is just a dummy placeholder
15
+ export SONAR_TOKEN=$($VAULT_HOME/vault kv get -field token secret/inspec/train-k8s-container/sonar)
16
+
17
+ if [ -n "${SONAR_TOKEN:-}" ]; then
18
+ echo " ++ SONAR_TOKEN set successfully"
19
+ else
20
+ echo " !! SONAR_TOKEN not set - exiting "
21
+ exit 1 # TODO: Remove this line if we wish not to exit
22
+ fi
23
+ fi
24
+
25
+ # If coverage is enabled, then we need to pick up the coverage/coverage.json file
26
+ if [ -n "${CI_ENABLE_COVERAGE:-}" ]; then
27
+ echo "--- installing sonarscanner"
28
+ export SONAR_SCANNER_VERSION=4.7.0.2747
29
+ export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
30
+ curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
31
+ unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
32
+ export PATH=$SONAR_SCANNER_HOME/bin:$PATH
33
+ export SONAR_SCANNER_OPTS="-server"
34
+
35
+ # Delete the vendor/ directory.
36
+ # Excluding it using sonar.exclusions, appears to get ignored,
37
+ # ending up analyzing the gemfile install which blows the analysis.
38
+ echo "--- deleting installed gems"
39
+ rm -rf vendor/
40
+
41
+ # See sonar-project.properties for additional settings
42
+ echo "--- running sonarscanner"
43
+ sonar-scanner \
44
+ -Dsonar.sources=. \
45
+ -Dsonar.host.url=https://sonar.progress.com
46
+ fi
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ set -ue
4
+
5
+ export USER="root"
6
+ export LANG=C.UTF-8 LANGUAGE=C.UTF-8
7
+
8
+ echo "--- bundle install"
9
+ bundle config --local path vendor/bundle
10
+ bundle install --jobs=7 --retry=3
11
+
12
+ echo "+++ bundle exec task"
13
+ bundle exec $@
14
+ RAKE_EXIT=$?
15
+
16
+ exit $RAKE_EXIT
@@ -0,0 +1,61 @@
1
+ # Documentation available at https://expeditor.chef.io/docs/getting-started/
2
+ ---
3
+
4
+ project:
5
+ alias: train-k8s-container
6
+
7
+ # https://expeditor.chef.io/docs/integrations/slack/
8
+ slack:
9
+ notify_channel: inspec-notify
10
+
11
+ # https://expeditor.chef.io/docs/integrations/rubygems/
12
+ # This publish is triggered by the `built_in:publish_rubygems` artifact_action.
13
+ rubygems:
14
+ - train-k8s-container
15
+
16
+ # https://expeditor.chef.io/docs/integrations/github/
17
+ github:
18
+ # This deletes the GitHub PR branch after successfully merged into the release branch
19
+ delete_branch_on_merge: true
20
+ # The tag format to use (e.g. v1.0.0)
21
+ version_tag_format: "v{{version}}"
22
+ # allow bumping the minor release via label
23
+ minor_bump_labels:
24
+ - "Expeditor: Bump Version Minor"
25
+ # allow bumping the major release via label
26
+ major_bump_labels:
27
+ - "Expeditor: Bump Version Major"
28
+
29
+ pipelines:
30
+ - verify:
31
+ description: Pull Request validation tests
32
+ # public: true # Uncomment to make this pipeline public
33
+ - coverage:
34
+ description: Generate test coverage report
35
+ trigger: pull_request
36
+
37
+ changelog:
38
+ rollup_header: Changes not yet released to rubygems.org
39
+
40
+
41
+ subscriptions:
42
+ # These actions are taken, in order they are specified, anytime a Pull Request is merged.
43
+ - workload: pull_request_merged:{{github_repo}}:{{release_branch}}:*
44
+ actions:
45
+ - built_in:bump_version:
46
+ ignore_labels:
47
+ - "Expeditor: Skip Version Bump"
48
+ - "Expeditor: Skip All"
49
+ - bash:.expeditor/update_version.sh:
50
+ only_if: built_in:bump_version
51
+ - built_in:update_changelog:
52
+ ignore_labels:
53
+ - "Expeditor: Skip Changelog"
54
+ - "Expeditor: Skip All"
55
+ - built_in:build_gem:
56
+ only_if: built_in:bump_version
57
+
58
+ - workload: project_promoted:{{agent_id}}:*
59
+ actions:
60
+ - built_in:rollover_changelog
61
+ - built_in:publish_rubygems
@@ -0,0 +1,19 @@
1
+ ---
2
+ expeditor:
3
+ defaults:
4
+ buildkite:
5
+ timeout_in_minutes: 45
6
+ retry:
7
+ automatic:
8
+ limit: 1
9
+
10
+ steps:
11
+
12
+ - label: coverage-pipeline-with-ruby-3.0
13
+ command:
14
+ - CI_ENABLE_COVERAGE=1 /workdir/.expeditor/buildkite/coverage.sh
15
+ expeditor:
16
+ secrets: true
17
+ executor:
18
+ docker:
19
+ image: ruby:3.0
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+ #
3
+ # After a PR merge, Chef Expeditor will bump the PATCH version in the VERSION file.
4
+ # It then executes this file to update any other files/components with that new version.
5
+ #
6
+
7
+ set -evx
8
+
9
+ sed -i -r "s/VERSION = \".*\"/VERSION = \"$(cat VERSION)\"/" lib/train/k8s/container/version.rb
10
+
11
+ # Once Expeditor finishes executing this script, it will commit the changes and push
12
+ # the commit as a new tag corresponding to the value in the VERSION file.
@@ -0,0 +1,44 @@
1
+ ---
2
+ expeditor:
3
+ cached_folders:
4
+ - vendor
5
+ defaults:
6
+ buildkite:
7
+ retry:
8
+ automatic:
9
+ limit: 1
10
+ timeout_in_minutes: 30
11
+
12
+ steps:
13
+
14
+ - label: lint-chefstyle
15
+ command:
16
+ - /workdir/.expeditor/buildkite/run_linux_tests.sh "rake style"
17
+ expeditor:
18
+ executor:
19
+ docker:
20
+ image: ruby:3.0
21
+
22
+ - label: run-specs-ruby-3.0
23
+ command:
24
+ - /workdir/.expeditor/buildkite/run_linux_tests.sh "rake spec"
25
+ expeditor:
26
+ executor:
27
+ docker:
28
+ image: ruby:3.0
29
+
30
+ - label: run-specs-ruby-3.1
31
+ command:
32
+ - /workdir/.expeditor/buildkite/run_linux_tests.sh "rake spec"
33
+ expeditor:
34
+ executor:
35
+ docker:
36
+ image: ruby:3.1
37
+
38
+ - label: run-specs-ruby-3.1
39
+ command:
40
+ - /workdir/.expeditor/buildkite/run_linux_tests.sh "rake spec"
41
+ expeditor:
42
+ executor:
43
+ docker:
44
+ image: ruby:3.1
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --require spec_helper
2
+ --color
3
+ --format documentation
4
+ --tag ~integration
data/.rubocop.yml ADDED
@@ -0,0 +1,57 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1 # Match gemspec minimum (InSpec 6.x embedded Ruby)
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+ Exclude:
6
+ - vendor/**/*
7
+
8
+ # Naming/FileName - train-k8s-container.rb is correct gem convention
9
+ Naming/FileName:
10
+ Enabled: false
11
+
12
+ # Metrics - Transport plugins need larger classes for connection/platform management
13
+ # Following InSpec ecosystem standard (train-kubernetes, inspec-aws disable these)
14
+ Metrics/ClassLength:
15
+ Enabled: false # InSpec plugins inherently have larger connection classes
16
+
17
+ Metrics/ParameterLists:
18
+ Max: 7 # Ruby 3.1+ keyword arguments are self-documenting and preferred
19
+
20
+ Metrics/AbcSize:
21
+ Enabled: false
22
+
23
+ Metrics/CyclomaticComplexity:
24
+ Enabled: false
25
+
26
+ Metrics/PerceivedComplexity:
27
+ Enabled: false
28
+
29
+ Metrics/MethodLength:
30
+ Enabled: false
31
+
32
+ # RSpec tests will have longer blocks - acceptable
33
+ Metrics/BlockLength:
34
+ Exclude:
35
+ - spec/**/*_spec.rb
36
+
37
+ # Allow reasonable line length (Chef standard is 150)
38
+ Layout/LineLength:
39
+ Max: 150
40
+
41
+ # Gemspec - Support Ruby >= 3.1 (InSpec 6.x) but develop on 3.3
42
+ Gemspec/RequiredRubyVersion:
43
+ Enabled: false
44
+
45
+ # Use consistent style for percent literals (avoid flip-flopping during autocorrect)
46
+ Style/PercentLiteralDelimiters:
47
+ PreferredDelimiters:
48
+ default: '[]'
49
+ '%w': '[]'
50
+ '%i': '[]'
51
+
52
+ # Trailing commas in multiline (Chef standard)
53
+ Style/TrailingCommaInArrayLiteral:
54
+ EnforcedStyleForMultiline: consistent_comma
55
+
56
+ Style/TrailingCommaInHashLiteral:
57
+ EnforcedStyleForMultiline: consistent_comma
data/CHANGELOG.md ADDED
@@ -0,0 +1,158 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - **ci**: Real STIG profile execution (canonical-ubuntu-22.04-lts-stig-baseline)
13
+ - **ci**: Same-pod container-to-container scanning test
14
+ - **ci**: Pod-to-pod scanning with cinc-scanner Docker image
15
+
16
+ ### Documentation
17
+
18
+ - MITRE standards documentation (LICENSE.md, NOTICE.md, CODE_OF_CONDUCT.md)
19
+ - CONTRIBUTING.md with development workflow
20
+ - DEVELOPMENT.md with local testing guide (kind cluster setup)
21
+ - README.md rewrite with MITRE branding and comprehensive usage docs
22
+ - SECURITY.md with MITRE SAF contact info
23
+
24
+ ### Fixed
25
+
26
+ - **ci**: Use pre-built cinc-scanner:local image for same-pod testing
27
+ - **platform**: Detect+Context pattern for accurate OS detection
28
+
29
+ ### Miscellaneous Tasks
30
+
31
+ - Switch from InSpec to Cinc Auditor (open source, license-free)
32
+ - Add git-cliff configuration for automated changelog generation
33
+ - Add release-tag.yml workflow for RubyGems publication
34
+
35
+ ## [2.0.0] - 2025-10-04
36
+
37
+ ### Breaking Changes
38
+
39
+ - **BREAKING**: Namespace changed from `Train::K8s::Container` to `TrainPlugins::K8sContainer` (Train v2 standard)
40
+ - **BREAKING**: File structure changed from `lib/train/k8s/container/*` to `lib/train-k8s-container/*`
41
+ - Ruby requirement: >= 3.1
42
+
43
+ ### Added
44
+
45
+ - **Platform Detection**: Detect+Context pattern using `Train::Platforms::Detect.scan(self)`
46
+ - Returns actual OS (ubuntu, alpine, centos) so InSpec resources work correctly
47
+ - Adds `kubernetes` and `container` families for transport awareness
48
+ - Fallback platform for distroless/minimal containers
49
+ - **Shell Detection**: Tiered detection with automatic fallback
50
+ - Unix: bash → sh → ash → zsh
51
+ - Windows: cmd.exe → powershell.exe → pwsh.exe (scaffolded, not tested)
52
+ - Linux family detection from /etc/os-release
53
+ - **Security Hardening**:
54
+ - ANSI escape sequence sanitization (CVE-2021-25743 mitigation)
55
+ - Command injection prevention with Shellwords.escape
56
+ - RFC 1123 validation for pod/container names
57
+ - **Error Handling**:
58
+ - Custom error classes (ConnectionError, CommandError, ValidationError)
59
+ - Retry logic with exponential backoff for transient failures
60
+ - **CI/CD Pipeline**:
61
+ - GitHub Actions with kind cluster integration tests
62
+ - Multi-version Ruby (3.1, 3.2, 3.3) and Kubernetes (1.29, 1.30, 1.31) matrix
63
+ - Security scanning (TruffleHog, bundler-audit, SBOM generation)
64
+ - Pod-to-pod testing with InSpec running inside cluster
65
+ - **Code Quality**:
66
+ - Cookstyle linting (replaced deprecated chefstyle)
67
+ - 95%+ test coverage with SimpleCov
68
+ - Unit tests (mocked) and integration tests (real kubectl)
69
+
70
+ ### Changed
71
+
72
+ - Transport: Proper Train v2 plugin API implementation
73
+ - Connection: Lazy initialization of kubectl client
74
+ - Platform: Uses Train's built-in detection instead of force_platform!
75
+
76
+ ### Fixed
77
+
78
+ - Shell detection command escaping
79
+ - Platform detection accuracy (returns real OS, not generic k8s-container)
80
+ - Thread safety in session management
81
+
82
+ ### Security
83
+
84
+ - ANSI injection prevention (sanitizes terminal escape sequences)
85
+ - Command escaping with Shellwords
86
+ - Input validation for Kubernetes resource names
87
+
88
+ ### Components
89
+
90
+ | File | Purpose |
91
+ |------|---------|
92
+ | `transport.rb` | Train v2 plugin registration |
93
+ | `connection.rb` | URI parsing, connection management |
94
+ | `kubectl_exec_client.rb` | kubectl command execution |
95
+ | `platform.rb` | Detect+Context platform detection |
96
+ | `shell_detector.rb` | Shell availability detection |
97
+ | `ansi_sanitizer.rb` | CVE-2021-25743 mitigation |
98
+ | `kubernetes_name_validator.rb` | RFC 1123 validation |
99
+ | `retry_handler.rb` | Exponential backoff retry logic |
100
+
101
+ ## [1.3.1] - 2024-03-05
102
+
103
+ ### Fixed
104
+
105
+ - Fix run command to use Bourne shell for OS resource commands ([#21](https://github.com/inspec/train-k8s-container/pull/21))
106
+
107
+ ## [1.3.0] - 2024-01-31
108
+
109
+ ### Added
110
+
111
+ - Add support for file connections ([#19](https://github.com/inspec/train-k8s-container/pull/19))
112
+
113
+ ## [1.2.1] - 2024-01-18
114
+
115
+ ### Fixed
116
+
117
+ - Fix for undefined method presence ([#17](https://github.com/inspec/train-k8s-container/pull/17))
118
+
119
+ ## [1.2.0] - 2024-01-16
120
+
121
+ ### Changed
122
+
123
+ - Update README and InSpec compatibility ([#15](https://github.com/inspec/train-k8s-container/pull/15))
124
+
125
+ ## [1.1.2] - 2024-01-16
126
+
127
+ ### Fixed
128
+
129
+ - Connection to container improvements ([#14](https://github.com/inspec/train-k8s-container/pull/14))
130
+
131
+ ## [1.1.1] - 2024-01-15
132
+
133
+ ### Testing
134
+
135
+ - Specs for transporter ([#13](https://github.com/inspec/train-k8s-container/pull/13))
136
+
137
+ ## [1.1.0] - 2024-01-11
138
+
139
+ ### Added
140
+
141
+ - kubectl exec client implementation ([#10](https://github.com/inspec/train-k8s-container/pull/10))
142
+
143
+ ## [1.0.0] - 2024-01-11
144
+
145
+ ### Added
146
+
147
+ - Initial transporter for k8s container ([#9](https://github.com/inspec/train-k8s-container/pull/9))
148
+
149
+ ## Pre-1.0 Releases
150
+
151
+ - **0.0.7** - Pipeline updates
152
+ - **0.0.6** - Version bumper
153
+ - **0.0.5** - Apache v2.0 license
154
+ - **0.0.4** - SonarQube integration
155
+ - **0.0.3** - Initial repo setup
156
+ - **0.0.2** - Expeditor configuration
157
+
158
+ <!-- generated by git-cliff -->
@@ -0,0 +1,13 @@
1
+ # Code of Conduct
2
+
3
+ This project adopts the [Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/) as our code of conduct.
4
+
5
+ ## Our Pledge
6
+
7
+ We are committed to making participation in this project a welcoming experience for everyone.
8
+
9
+ ## Enforcement
10
+
11
+ Instances of unacceptable behavior may be reported to the project team at [saf@mitre.org](mailto:saf@mitre.org).
12
+
13
+ For the full text of our code of conduct, please see: https://www.contributor-covenant.org/version/2/1/code_of_conduct/
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,161 @@
1
+ # Contributing to train-k8s-container
2
+
3
+ Thank you for your interest in contributing to the train-k8s-container plugin! We welcome contributions from the community.
4
+
5
+ ## Development Workflow
6
+
7
+ We use a standard GitFlow workflow:
8
+
9
+ ### Quick Setup
10
+
11
+ ```bash
12
+ # Fork and clone
13
+ git clone https://github.com/YOUR_USERNAME/train-k8s-container.git
14
+ cd train-k8s-container
15
+ bundle install
16
+
17
+ # Run tests
18
+ bundle exec rspec
19
+ ```
20
+
21
+ ### Step by Step
22
+
23
+ 1. **Fork** the repository on GitHub
24
+ 2. **Clone** your fork locally
25
+ 3. **Create a feature branch** from `main`:
26
+ ```bash
27
+ git checkout -b feature/your-feature-name
28
+ ```
29
+ 4. **Make your changes** with appropriate tests
30
+ 5. **Run the test suite** to ensure everything passes:
31
+ ```bash
32
+ bundle install
33
+ bundle exec rspec
34
+ bundle exec rake style
35
+ ```
36
+ 6. **Commit your changes** with clear, descriptive messages
37
+ 7. **Push** to your fork and **create a Pull Request**
38
+
39
+ ## Code Requirements
40
+
41
+ All contributions must meet our quality standards before merging.
42
+
43
+ ### Testing
44
+
45
+ - **All new functionality must include tests**
46
+ - **Tests must pass**: `bundle exec rspec`
47
+ - **Maintain or improve code coverage** (currently 95%+)
48
+
49
+ ### Code Style
50
+
51
+ - **Follow existing Ruby style conventions**
52
+ - **Run linting**: `bundle exec rake style` or `bundle exec rubocop`
53
+ - **No RuboCop violations**
54
+
55
+ ### Documentation
56
+
57
+ - **Update README.md** for user-facing changes
58
+ - **Add inline documentation** for new methods
59
+ - **Update DEVELOPMENT.md** for development workflow changes
60
+
61
+ ## Types of Contributions
62
+
63
+ ### Bug Reports
64
+
65
+ Help us fix problems by providing detailed bug reports.
66
+
67
+ **Requirements:**
68
+ - Use GitHub Issues with the "bug" label
69
+ - Include steps to reproduce
70
+ - Provide InSpec/Cinc and Ruby version information
71
+ - Include relevant log output with `-l debug`
72
+
73
+ ### Feature Requests
74
+
75
+ We love new ideas! Please discuss before implementing.
76
+
77
+ **Process:**
78
+ - Open a GitHub Issue with the "enhancement" label
79
+ - Describe the use case and expected behavior
80
+ - Discuss implementation approach before coding
81
+
82
+ ### Code Contributions
83
+
84
+ - Bug fixes
85
+ - New features
86
+ - Documentation improvements
87
+ - Test coverage improvements
88
+
89
+ ## Development Setup
90
+
91
+ See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed local development and testing instructions, including:
92
+
93
+ - Setting up a kind cluster for integration testing
94
+ - Running unit tests vs integration tests
95
+ - Testing with real Kubernetes pods
96
+ - Debugging tips
97
+
98
+ ## Testing Guidelines
99
+
100
+ ### Unit Tests
101
+
102
+ - Test all public methods
103
+ - Mock external dependencies (kubectl, kubernetes API)
104
+ - Fast execution (< 30 seconds total)
105
+
106
+ ### Integration Tests
107
+
108
+ - Test real kubectl connectivity
109
+ - Use kind cluster for testing
110
+ - Document any manual testing requirements
111
+
112
+ ### Running Tests
113
+
114
+ ```bash
115
+ # Unit tests only (fast, no kubectl required)
116
+ bundle exec rspec spec/train-k8s-container
117
+
118
+ # Integration tests (requires kind cluster)
119
+ bundle exec rspec spec/integration
120
+
121
+ # All tests
122
+ bundle exec rspec
123
+
124
+ # With coverage report
125
+ bundle exec rspec
126
+ open coverage/index.html
127
+ ```
128
+
129
+ ## Pull Request Process
130
+
131
+ 1. **Update Documentation**: Ensure README and relevant docs are updated
132
+ 2. **Test Coverage**: Maintain or improve test coverage percentage
133
+ 3. **Security Review**: Run `bundle audit` and check for vulnerabilities
134
+ 4. **Code Review**: Address feedback from maintainers
135
+ 5. **CI Passing**: All GitHub Actions checks must pass
136
+ 6. **Merge**: Maintainers will merge approved PRs
137
+
138
+ ## Release Process
139
+
140
+ Releases are managed by project maintainers:
141
+
142
+ 1. Version bump in `VERSION` file
143
+ 2. Update `CHANGELOG.md`
144
+ 3. Create release tag (e.g., `v2.0.0`)
145
+ 4. GitHub Actions automatically publishes to RubyGems.org
146
+
147
+ ## Getting Help
148
+
149
+ - **Questions**: Open a GitHub Discussion or Issue
150
+ - **Real-time help**: Email [saf@mitre.org](mailto:saf@mitre.org)
151
+ - **Security issues**: Email [saf-security@mitre.org](mailto:saf-security@mitre.org)
152
+
153
+ ## Community
154
+
155
+ - Follow our [Code of Conduct](CODE_OF_CONDUCT.md)
156
+ - Be respectful and collaborative
157
+ - Help others learn and contribute
158
+
159
+ ## License
160
+
161
+ By contributing, you agree that your contributions will be licensed under the same Apache-2.0 license that covers the project.