Skip to content

feat: Updated license.go file to include the feature for licenseSecret as well#54

Merged
theishshah merged 5 commits intomainfrom
aman/add-licensesecret-feature
Feb 27, 2025
Merged

feat: Updated license.go file to include the feature for licenseSecret as well#54
theishshah merged 5 commits intomainfrom
aman/add-licensesecret-feature

Conversation

@amanpruthi
Copy link
Copy Markdown
Contributor

@amanpruthi amanpruthi commented Feb 13, 2025

Summary by CodeRabbit

  • New Features
    • Enhanced license retrieval for improved stability, including a fallback approach when primary license data isn’t available.
    • Increased observability with additional logging for clearer insights into license handling and error conditions.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 13, 2025

Walkthrough

The changes update the license retrieval process. The GetLicense function now incorporates additional logging and error tracking. A Kubernetes client is created through the new createKubeClient function. The logic has been streamlined to first check if the license is specified within the provided values. If not, the function calls getLicenseFromSecret to retrieve the license from a Kubernetes secret, handling errors and logging relevant information throughout the process.

Changes

File Change Summary
pkg/wandb/spec/utils/license.go Added createKubeClient and getLicenseFromSecret functions; enhanced GetLicense with combined nil checks, logging, and error handling for secret retrieval.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant GL as GetLicense
    participant CK as createKubeClient
    participant GS as getLicenseFromSecret
    participant K8s as Kubernetes API

    U->>GL: Request license
    GL->>CK: Create Kubernetes client
    CK-->>GL: Return client or error
    GL->>GL: Check spec & values for license
    alt License exists in values
        GL->>U: Log and return license
    else License missing
        GL->>GS: Call getLicenseFromSecret with client, secretName, secretKey
        GS->>K8s: Request secret data
        K8s-->>GS: Return secret data or error
        GS->>GL: Log outcome and return license or error
        GL->>U: Return license from secret
    end
Loading

Possibly related PRs

Poem

Oh, what a hop in the code today,
As logs and secrets lead the way.
The client springs with a joyful bound,
In secret paths, the license is found.
This rabbit cheers in code delight,
Leaping through changes with pure insight! 🐰✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 golangci-lint (1.62.2)

Error: can't load config: the Go language version (go1.23) used to build golangci-lint is lower than the targeted Go version (1.24.0)
Failed executing command with error: can't load config: the Go language version (go1.23) used to build golangci-lint is lower than the targeted Go version (1.24.0)

✨ Finishing Touches
  • 📝 Generate Docstrings

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.
  • @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
Copy Markdown

@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)
pkg/wandb/spec/utils/license.go (4)

17-21: Consider exposing errors instead of returning an empty string.

