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

fix(generic-app): update svc to support empty ports #456

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

calinah
Copy link
Contributor

@calinah calinah commented Jan 10, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced Helm chart configuration with more flexible service and StatefulSet settings
    • Added conditional service configuration options
  • Documentation

    • Updated chart version to 0.3.0
    • Improved README with clearer configuration guidance
    • Added comments explaining service port configuration
  • Chores

    • Removed explicit port definitions in service configuration
    • Simplified service template logic

Copy link

coderabbitai bot commented Jan 10, 2025

Walkthrough

This pull request introduces updates to the generic-app Helm chart, focusing on version incrementation and service configuration refinements. The changes span across multiple files in the chart, including Chart.yaml, README.md, templates/apps.yaml, and values.yaml. The primary modifications involve updating the chart version to 0.3.0, removing explicit port definitions, and adding conditional logic for service and StatefulSet configurations.

Changes

File Change Summary
charts/generic-app/Chart.yaml Version updated from 0.2.0 to 0.3.0
charts/generic-app/README.md - Version badge updated to 0.3.0
- Removed explicit port listings for apps.example-app.service
charts/generic-app/templates/apps.yaml - Added conditional clusterIP: None for ClusterIP services
- Added conditional serviceName for StatefulSets
charts/generic-app/values.yaml Removed explicit service port definitions, replaced with explanatory comments

Sequence Diagram

sequenceDiagram
    participant Chart as Helm Chart
    participant Service as Kubernetes Service
    participant StatefulSet as StatefulSet

    Chart->>Service: Configure Service
    alt ClusterIP Service
        Chart-->>Service: Set clusterIP to None
    end

    Chart->>StatefulSet: Configure StatefulSet
    alt Service Enabled
        Chart-->>StatefulSet: Set serviceName dynamically
    end
Loading

Possibly related PRs

Suggested reviewers

  • cjorge-graphops

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 to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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

@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: 1

🧹 Nitpick comments (1)
charts/generic-app/templates/apps.yaml (1)

315-317: LGTM! Well-structured headless service configuration.

The addition of clusterIP: None for ClusterIP services is correct and follows Kubernetes best practices for headless services, which is particularly useful for StatefulSet DNS-based discovery.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c22ab69 and d671ea6.

📒 Files selected for processing (4)
  • charts/generic-app/Chart.yaml (1 hunks)
  • charts/generic-app/README.md (3 hunks)
  • charts/generic-app/templates/apps.yaml (3 hunks)
  • charts/generic-app/values.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • charts/generic-app/values.yaml
🔇 Additional comments (5)
charts/generic-app/Chart.yaml (1)

17-17: Consider using patch version for bug fixes.

The PR title indicates this is a bug fix (fix: update svc to support empty ports), but the version bump from 0.2.0 to 0.3.0 suggests a minor release with new features. According to semantic versioning:

  • Patch version (0.2.1): Bug fixes and patches
  • Minor version (0.3.0): New backward-compatible functionality

Consider using a patch version bump (0.2.1) instead, unless this change introduces new features not mentioned in the PR title.

Run this script to check the scope of changes and verify if this warrants a minor version bump:

✅ Verification successful

Minor version bump (0.3.0) is appropriate

While the PR title mentions a fix, the change introduces new functionality by making service ports optional, which is a backward-compatible enhancement to the chart's capabilities. This aligns with semantic versioning principles where minor version bumps (0.x.0) are used for new features.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the scope of changes to determine if this warrants a minor version bump

# Check for new features or breaking changes in the templates
echo "Checking for significant changes in templates..."
rg -l "template" charts/generic-app/templates/

# Look for changes in values.yaml that might indicate new features
echo "Checking for new configuration options..."
rg -A 5 "ports:|service:" charts/generic-app/values.yaml

Length of output: 922

charts/generic-app/README.md (2)

5-5: LGTM! Version update is consistent.

The version badge has been correctly updated to match the new chart version 0.3.0.


330-331: Verify the example configuration aligns with empty ports support.

The example configuration still shows explicit port definitions in the default values, which might confuse users about the new empty ports support feature.

Let's verify if there are any other examples in the codebase that need to be updated:

charts/generic-app/templates/apps.yaml (2)

Line range hint 318-331: LGTM! Proper handling of optional ports.

The conditional block for ports aligns with the PR objective to support empty ports while maintaining backward compatibility for services that define ports.


350-354: LGTM! Verify StatefulSet behavior when service is disabled.

