Skip to content

Commit f444867

Browse files
committed
enhance matching
This commit reworks matching. The new matcher ignores spacing and order differences from Helm. The format of the `Map.yaml` file has been simplified to reflect these changes. The README.md has been updated, and a new converter tool has been provided. The current `Map.yaml` in this PR was generated from the previous `Map.yaml` via the converter. Signed-off-by: Aaron Hurt <[email protected]>
1 parent 45c1c7f commit f444867

File tree

9 files changed

+781
-355
lines changed

9 files changed

+781
-355
lines changed

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ build:
77
export CGO_ENABLED=0 && \
88
go build -o bin/${HELM_PLUGIN_NAME} -ldflags $(LDFLAGS) ./cmd/mapkubeapis
99

10+
.PHONY: converter
11+
converter:
12+
export CGO_ENABLED=0 && \
13+
go build -o bin/converter ./cmd/converter
14+
1015
.PHONY: bootstrap
1116
bootstrap:
1217
export GO111MODULE=on && \

README.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
> Note: Charts need to be updated also to supported Kubernetes APIs to avoid failure during deployment in a Kubernetes version. This is a separate task to the plugin.
1111
12+
> Note: The mapfile format has changed from the previous release. The new format is more resilient to changes in spacing and ordering of the Helm release metadata. The new format is described in the [API Mapping](#api-mapping) section. A converter has been provided to convert the old format to the new format. The converter may be found in the `cmd/converter` directory, built via `make converter`, and ran via `./bin/converter`.
13+
1214
## Prerequisite
1315

1416
- Helm client with `mapkubeapis` plugin installed on the same system
@@ -95,10 +97,14 @@ kind: ClusterRoleBinding
9597
The mapping information of deprecated or removed APIs to supported APIs is configured in the [Map.yaml](https://github.com/helm/helm-mapkubeapis/blob/master/config/Map.yaml) file. The file is a list of entries similar to the following:
9698

9799
```yaml
98-
- deprecatedAPI: "apiVersion: extensions/v1beta1\nkind: Deployment"
99-
newAPI: "apiVersion: apps/v1\nkind: Deployment"
100-
deprecatedInVersion: "v1.9"
101-
removedInVersion: "v1.16"
100+
- deprecatedAPI:
101+
apiVersion: extensions/v1beta1
102+
kind: Deployment
103+
newAPI:
104+
apiVersion: apps/v1
105+
kind: Deployment
106+
deprecatedInVersion: "v1.9"
107+
removedInVersion: "v1.16"
102108
```
103109
104110
The plugin when performing update of a Helm release metadata first loads the map file from the `config` directory where the plugin is run from. If the map file is a different name or in a different location, you can use the `--mapfile` flag to specify the different mapping file.

cmd/converter/main.go

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strings"
7+
8+
"github.com/helm/helm-mapkubeapis/pkg/common"
9+
"github.com/helm/helm-mapkubeapis/pkg/mapping"
10+
"sigs.k8s.io/yaml"
11+
)
12+
13+
func readConfig(f string) ([]common.GenericYAML, error) {
14+
b, err := os.ReadFile(f)
15+
if err != nil {
16+
return nil, err
17+
}
18+
return common.ParseYAML(string(b))
19+
}
20+
21+
func exitOnError(err error) {
22+
if err != nil {
23+
_, _ = os.Stderr.WriteString(err.Error() + "\n")
24+
os.Exit(1)
25+
}
26+
}
27+
28+
func main() {
29+
var config string
30+
if len(os.Args) == 1 || strings.HasPrefix(os.Args[1], "-h") || strings.HasPrefix(os.Args[1], "--h") {
31+
_, _ = os.Stdout.WriteString("Usage: " + os.Args[0] + " [file]\n")
32+
os.Exit(0)
33+
}
34+
config = os.Args[1]
35+
input, err := readConfig(config)
36+
exitOnError(err)
37+
var mappings []any
38+
if v, ok := input[0]["mappings"].([]any); ok {
39+
mappings = v
40+
}
41+
if len(mappings) == 0 {
42+
exitOnError(fmt.Errorf("failed to read mappings"))
43+
}
44+
var output mapping.Metadata
45+
var m common.GenericYAML
46+
var s string
47+
var ok bool
48+
for _, val := range mappings {
49+
var om mapping.Mapping
50+
if m, ok = val.(common.GenericYAML); !ok {
51+
continue // skip invalid mappings
52+
}
53+
if s, ok = m["deprecatedAPI"].(string); ok {
54+
apiVersion, kind := parseAPIString(s)
55+
if apiVersion == "" || kind == "" {
56+
continue // skip invalid mappings
57+
}
58+
om.DeprecatedAPI.APIVersion = apiVersion
59+
om.DeprecatedAPI.Kind = kind
60+
}
61+
if s, ok = m["newAPI"].(string); ok {
62+
apiVersion, kind := parseAPIString(s)
63+
if apiVersion == "" || kind == "" {
64+
continue // skip invalid mappings
65+
}
66+
om.NewAPI.APIVersion = apiVersion
67+
om.NewAPI.Kind = kind
68+
}
69+
if s, ok = m["deprecatedInVersion"].(string); ok {
70+
om.DeprecatedInVersion = s
71+
}
72+
if s, ok = m["removedInVersion"].(string); ok {
73+
om.RemovedInVersion = s
74+
}
75+
output.Mappings = append(output.Mappings, &om)
76+
}
77+
var b []byte
78+
b, err = yaml.Marshal(output)
79+
exitOnError(err)
80+
_, _ = os.Stdout.Write(b)
81+
}

cmd/converter/parse.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package main
2+
3+
import "strings"
4+
5+
const (
6+
apiVersionLabel = "apiVersion:"
7+
kindLabel = "kind:"
8+
apiVersionLabelSize = len(apiVersionLabel)
9+
kindLabelSize = len(kindLabel)
10+
)
11+
12+
// parseAPIString parses the API string into version and kind components
13+
func parseAPIString(apiString string) (version, kind string) {
14+
idx := strings.Index(apiString, apiVersionLabel)
15+
if idx != -1 {
16+
temps := apiString[idx+apiVersionLabelSize:]
17+
idx = strings.Index(temps, "\n")
18+
if idx != -1 {
19+
temps = temps[:idx]
20+
version = strings.TrimSpace(temps)
21+
}
22+
}
23+
idx = strings.Index(apiString, kindLabel)
24+
if idx != -1 {
25+
temps := apiString[idx+kindLabelSize:]
26+
idx = strings.Index(temps, "\n")
27+
if idx != -1 {
28+
temps = temps[:idx]
29+
kind = strings.TrimSpace(temps)
30+
}
31+
}
32+
return version, kind
33+
}

0 commit comments

Comments
 (0)