Skip to content

Commit 45a3526

Browse files
Merge pull request #122 from rajathagasthya/apply-crds
Refactor crdutil library and add delete support
2 parents c80af13 + 7dfe3b8 commit 45a3526

File tree

9 files changed

+536
-171
lines changed

9 files changed

+536
-171
lines changed

cmd/apply-crds/main.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

examples/apply-crds/main.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright 2025 NVIDIA CORPORATION & AFFILIATES
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package main demonstrates how to use the crdutil package to manage CRDs.
18+
// This is a simple example that shows how to apply and delete CRDs from directories or files.
19+
package main
20+
21+
import (
22+
"context"
23+
"flag"
24+
"log"
25+
26+
"github.com/NVIDIA/k8s-operator-libs/pkg/crdutil"
27+
)
28+
29+
var (
30+
crdsPath string
31+
operation string
32+
)
33+
34+
func init() {
35+
flag.StringVar(&crdsPath, "crds-path", "",
36+
"Path to CRD manifest file or directory (directories are searched recursively)")
37+
flag.StringVar(&operation, "operation", "apply", "Operation to perform: 'apply' or 'delete'")
38+
}
39+
40+
func main() {
41+
flag.Parse()
42+
43+
if crdsPath == "" {
44+
log.Fatal("Error: --crds-path flag is required")
45+
}
46+
47+
ctx := context.Background()
48+
49+
switch operation {
50+
case "apply":
51+
if err := crdutil.ProcessCRDs(ctx, []string{crdsPath}, crdutil.CRDOperationApply); err != nil {
52+
log.Fatalf("Failed to apply CRDs: %v", err)
53+
}
54+
case "delete":
55+
if err := crdutil.ProcessCRDs(ctx, []string{crdsPath}, crdutil.CRDOperationDelete); err != nil {
56+
log.Fatalf("Failed to delete CRDs: %v", err)
57+
}
58+
default:
59+
log.Fatalf("Invalid operation: %s (must be 'apply' or 'delete')", operation)
60+
}
61+
}

pkg/crdutil/README.md

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,41 @@
1-
# CRD Apply Tool
1+
# CRD Management Library
22

3-
This tool is designed to help deploy and manage Custom Resource Definitions (CRDs) in a Kubernetes cluster.
4-
It applies all CRDs found in specified directories, providing a solution to some of the limitations of Helm when it comes to managing CRDs.
3+
A Go library for deploying and managing Custom Resource Definitions (CRDs) in Kubernetes clusters.
4+
It supports both applying (creating/updating) and deleting CRDs from individual files or directories (searched recursively).
5+
6+
This package is intended to be used programmatically in Go applications. An example CLI implementation is provided in [`examples/apply-crds/`](../../examples/apply-crds/) to demonstrate usage.
57

68
## Motivation
79

810
While Helm is commonly used for managing Kubernetes resources, it has certain restrictions with CRDs:
911

10-
- CRDs placed in Helm's top-level `crds/` directory are not updated on upgrades or rollbacks.
11-
- Placing CRDs in Helms `templates/` directory is not entirely safe, as deletions and upgrades of CRDs are not always handled properly.
12+
- CRDs placed in a Helm chart's top-level `crds/` directory are installed once but not updated on upgrades or deleted on uninstalls.
13+
- Placing CRDs in a Helm chart's `templates/` directory allows updates but can be risky since CRDs are deleted on uninstall unless protected with the `helm.sh/resource-policy: keep` annotation.
1214

13-
This tool offers a more reliable way to apply CRDs, ensuring they are created or updated as needed.
15+
This library offers a more reliable way to manage CRDs, ensuring they are created, updated, or deleted as needed.
1416

1517
## Features
1618

17-
- **Apply CRDs from multiple directories**: Allows specifying multiple directories containing CRD YAML manifests.
18-
- **Recursive directory search**: Walks through each specified directory to find and apply all YAML files.
19-
- **Safe update mechanism**: Checks if a CRD already exists; if so, it updates it with the latest version.
19+
- **Apply and Delete CRDs**: Supports both applying (creating/updating) and deleting CRDs.
20+
- **Flexible input**: Accepts individual YAML files or directories (or a mix of both).
21+
- **Recursive directory search**: Automatically walks through directories to find and process all YAML files.
22+
- **Safe update mechanism**: Checks if a CRD already exists; if so, it updates it with retry-on-conflict logic.
23+
- **Idempotent operations**: Both apply and delete operations can be run multiple times safely.
2024
- **Handles multiple YAML documents**: Supports files containing multiple CRD documents separated by YAML document delimiters.
2125

22-
## Usage
26+
## Quick Start
2327

24-
Compile and run the tool by providing the `-crds-dir` flag with paths to the directories containing the CRD YAML files:
28+
For usage examples, see [`examples/apply-crds/`](../../examples/apply-crds/).
2529

26-
```bash
27-
go build -o crd-apply-tool
28-
./crd-apply-tool -crds-dir /path/to/crds1 -crds-dir /path/to/crds2
29-
```
30+
## Integration Examples
31+
32+
### Using in Helm Hooks
3033

31-
In a Helm pre-install hook it can look like:
34+
You can build a custom binary using this library and deploy it as a Helm hook. Here's an example:
35+
36+
#### Pre-install/Pre-upgrade Hook
37+
38+
Apply CRDs before installation or upgrade:
3239

3340
```yaml
3441
apiVersion: batch/v1
@@ -51,11 +58,10 @@ spec:
5158
command:
5259
- /apply-crds
5360
args:
54-
- --crds-dir=/crds/operator
61+
- --crds-path=/opt/config/crds
62+
- --operation=apply
5563
```
5664
57-
> Note: the image must contain all your CRDs in e.g. the `/crds/operator` directory.
58-
59-
## Flags
65+
#### Pre-delete Hook
6066
61-
- `-crds-dir` (required): Specifies a directory path that contains the CRD manifests in YAML format. This flag can be provided multiple times to apply CRDs from multiple directories.
67+
By default, Helm does not delete CRDs when a chart is uninstalled. Use caution when deleting CRDs in a pre-delete Helm hook. Deleting a CRD also removes all associated Custom Resources (CRs), which can lead to data loss if users upgrade by uninstalling and reinstalling the chart.

0 commit comments

Comments
 (0)