pkg/processor/storage/pvc.go
package storage
import (
"fmt"
"github.com/arttor/helmify/pkg/helmify"
"github.com/arttor/helmify/pkg/processor"
yamlformat "github.com/arttor/helmify/pkg/yaml"
"github.com/iancoleman/strcase"
"io"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"strings"
"text/template"
)
var pvcTempl, _ = template.New("pvc").Parse(
`{{ .Meta }}
{{ .Spec }}`)
var pvcGVC = schema.GroupVersionKind{
Group: "",
Version: "v1",
Kind: "PersistentVolumeClaim",
}
// New creates processor for k8s PVC resource.
func New() helmify.Processor {
return &pvc{}
}
type pvc struct{}
// Process k8s PVC object into template. Returns false if not capable of processing given resource type.
func (p pvc) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured) (bool, helmify.Template, error) {
if obj.GroupVersionKind() != pvcGVC {
return false, nil, nil
}
meta, err := processor.ProcessObjMeta(appMeta, obj)
if err != nil {
return true, nil, err
}
name := appMeta.TrimName(obj.GetName())
nameCamelCase := strcase.ToLowerCamel(name)
values := helmify.Values{}
claim := corev1.PersistentVolumeClaim{}
err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &claim)
if err != nil {
return true, nil, fmt.Errorf("%w: unable to cast to PVC", err)
}
// template storage class name
if claim.Spec.StorageClassName != nil {
templatedSC, err := values.Add(*claim.Spec.StorageClassName, "pvc", nameCamelCase, "storageClass")
if err != nil {
return true, nil, err
}
claim.Spec.StorageClassName = &templatedSC
}
// template resources
specMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&claim.Spec)
if err != nil {
return true, nil, err
}
storageReq, ok, _ := unstructured.NestedString(specMap, "resources", "requests", "storage")
if ok {
templatedStorageReq, err := values.Add(storageReq, "pvc", nameCamelCase, "storageRequest")
if err != nil {
return true, nil, err
}
err = unstructured.SetNestedField(specMap, templatedStorageReq, "resources", "requests", "storage")
if err != nil {
return true, nil, err
}
}
storageLim, ok, _ := unstructured.NestedString(specMap, "resources", "limits", "storage")
if ok {
templatedStorageLim, err := values.Add(storageLim, "pvc", nameCamelCase, "storageLimit")
if err != nil {
return true, nil, err
}
err = unstructured.SetNestedField(specMap, templatedStorageLim, "resources", "limits", "storage")
if err != nil {
return true, nil, err
}
}
spec, err := yamlformat.Marshal(map[string]interface{}{"spec": specMap}, 0)
if err != nil {
return true, nil, err
}
spec = strings.ReplaceAll(spec, "'", "")
return true, &result{
name: name + ".yaml",
data: struct {
Meta string
Spec string
}{Meta: meta, Spec: spec},
values: values,
}, nil
}
type result struct {
name string
data struct {
Meta string
Spec string
}
values helmify.Values
}
func (r *result) Filename() string {
return r.name
}
func (r *result) Values() helmify.Values {
return r.values
}
func (r *result) Write(writer io.Writer) error {
return pvcTempl.Execute(writer, r.data)
}