diff --git a/go.mod b/go.mod index 6fcdf323..07d4f8a4 100644 --- a/go.mod +++ b/go.mod @@ -32,15 +32,14 @@ require ( github.com/urfave/cli/v2 v2.27.5 go.uber.org/mock v0.5.0 golang.org/x/sync v0.12.0 + google.golang.org/protobuf v1.35.2 gopkg.in/yaml.v3 v3.0.1 - helm.sh/helm/v3 v3.17.2 k8s.io/api v0.32.2 k8s.io/apiextensions-apiserver v0.32.2 k8s.io/apimachinery v0.32.2 k8s.io/apiserver v0.32.2 k8s.io/client-go v0.32.2 k8s.io/component-base v0.32.2 - k8s.io/helm v2.17.0+incompatible k8s.io/klog v1.0.0 k8s.io/kube-aggregator v0.32.1 k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f @@ -48,11 +47,11 @@ require ( k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 modernc.org/sqlite v1.36.0 sigs.k8s.io/controller-runtime v0.19.0 + sigs.k8s.io/yaml v1.4.0 ) require ( cel.dev/expr v0.18.0 // indirect - github.com/Masterminds/semver/v3 v3.3.0 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect @@ -132,7 +131,6 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect google.golang.org/grpc v1.65.0 // indirect - google.golang.org/protobuf v1.35.2 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect @@ -146,5 +144,4 @@ require ( sigs.k8s.io/cli-utils v0.37.2 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.3 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 9c6afee4..2aae7e2b 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,6 @@ cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= @@ -13,8 +11,6 @@ github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxB github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= @@ -445,8 +441,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -helm.sh/helm/v3 v3.17.2 h1:agYQ5ew2jq5vdx2K7q5W44KyKQrnSubUMCQsjkiv3/o= -helm.sh/helm/v3 v3.17.2/go.mod h1:+uJKMH/UiMzZQOALR3XUf3BLIoczI2RKKD6bMhPh4G8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8= @@ -465,8 +459,6 @@ k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= k8s.io/component-base v0.32.2 h1:1aUL5Vdmu7qNo4ZsE+569PV5zFatM9hl+lb3dEea2zU= k8s.io/component-base v0.32.2/go.mod h1:PXJ61Vx9Lg+P5mS8TLd7bCIr+eMJRQTyXe8KvkrvJq0= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/helm v2.17.0+incompatible h1:Bpn6o1wKLYqKM3+Osh8e+1/K2g/GsQJ4F4yNF2+deao= -k8s.io/helm v2.17.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= diff --git a/pkg/resources/formatters/formatter.go b/pkg/resources/formatters/formatter.go index c605ceea..7bafa5da 100644 --- a/pkg/resources/formatters/formatter.go +++ b/pkg/resources/formatters/formatter.go @@ -7,14 +7,17 @@ import ( "encoding/json" "io" + // helm v2 is long since deprecated + // Unlike helm v3, it uses Protobuf encoding, so we can't use generic decoding without the message descriptors. + // The relevant types were vendored, since they won't change anymore. We should consider dropping support for Helm v2. + rspb "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api" + "github.com/golang/protobuf/proto" "github.com/pkg/errors" "github.com/rancher/apiserver/pkg/types" "github.com/rancher/norman/types/convert" "github.com/rancher/wrangler/v3/pkg/data" "github.com/sirupsen/logrus" - "helm.sh/helm/v3/pkg/release" - rspb "k8s.io/helm/pkg/proto/hapi/release" ) var ( @@ -57,7 +60,7 @@ func HandleHelmData(request *types.APIRequest, resource *types.RawResource) { } } -func Pod(request *types.APIRequest, resource *types.RawResource) { +func Pod(_ *types.APIRequest, resource *types.RawResource) { data := resource.APIObject.Data() fields := data.StringSlice("metadata", "fields") if len(fields) > 2 { @@ -67,7 +70,7 @@ func Pod(request *types.APIRequest, resource *types.RawResource) { // decodeHelm3 receives a helm3 release data string, decodes the string data using the standard base64 library // and unmarshals the data into release.Release struct to return it. -func decodeHelm3(data string) (*release.Release, error) { +func decodeHelm3(data string) (any, error) { b, err := base64.StdEncoding.DecodeString(data) if err != nil { return nil, err @@ -77,25 +80,23 @@ func decodeHelm3(data string) (*release.Release, error) { if len(b) <= 3 { return nil, ErrNotHelmRelease } + var r io.Reader = bytes.NewReader(b) // For backwards compatibility with releases that were stored before // compression was introduced we skip decompression if the // gzip magic header is not found if bytes.Equal(b[0:3], magicGzip) { - r, err := gzip.NewReader(bytes.NewReader(b)) + gzr, err := gzip.NewReader(r) if err != nil { return nil, err } - b2, err := io.ReadAll(r) - if err != nil { - return nil, err - } - b = b2 + defer gzr.Close() + r = gzr } - var rls release.Release - // unmarshal release object bytes - if err := json.Unmarshal(b, &rls); err != nil { + var rls json.RawMessage + // unmarshal JSON release payload + if err := json.NewDecoder(r).Decode(&rls); err != nil { return nil, err } return &rls, nil @@ -116,6 +117,8 @@ func decodeHelm2(data string) (*rspb.Release, error) { if err != nil { return nil, err } + defer r.Close() + b2, err := io.ReadAll(r) if err != nil { return nil, err diff --git a/pkg/resources/formatters/formatter_test.go b/pkg/resources/formatters/formatter_test.go index 7bf045b2..b02a3b5e 100644 --- a/pkg/resources/formatters/formatter_test.go +++ b/pkg/resources/formatters/formatter_test.go @@ -5,33 +5,25 @@ import ( "compress/gzip" "encoding/base64" "encoding/json" - "github.com/golang/protobuf/proto" - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" - "helm.sh/helm/v3/pkg/chart" - "helm.sh/helm/v3/pkg/release" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - pbchart "k8s.io/helm/pkg/proto/hapi/chart" - rspb "k8s.io/helm/pkg/proto/hapi/release" "net/url" + "os" "testing" + pbchart "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api" + rspb "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api" + + "github.com/golang/protobuf/proto" + "github.com/google/go-cmp/cmp" "github.com/rancher/apiserver/pkg/types" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + yaml "sigs.k8s.io/yaml/goyaml.v3" ) -var r = release.Release{ - Name: "helmV3Release", - Chart: &chart.Chart{ - Values: map[string]interface{}{ - "key": "value", - }, - }, - Version: 1, - Namespace: "default", -} - var rv2 = rspb.Release{ - Name: "helmV3Release", + Name: "helmV2Release", Chart: &pbchart.Chart{ Metadata: &pbchart.Metadata{ Name: "chartName", @@ -48,41 +40,53 @@ var rv2 = rspb.Release{ } func Test_HandleHelmData(t *testing.T) { + const helmRelease = `{ + "name": "helmV3Release", + "chart": { + "values": { + "key": "value" + } + }, + "version": 1, + "namespace": "default" +} +` + var r map[string]any + if err := json.Unmarshal([]byte(helmRelease), &r); err != nil { + t.Fatal(err) + } + tests := []struct { - name string - resource *types.RawResource - request *types.APIRequest - want *types.RawResource - helmVersion int - }{ //helm v3 + name string + resource *types.RawResource + request *types.APIRequest + want *types.RawResource + }{ { name: "When receiving a SECRET resource with includeHelmData set to TRUE and owner set to HELM, it should decode the helm3 release", - resource: newSecret("helm", map[string]interface{}{ - "release": base64.StdEncoding.EncodeToString([]byte(newV3Release())), + resource: newSecret("helm", map[string]any{ + "release": toGzippedBase64(t, helmRelease), }), request: newRequest("true"), - want: newSecret("helm", map[string]interface{}{ - "release": &r, + want: newSecret("helm", map[string]any{ + "release": r, }), - helmVersion: 3, }, { name: "When receiving a SECRET resource with includeHelmData set to FALSE and owner set to HELM, it should drop the helm data", - resource: newSecret("helm", map[string]interface{}{ - "release": base64.StdEncoding.EncodeToString([]byte(newV3Release())), + resource: newSecret("helm", map[string]any{ + "release": toGzippedBase64(t, helmRelease), }), - request: newRequest("false"), - want: newSecret("helm", map[string]interface{}{}), - helmVersion: 3, + request: newRequest("false"), + want: newSecret("helm", map[string]any{}), }, { name: "When receiving a SECRET resource WITHOUT the includeHelmData query parameter and owner set to HELM, it should drop the helm data", - resource: newSecret("helm", map[string]interface{}{ - "release": base64.StdEncoding.EncodeToString([]byte(newV3Release())), + resource: newSecret("helm", map[string]any{ + "release": base64.StdEncoding.EncodeToString([]byte(toGzippedBase64(t, helmRelease))), }), - request: newRequest(""), - want: newSecret("helm", map[string]interface{}{}), - helmVersion: 3, + request: newRequest(""), + want: newSecret("helm", map[string]any{}), }, { name: "When receiving a non-helm SECRET or CONFIGMAP resource with includeHelmData set to TRUE, it shouldn't change the resource", @@ -107,7 +111,6 @@ func Test_HandleHelmData(t *testing.T) { }, }}}, }, - helmVersion: 3, }, { name: "When receiving a non-helm SECRET or CONFIGMAP resource with includeHelmData set to FALSE, it shouldn't change the resource", @@ -132,7 +135,6 @@ func Test_HandleHelmData(t *testing.T) { }, }}}, }, - helmVersion: 3, }, { name: "When receiving a non-helm SECRET or CONFIGMAP resource WITHOUT the includeHelmData query parameter, it shouldn't change the resource", @@ -157,66 +159,85 @@ func Test_HandleHelmData(t *testing.T) { }, }}}, }, - helmVersion: 3, }, { name: "When receiving a CONFIGMAP resource with includeHelmData set to TRUE and owner set to HELM, it should decode the helm3 release", - resource: newConfigMap("helm", map[string]interface{}{ - "release": newV3Release(), + resource: newConfigMap("helm", map[string]any{ + "release": toGzippedBase64(t, helmRelease), }), request: newRequest("true"), - want: newConfigMap("helm", map[string]interface{}{ - "release": &r, + want: newConfigMap("helm", map[string]any{ + "release": r, }), - helmVersion: 3, }, { name: "When receiving a CONFIGMAP resource with includeHelmData set to FALSE and owner set to HELM, it should drop the helm data", - resource: newConfigMap("helm", map[string]interface{}{ - "release": newV3Release(), + resource: newConfigMap("helm", map[string]any{ + "release": toGzippedBase64(t, helmRelease), }), - request: newRequest("false"), - want: newConfigMap("helm", map[string]interface{}{}), - helmVersion: 3, + request: newRequest("false"), + want: newConfigMap("helm", map[string]any{}), }, { name: "When receiving a CONFIGMAP resource WITHOUT the includeHelmData query parameter and owner set to HELM, it should drop the helm data", - resource: newConfigMap("helm", map[string]interface{}{ - "release": newV3Release(), + resource: newConfigMap("helm", map[string]any{ + "release": toGzippedBase64(t, helmRelease), }), - request: newRequest(""), - want: newConfigMap("helm", map[string]interface{}{}), - helmVersion: 3, + request: newRequest(""), + want: newConfigMap("helm", map[string]any{}), }, - //helm v2 + { + name: "[no magic gzip] When receiving a SECRET resource with includeHelmData set to TRUE and owner set to HELM, it should decode the helm3 release", + resource: newSecret("helm", map[string]any{ + "release": base64.StdEncoding.EncodeToString([]byte(helmRelease)), + }), + request: newRequest("true"), + want: newSecret("helm", map[string]any{ + "release": r, + }), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + HandleHelmData(tt.request, tt.resource) + // data will be serialized, so it makes sense to compare their JSON representation + assert.Empty(t, cmp.Diff(toPlainMap(t, tt.resource), toPlainMap(t, tt.want))) + }) + } +} + +func Test_HandleLegacyHelmV2Data(t *testing.T) { + tests := []struct { + name string + resource *types.RawResource + request *types.APIRequest + want *types.RawResource + }{ { name: "When receiving a SECRET resource with includeHelmData set to TRUE and owner set to TILLER, it should decode the helm2 release", resource: newSecret("TILLER", map[string]interface{}{ - "release": base64.StdEncoding.EncodeToString([]byte(newV2Release())), + "release": newV2Release(), }), request: newRequest("true"), want: newSecret("TILLER", map[string]interface{}{ "release": &rv2, }), - helmVersion: 2, }, { name: "When receiving a SECRET resource with includeHelmData set to FALSE and owner set to TILLER, it should drop the helm data", resource: newSecret("TILLER", map[string]interface{}{ - "release": base64.StdEncoding.EncodeToString([]byte(newV2Release())), + "release": newV2Release(), }), - request: newRequest("false"), - want: newSecret("TILLER", map[string]interface{}{}), - helmVersion: 2, + request: newRequest("false"), + want: newSecret("TILLER", map[string]interface{}{}), }, { name: "When receiving a SECRET resource WITHOUT the includeHelmData query parameter and owner set to TILLER, it should drop the helm data", resource: newSecret("TILLER", map[string]interface{}{ - "release": base64.StdEncoding.EncodeToString([]byte(newV2Release())), + "release": newV2Release(), }), - request: newRequest(""), - want: newSecret("TILLER", map[string]interface{}{}), - helmVersion: 2, + request: newRequest(""), + want: newSecret("TILLER", map[string]interface{}{}), }, { name: "When receiving a CONFIGMAP resource with includeHelmData set to TRUE and owner set to TILLER, it should decode the helm2 release", @@ -227,65 +248,46 @@ func Test_HandleHelmData(t *testing.T) { want: newConfigMap("TILLER", map[string]interface{}{ "release": &rv2, }), - helmVersion: 2, }, { name: "When receiving a CONFIGMAP resource with includeHelmData set to FALSE and owner set to TILLER, it should drop the helm data", resource: newConfigMap("TILLER", map[string]interface{}{ "release": newV2Release(), }), - request: newRequest("false"), - want: newConfigMap("TILLER", map[string]interface{}{}), - helmVersion: 2, + request: newRequest("false"), + want: newConfigMap("TILLER", map[string]interface{}{}), }, { name: "When receiving a CONFIGMAP resource WITHOUT the includeHelmData query parameter and owner set to TILLER, it should drop the helm data", resource: newConfigMap("TILLER", map[string]interface{}{ "release": newV2Release(), }), - request: newRequest(""), - want: newConfigMap("TILLER", map[string]interface{}{}), - helmVersion: 2, - }, - { - name: "[no magic gzip] When receiving a SECRET resource with includeHelmData set to TRUE and owner set to HELM, it should decode the helm3 release", - resource: newSecret("helm", map[string]interface{}{ - "release": base64.StdEncoding.EncodeToString([]byte(newV3ReleaseWithoutGzip())), - }), - request: newRequest("true"), - want: newSecret("helm", map[string]interface{}{ - "release": &r, - }), - helmVersion: 3, + request: newRequest(""), + want: newConfigMap("TILLER", map[string]interface{}{}), }, { name: "[no magic gzip] When receiving a SECRET resource with includeHelmData set to TRUE and owner set to TILLER, it should decode the helm2 release", resource: newSecret("TILLER", map[string]interface{}{ - "release": base64.StdEncoding.EncodeToString([]byte(newV2ReleaseWithoutGzip())), + "release": newV2ReleaseWithoutGzip(), }), request: newRequest("true"), want: newSecret("TILLER", map[string]interface{}{ "release": &rv2, }), - helmVersion: 2, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { HandleHelmData(tt.request, tt.resource) - if tt.helmVersion == 2 { - u, ok := tt.resource.APIObject.Object.(*unstructured.Unstructured) + u, ok := tt.resource.APIObject.Object.(*unstructured.Unstructured) + assert.True(t, ok) + rl, ok := u.UnstructuredContent()["data"].(map[string]interface{})["release"] + if ok { + u, ok = tt.want.APIObject.Object.(*unstructured.Unstructured) assert.True(t, ok) - rl, ok := u.UnstructuredContent()["data"].(map[string]interface{})["release"] - if ok { - u, ok = tt.want.APIObject.Object.(*unstructured.Unstructured) - assert.True(t, ok) - rl2, ok := u.UnstructuredContent()["data"].(map[string]interface{})["release"] - assert.True(t, ok) - assert.True(t, proto.Equal(rl.(proto.Message), rl2.(proto.Message))) - } else { - assert.Equal(t, tt.resource, tt.want) - } + rl2, ok := u.UnstructuredContent()["data"].(map[string]interface{})["release"] + assert.True(t, ok) + assert.True(t, proto.Equal(rl.(proto.Message), rl2.(proto.Message))) } else { assert.Equal(t, tt.resource, tt.want) } @@ -293,17 +295,46 @@ func Test_HandleHelmData(t *testing.T) { } } -func newSecret(owner string, data map[string]interface{}) *types.RawResource { +func toPlainMap(t *testing.T, v interface{}) map[string]any { + t.Helper() + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(v); err != nil { + t.Fatal(err) + } + var res map[string]any + if err := json.NewDecoder(&buf).Decode(&res); err != nil { + t.Fatal(err) + } + pruneNullValues(res) + return res +} + +func pruneNullValues(m map[string]any) { + for k, v := range m { + if v == nil { + delete(m, k) + } else if mm, ok := v.(map[string]any); ok { + pruneNullValues(mm) + } + } + return +} + +func newSecret(owner string, data map[string]any) *types.RawResource { + for k, v := range data { + if s, ok := v.(string); ok { + data[k] = base64.StdEncoding.EncodeToString([]byte(s)) + } + } secret := &unstructured.Unstructured{Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", "data": data, }} - if owner == "helm" { - secret.SetLabels(map[string]string{"owner": owner}) - } if owner == "TILLER" { secret.SetLabels(map[string]string{"OWNER": owner}) + } else { + secret.SetLabels(map[string]string{"owner": owner}) } return &types.RawResource{ Type: "secret", @@ -317,11 +348,10 @@ func newConfigMap(owner string, data map[string]interface{}) *types.RawResource "kind": "configmap", "data": data, }} - if owner == "helm" { - cfgMap.SetLabels(map[string]string{"owner": owner}) - } if owner == "TILLER" { cfgMap.SetLabels(map[string]string{"OWNER": owner}) + } else { + cfgMap.SetLabels(map[string]string{"owner": owner}) } return &types.RawResource{ Type: "configmap", @@ -351,24 +381,18 @@ func newV2ReleaseWithoutGzip() string { return base64.StdEncoding.EncodeToString(b) } -func newV3Release() string { - b, err := json.Marshal(r) - if err != nil { - logrus.Errorf("Failed to marshal release: %v", err) - } - buf := bytes.Buffer{} +func toGzippedBase64(t *testing.T, v string) string { + t.Helper() + var buf bytes.Buffer gz := gzip.NewWriter(&buf) - gz.Write(b) - gz.Close() - return base64.StdEncoding.EncodeToString(buf.Bytes()) -} - -func newV3ReleaseWithoutGzip() string { - b, err := json.Marshal(r) - if err != nil { - logrus.Errorf("Failed to marshal release: %v", err) + defer gz.Close() + if _, err := gz.Write([]byte(v)); err != nil { + t.Fatal(err) } - return base64.StdEncoding.EncodeToString(b) + if err := gz.Close(); err != nil { + t.Fatal(err) + } + return base64.StdEncoding.EncodeToString(buf.Bytes()) } func newRequest(value string) *types.APIRequest { @@ -378,3 +402,39 @@ func newRequest(value string) *types.APIRequest { } return req } + +func loadTestYamlFile(t *testing.T, path string, into any) { + t.Helper() + f, err := os.Open(path) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + if err := yaml.NewDecoder(f).Decode(into); err != nil { + t.Fatal(err) + } +} + +func Test_decodeHelm2(t *testing.T) { + // sample ConfigMap from installing a "mariadb" chart using helm v2.1.7 + var cm corev1.ConfigMap + loadTestYamlFile(t, "testdata/release-cm.yaml", &cm) + + releaseData := cm.Data["release"] + if releaseData == "" { + t.Fatalf("release data is empty") + } + + release, err := decodeHelm2(releaseData) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, "mariadb", release.Name) + assert.Equal(t, "default", release.Namespace) + assert.Equal(t, "mariadb", release.Chart.Metadata.Name) + assert.Equal(t, "7.3.14", release.Chart.Metadata.Version) + assert.NotEmpty(t, release.Chart.GetValues().GetRaw()) + assert.Equal(t, "{}\n", release.GetConfig().GetRaw()) +} diff --git a/pkg/resources/formatters/internal/legacytypes/Makefile b/pkg/resources/formatters/internal/legacytypes/Makefile new file mode 100644 index 00000000..930975b8 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/Makefile @@ -0,0 +1,10 @@ +.PHONY: all +all: protos + +.PHONY: protos +protos: + protoc --proto_path=helmv2api --go_out=helmv2api --go_opt=paths=source_relative helmv2api/*.proto + +.PHONY: clean +clean: + @rm -rf helmv2api/*.pb.go 2>/dev/null diff --git a/pkg/resources/formatters/internal/legacytypes/README.md b/pkg/resources/formatters/internal/legacytypes/README.md new file mode 100644 index 00000000..cb93ef5e --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/README.md @@ -0,0 +1 @@ +# Copied and adapted from (https://github.com/helm/helm/tree/v2.17.0/_proto) diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/chart.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/chart.pb.go new file mode 100644 index 00000000..96e68fc0 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/chart.pb.go @@ -0,0 +1,193 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: chart.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Chart is a helm package that contains metadata, a default config, zero or more +// optionally parameterizable templates, and zero or more charts (dependencies). +type Chart struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Contents of the Chartfile. + Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // Templates for this chart. + Templates []*Template `protobuf:"bytes,2,rep,name=templates,proto3" json:"templates,omitempty"` + // Charts that this chart depends on. + Dependencies []*Chart `protobuf:"bytes,3,rep,name=dependencies,proto3" json:"dependencies,omitempty"` + // Default config for this template. + Values *Config `protobuf:"bytes,4,opt,name=values,proto3" json:"values,omitempty"` + // Miscellaneous files in a chart archive, + // e.g. README, LICENSE, etc. + Files []*anypb.Any `protobuf:"bytes,5,rep,name=files,proto3" json:"files,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Chart) Reset() { + *x = Chart{} + mi := &file_chart_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Chart) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Chart) ProtoMessage() {} + +func (x *Chart) ProtoReflect() protoreflect.Message { + mi := &file_chart_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Chart.ProtoReflect.Descriptor instead. +func (*Chart) Descriptor() ([]byte, []int) { + return file_chart_proto_rawDescGZIP(), []int{0} +} + +func (x *Chart) GetMetadata() *Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *Chart) GetTemplates() []*Template { + if x != nil { + return x.Templates + } + return nil +} + +func (x *Chart) GetDependencies() []*Chart { + if x != nil { + return x.Dependencies + } + return nil +} + +func (x *Chart) GetValues() *Config { + if x != nil { + return x.Values + } + return nil +} + +func (x *Chart) GetFiles() []*anypb.Any { + if x != nil { + return x.Files + } + return nil +} + +var File_chart_proto protoreflect.FileDescriptor + +const file_chart_proto_rawDesc = "" + + "\n" + + "\vchart.proto\x12\x15legacytypes.helmv2api\x1a\fconfig.proto\x1a\x0emetadata.proto\x1a\x0etemplate.proto\x1a\x19google/protobuf/any.proto\"\xa8\x02\n" + + "\x05Chart\x12;\n" + + "\bmetadata\x18\x01 \x01(\v2\x1f.legacytypes.helmv2api.MetadataR\bmetadata\x12=\n" + + "\ttemplates\x18\x02 \x03(\v2\x1f.legacytypes.helmv2api.TemplateR\ttemplates\x12@\n" + + "\fdependencies\x18\x03 \x03(\v2\x1c.legacytypes.helmv2api.ChartR\fdependencies\x125\n" + + "\x06values\x18\x04 \x01(\v2\x1d.legacytypes.helmv2api.ConfigR\x06values\x12*\n" + + "\x05files\x18\x05 \x03(\v2\x14.google.protobuf.AnyR\x05filesBRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_chart_proto_rawDescOnce sync.Once + file_chart_proto_rawDescData []byte +) + +func file_chart_proto_rawDescGZIP() []byte { + file_chart_proto_rawDescOnce.Do(func() { + file_chart_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_chart_proto_rawDesc), len(file_chart_proto_rawDesc))) + }) + return file_chart_proto_rawDescData +} + +var file_chart_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_chart_proto_goTypes = []any{ + (*Chart)(nil), // 0: legacytypes.helmv2api.Chart + (*Metadata)(nil), // 1: legacytypes.helmv2api.Metadata + (*Template)(nil), // 2: legacytypes.helmv2api.Template + (*Config)(nil), // 3: legacytypes.helmv2api.Config + (*anypb.Any)(nil), // 4: google.protobuf.Any +} +var file_chart_proto_depIdxs = []int32{ + 1, // 0: legacytypes.helmv2api.Chart.metadata:type_name -> legacytypes.helmv2api.Metadata + 2, // 1: legacytypes.helmv2api.Chart.templates:type_name -> legacytypes.helmv2api.Template + 0, // 2: legacytypes.helmv2api.Chart.dependencies:type_name -> legacytypes.helmv2api.Chart + 3, // 3: legacytypes.helmv2api.Chart.values:type_name -> legacytypes.helmv2api.Config + 4, // 4: legacytypes.helmv2api.Chart.files:type_name -> google.protobuf.Any + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_chart_proto_init() } +func file_chart_proto_init() { + if File_chart_proto != nil { + return + } + file_config_proto_init() + file_metadata_proto_init() + file_template_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_chart_proto_rawDesc), len(file_chart_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_chart_proto_goTypes, + DependencyIndexes: file_chart_proto_depIdxs, + MessageInfos: file_chart_proto_msgTypes, + }.Build() + File_chart_proto = out.File + file_chart_proto_goTypes = nil + file_chart_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/chart.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/chart.proto new file mode 100644 index 00000000..29bffe89 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/chart.proto @@ -0,0 +1,44 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +import "config.proto"; +import "metadata.proto"; +import "template.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +// Chart is a helm package that contains metadata, a default config, zero or more +// optionally parameterizable templates, and zero or more charts (dependencies). +message Chart { + // Contents of the Chartfile. + helmv2api.Metadata metadata = 1; + + // Templates for this chart. + repeated helmv2api.Template templates = 2; + + // Charts that this chart depends on. + repeated Chart dependencies = 3; + + // Default config for this template. + helmv2api.Config values = 4; + + // Miscellaneous files in a chart archive, + // e.g. README, LICENSE, etc. + repeated google.protobuf.Any files = 5; +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/config.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/config.pb.go new file mode 100644 index 00000000..a17497b0 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/config.pb.go @@ -0,0 +1,200 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: config.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Config supplies values to the parametrizable templates of a chart. +type Config struct { + state protoimpl.MessageState `protogen:"open.v1"` + Raw string `protobuf:"bytes,1,opt,name=raw,proto3" json:"raw,omitempty"` + Values map[string]*Value `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Config) Reset() { + *x = Config{} + mi := &file_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Config) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Config) ProtoMessage() {} + +func (x *Config) ProtoReflect() protoreflect.Message { + mi := &file_config_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Config.ProtoReflect.Descriptor instead. +func (*Config) Descriptor() ([]byte, []int) { + return file_config_proto_rawDescGZIP(), []int{0} +} + +func (x *Config) GetRaw() string { + if x != nil { + return x.Raw + } + return "" +} + +func (x *Config) GetValues() map[string]*Value { + if x != nil { + return x.Values + } + return nil +} + +// Value describes a configuration value as a string. +type Value struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Value) Reset() { + *x = Value{} + mi := &file_config_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Value) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Value) ProtoMessage() {} + +func (x *Value) ProtoReflect() protoreflect.Message { + mi := &file_config_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Value.ProtoReflect.Descriptor instead. +func (*Value) Descriptor() ([]byte, []int) { + return file_config_proto_rawDescGZIP(), []int{1} +} + +func (x *Value) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +var File_config_proto protoreflect.FileDescriptor + +const file_config_proto_rawDesc = "" + + "\n" + + "\fconfig.proto\x12\x15legacytypes.helmv2api\"\xb6\x01\n" + + "\x06Config\x12\x10\n" + + "\x03raw\x18\x01 \x01(\tR\x03raw\x12A\n" + + "\x06values\x18\x02 \x03(\v2).legacytypes.helmv2api.Config.ValuesEntryR\x06values\x1aW\n" + + "\vValuesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x122\n" + + "\x05value\x18\x02 \x01(\v2\x1c.legacytypes.helmv2api.ValueR\x05value:\x028\x01\"\x1d\n" + + "\x05Value\x12\x14\n" + + "\x05value\x18\x01 \x01(\tR\x05valueBRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_config_proto_rawDescOnce sync.Once + file_config_proto_rawDescData []byte +) + +func file_config_proto_rawDescGZIP() []byte { + file_config_proto_rawDescOnce.Do(func() { + file_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_config_proto_rawDesc), len(file_config_proto_rawDesc))) + }) + return file_config_proto_rawDescData +} + +var file_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_config_proto_goTypes = []any{ + (*Config)(nil), // 0: legacytypes.helmv2api.Config + (*Value)(nil), // 1: legacytypes.helmv2api.Value + nil, // 2: legacytypes.helmv2api.Config.ValuesEntry +} +var file_config_proto_depIdxs = []int32{ + 2, // 0: legacytypes.helmv2api.Config.values:type_name -> legacytypes.helmv2api.Config.ValuesEntry + 1, // 1: legacytypes.helmv2api.Config.ValuesEntry.value:type_name -> legacytypes.helmv2api.Value + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_config_proto_init() } +func file_config_proto_init() { + if File_config_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_config_proto_rawDesc), len(file_config_proto_rawDesc)), + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_config_proto_goTypes, + DependencyIndexes: file_config_proto_depIdxs, + MessageInfos: file_config_proto_msgTypes, + }.Build() + File_config_proto = out.File + file_config_proto_goTypes = nil + file_config_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/config.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/config.proto new file mode 100644 index 00000000..40e6fbd1 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/config.proto @@ -0,0 +1,31 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +// Config supplies values to the parametrizable templates of a chart. +message Config { + string raw = 1; + + map values = 2; +} + +// Value describes a configuration value as a string. +message Value { + string value = 1; +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/hook.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/hook.pb.go new file mode 100644 index 00000000..cc54703d --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/hook.pb.go @@ -0,0 +1,372 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: hook.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Hook_Event int32 + +const ( + Hook_UNKNOWN Hook_Event = 0 + Hook_PRE_INSTALL Hook_Event = 1 + Hook_POST_INSTALL Hook_Event = 2 + Hook_PRE_DELETE Hook_Event = 3 + Hook_POST_DELETE Hook_Event = 4 + Hook_PRE_UPGRADE Hook_Event = 5 + Hook_POST_UPGRADE Hook_Event = 6 + Hook_PRE_ROLLBACK Hook_Event = 7 + Hook_POST_ROLLBACK Hook_Event = 8 + Hook_RELEASE_TEST_SUCCESS Hook_Event = 9 + Hook_RELEASE_TEST_FAILURE Hook_Event = 10 + Hook_CRD_INSTALL Hook_Event = 11 +) + +// Enum value maps for Hook_Event. +var ( + Hook_Event_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PRE_INSTALL", + 2: "POST_INSTALL", + 3: "PRE_DELETE", + 4: "POST_DELETE", + 5: "PRE_UPGRADE", + 6: "POST_UPGRADE", + 7: "PRE_ROLLBACK", + 8: "POST_ROLLBACK", + 9: "RELEASE_TEST_SUCCESS", + 10: "RELEASE_TEST_FAILURE", + 11: "CRD_INSTALL", + } + Hook_Event_value = map[string]int32{ + "UNKNOWN": 0, + "PRE_INSTALL": 1, + "POST_INSTALL": 2, + "PRE_DELETE": 3, + "POST_DELETE": 4, + "PRE_UPGRADE": 5, + "POST_UPGRADE": 6, + "PRE_ROLLBACK": 7, + "POST_ROLLBACK": 8, + "RELEASE_TEST_SUCCESS": 9, + "RELEASE_TEST_FAILURE": 10, + "CRD_INSTALL": 11, + } +) + +func (x Hook_Event) Enum() *Hook_Event { + p := new(Hook_Event) + *p = x + return p +} + +func (x Hook_Event) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Hook_Event) Descriptor() protoreflect.EnumDescriptor { + return file_hook_proto_enumTypes[0].Descriptor() +} + +func (Hook_Event) Type() protoreflect.EnumType { + return &file_hook_proto_enumTypes[0] +} + +func (x Hook_Event) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Hook_Event.Descriptor instead. +func (Hook_Event) EnumDescriptor() ([]byte, []int) { + return file_hook_proto_rawDescGZIP(), []int{0, 0} +} + +type Hook_DeletePolicy int32 + +const ( + Hook_SUCCEEDED Hook_DeletePolicy = 0 + Hook_FAILED Hook_DeletePolicy = 1 + Hook_BEFORE_HOOK_CREATION Hook_DeletePolicy = 2 +) + +// Enum value maps for Hook_DeletePolicy. +var ( + Hook_DeletePolicy_name = map[int32]string{ + 0: "SUCCEEDED", + 1: "FAILED", + 2: "BEFORE_HOOK_CREATION", + } + Hook_DeletePolicy_value = map[string]int32{ + "SUCCEEDED": 0, + "FAILED": 1, + "BEFORE_HOOK_CREATION": 2, + } +) + +func (x Hook_DeletePolicy) Enum() *Hook_DeletePolicy { + p := new(Hook_DeletePolicy) + *p = x + return p +} + +func (x Hook_DeletePolicy) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Hook_DeletePolicy) Descriptor() protoreflect.EnumDescriptor { + return file_hook_proto_enumTypes[1].Descriptor() +} + +func (Hook_DeletePolicy) Type() protoreflect.EnumType { + return &file_hook_proto_enumTypes[1] +} + +func (x Hook_DeletePolicy) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Hook_DeletePolicy.Descriptor instead. +func (Hook_DeletePolicy) EnumDescriptor() ([]byte, []int) { + return file_hook_proto_rawDescGZIP(), []int{0, 1} +} + +// Hook defines a hook object. +type Hook struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Kind is the Kubernetes kind. + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + // Path is the chart-relative path to the template. + Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + // Manifest is the manifest contents. + Manifest string `protobuf:"bytes,4,opt,name=manifest,proto3" json:"manifest,omitempty"` + // Events are the events that this hook fires on. + Events []Hook_Event `protobuf:"varint,5,rep,packed,name=events,proto3,enum=legacytypes.helmv2api.Hook_Event" json:"events,omitempty"` + // LastRun indicates the date/time this was last run. + LastRun *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=last_run,json=lastRun,proto3" json:"last_run,omitempty"` + // Weight indicates the sort order for execution among similar Hook type + Weight int32 `protobuf:"varint,7,opt,name=weight,proto3" json:"weight,omitempty"` + // DeletePolicies are the policies that indicate when to delete the hook + DeletePolicies []Hook_DeletePolicy `protobuf:"varint,8,rep,packed,name=delete_policies,json=deletePolicies,proto3,enum=legacytypes.helmv2api.Hook_DeletePolicy" json:"delete_policies,omitempty"` + // DeleteTimeout indicates how long to wait for a resource to be deleted before timing out + DeleteTimeout int64 `protobuf:"varint,9,opt,name=delete_timeout,json=deleteTimeout,proto3" json:"delete_timeout,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Hook) Reset() { + *x = Hook{} + mi := &file_hook_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Hook) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Hook) ProtoMessage() {} + +func (x *Hook) ProtoReflect() protoreflect.Message { + mi := &file_hook_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Hook.ProtoReflect.Descriptor instead. +func (*Hook) Descriptor() ([]byte, []int) { + return file_hook_proto_rawDescGZIP(), []int{0} +} + +func (x *Hook) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Hook) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *Hook) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *Hook) GetManifest() string { + if x != nil { + return x.Manifest + } + return "" +} + +func (x *Hook) GetEvents() []Hook_Event { + if x != nil { + return x.Events + } + return nil +} + +func (x *Hook) GetLastRun() *timestamppb.Timestamp { + if x != nil { + return x.LastRun + } + return nil +} + +func (x *Hook) GetWeight() int32 { + if x != nil { + return x.Weight + } + return 0 +} + +func (x *Hook) GetDeletePolicies() []Hook_DeletePolicy { + if x != nil { + return x.DeletePolicies + } + return nil +} + +func (x *Hook) GetDeleteTimeout() int64 { + if x != nil { + return x.DeleteTimeout + } + return 0 +} + +var File_hook_proto protoreflect.FileDescriptor + +const file_hook_proto_rawDesc = "" + + "\n" + + "\n" + + "hook.proto\x12\x15legacytypes.helmv2api\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8f\x05\n" + + "\x04Hook\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + + "\x04kind\x18\x02 \x01(\tR\x04kind\x12\x12\n" + + "\x04path\x18\x03 \x01(\tR\x04path\x12\x1a\n" + + "\bmanifest\x18\x04 \x01(\tR\bmanifest\x129\n" + + "\x06events\x18\x05 \x03(\x0e2!.legacytypes.helmv2api.Hook.EventR\x06events\x125\n" + + "\blast_run\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\alastRun\x12\x16\n" + + "\x06weight\x18\a \x01(\x05R\x06weight\x12Q\n" + + "\x0fdelete_policies\x18\b \x03(\x0e2(.legacytypes.helmv2api.Hook.DeletePolicyR\x0edeletePolicies\x12%\n" + + "\x0edelete_timeout\x18\t \x01(\x03R\rdeleteTimeout\"\xe5\x01\n" + + "\x05Event\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\x0f\n" + + "\vPRE_INSTALL\x10\x01\x12\x10\n" + + "\fPOST_INSTALL\x10\x02\x12\x0e\n" + + "\n" + + "PRE_DELETE\x10\x03\x12\x0f\n" + + "\vPOST_DELETE\x10\x04\x12\x0f\n" + + "\vPRE_UPGRADE\x10\x05\x12\x10\n" + + "\fPOST_UPGRADE\x10\x06\x12\x10\n" + + "\fPRE_ROLLBACK\x10\a\x12\x11\n" + + "\rPOST_ROLLBACK\x10\b\x12\x18\n" + + "\x14RELEASE_TEST_SUCCESS\x10\t\x12\x18\n" + + "\x14RELEASE_TEST_FAILURE\x10\n" + + "\x12\x0f\n" + + "\vCRD_INSTALL\x10\v\"C\n" + + "\fDeletePolicy\x12\r\n" + + "\tSUCCEEDED\x10\x00\x12\n" + + "\n" + + "\x06FAILED\x10\x01\x12\x18\n" + + "\x14BEFORE_HOOK_CREATION\x10\x02BRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_hook_proto_rawDescOnce sync.Once + file_hook_proto_rawDescData []byte +) + +func file_hook_proto_rawDescGZIP() []byte { + file_hook_proto_rawDescOnce.Do(func() { + file_hook_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_hook_proto_rawDesc), len(file_hook_proto_rawDesc))) + }) + return file_hook_proto_rawDescData +} + +var file_hook_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_hook_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_hook_proto_goTypes = []any{ + (Hook_Event)(0), // 0: legacytypes.helmv2api.Hook.Event + (Hook_DeletePolicy)(0), // 1: legacytypes.helmv2api.Hook.DeletePolicy + (*Hook)(nil), // 2: legacytypes.helmv2api.Hook + (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp +} +var file_hook_proto_depIdxs = []int32{ + 0, // 0: legacytypes.helmv2api.Hook.events:type_name -> legacytypes.helmv2api.Hook.Event + 3, // 1: legacytypes.helmv2api.Hook.last_run:type_name -> google.protobuf.Timestamp + 1, // 2: legacytypes.helmv2api.Hook.delete_policies:type_name -> legacytypes.helmv2api.Hook.DeletePolicy + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_hook_proto_init() } +func file_hook_proto_init() { + if File_hook_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hook_proto_rawDesc), len(file_hook_proto_rawDesc)), + NumEnums: 2, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_hook_proto_goTypes, + DependencyIndexes: file_hook_proto_depIdxs, + EnumInfos: file_hook_proto_enumTypes, + MessageInfos: file_hook_proto_msgTypes, + }.Build() + File_hook_proto = out.File + file_hook_proto_goTypes = nil + file_hook_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/hook.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/hook.proto new file mode 100644 index 00000000..27750400 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/hook.proto @@ -0,0 +1,61 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +// Hook defines a hook object. +message Hook { + enum Event { + UNKNOWN = 0; + PRE_INSTALL = 1; + POST_INSTALL = 2; + PRE_DELETE = 3; + POST_DELETE = 4; + PRE_UPGRADE = 5; + POST_UPGRADE = 6; + PRE_ROLLBACK = 7; + POST_ROLLBACK = 8; + RELEASE_TEST_SUCCESS = 9; + RELEASE_TEST_FAILURE = 10; + CRD_INSTALL = 11; + } + enum DeletePolicy { + SUCCEEDED = 0; + FAILED = 1; + BEFORE_HOOK_CREATION = 2; + } + string name = 1; + // Kind is the Kubernetes kind. + string kind = 2; + // Path is the chart-relative path to the template. + string path = 3; + // Manifest is the manifest contents. + string manifest = 4; + // Events are the events that this hook fires on. + repeated Event events = 5; + // LastRun indicates the date/time this was last run. + google.protobuf.Timestamp last_run = 6; + // Weight indicates the sort order for execution among similar Hook type + int32 weight = 7; + // DeletePolicies are the policies that indicate when to delete the hook + repeated DeletePolicy delete_policies = 8; + // DeleteTimeout indicates how long to wait for a resource to be deleted before timing out + int64 delete_timeout = 9; +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/info.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/info.pb.go new file mode 100644 index 00000000..9c7f0a0b --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/info.pb.go @@ -0,0 +1,184 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: info.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Info describes release information. +type Info struct { + state protoimpl.MessageState `protogen:"open.v1"` + Status *Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + FirstDeployed *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=first_deployed,json=firstDeployed,proto3" json:"first_deployed,omitempty"` + LastDeployed *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=last_deployed,json=lastDeployed,proto3" json:"last_deployed,omitempty"` + // Deleted tracks when this object was deleted. + Deleted *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=deleted,proto3" json:"deleted,omitempty"` + // Description is human-friendly "log entry" about this release. + Description string `protobuf:"bytes,5,opt,name=Description,proto3" json:"Description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Info) Reset() { + *x = Info{} + mi := &file_info_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Info) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Info) ProtoMessage() {} + +func (x *Info) ProtoReflect() protoreflect.Message { + mi := &file_info_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Info.ProtoReflect.Descriptor instead. +func (*Info) Descriptor() ([]byte, []int) { + return file_info_proto_rawDescGZIP(), []int{0} +} + +func (x *Info) GetStatus() *Status { + if x != nil { + return x.Status + } + return nil +} + +func (x *Info) GetFirstDeployed() *timestamppb.Timestamp { + if x != nil { + return x.FirstDeployed + } + return nil +} + +func (x *Info) GetLastDeployed() *timestamppb.Timestamp { + if x != nil { + return x.LastDeployed + } + return nil +} + +func (x *Info) GetDeleted() *timestamppb.Timestamp { + if x != nil { + return x.Deleted + } + return nil +} + +func (x *Info) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +var File_info_proto protoreflect.FileDescriptor + +const file_info_proto_rawDesc = "" + + "\n" + + "\n" + + "info.proto\x12\x15legacytypes.helmv2api\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\fstatus.proto\"\x99\x02\n" + + "\x04Info\x125\n" + + "\x06status\x18\x01 \x01(\v2\x1d.legacytypes.helmv2api.StatusR\x06status\x12A\n" + + "\x0efirst_deployed\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\rfirstDeployed\x12?\n" + + "\rlast_deployed\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\flastDeployed\x124\n" + + "\adeleted\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\adeleted\x12 \n" + + "\vDescription\x18\x05 \x01(\tR\vDescriptionBRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_info_proto_rawDescOnce sync.Once + file_info_proto_rawDescData []byte +) + +func file_info_proto_rawDescGZIP() []byte { + file_info_proto_rawDescOnce.Do(func() { + file_info_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_info_proto_rawDesc), len(file_info_proto_rawDesc))) + }) + return file_info_proto_rawDescData +} + +var file_info_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_info_proto_goTypes = []any{ + (*Info)(nil), // 0: legacytypes.helmv2api.Info + (*Status)(nil), // 1: legacytypes.helmv2api.Status + (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp +} +var file_info_proto_depIdxs = []int32{ + 1, // 0: legacytypes.helmv2api.Info.status:type_name -> legacytypes.helmv2api.Status + 2, // 1: legacytypes.helmv2api.Info.first_deployed:type_name -> google.protobuf.Timestamp + 2, // 2: legacytypes.helmv2api.Info.last_deployed:type_name -> google.protobuf.Timestamp + 2, // 3: legacytypes.helmv2api.Info.deleted:type_name -> google.protobuf.Timestamp + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_info_proto_init() } +func file_info_proto_init() { + if File_info_proto != nil { + return + } + file_status_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_info_proto_rawDesc), len(file_info_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_info_proto_goTypes, + DependencyIndexes: file_info_proto_depIdxs, + MessageInfos: file_info_proto_msgTypes, + }.Build() + File_info_proto = out.File + file_info_proto_goTypes = nil + file_info_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/info.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/info.proto new file mode 100644 index 00000000..bbe8e91e --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/info.proto @@ -0,0 +1,37 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +import "google/protobuf/timestamp.proto"; +import "status.proto"; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +// Info describes release information. +message Info { + Status status = 1; + + google.protobuf.Timestamp first_deployed = 2; + + google.protobuf.Timestamp last_deployed = 3; + + // Deleted tracks when this object was deleted. + google.protobuf.Timestamp deleted = 4; + + // Description is human-friendly "log entry" about this release. + string Description = 5; +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/metadata.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/metadata.pb.go new file mode 100644 index 00000000..beba057e --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/metadata.pb.go @@ -0,0 +1,437 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: metadata.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Metadata_Engine int32 + +const ( + Metadata_UNKNOWN Metadata_Engine = 0 + Metadata_GOTPL Metadata_Engine = 1 +) + +// Enum value maps for Metadata_Engine. +var ( + Metadata_Engine_name = map[int32]string{ + 0: "UNKNOWN", + 1: "GOTPL", + } + Metadata_Engine_value = map[string]int32{ + "UNKNOWN": 0, + "GOTPL": 1, + } +) + +func (x Metadata_Engine) Enum() *Metadata_Engine { + p := new(Metadata_Engine) + *p = x + return p +} + +func (x Metadata_Engine) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Metadata_Engine) Descriptor() protoreflect.EnumDescriptor { + return file_metadata_proto_enumTypes[0].Descriptor() +} + +func (Metadata_Engine) Type() protoreflect.EnumType { + return &file_metadata_proto_enumTypes[0] +} + +func (x Metadata_Engine) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Metadata_Engine.Descriptor instead. +func (Metadata_Engine) EnumDescriptor() ([]byte, []int) { + return file_metadata_proto_rawDescGZIP(), []int{1, 0} +} + +// Maintainer describes a Chart maintainer. +type Maintainer struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Name is a user name or organization name + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Email is an optional email address to contact the named maintainer + Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + // Url is an optional URL to an address for the named maintainer + Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Maintainer) Reset() { + *x = Maintainer{} + mi := &file_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Maintainer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Maintainer) ProtoMessage() {} + +func (x *Maintainer) ProtoReflect() protoreflect.Message { + mi := &file_metadata_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Maintainer.ProtoReflect.Descriptor instead. +func (*Maintainer) Descriptor() ([]byte, []int) { + return file_metadata_proto_rawDescGZIP(), []int{0} +} + +func (x *Maintainer) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Maintainer) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *Maintainer) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +// Metadata for a Chart file. This models the structure of a Chart.yaml file. +// +// Spec: https://k8s.io/helm/blob/master/docs/design/chart_format.md#the-chart-file +type Metadata struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The name of the chart + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The URL to a relevant project page, git repo, or contact person + Home string `protobuf:"bytes,2,opt,name=home,proto3" json:"home,omitempty"` + // Source is the URL to the source code of this chart + Sources []string `protobuf:"bytes,3,rep,name=sources,proto3" json:"sources,omitempty"` + // A SemVer 2 conformant version string of the chart + Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` + // A one-sentence description of the chart + Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + // A list of string keywords + Keywords []string `protobuf:"bytes,6,rep,name=keywords,proto3" json:"keywords,omitempty"` + // A list of name and URL/email address combinations for the maintainer(s) + Maintainers []*Maintainer `protobuf:"bytes,7,rep,name=maintainers,proto3" json:"maintainers,omitempty"` + // The name of the template engine to use. Defaults to 'gotpl'. + Engine string `protobuf:"bytes,8,opt,name=engine,proto3" json:"engine,omitempty"` + // The URL to an icon file. + Icon string `protobuf:"bytes,9,opt,name=icon,proto3" json:"icon,omitempty"` + // The API Version of this chart. + ApiVersion string `protobuf:"bytes,10,opt,name=apiVersion,proto3" json:"apiVersion,omitempty"` + // The condition to check to enable chart + Condition string `protobuf:"bytes,11,opt,name=condition,proto3" json:"condition,omitempty"` + // The tags to check to enable chart + Tags string `protobuf:"bytes,12,opt,name=tags,proto3" json:"tags,omitempty"` + // The version of the application enclosed inside of this chart. + AppVersion string `protobuf:"bytes,13,opt,name=appVersion,proto3" json:"appVersion,omitempty"` + // Whether or not this chart is deprecated + Deprecated bool `protobuf:"varint,14,opt,name=deprecated,proto3" json:"deprecated,omitempty"` + // TillerVersion is a SemVer constraints on what version of Tiller is required. + // See SemVer ranges here: https://github.com/Masterminds/semver#basic-comparisons + TillerVersion string `protobuf:"bytes,15,opt,name=tillerVersion,proto3" json:"tillerVersion,omitempty"` + // Annotations are additional mappings uninterpreted by Tiller, + // made available for inspection by other applications. + Annotations map[string]string `protobuf:"bytes,16,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // KubeVersion is a SemVer constraint specifying the version of Kubernetes required. + KubeVersion string `protobuf:"bytes,17,opt,name=kubeVersion,proto3" json:"kubeVersion,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Metadata) Reset() { + *x = Metadata{} + mi := &file_metadata_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Metadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Metadata) ProtoMessage() {} + +func (x *Metadata) ProtoReflect() protoreflect.Message { + mi := &file_metadata_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. +func (*Metadata) Descriptor() ([]byte, []int) { + return file_metadata_proto_rawDescGZIP(), []int{1} +} + +func (x *Metadata) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Metadata) GetHome() string { + if x != nil { + return x.Home + } + return "" +} + +func (x *Metadata) GetSources() []string { + if x != nil { + return x.Sources + } + return nil +} + +func (x *Metadata) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *Metadata) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Metadata) GetKeywords() []string { + if x != nil { + return x.Keywords + } + return nil +} + +func (x *Metadata) GetMaintainers() []*Maintainer { + if x != nil { + return x.Maintainers + } + return nil +} + +func (x *Metadata) GetEngine() string { + if x != nil { + return x.Engine + } + return "" +} + +func (x *Metadata) GetIcon() string { + if x != nil { + return x.Icon + } + return "" +} + +func (x *Metadata) GetApiVersion() string { + if x != nil { + return x.ApiVersion + } + return "" +} + +func (x *Metadata) GetCondition() string { + if x != nil { + return x.Condition + } + return "" +} + +func (x *Metadata) GetTags() string { + if x != nil { + return x.Tags + } + return "" +} + +func (x *Metadata) GetAppVersion() string { + if x != nil { + return x.AppVersion + } + return "" +} + +func (x *Metadata) GetDeprecated() bool { + if x != nil { + return x.Deprecated + } + return false +} + +func (x *Metadata) GetTillerVersion() string { + if x != nil { + return x.TillerVersion + } + return "" +} + +func (x *Metadata) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *Metadata) GetKubeVersion() string { + if x != nil { + return x.KubeVersion + } + return "" +} + +var File_metadata_proto protoreflect.FileDescriptor + +const file_metadata_proto_rawDesc = "" + + "\n" + + "\x0emetadata.proto\x12\x15legacytypes.helmv2api\"H\n" + + "\n" + + "Maintainer\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + + "\x05email\x18\x02 \x01(\tR\x05email\x12\x10\n" + + "\x03url\x18\x03 \x01(\tR\x03url\"\xa5\x05\n" + + "\bMetadata\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + + "\x04home\x18\x02 \x01(\tR\x04home\x12\x18\n" + + "\asources\x18\x03 \x03(\tR\asources\x12\x18\n" + + "\aversion\x18\x04 \x01(\tR\aversion\x12 \n" + + "\vdescription\x18\x05 \x01(\tR\vdescription\x12\x1a\n" + + "\bkeywords\x18\x06 \x03(\tR\bkeywords\x12C\n" + + "\vmaintainers\x18\a \x03(\v2!.legacytypes.helmv2api.MaintainerR\vmaintainers\x12\x16\n" + + "\x06engine\x18\b \x01(\tR\x06engine\x12\x12\n" + + "\x04icon\x18\t \x01(\tR\x04icon\x12\x1e\n" + + "\n" + + "apiVersion\x18\n" + + " \x01(\tR\n" + + "apiVersion\x12\x1c\n" + + "\tcondition\x18\v \x01(\tR\tcondition\x12\x12\n" + + "\x04tags\x18\f \x01(\tR\x04tags\x12\x1e\n" + + "\n" + + "appVersion\x18\r \x01(\tR\n" + + "appVersion\x12\x1e\n" + + "\n" + + "deprecated\x18\x0e \x01(\bR\n" + + "deprecated\x12$\n" + + "\rtillerVersion\x18\x0f \x01(\tR\rtillerVersion\x12R\n" + + "\vannotations\x18\x10 \x03(\v20.legacytypes.helmv2api.Metadata.AnnotationsEntryR\vannotations\x12 \n" + + "\vkubeVersion\x18\x11 \x01(\tR\vkubeVersion\x1a>\n" + + "\x10AnnotationsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\" \n" + + "\x06Engine\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\t\n" + + "\x05GOTPL\x10\x01BRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_metadata_proto_rawDescOnce sync.Once + file_metadata_proto_rawDescData []byte +) + +func file_metadata_proto_rawDescGZIP() []byte { + file_metadata_proto_rawDescOnce.Do(func() { + file_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_metadata_proto_rawDesc), len(file_metadata_proto_rawDesc))) + }) + return file_metadata_proto_rawDescData +} + +var file_metadata_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_metadata_proto_goTypes = []any{ + (Metadata_Engine)(0), // 0: legacytypes.helmv2api.Metadata.Engine + (*Maintainer)(nil), // 1: legacytypes.helmv2api.Maintainer + (*Metadata)(nil), // 2: legacytypes.helmv2api.Metadata + nil, // 3: legacytypes.helmv2api.Metadata.AnnotationsEntry +} +var file_metadata_proto_depIdxs = []int32{ + 1, // 0: legacytypes.helmv2api.Metadata.maintainers:type_name -> legacytypes.helmv2api.Maintainer + 3, // 1: legacytypes.helmv2api.Metadata.annotations:type_name -> legacytypes.helmv2api.Metadata.AnnotationsEntry + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_metadata_proto_init() } +func file_metadata_proto_init() { + if File_metadata_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_metadata_proto_rawDesc), len(file_metadata_proto_rawDesc)), + NumEnums: 1, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_metadata_proto_goTypes, + DependencyIndexes: file_metadata_proto_depIdxs, + EnumInfos: file_metadata_proto_enumTypes, + MessageInfos: file_metadata_proto_msgTypes, + }.Build() + File_metadata_proto = out.File + file_metadata_proto_goTypes = nil + file_metadata_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/metadata.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/metadata.proto new file mode 100644 index 00000000..a6550a1f --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/metadata.proto @@ -0,0 +1,93 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +// Maintainer describes a Chart maintainer. +message Maintainer { + // Name is a user name or organization name + string name = 1; + + // Email is an optional email address to contact the named maintainer + string email = 2; + + // Url is an optional URL to an address for the named maintainer + string url = 3; +} + +// Metadata for a Chart file. This models the structure of a Chart.yaml file. +// +// Spec: https://k8s.io/helm/blob/master/docs/design/chart_format.md#the-chart-file +message Metadata { + enum Engine { + UNKNOWN = 0; + GOTPL = 1; + } + // The name of the chart + string name = 1; + + // The URL to a relevant project page, git repo, or contact person + string home = 2; + + // Source is the URL to the source code of this chart + repeated string sources = 3; + + // A SemVer 2 conformant version string of the chart + string version = 4; + + // A one-sentence description of the chart + string description = 5; + + // A list of string keywords + repeated string keywords = 6; + + // A list of name and URL/email address combinations for the maintainer(s) + repeated Maintainer maintainers = 7; + + // The name of the template engine to use. Defaults to 'gotpl'. + string engine = 8; + + // The URL to an icon file. + string icon = 9; + + // The API Version of this chart. + string apiVersion = 10; + + // The condition to check to enable chart + string condition = 11; + + // The tags to check to enable chart + string tags = 12; + + // The version of the application enclosed inside of this chart. + string appVersion = 13; + + // Whether or not this chart is deprecated + bool deprecated = 14; + + // TillerVersion is a SemVer constraints on what version of Tiller is required. + // See SemVer ranges here: https://github.com/Masterminds/semver#basic-comparisons + string tillerVersion = 15; + + // Annotations are additional mappings uninterpreted by Tiller, + // made available for inspection by other applications. + map annotations = 16; + + // KubeVersion is a SemVer constraint specifying the version of Kubernetes required. + string kubeVersion = 17; +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/release.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/release.pb.go new file mode 100644 index 00000000..fd32a4bf --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/release.pb.go @@ -0,0 +1,224 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: release.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Release describes a deployment of a chart, together with the chart +// and the variables used to deploy that chart. +type Release struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Name is the name of the release + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Info provides information about a release + Info *Info `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"` + // Chart is the chart that was released. + Chart *Chart `protobuf:"bytes,3,opt,name=chart,proto3" json:"chart,omitempty"` + // Config is the set of extra Values added to the chart. + // These values override the default values inside of the chart. + Config *Config `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` + // Manifest is the string representation of the rendered template. + Manifest string `protobuf:"bytes,5,opt,name=manifest,proto3" json:"manifest,omitempty"` + // Hooks are all of the hooks declared for this release. + Hooks []*Hook `protobuf:"bytes,6,rep,name=hooks,proto3" json:"hooks,omitempty"` + // Version is an int32 which represents the version of the release. + Version int32 `protobuf:"varint,7,opt,name=version,proto3" json:"version,omitempty"` + // Namespace is the kubernetes namespace of the release. + Namespace string `protobuf:"bytes,8,opt,name=namespace,proto3" json:"namespace,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Release) Reset() { + *x = Release{} + mi := &file_release_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Release) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Release) ProtoMessage() {} + +func (x *Release) ProtoReflect() protoreflect.Message { + mi := &file_release_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Release.ProtoReflect.Descriptor instead. +func (*Release) Descriptor() ([]byte, []int) { + return file_release_proto_rawDescGZIP(), []int{0} +} + +func (x *Release) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Release) GetInfo() *Info { + if x != nil { + return x.Info + } + return nil +} + +func (x *Release) GetChart() *Chart { + if x != nil { + return x.Chart + } + return nil +} + +func (x *Release) GetConfig() *Config { + if x != nil { + return x.Config + } + return nil +} + +func (x *Release) GetManifest() string { + if x != nil { + return x.Manifest + } + return "" +} + +func (x *Release) GetHooks() []*Hook { + if x != nil { + return x.Hooks + } + return nil +} + +func (x *Release) GetVersion() int32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *Release) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +var File_release_proto protoreflect.FileDescriptor + +const file_release_proto_rawDesc = "" + + "\n" + + "\rrelease.proto\x12\x15legacytypes.helmv2api\x1a\n" + + "hook.proto\x1a\n" + + "info.proto\x1a\fconfig.proto\x1a\vchart.proto\"\xc0\x02\n" + + "\aRelease\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12/\n" + + "\x04info\x18\x02 \x01(\v2\x1b.legacytypes.helmv2api.InfoR\x04info\x122\n" + + "\x05chart\x18\x03 \x01(\v2\x1c.legacytypes.helmv2api.ChartR\x05chart\x125\n" + + "\x06config\x18\x04 \x01(\v2\x1d.legacytypes.helmv2api.ConfigR\x06config\x12\x1a\n" + + "\bmanifest\x18\x05 \x01(\tR\bmanifest\x121\n" + + "\x05hooks\x18\x06 \x03(\v2\x1b.legacytypes.helmv2api.HookR\x05hooks\x12\x18\n" + + "\aversion\x18\a \x01(\x05R\aversion\x12\x1c\n" + + "\tnamespace\x18\b \x01(\tR\tnamespaceBRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_release_proto_rawDescOnce sync.Once + file_release_proto_rawDescData []byte +) + +func file_release_proto_rawDescGZIP() []byte { + file_release_proto_rawDescOnce.Do(func() { + file_release_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_release_proto_rawDesc), len(file_release_proto_rawDesc))) + }) + return file_release_proto_rawDescData +} + +var file_release_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_release_proto_goTypes = []any{ + (*Release)(nil), // 0: legacytypes.helmv2api.Release + (*Info)(nil), // 1: legacytypes.helmv2api.Info + (*Chart)(nil), // 2: legacytypes.helmv2api.Chart + (*Config)(nil), // 3: legacytypes.helmv2api.Config + (*Hook)(nil), // 4: legacytypes.helmv2api.Hook +} +var file_release_proto_depIdxs = []int32{ + 1, // 0: legacytypes.helmv2api.Release.info:type_name -> legacytypes.helmv2api.Info + 2, // 1: legacytypes.helmv2api.Release.chart:type_name -> legacytypes.helmv2api.Chart + 3, // 2: legacytypes.helmv2api.Release.config:type_name -> legacytypes.helmv2api.Config + 4, // 3: legacytypes.helmv2api.Release.hooks:type_name -> legacytypes.helmv2api.Hook + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_release_proto_init() } +func file_release_proto_init() { + if File_release_proto != nil { + return + } + file_hook_proto_init() + file_info_proto_init() + file_config_proto_init() + file_chart_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_release_proto_rawDesc), len(file_release_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_release_proto_goTypes, + DependencyIndexes: file_release_proto_depIdxs, + MessageInfos: file_release_proto_msgTypes, + }.Build() + File_release_proto = out.File + file_release_proto_goTypes = nil + file_release_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/release.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/release.proto new file mode 100644 index 00000000..5a4a51e1 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/release.proto @@ -0,0 +1,53 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +import "hook.proto"; +import "info.proto"; +import "config.proto"; +import "chart.proto"; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +// Release describes a deployment of a chart, together with the chart +// and the variables used to deploy that chart. +message Release { + // Name is the name of the release + string name = 1; + + // Info provides information about a release + helmv2api.Info info = 2; + + // Chart is the chart that was released. + helmv2api.Chart chart = 3; + + // Config is the set of extra Values added to the chart. + // These values override the default values inside of the chart. + helmv2api.Config config = 4; + + // Manifest is the string representation of the rendered template. + string manifest = 5; + + // Hooks are all of the hooks declared for this release. + repeated helmv2api.Hook hooks = 6; + + // Version is an int32 which represents the version of the release. + int32 version = 7; + + // Namespace is the kubernetes namespace of the release. + string namespace = 8; +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/status.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/status.pb.go new file mode 100644 index 00000000..d9d5f424 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/status.pb.go @@ -0,0 +1,262 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: status.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Status_Code int32 + +const ( + // Status_UNKNOWN indicates that a release is in an uncertain state. + Status_UNKNOWN Status_Code = 0 + // Status_DEPLOYED indicates that the release has been pushed to Kubernetes. + Status_DEPLOYED Status_Code = 1 + // Status_DELETED indicates that a release has been deleted from Kubernetes. + Status_DELETED Status_Code = 2 + // Status_SUPERSEDED indicates that this release object is outdated and a newer one exists. + Status_SUPERSEDED Status_Code = 3 + // Status_FAILED indicates that the release was not successfully deployed. + Status_FAILED Status_Code = 4 + // Status_DELETING indicates that a delete operation is underway. + Status_DELETING Status_Code = 5 + // Status_PENDING_INSTALL indicates that an install operation is underway. + Status_PENDING_INSTALL Status_Code = 6 + // Status_PENDING_UPGRADE indicates that an upgrade operation is underway. + Status_PENDING_UPGRADE Status_Code = 7 + // Status_PENDING_ROLLBACK indicates that a rollback operation is underway. + Status_PENDING_ROLLBACK Status_Code = 8 +) + +// Enum value maps for Status_Code. +var ( + Status_Code_name = map[int32]string{ + 0: "UNKNOWN", + 1: "DEPLOYED", + 2: "DELETED", + 3: "SUPERSEDED", + 4: "FAILED", + 5: "DELETING", + 6: "PENDING_INSTALL", + 7: "PENDING_UPGRADE", + 8: "PENDING_ROLLBACK", + } + Status_Code_value = map[string]int32{ + "UNKNOWN": 0, + "DEPLOYED": 1, + "DELETED": 2, + "SUPERSEDED": 3, + "FAILED": 4, + "DELETING": 5, + "PENDING_INSTALL": 6, + "PENDING_UPGRADE": 7, + "PENDING_ROLLBACK": 8, + } +) + +func (x Status_Code) Enum() *Status_Code { + p := new(Status_Code) + *p = x + return p +} + +func (x Status_Code) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Status_Code) Descriptor() protoreflect.EnumDescriptor { + return file_status_proto_enumTypes[0].Descriptor() +} + +func (Status_Code) Type() protoreflect.EnumType { + return &file_status_proto_enumTypes[0] +} + +func (x Status_Code) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Status_Code.Descriptor instead. +func (Status_Code) EnumDescriptor() ([]byte, []int) { + return file_status_proto_rawDescGZIP(), []int{0, 0} +} + +// Status defines the status of a release. +type Status struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code Status_Code `protobuf:"varint,1,opt,name=code,proto3,enum=legacytypes.helmv2api.Status_Code" json:"code,omitempty"` + // Cluster resources as kubectl would print them. + Resources string `protobuf:"bytes,3,opt,name=resources,proto3" json:"resources,omitempty"` + // Contains the rendered templates/NOTES.txt if available + Notes string `protobuf:"bytes,4,opt,name=notes,proto3" json:"notes,omitempty"` + // LastTestSuiteRun provides results on the last test run on a release + LastTestSuiteRun *TestSuite `protobuf:"bytes,5,opt,name=last_test_suite_run,json=lastTestSuiteRun,proto3" json:"last_test_suite_run,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Status) Reset() { + *x = Status{} + mi := &file_status_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Status) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Status) ProtoMessage() {} + +func (x *Status) ProtoReflect() protoreflect.Message { + mi := &file_status_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Status.ProtoReflect.Descriptor instead. +func (*Status) Descriptor() ([]byte, []int) { + return file_status_proto_rawDescGZIP(), []int{0} +} + +func (x *Status) GetCode() Status_Code { + if x != nil { + return x.Code + } + return Status_UNKNOWN +} + +func (x *Status) GetResources() string { + if x != nil { + return x.Resources + } + return "" +} + +func (x *Status) GetNotes() string { + if x != nil { + return x.Notes + } + return "" +} + +func (x *Status) GetLastTestSuiteRun() *TestSuite { + if x != nil { + return x.LastTestSuiteRun + } + return nil +} + +var File_status_proto protoreflect.FileDescriptor + +const file_status_proto_rawDesc = "" + + "\n" + + "\fstatus.proto\x12\x15legacytypes.helmv2api\x1a\x10test_suite.proto\"\xe0\x02\n" + + "\x06Status\x126\n" + + "\x04code\x18\x01 \x01(\x0e2\".legacytypes.helmv2api.Status.CodeR\x04code\x12\x1c\n" + + "\tresources\x18\x03 \x01(\tR\tresources\x12\x14\n" + + "\x05notes\x18\x04 \x01(\tR\x05notes\x12O\n" + + "\x13last_test_suite_run\x18\x05 \x01(\v2 .legacytypes.helmv2api.TestSuiteR\x10lastTestSuiteRun\"\x98\x01\n" + + "\x04Code\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\f\n" + + "\bDEPLOYED\x10\x01\x12\v\n" + + "\aDELETED\x10\x02\x12\x0e\n" + + "\n" + + "SUPERSEDED\x10\x03\x12\n" + + "\n" + + "\x06FAILED\x10\x04\x12\f\n" + + "\bDELETING\x10\x05\x12\x13\n" + + "\x0fPENDING_INSTALL\x10\x06\x12\x13\n" + + "\x0fPENDING_UPGRADE\x10\a\x12\x14\n" + + "\x10PENDING_ROLLBACK\x10\bBRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_status_proto_rawDescOnce sync.Once + file_status_proto_rawDescData []byte +) + +func file_status_proto_rawDescGZIP() []byte { + file_status_proto_rawDescOnce.Do(func() { + file_status_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_status_proto_rawDesc), len(file_status_proto_rawDesc))) + }) + return file_status_proto_rawDescData +} + +var file_status_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_status_proto_goTypes = []any{ + (Status_Code)(0), // 0: legacytypes.helmv2api.Status.Code + (*Status)(nil), // 1: legacytypes.helmv2api.Status + (*TestSuite)(nil), // 2: legacytypes.helmv2api.TestSuite +} +var file_status_proto_depIdxs = []int32{ + 0, // 0: legacytypes.helmv2api.Status.code:type_name -> legacytypes.helmv2api.Status.Code + 2, // 1: legacytypes.helmv2api.Status.last_test_suite_run:type_name -> legacytypes.helmv2api.TestSuite + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_status_proto_init() } +func file_status_proto_init() { + if File_status_proto != nil { + return + } + file_test_suite_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_status_proto_rawDesc), len(file_status_proto_rawDesc)), + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_status_proto_goTypes, + DependencyIndexes: file_status_proto_depIdxs, + EnumInfos: file_status_proto_enumTypes, + MessageInfos: file_status_proto_msgTypes, + }.Build() + File_status_proto = out.File + file_status_proto_goTypes = nil + file_status_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/status.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/status.proto new file mode 100644 index 00000000..6e2d81cf --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/status.proto @@ -0,0 +1,59 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +import "test_suite.proto"; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +// Status defines the status of a release. +message Status { + enum Code { + // Status_UNKNOWN indicates that a release is in an uncertain state. + UNKNOWN = 0; + // Status_DEPLOYED indicates that the release has been pushed to Kubernetes. + DEPLOYED = 1; + // Status_DELETED indicates that a release has been deleted from Kubernetes. + DELETED = 2; + // Status_SUPERSEDED indicates that this release object is outdated and a newer one exists. + SUPERSEDED = 3; + // Status_FAILED indicates that the release was not successfully deployed. + FAILED = 4; + // Status_DELETING indicates that a delete operation is underway. + DELETING = 5; + // Status_PENDING_INSTALL indicates that an install operation is underway. + PENDING_INSTALL = 6; + // Status_PENDING_UPGRADE indicates that an upgrade operation is underway. + PENDING_UPGRADE = 7; + // Status_PENDING_ROLLBACK indicates that a rollback operation is underway. + PENDING_ROLLBACK = 8; + } + + Code code = 1; + + // Deprecated + // google.protobuf.Any details = 2; + + // Cluster resources as kubectl would print them. + string resources = 3; + + // Contains the rendered templates/NOTES.txt if available + string notes = 4; + + // LastTestSuiteRun provides results on the last test run on a release + helmv2api.TestSuite last_test_suite_run = 5; +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/template.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/template.pb.go new file mode 100644 index 00000000..94c74bba --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/template.pb.go @@ -0,0 +1,151 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: template.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Template represents a template as a name/value pair. +// +// By convention, name is a relative path within the scope of the chart's +// base directory. +type Template struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Name is the path-like name of the template. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Data is the template as byte data. + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Template) Reset() { + *x = Template{} + mi := &file_template_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Template) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Template) ProtoMessage() {} + +func (x *Template) ProtoReflect() protoreflect.Message { + mi := &file_template_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Template.ProtoReflect.Descriptor instead. +func (*Template) Descriptor() ([]byte, []int) { + return file_template_proto_rawDescGZIP(), []int{0} +} + +func (x *Template) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Template) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +var File_template_proto protoreflect.FileDescriptor + +const file_template_proto_rawDesc = "" + + "\n" + + "\x0etemplate.proto\x12\x15legacytypes.helmv2api\"2\n" + + "\bTemplate\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + + "\x04data\x18\x02 \x01(\fR\x04dataBRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_template_proto_rawDescOnce sync.Once + file_template_proto_rawDescData []byte +) + +func file_template_proto_rawDescGZIP() []byte { + file_template_proto_rawDescOnce.Do(func() { + file_template_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_template_proto_rawDesc), len(file_template_proto_rawDesc))) + }) + return file_template_proto_rawDescData +} + +var file_template_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_template_proto_goTypes = []any{ + (*Template)(nil), // 0: legacytypes.helmv2api.Template +} +var file_template_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_template_proto_init() } +func file_template_proto_init() { + if File_template_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_template_proto_rawDesc), len(file_template_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_template_proto_goTypes, + DependencyIndexes: file_template_proto_depIdxs, + MessageInfos: file_template_proto_msgTypes, + }.Build() + File_template_proto = out.File + file_template_proto_goTypes = nil + file_template_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/template.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/template.proto new file mode 100644 index 00000000..99801eee --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/template.proto @@ -0,0 +1,31 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +// Template represents a template as a name/value pair. +// +// By convention, name is a relative path within the scope of the chart's +// base directory. +message Template { + // Name is the path-like name of the template. + string name = 1; + + // Data is the template as byte data. + bytes data = 2; +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/test_run.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/test_run.pb.go new file mode 100644 index 00000000..df0e0a65 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/test_run.pb.go @@ -0,0 +1,238 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: test_run.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type TestRun_Status int32 + +const ( + TestRun_UNKNOWN TestRun_Status = 0 + TestRun_SUCCESS TestRun_Status = 1 + TestRun_FAILURE TestRun_Status = 2 + TestRun_RUNNING TestRun_Status = 3 +) + +// Enum value maps for TestRun_Status. +var ( + TestRun_Status_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SUCCESS", + 2: "FAILURE", + 3: "RUNNING", + } + TestRun_Status_value = map[string]int32{ + "UNKNOWN": 0, + "SUCCESS": 1, + "FAILURE": 2, + "RUNNING": 3, + } +) + +func (x TestRun_Status) Enum() *TestRun_Status { + p := new(TestRun_Status) + *p = x + return p +} + +func (x TestRun_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TestRun_Status) Descriptor() protoreflect.EnumDescriptor { + return file_test_run_proto_enumTypes[0].Descriptor() +} + +func (TestRun_Status) Type() protoreflect.EnumType { + return &file_test_run_proto_enumTypes[0] +} + +func (x TestRun_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TestRun_Status.Descriptor instead. +func (TestRun_Status) EnumDescriptor() ([]byte, []int) { + return file_test_run_proto_rawDescGZIP(), []int{0, 0} +} + +type TestRun struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Status TestRun_Status `protobuf:"varint,2,opt,name=status,proto3,enum=legacytypes.helmv2api.TestRun_Status" json:"status,omitempty"` + Info string `protobuf:"bytes,3,opt,name=info,proto3" json:"info,omitempty"` + StartedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"` + CompletedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=completed_at,json=completedAt,proto3" json:"completed_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TestRun) Reset() { + *x = TestRun{} + mi := &file_test_run_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TestRun) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestRun) ProtoMessage() {} + +func (x *TestRun) ProtoReflect() protoreflect.Message { + mi := &file_test_run_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TestRun.ProtoReflect.Descriptor instead. +func (*TestRun) Descriptor() ([]byte, []int) { + return file_test_run_proto_rawDescGZIP(), []int{0} +} + +func (x *TestRun) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *TestRun) GetStatus() TestRun_Status { + if x != nil { + return x.Status + } + return TestRun_UNKNOWN +} + +func (x *TestRun) GetInfo() string { + if x != nil { + return x.Info + } + return "" +} + +func (x *TestRun) GetStartedAt() *timestamppb.Timestamp { + if x != nil { + return x.StartedAt + } + return nil +} + +func (x *TestRun) GetCompletedAt() *timestamppb.Timestamp { + if x != nil { + return x.CompletedAt + } + return nil +} + +var File_test_run_proto protoreflect.FileDescriptor + +const file_test_run_proto_rawDesc = "" + + "\n" + + "\x0etest_run.proto\x12\x15legacytypes.helmv2api\x1a\x1fgoogle/protobuf/timestamp.proto\"\xa8\x02\n" + + "\aTestRun\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12=\n" + + "\x06status\x18\x02 \x01(\x0e2%.legacytypes.helmv2api.TestRun.StatusR\x06status\x12\x12\n" + + "\x04info\x18\x03 \x01(\tR\x04info\x129\n" + + "\n" + + "started_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\tstartedAt\x12=\n" + + "\fcompleted_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\vcompletedAt\"<\n" + + "\x06Status\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\v\n" + + "\aSUCCESS\x10\x01\x12\v\n" + + "\aFAILURE\x10\x02\x12\v\n" + + "\aRUNNING\x10\x03BRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_test_run_proto_rawDescOnce sync.Once + file_test_run_proto_rawDescData []byte +) + +func file_test_run_proto_rawDescGZIP() []byte { + file_test_run_proto_rawDescOnce.Do(func() { + file_test_run_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_test_run_proto_rawDesc), len(file_test_run_proto_rawDesc))) + }) + return file_test_run_proto_rawDescData +} + +var file_test_run_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_test_run_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_test_run_proto_goTypes = []any{ + (TestRun_Status)(0), // 0: legacytypes.helmv2api.TestRun.Status + (*TestRun)(nil), // 1: legacytypes.helmv2api.TestRun + (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp +} +var file_test_run_proto_depIdxs = []int32{ + 0, // 0: legacytypes.helmv2api.TestRun.status:type_name -> legacytypes.helmv2api.TestRun.Status + 2, // 1: legacytypes.helmv2api.TestRun.started_at:type_name -> google.protobuf.Timestamp + 2, // 2: legacytypes.helmv2api.TestRun.completed_at:type_name -> google.protobuf.Timestamp + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_test_run_proto_init() } +func file_test_run_proto_init() { + if File_test_run_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_test_run_proto_rawDesc), len(file_test_run_proto_rawDesc)), + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_run_proto_goTypes, + DependencyIndexes: file_test_run_proto_depIdxs, + EnumInfos: file_test_run_proto_enumTypes, + MessageInfos: file_test_run_proto_msgTypes, + }.Build() + File_test_run_proto = out.File + file_test_run_proto_goTypes = nil + file_test_run_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/test_run.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/test_run.proto new file mode 100644 index 00000000..a5b769f5 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/test_run.proto @@ -0,0 +1,37 @@ + +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +message TestRun { + enum Status { + UNKNOWN = 0; + SUCCESS = 1; + FAILURE = 2; + RUNNING = 3; + } + + string name = 1; + Status status = 2; + string info = 3; + google.protobuf.Timestamp started_at = 4; + google.protobuf.Timestamp completed_at = 5; +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/test_suite.pb.go b/pkg/resources/formatters/internal/legacytypes/helmv2api/test_suite.pb.go new file mode 100644 index 00000000..e2bd7032 --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/test_suite.pb.go @@ -0,0 +1,166 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v5.29.3 +// source: test_suite.proto + +package helmv2api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// TestSuite comprises of the last run of the pre-defined test suite of a release version +type TestSuite struct { + state protoimpl.MessageState `protogen:"open.v1"` + // StartedAt indicates the date/time this test suite was kicked off + StartedAt *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=started_at,json=startedAt,proto3" json:"started_at,omitempty"` + // CompletedAt indicates the date/time this test suite was completed + CompletedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=completed_at,json=completedAt,proto3" json:"completed_at,omitempty"` + // Results are the results of each segment of the test + Results []*TestRun `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TestSuite) Reset() { + *x = TestSuite{} + mi := &file_test_suite_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TestSuite) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestSuite) ProtoMessage() {} + +func (x *TestSuite) ProtoReflect() protoreflect.Message { + mi := &file_test_suite_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TestSuite.ProtoReflect.Descriptor instead. +func (*TestSuite) Descriptor() ([]byte, []int) { + return file_test_suite_proto_rawDescGZIP(), []int{0} +} + +func (x *TestSuite) GetStartedAt() *timestamppb.Timestamp { + if x != nil { + return x.StartedAt + } + return nil +} + +func (x *TestSuite) GetCompletedAt() *timestamppb.Timestamp { + if x != nil { + return x.CompletedAt + } + return nil +} + +func (x *TestSuite) GetResults() []*TestRun { + if x != nil { + return x.Results + } + return nil +} + +var File_test_suite_proto protoreflect.FileDescriptor + +const file_test_suite_proto_rawDesc = "" + + "\n" + + "\x10test_suite.proto\x12\x15legacytypes.helmv2api\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x0etest_run.proto\"\xbf\x01\n" + + "\tTestSuite\x129\n" + + "\n" + + "started_at\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\tstartedAt\x12=\n" + + "\fcompleted_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\vcompletedAt\x128\n" + + "\aresults\x18\x03 \x03(\v2\x1e.legacytypes.helmv2api.TestRunR\aresultsBRZPgithub.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2apib\x06proto3" + +var ( + file_test_suite_proto_rawDescOnce sync.Once + file_test_suite_proto_rawDescData []byte +) + +func file_test_suite_proto_rawDescGZIP() []byte { + file_test_suite_proto_rawDescOnce.Do(func() { + file_test_suite_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_test_suite_proto_rawDesc), len(file_test_suite_proto_rawDesc))) + }) + return file_test_suite_proto_rawDescData +} + +var file_test_suite_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_test_suite_proto_goTypes = []any{ + (*TestSuite)(nil), // 0: legacytypes.helmv2api.TestSuite + (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp + (*TestRun)(nil), // 2: legacytypes.helmv2api.TestRun +} +var file_test_suite_proto_depIdxs = []int32{ + 1, // 0: legacytypes.helmv2api.TestSuite.started_at:type_name -> google.protobuf.Timestamp + 1, // 1: legacytypes.helmv2api.TestSuite.completed_at:type_name -> google.protobuf.Timestamp + 2, // 2: legacytypes.helmv2api.TestSuite.results:type_name -> legacytypes.helmv2api.TestRun + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_test_suite_proto_init() } +func file_test_suite_proto_init() { + if File_test_suite_proto != nil { + return + } + file_test_run_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_test_suite_proto_rawDesc), len(file_test_suite_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_suite_proto_goTypes, + DependencyIndexes: file_test_suite_proto_depIdxs, + MessageInfos: file_test_suite_proto_msgTypes, + }.Build() + File_test_suite_proto = out.File + file_test_suite_proto_goTypes = nil + file_test_suite_proto_depIdxs = nil +} diff --git a/pkg/resources/formatters/internal/legacytypes/helmv2api/test_suite.proto b/pkg/resources/formatters/internal/legacytypes/helmv2api/test_suite.proto new file mode 100644 index 00000000..0a12227f --- /dev/null +++ b/pkg/resources/formatters/internal/legacytypes/helmv2api/test_suite.proto @@ -0,0 +1,34 @@ +// Copyright The Helm Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package legacytypes.helmv2api; + +import "google/protobuf/timestamp.proto"; +import "test_run.proto"; + +option go_package = "github.com/rancher/steve/pkg/resources/formatters/internal/legacytypes/helmv2api"; + +// TestSuite comprises of the last run of the pre-defined test suite of a release version +message TestSuite { + // StartedAt indicates the date/time this test suite was kicked off + google.protobuf.Timestamp started_at = 1; + + // CompletedAt indicates the date/time this test suite was completed + google.protobuf.Timestamp completed_at = 2; + + // Results are the results of each segment of the test + repeated helmv2api.TestRun results = 3; +} diff --git a/pkg/resources/formatters/testdata/release-cm.yaml b/pkg/resources/formatters/testdata/release-cm.yaml new file mode 100644 index 00000000..b1f9c522 --- /dev/null +++ b/pkg/resources/formatters/testdata/release-cm.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +data: + release: 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 +kind: ConfigMap +metadata: + creationTimestamp: "2025-04-24T15:24:35Z" + labels: + MODIFIED_AT: "1745508275" + NAME: mariadb + OWNER: TILLER + STATUS: DEPLOYED + VERSION: "1" + name: mariadb.v1 + namespace: kube-system + resourceVersion: "348756" + uid: 6eda5c45-1a60-411a-9acd-29f7ed9c5ba1