Currently, if the Kubernetes client cannot be created, you log the error but return an empty string, which might obscure the root cause for consumers. It's often better to bubble up errors so they can be handled more gracefully. For example:

 func GetLicense(specs ...*spec.Spec) (string, error) {
     log := ctrllog.Log.WithName("GetLicense")

     kubeClient, err := createKubeClient()
     if err != nil {
         log.Error(err, "Error creating Kubernetes client")
-        return ""
+        return "", err
     }

37-44: Allow specifying a namespace instead of hardcoding "default".

You're calling getLicenseFromSecret with only the secret name and key, but the implementation always uses the "default" namespace. This may limit usage in multi-namespace scenarios. As a good-to-have improvement, consider passing the desired namespace in the function call:

-license := getLicenseFromSecret(kubeClient, secretName, secretKey)
+license := getLicenseFromSecret(kubeClient, secretName, secretKey, "operator-namespace")

(See below for further changes to getLicenseFromSecret that accept a namespace.)


48-55: Avoid using GetConfigOrDie to reduce the risk of panics.

Using GetConfigOrDie() will cause the program to panic if the configuration is invalid. Instead, you can use GetConfig() and handle any errors gracefully, as shown below:

 func createKubeClient() (client.Client, error) {
-    kubeConfig := config.GetConfigOrDie()
-    kubeClient, err := client.New(kubeConfig, client.Options{})
+    cfg, err := config.GetConfig()
+    if err != nil {
+        return nil, err
+    }
+    kubeClient, err := client.New(cfg, client.Options{})
     if err != nil {
         return nil, err
     }
     return kubeClient, nil
 }

57-78: Return errors instead of empty strings when retrieving secrets.

Currently, this function returns an empty string on failures, making it hard to distinguish between various error cases (missing secret, missing key, or reading failure). Consider refactoring the function signature to return (string, error):

-func getLicenseFromSecret(kubeClient client.Client, secretName, secretKey string) string {
+func getLicenseFromSecret(kubeClient client.Client, secretName, secretKey, namespace string) (string, error) {
     log := ctrllog.Log.WithName("getLicenseFromSecret")
     secret := &corev1.Secret{}
     ctx := context.TODO()

-    err := kubeClient.Get(ctx, client.ObjectKey{Name: secretName, Namespace: "default"}, secret)
+    err := kubeClient.Get(ctx, client.ObjectKey{Name: secretName, Namespace: namespace}, secret)
     if err != nil {
         log.Error(err, "Error retrieving secret", "secretName", secretName)
-        return ""
+        return "", err
     }

     if secret.Data == nil {
         log.Info("Secret has no data", "secretName", secretName)
-        return ""
+        return "", fmt.Errorf("secret %q has no data", secretName)
     }

     license, exists := secret.Data[secretKey]
     if !exists {
         log.Info("Key not found in secret", "secretKey", secretKey, "secretName", secretName)
-        return ""
+        return "", fmt.Errorf("secret %q missing key %q", secretName, secretKey)
     }
     log.Info("Successfully retrieved license from secret", "secretName", secretName)
-    return string(license)
+    return string(license), nil
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6048c7b and 86203c0.

📒 Files selected for processing (1)
  • pkg/wandb/spec/utils/license.go (1 hunks)
🔇 Additional comments (8)
pkg/wandb/spec/utils/license.go (8)

4-4: No concerns.


6-9: No concerns.


15-15: No concerns.


24-24: No concerns.


30-30: No concerns.


34-35: No concerns.


45-45: No concerns.


46-46: No concerns.

Copy link
Copy Markdown

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

🧹 Nitpick comments (2)
pkg/wandb/spec/utils/license.go (2)

14-21: Consider adding context cancellation and timeout.

The Kubernetes client operations should have proper context management to prevent hanging in case of connectivity issues.

 func GetLicense(specs ...*spec.Spec) string {
 	log := ctrllog.Log.WithName("GetLicense")
+	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+	defer cancel()
 
-	kubeClient, err := createKubeClient()
+	kubeClient, err := createKubeClient(ctx)
 	if err != nil {
 		log.Error(err, "Error creating Kubernetes client")
 		return ""
 	}

23-41: Consider adding validation for secret parameters.

The secret name and key should be validated for length and format before making the Kubernetes API call.

 		secretName := s.Values.GetString("global.licenseSecret.name")
 		secretKey := s.Values.GetString("global.licenseSecret.key")
 		secretNamespace := s.Values.GetString("global.licenseSecret.namespace")
+		if len(secretName) > 253 || !isValidKubernetesName(secretName) {
+			log.Info("Invalid secret name", "secretName", secretName)
+			continue
+		}
+		if len(secretKey) == 0 {
+			log.Info("Empty secret key")
+			continue
+		}
 		if secretNamespace == "" {
 			secretNamespace = "default"
 		}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 86203c0 and 356c115.

📒 Files selected for processing (1)
  • pkg/wandb/spec/utils/license.go (1 hunks)

Comment thread pkg/wandb/spec/utils/license.go
Comment thread pkg/wandb/spec/utils/license.go
@zacharyblasczyk zacharyblasczyk changed the title Updated license.go file to include the feature for licenseSecret as well feat: Updated license.go file to include the feature for licenseSecret as well Feb 26, 2025
Copy link
Copy Markdown

@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

♻️ Duplicate comments (2)
pkg/wandb/spec/utils/license.go (2)

62-78: 🛠️ Refactor suggestion

Add context parameter to createKubeClient function.

The implementation follows the recommended pattern with proper validation and error handling, but doesn't accept a context parameter for propagating cancellation signals.

Apply this diff to improve the function:

-func createKubeClient() (client.Client, error) {
+func createKubeClient(ctx context.Context) (client.Client, error) {
 	kubeConfig, err := config.GetConfig()
 	if err != nil {
 		return nil, err
 	}
 	if kubeConfig.Host == "" {
 		return nil, fmt.Errorf("invalid kubernetes configuration: empty host")
 	}
 
 	kubeClient, err := client.New(kubeConfig, client.Options{
 		Scheme: scheme.Scheme,
 	})
 	if err != nil {
 		return nil, err
 	}
 	return kubeClient, nil
 }

80-107: 🛠️ Refactor suggestion

Use provided context instead of creating a new one.

The function should accept a context parameter instead of creating a new background context. This allows proper propagation of cancellation signals and request deadlines.

Apply this diff to improve context management:

-func getLicenseFromSecret(kubeClient client.Client, secretName, secretKey, secretNamespace string) string {
+func getLicenseFromSecret(ctx context.Context, kubeClient client.Client, secretName, secretKey, secretNamespace string) string {
 	log := ctrllog.Log.WithName("getLicenseFromSecret")
 	secret := &corev1.Secret{}
 
-	err := kubeClient.Get(context.Background(), client.ObjectKey{Name: secretName, Namespace: secretNamespace}, secret)
+	err := kubeClient.Get(ctx, client.ObjectKey{Name: secretName, Namespace: secretNamespace}, secret)
 	if err != nil {
 		log.Error(err, "Error retrieving secret")
 		return ""
 	}
 
 	if secret.Data == nil {
 		log.Info("Secret has no data")
 		return ""
 	}
 	license, exists := secret.Data[secretKey]
 	if !exists {
 		log.Info("Key not found in secret")
 		return ""
 	}
 
 	if len(license) == 0 {
 		log.Info("Empty license value in secret")
 		return ""
 	}
 
 	log.Info("Successfully retrieved license from secret")
 	return string(license)
 }
🧹 Nitpick comments (2)
pkg/wandb/spec/utils/license.go (2)

84-84: Add timeout for Kubernetes API calls.

The current implementation uses a context without a timeout for Kubernetes API calls, which could lead to hanging requests in case of network issues or an unresponsive API server.

Consider using a timeout context for the Kubernetes API call:

-	err := kubeClient.Get(context.Background(), client.ObjectKey{Name: secretName, Namespace: secretNamespace}, secret)
+	ctxWithTimeout, cancel := context.WithTimeout(ctx, 10*time.Second)
+	defer cancel()
+	err := kubeClient.Get(ctxWithTimeout, client.ObjectKey{Name: secretName, Namespace: secretNamespace}, secret)

Don't forget to add the time package to imports:

+	"time"

44-57: Add validation for secret configuration values.

The code doesn't validate that the retrieved values for secretName, secretKey, and secretNamespace meet minimum requirements before using them.

Add validation for the secret configuration values:

 		secretName := s.Values.GetString("global.licenseSecret.name")
 		secretKey := s.Values.GetString("global.licenseSecret.key")
 		secretNamespace := s.Values.GetString("global.licenseSecret.namespace")
 		if secretNamespace == "" {
 			secretNamespace = "default"
 		}
 
-		if secretName != "" && secretKey != "" {
+		if secretName == "" {
+			log.Info("Secret name is empty, skipping secret lookup")
+			continue
+		}
+		
+		if secretKey == "" {
+			log.Info("Secret key is empty, skipping secret lookup")
+			continue
+		}
+		
+		log.Info("Attempting to retrieve license from secret", "name", secretName, "namespace", secretNamespace)
 			license := getLicenseFromSecret(kubeClient, secretName, secretKey, secretNamespace)
 			if license != "" {
 				log.Info("License retrieved from Kubernetes secret")
 				return license
 			}
-		}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 531cf4b and f2033c9.

📒 Files selected for processing (1)
  • pkg/wandb/spec/utils/license.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Test
  • GitHub Check: Build
  • GitHub Check: build-and-scan

Comment on lines 16 to 60
func GetLicense(specs ...*spec.Spec) string {
log := ctrllog.Log.WithName("GetLicense")

// First check if license is directly provided in values
for _, s := range specs {
if s == nil {
continue
}
if s.Values == nil {
if s == nil || s.Values == nil {
continue
}

license := s.Values.GetString("global.license")
if license != "" {
log.Info("License retrieved from values.yaml")
return license
}
}

// Then try to get from secret if no direct license was found
kubeClient, err := createKubeClient()
if err != nil {
log.Error(err, "Error creating Kubernetes client")
return ""
}

for _, s := range specs {
if s == nil || s.Values == nil {
continue
}

secretName := s.Values.GetString("global.licenseSecret.name")
secretKey := s.Values.GetString("global.licenseSecret.key")
secretNamespace := s.Values.GetString("global.licenseSecret.namespace")
if secretNamespace == "" {
secretNamespace = "default"
}

if secretName != "" && secretKey != "" {
license := getLicenseFromSecret(kubeClient, secretName, secretKey, secretNamespace)
if license != "" {
log.Info("License retrieved from Kubernetes secret")
return license
}
}
}
return ""
}
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Feb 26, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance context propagation in GetLicense function.

The updated GetLicense function has improved logging and error handling, which is excellent. However, it doesn't accept a context parameter for proper cancellation signal propagation, which is passed down to lower-level functions.

Apply this diff to improve context management:

-func GetLicense(specs ...*spec.Spec) string {
+func GetLicense(ctx context.Context, specs ...*spec.Spec) string {
 	log := ctrllog.Log.WithName("GetLicense")
 
 	// First check if license is directly provided in values
 	for _, s := range specs {
 		if s == nil || s.Values == nil {
 			continue
 		}
 
 		license := s.Values.GetString("global.license")
 		if license != "" {
 			log.Info("License retrieved from values.yaml")
 			return license
 		}
 	}
 
 	// Then try to get from secret if no direct license was found
-	kubeClient, err := createKubeClient()
+	kubeClient, err := createKubeClient(ctx)
 	if err != nil {
 		log.Error(err, "Error creating Kubernetes client")
 		return ""
 	}
 
 	for _, s := range specs {
 		if s == nil || s.Values == nil {
 			continue
 		}
 
 		secretName := s.Values.GetString("global.licenseSecret.name")
 		secretKey := s.Values.GetString("global.licenseSecret.key")
 		secretNamespace := s.Values.GetString("global.licenseSecret.namespace")
 		if secretNamespace == "" {
 			secretNamespace = "default"
 		}
 
 		if secretName != "" && secretKey != "" {
-			license := getLicenseFromSecret(kubeClient, secretName, secretKey, secretNamespace)
+			license := getLicenseFromSecret(ctx, kubeClient, secretName, secretKey, secretNamespace)
 			if license != "" {
 				log.Info("License retrieved from Kubernetes secret")
 				return license
 			}
 		}
 	}
 	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.

Suggested change
func GetLicense(specs ...*spec.Spec) string {
log := ctrllog.Log.WithName("GetLicense")
// First check if license is directly provided in values
for _, s := range specs {
if s == nil {
continue
}
if s.Values == nil {
if s == nil || s.Values == nil {
continue
}
license := s.Values.GetString("global.license")
if license != "" {
log.Info("License retrieved from values.yaml")
return license
}
}
// Then try to get from secret if no direct license was found
kubeClient, err := createKubeClient()
if err != nil {
log.Error(err, "Error creating Kubernetes client")
return ""
}
for _, s := range specs {
if s == nil || s.Values == nil {
continue
}
secretName := s.Values.GetString("global.licenseSecret.name")
secretKey := s.Values.GetString("global.licenseSecret.key")
secretNamespace := s.Values.GetString("global.licenseSecret.namespace")
if secretNamespace == "" {
secretNamespace = "default"
}
if secretName != "" && secretKey != "" {
license := getLicenseFromSecret(kubeClient, secretName, secretKey, secretNamespace)
if license != "" {
log.Info("License retrieved from Kubernetes secret")
return license
}
}
}
return ""
}
func GetLicense(ctx context.Context, specs ...*spec.Spec) string {
log := ctrllog.Log.WithName("GetLicense")
// First check if license is directly provided in values
for _, s := range specs {
if s == nil || s.Values == nil {
continue
}
license := s.Values.GetString("global.license")
if license != "" {
log.Info("License retrieved from values.yaml")
return license
}
}
// Then try to get from secret if no direct license was found
kubeClient, err := createKubeClient(ctx)
if err != nil {
log.Error(err, "Error creating Kubernetes client")
return ""
}
for _, s := range specs {
if s == nil || s.Values == nil {
continue
}
secretName := s.Values.GetString("global.licenseSecret.name")
secretKey := s.Values.GetString("global.licenseSecret.key")
secretNamespace := s.Values.GetString("global.licenseSecret.namespace")
if secretNamespace == "" {
secretNamespace = "default"
}
if secretName != "" && secretKey != "" {
license := getLicenseFromSecret(ctx, kubeClient, secretName, secretKey, secretNamespace)
if license != "" {
log.Info("License retrieved from Kubernetes secret")
return license
}
}
}
return ""
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@coderabbitai are we doing the ctx propagation elsewhere in the code? Or is this a new paradigm you are recommending?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Look for functions that accept a context parameter
echo "=== Functions accepting context parameters ==="
rg -t go "func.*\(.*context\.Context.*\)" --stats

# Find direct uses of context.Background()
echo -e "\n=== Direct uses of context.Background() ==="
rg -t go "context\.Background\(\)" --stats

# Look for context propagation patterns (functions that receive ctx and pass it to other functions)
echo -e "\n=== Context propagation patterns ==="
rg -t go "func.*\((ctx|context|c).*context\.Context.*\).*\{" -A 10 -B 2 | rg "(ctx|context|c).*\,"

# Check the imports in the current file to see if context is commonly imported
echo -e "\n=== Current file imports ==="
cat pkg/wandb/spec/utils/license.go | rg "import"

Length of output: 4739


@zacharyblasczyk Based on my search of the codebase, I can see that context propagation is used in several parts of the code, particularly in controllers like WeightsAndBiasesReconciler where functions accept and propagate a context parameter. However, it's not consistently applied throughout the codebase.

In your current implementation of getLicenseFromSecret, you're directly using context.Background() rather than propagating a context from the caller. This approach works but doesn't allow for proper cancellation signals to flow through the call stack.

Adding context propagation would align with Kubernetes controller-runtime best practices and the patterns already present in your controller code. It's not a completely new paradigm for your codebase, but rather making the pattern more consistent across your utilities.

Would you like me to suggest an updated implementation that maintains the current behavior while supporting context propagation?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@danielpanzella, do you have an opinion, I think for now this is fine. Giving approval.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

@theishshah theishshah merged commit bb55caa into main Feb 27, 2025
@theishshah theishshah deleted the aman/add-licensesecret-feature branch February 27, 2025 17:51
jsbroks pushed a commit that referenced this pull request Feb 27, 2025
## [1.19.0](v1.18.5...v1.19.0) (2025-02-27)

### Features

* Updated license.go file to include the feature for licenseSecret as well ([#54](#54)) ([bb55caa](bb55caa))
@jsbroks
Copy link
Copy Markdown
Member

jsbroks commented Feb 27, 2025

This PR is included in version 1.19.0 🎉

sqaisar pushed a commit to sqaisar/wandb-operator that referenced this pull request Apr 11, 2025
## 1.0.0 (2025-04-11)

### Features

* Add active-state cm ([wandb#2](https://github.com/sqaisar/wandb-operator/issues/2)) ([5a6c4c3](5a6c4c3))
* Add caching for deployer release requests ([1185b40](1185b40))
* Add events recording ([388d37b](388d37b))
* Add helm support ([077765c](077765c))
* Add option to set reconcileFrequency ([484c014](484c014))
* Add support for helm repo releases ([dfef752](dfef752))
* Add support for release from a git repository ([8a6b073](8a6b073))
* Adding owner ref and wait and timeout  to uninstall  ([wandb#51](https://github.com/sqaisar/wandb-operator/issues/51)) ([f21fd6d](f21fd6d))
* Allow the operator to support installation without cluster level permissions ([wandb#16](https://github.com/sqaisar/wandb-operator/issues/16)) ([6f29a3e](6f29a3e))
* Make wandb operator available on OperatorHub ([wandb#32](https://github.com/sqaisar/wandb-operator/issues/32)) ([1a59dab](1a59dab))
* **operator:** Add airgapped support ([wandb#12](https://github.com/sqaisar/wandb-operator/issues/12)) ([bfd3796](bfd3796))
* Prevent Logging of Sensitive info in Plain Text ([wandb#31](https://github.com/sqaisar/wandb-operator/issues/31)) ([5530cb3](5530cb3))
* Prevent Logging of Sensitive info in Plain Text ([wandb#35](https://github.com/sqaisar/wandb-operator/issues/35)) ([9a752fd](9a752fd))
* Release Version Pinning Init ([wandb#28](https://github.com/sqaisar/wandb-operator/issues/28)) ([dfe8bda](dfe8bda))
* Replace base image with RHEL UBI ([wandb#44](https://github.com/sqaisar/wandb-operator/issues/44)) ([12497d2](12497d2))
* Support for deploymenting via jobs ([da801ea](da801ea))
* Updated license.go file to include the feature for licenseSecret as well ([wandb#54](https://github.com/sqaisar/wandb-operator/issues/54)) ([bb55caa](bb55caa))
* Use container based deployments only ([3e6b222](3e6b222))
* use secrets instead of configmaps ([049797f](049797f))

### Bug Fixes

* add applied config to download bundle ([bef77c2](bef77c2))
* Add console namespace and service name to config properties ([0b9efef](0b9efef))
* Add debugging for installing release ([893ebd9](893ebd9))
* add gh token for ci ([72d456f](72d456f))
* add license log ([wandb#11](https://github.com/sqaisar/wandb-operator/issues/11)) ([e129fab](e129fab))
* Add operator namespace env ([846731a](846731a))
* add operator properties to config ([b5f48f0](b5f48f0))
* add pnpm, node and git to docker image ([176b6f0](176b6f0))
* Add Tilt configs for local development ([wandb#53](https://github.com/sqaisar/wandb-operator/issues/53)) ([5ef82b5](5ef82b5))
* added changelog commits ([61b5f5d](61b5f5d))
* Assign metadata instead of merging it ([908c839](908c839))
* Basic Auth Fix ([wandb#56](https://github.com/sqaisar/wandb-operator/issues/56)) ([414b2cf](414b2cf))
* Bump controller tools version to latest ([wandb#13](https://github.com/sqaisar/wandb-operator/issues/13)) ([c52dbb6](c52dbb6))
* Bump deps ([wandb#36](https://github.com/sqaisar/wandb-operator/issues/36)) ([eefb59c](eefb59c))
* Bump deps ([wandb#70](https://github.com/sqaisar/wandb-operator/issues/70)) ([11ba9f8](11ba9f8))
* Channel spec not getting applied correctly ([6e763a8](6e763a8))
* Charts download ([57355ce](57355ce))
* Clean up docker image ([ef7c629](ef7c629))
* clean up env for image push ([7213ed2](7213ed2))
* Correct merge order ([cd49cef](cd49cef))
* correctly check if chart is installed based on status ([384d330](384d330))
* Create release rc files ([f7f4622](f7f4622))
* Debug logging errors ([wandb#26](https://github.com/sqaisar/wandb-operator/issues/26)) ([a641621](a641621))
* Debug logging the cache ([wandb#21](https://github.com/sqaisar/wandb-operator/issues/21)) ([26e8fd5](26e8fd5))
* Debugging logic ([wandb#22](https://github.com/sqaisar/wandb-operator/issues/22)) ([2c019b8](2c019b8))
* Default to dev mode ([d961f77](d961f77))
* docker build ([d160a9c](d160a9c))
* docker image push ([e08b3da](e08b3da))
* Git release pulls correctly ([d47aebd](d47aebd))
* init controller ([0f0a9e9](0f0a9e9))
* install go version ([6664b4b](6664b4b))
* Install kubectl in docker image ([e5df9de](e5df9de))
* Jobs work? ([9972d26](9972d26))
* kubectl not working in docker image ([ffc694e](ffc694e))
* Local_resource and kubectl apply could risk deploying to the wrong context ([wandb#66](https://github.com/sqaisar/wandb-operator/issues/66)) ([a90a270](a90a270))
* lock pnpm version ([c2608f7](c2608f7))
* Log the diff of specs ([wandb#23](https://github.com/sqaisar/wandb-operator/issues/23)) ([c0ea0d8](c0ea0d8))
* Look for secret in namespace of wandb CR ([wandb#78](https://github.com/sqaisar/wandb-operator/issues/78)) ([e374c9a](e374c9a))
* Mask sensitive values in log ([wandb#14](https://github.com/sqaisar/wandb-operator/issues/14)) ([514336d](514336d))
* merge func ([94aa0d0](94aa0d0))
* Output json format logs ([90af7b6](90af7b6))
* Pass namespace into chart ([e8e0b8f](e8e0b8f))
* pass spec namespace and name ([79d77f2](79d77f2))
* Preserve unknown fields ([565a25f](565a25f))
* properly get license ([6ff6533](6ff6533))
* Properly merge chart specs together ([37c41bc](37c41bc))
* Properly parse chart from deployer ([5eabdfe](5eabdfe))
* Properly set namespace for deployments ([53f51a9](53f51a9))
* Properly update complete status ([86a5196](86a5196))
* push images to dockerhub ([d4cdd27](d4cdd27))
* refactor spec ([87be86b](87be86b))
* Refactor specs ([7c6da34](7c6da34))
* Release needs ginkgo ([wandb#65](https://github.com/sqaisar/wandb-operator/issues/65)) ([c51df78](c51df78))
* remove console ([fba45ee](fba45ee))
* remove debugging logs ([d4da31f](d4da31f))
* remove submodule ([bdb408a](bdb408a))
* Remove ui building step ([08ee985](08ee985))
* Rename config -> values and release -> chart ([519cd1b](519cd1b))
* Rename config spec cfs ([672100a](672100a))
* rename configs ([8727281](8727281))
* rename docker variables ([274e20c](274e20c))
* rename versioning step name ([77bf4ed](77bf4ed))
* reorder backup ([ab66486](ab66486))
* revert to v2 for semver ([535a721](535a721))
* Save active spec metadata ([47bd862](47bd862))
* Secret reading metadata ([6dab7ed](6dab7ed))
* secrets stored with correct values ([f6d61e9](f6d61e9))
* Serve console with gin ([c9e04aa](c9e04aa))
* set namespace when running kubectl apply ([1d6f00c](1d6f00c))
* Setting cached release namespace incorrectly ([e585555](e585555))
* Simplify docker image ([1cf55e4](1cf55e4))
* Support Openshift permissions schema for the helm cache ([wandb#17](https://github.com/sqaisar/wandb-operator/issues/17)) ([b498f79](b498f79))
* TLS ([wandb#67](https://github.com/sqaisar/wandb-operator/issues/67)) ([0d3013c](0d3013c))
* Tmp directory permissions ([b0820f5](b0820f5))
* Update to fix some CVEs ([wandb#55](https://github.com/sqaisar/wandb-operator/issues/55)) ([9a34cbe](9a34cbe))
* upgrade semantic to v3 ([594c463](594c463))
* Use cdk8s image for apply container ([189bc08](189bc08))
* Use deployer release channels ([480b380](480b380))
* Using validate for job spec ([5c7ff66](5c7ff66))
* x-kubernetes-preserve-unknown-fields ([bedac52](bedac52))
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.

5 participants