The conditional serviceName configuration is correct. However, please verify that disabling the service doesn't break any StatefulSet that relies on DNS-based discovery.

Let's check for potential StatefulSet configurations that might rely on DNS discovery:

✅ Verification successful

Verification complete - conditional serviceName is correct and safe

The current implementation is the right approach. When service is disabled, it implies DNS-based discovery isn't needed for that StatefulSet deployment, so omitting serviceName is the correct behavior.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for StatefulSet configurations that might need DNS discovery
# Look for patterns indicating DNS usage in container specs

# Search for DNS-related environment variables or command arguments
rg -l '(?i)(hostname|dns|service|discovery)' --type yaml

# Search for StatefulSet configurations with potential service dependencies
ast-grep --pattern 'kind: StatefulSet
  $$$
  spec {
    $$$
    template {
      $$$
      spec {
        $$$
        containers {
          $$$
          env {
            $$$
            valueFrom {
              fieldRef {
                fieldPath: "metadata.name"
              }
            }
            $$$
          }
          $$$
        }
        $$$
      }
      $$$
    }
    $$$
  }'

Length of output: 6337

@@ -367,7 +367,7 @@ We do not recommend that you upgrade the application by overriding `image.tag`.
| apps.example-app.nodeSelector | Node selector | object | `{"kubernetes.io/arch":"amd64","kubernetes.io/os":"linux"}` |
| apps.example-app.podSecurityContext | Pod security context | object | `{"fsGroup":2000}` |
| apps.example-app.replicaCount | Number of pod replicas to run | int | `1` |
| apps.example-app.service | Default service configuration | object | `{"annotations":{"prometheus.io/scrape":"true"},"enabled":true,"ports":{"http":8080,"metrics":9090},"type":"ClusterIP"}` |
| apps.example-app.service | Default service configuration | object | `{"annotations":{"prometheus.io/scrape":"true"},"enabled":true,"type":"ClusterIP"}` |
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Update service configuration documentation for empty ports.

The service configuration example still shows explicit port definitions, which doesn't reflect the new empty ports support feature mentioned in the PR title.

Consider updating the service configuration example to demonstrate both cases:

  1. With explicit ports
  2. Without ports (new feature)
 | apps.example-app.service | Default service configuration | object | `{"annotations":{"prometheus.io/scrape":"true"},"enabled":true,"type":"ClusterIP"}` |
+
+Note: The service configuration now supports empty ports. You can either:
+- Specify explicit ports:
+  ```yaml
+  service:
+    enabled: true
+    type: ClusterIP
+    ports:
+      http: 8080
+      metrics: 9090
+  ```
+- Or omit ports entirely:
+  ```yaml
+  service:
+    enabled: true
+    type: ClusterIP
+  ```

Comment on lines +315 to +317
{{- if eq $service.type "ClusterIP" }}
clusterIP: None
{{- end }}
Copy link
Contributor

@cjorge-graphops cjorge-graphops Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this spec must not be on a regular clusterIP type service. What I think you wanted here was type = "Headless" which will then have "clusterIP: None" (would be a new type, don't think it has been contemplated so far)

@@ -342,7 +347,11 @@ spec:
{{- include "app.selectorLabels" $ | nindent 6 }}
lname: {{ $lName }}
{{- if $appIsStatefulSet }}
{{- with .service }}
{{- if .enabled }}
serviceName: {{ $fullComponentName }}
Copy link
Contributor

@cjorge-graphops cjorge-graphops Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serviceName is mandatory in a StatefulSet I think, so the user needs to have a headless service to put here. The app supports defining multiple services, and the user when creating a headless one is also quite likely to create a regular clusterIP service. Do we want to force him to have to make this specific one the headless one?
Also defaults to $fullComponentName, presumably the non headless one will then need to have a different name. These things are tricky, try to find some sound defaults + a behavior that is not very tricky for the user (or reasonably documented... or the app just failing when a certain assumed condition isn't verified with a clear error message about the constraints... or anything else you may have as an idea).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can have a statefulset without a service hence way I left it as an option - I've tested that. In general however having a headless service is better for the consistent pod identity.

Copy link
Contributor

@cjorge-graphops cjorge-graphops Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't say you need to have a Service to have a StatefulSet, I said you need to have serviceName in a StatefulSet, which then implies a headless service must exist - otherwise what are you filling this field with?:

https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/stateful-set-v1/#StatefulSetSpec

serviceName (string), required

serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where "pod-specific-string" is managed by the StatefulSet controller.

it says required

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants