mirror of
https://github.com/rancher/steve.git
synced 2025-05-30 10:36:31 +00:00
* changing secret and configmap formatters to return decoded helm data if includeHelmData query parameter is present * update gomod
142 lines
3.7 KiB
Go
142 lines
3.7 KiB
Go
package formatters
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/gzip"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"io"
|
|
|
|
"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/v2/pkg/data"
|
|
"github.com/sirupsen/logrus"
|
|
"helm.sh/helm/v3/pkg/release"
|
|
rspb "k8s.io/helm/pkg/proto/hapi/release"
|
|
)
|
|
|
|
var (
|
|
ErrNotHelmRelease = errors.New("not helm release") // error for when it's not a helm release
|
|
magicGzip = []byte{0x1f, 0x8b, 0x08} // gzip magic header
|
|
)
|
|
|
|
func HandleHelmData(request *types.APIRequest, resource *types.RawResource) {
|
|
objData := resource.APIObject.Data()
|
|
if q := request.Query.Get("includeHelmData"); q == "true" {
|
|
var helmReleaseData string
|
|
if resource.Type == "secret" {
|
|
b, err := base64.StdEncoding.DecodeString(objData.String("data", "release"))
|
|
if err != nil {
|
|
return
|
|
}
|
|
helmReleaseData = string(b)
|
|
} else {
|
|
helmReleaseData = objData.String("data", "release")
|
|
}
|
|
if objData.String("metadata", "labels", "owner") == "helm" {
|
|
rl, err := decodeHelm3(helmReleaseData)
|
|
if err != nil {
|
|
logrus.Errorf("Failed to decode helm3 release data: %v", err)
|
|
return
|
|
}
|
|
objData.SetNested(rl, "data", "release")
|
|
}
|
|
if objData.String("metadata", "labels", "OWNER") == "TILLER" {
|
|
rl, err := decodeHelm2(helmReleaseData)
|
|
if err != nil {
|
|
logrus.Errorf("Failed to decode helm2 release data: %v", err)
|
|
return
|
|
}
|
|
objData.SetNested(rl, "data", "release")
|
|
}
|
|
|
|
} else {
|
|
DropHelmData(objData)
|
|
}
|
|
}
|
|
|
|
func Pod(request *types.APIRequest, resource *types.RawResource) {
|
|
data := resource.APIObject.Data()
|
|
fields := data.StringSlice("metadata", "fields")
|
|
if len(fields) > 2 {
|
|
data.SetNested(convert.LowerTitle(fields[2]), "metadata", "state", "name")
|
|
}
|
|
}
|
|
|
|
// 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) {
|
|
b, err := base64.StdEncoding.DecodeString(data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Data is too small to be helm 3 release object
|
|
if len(b) <= 3 {
|
|
return nil, ErrNotHelmRelease
|
|
}
|
|
|
|
// 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))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
b2, err := io.ReadAll(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
b = b2
|
|
}
|
|
|
|
var rls release.Release
|
|
// unmarshal release object bytes
|
|
if err := json.Unmarshal(b, &rls); err != nil {
|
|
return nil, err
|
|
}
|
|
return &rls, nil
|
|
}
|
|
|
|
// decodeHelm2 receives a helm2 release data and returns the corresponding helm2 release proto struct
|
|
func decodeHelm2(data string) (*rspb.Release, error) {
|
|
b, err := base64.StdEncoding.DecodeString(data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 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))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
b2, err := io.ReadAll(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
b = b2
|
|
}
|
|
|
|
var rls rspb.Release
|
|
// unmarshal protobuf bytes
|
|
if err := proto.Unmarshal(b, &rls); err != nil {
|
|
return nil, err
|
|
}
|
|
return &rls, nil
|
|
}
|
|
|
|
func DropHelmData(data data.Object) {
|
|
if data.String("metadata", "labels", "owner") == "helm" ||
|
|
data.String("metadata", "labels", "OWNER") == "TILLER" {
|
|
if data.String("data", "release") != "" {
|
|
delete(data.Map("data"), "release")
|
|
}
|
|
}
|
|
}
|