Skip to content

Commit

Permalink
fix: added env file support to kubeconfig in cfg (#469)
Browse files Browse the repository at this point in the history
  • Loading branch information
Al-Pragliola committed Feb 1, 2024
1 parent 1938705 commit f7dcbd7
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 98 deletions.
10 changes: 9 additions & 1 deletion internal/apis/kfd/v1alpha2/distribution/create/preflight.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/sighupio/furyctl/internal/cluster"
"github.com/sighupio/furyctl/internal/diffs"
"github.com/sighupio/furyctl/internal/distribution"
"github.com/sighupio/furyctl/internal/parser"
"github.com/sighupio/furyctl/internal/state"
"github.com/sighupio/furyctl/internal/tool/kubectl"
execx "github.com/sighupio/furyctl/internal/x/exec"
Expand Down Expand Up @@ -86,11 +87,15 @@ func NewPreFlight(
}

func (p *PreFlight) Exec() (*Status, error) {
var err error

status := &Status{
Diffs: r3diff.Changelog{},
Success: false,
}

cfgParser := parser.NewConfigParser(p.furyctlConfPath)

logrus.Info("Running preflight checks")

if err := p.CreateRootFolder(); err != nil {
Expand All @@ -100,7 +105,10 @@ func (p *PreFlight) Exec() (*Status, error) {
kubeconfigPath := os.Getenv("KUBECONFIG")

if distribution.HasFeature(p.kfd, distribution.FeatureKubeconfigInSchema) {
kubeconfigPath = p.furyctlConf.Spec.Distribution.Kubeconfig
kubeconfigPath, err = cfgParser.ParseDynamicValue(p.furyctlConf.Spec.Distribution.Kubeconfig)
if err != nil {
return status, fmt.Errorf("error parsing kubeconfig value: %w", err)
}
} else if kubeconfigPath == "" {
return status, ErrKubeconfigNotSet
}
Expand Down
24 changes: 17 additions & 7 deletions internal/apis/kfd/v1alpha2/distribution/delete/preflight.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/sighupio/fury-distribution/pkg/apis/kfddistribution/v1alpha2/public"
"github.com/sighupio/furyctl/internal/cluster"
"github.com/sighupio/furyctl/internal/distribution"
"github.com/sighupio/furyctl/internal/parser"
"github.com/sighupio/furyctl/internal/tool/kubectl"
execx "github.com/sighupio/furyctl/internal/x/exec"
kubex "github.com/sighupio/furyctl/internal/x/kube"
Expand All @@ -26,9 +27,10 @@ var ErrKubeconfigNotSet = errors.New("KUBECONFIG env variable is not set")
type PreFlight struct {
*cluster.OperationPhase

furyctlConf public.KfddistributionKfdV1Alpha2
kubeRunner *kubectl.Runner
kfdManifest config.KFD
furyctlConf public.KfddistributionKfdV1Alpha2
furyctlConfPath string
kubeRunner *kubectl.Runner
kfdManifest config.KFD
}

func NewPreFlight(
Expand All @@ -43,9 +45,10 @@ func NewPreFlight(
)

return &PreFlight{
OperationPhase: phase,
furyctlConf: furyctlConf,
kfdManifest: kfdManifest,
OperationPhase: phase,
furyctlConf: furyctlConf,
furyctlConfPath: paths.ConfigPath,
kfdManifest: kfdManifest,
kubeRunner: kubectl.NewRunner(
execx.NewStdExecutor(),
kubectl.Paths{
Expand All @@ -60,6 +63,10 @@ func NewPreFlight(
}

func (p *PreFlight) Exec() error {
var err error

cfgParser := parser.NewConfigParser(p.furyctlConfPath)

logrus.Info("Running preflight checks")

if err := p.CreateRootFolder(); err != nil {
Expand All @@ -69,7 +76,10 @@ func (p *PreFlight) Exec() error {
kubeconfigPath := os.Getenv("KUBECONFIG")

if distribution.HasFeature(p.kfdManifest, distribution.FeatureKubeconfigInSchema) {
kubeconfigPath = p.furyctlConf.Spec.Distribution.Kubeconfig
kubeconfigPath, err = cfgParser.ParseDynamicValue(p.furyctlConf.Spec.Distribution.Kubeconfig)
if err != nil {
return fmt.Errorf("error parsing kubeconfig value: %w", err)
}
} else if kubeconfigPath == "" {
return ErrKubeconfigNotSet
}
Expand Down
26 changes: 0 additions & 26 deletions internal/cluster/common.go

This file was deleted.

4 changes: 0 additions & 4 deletions internal/cluster/creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ func NewCreator(
upgrade bool,
externalUpgradesPath string,
) (Creator, error) {
if err := resetKubeconfigEnv(kfdManifest); err != nil {
return nil, fmt.Errorf("error resetting kubeconfig env: %w", err)
}

lcAPIVersion := strings.ToLower(minimalConf.APIVersion)
lcResourceType := strings.ToLower(minimalConf.Kind)

Expand Down
4 changes: 0 additions & 4 deletions internal/cluster/deleter.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ func NewDeleter(
vpnAutoConnect,
dryRun bool,
) (Deleter, error) {
if err := resetKubeconfigEnv(kfdManifest); err != nil {
return nil, fmt.Errorf("error resetting kubeconfig env: %w", err)
}

lcAPIVersion := strings.ToLower(minimalConf.APIVersion)
lcResourceType := strings.ToLower(minimalConf.Kind)

Expand Down
78 changes: 78 additions & 0 deletions internal/parser/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) 2017-present SIGHUP s.r.l All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package parser

import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
)

const (
Env = "env"
File = "file"
)

var RelativePathRegexp = regexp.MustCompile(`^\.{1,}\/`)

type ConfigParser struct {
baseDir string
}

func NewConfigParser(baseDir string) *ConfigParser {
return &ConfigParser{
baseDir: baseDir,
}
}

func (p *ConfigParser) ParseDynamicValue(val any) (string, error) {
strVal := fmt.Sprintf("%v", val)

spl := strings.Split(strVal, "://")

if len(spl) > 1 {
source := strings.TrimPrefix(spl[0], "{")
sourceValue := strings.TrimSuffix(spl[1], "}")

switch source {
case Env:
envVar := os.Getenv(sourceValue)

envVar = strings.TrimRight(envVar, "\n")

return envVar, nil

case File:
// If the value is a relative path, we need to convert it to an absolute path.
isRelativePath := RelativePathRegexp.MatchString(sourceValue)
if isRelativePath {
sourceValue = filepath.Clean(sourceValue)
sourceValue = filepath.Join(p.baseDir, sourceValue)
}

content, err := readValueFromFile(sourceValue)
if err != nil {
return "", fmt.Errorf("%w", err)
}

content = strings.TrimRight(content, "\n")

return content, nil

default:
return strVal, nil
}
}

return strVal, nil
}

func readValueFromFile(path string) (string, error) {
val, err := os.ReadFile(path)

return string(val), err
}
91 changes: 91 additions & 0 deletions internal/parser/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright (c) 2017-present SIGHUP s.r.l All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build unit

package parser_test

import (
"fmt"
"os"
"path"
"testing"

"github.com/sighupio/furyctl/internal/parser"
"github.com/stretchr/testify/assert"
)

func TestNewConfigParser(t *testing.T) {
t.Parallel()

cfgParser := parser.NewConfigParser("dummy/base/dir")

assert.NotNil(t, cfgParser)
}

func TestConfigParser_ParseDynamicValue(t *testing.T) {
t.Parallel()

tmpDir, err := os.MkdirTemp("", "test")
if err != nil {
t.Fatal(err)
}

exampleStr := "test"

err = os.WriteFile(tmpDir+"/test_file.txt", []byte(exampleStr), os.ModePerm)

defer os.RemoveAll(tmpDir)

assert.NoError(t, err)

testCases := []struct {
name string
baseDir string
envName string
envValue string
value any
expected string
}{
{
name: "parsing env",
baseDir: "dummy/base/dir",
envName: "TEST_ENV_VAR",
envValue: "test",
value: "{env://TEST_ENV_VAR}",
expected: "test",
},
{
name: "parsing file - relative path",
baseDir: tmpDir,
value: fmt.Sprintf("{file://./test_file.txt}"),
expected: "test",
},
{
name: "parsing file - absolute path",
baseDir: tmpDir,
value: fmt.Sprintf("{file://%s}", path.Join(tmpDir, "test_file.txt")),
expected: "test",
},
}

for _, tc := range testCases {
tc := tc

t.Run(tc.name, func(t *testing.T) {
cfgParser := parser.NewConfigParser(tc.baseDir)

if tc.envName != "" {
err := os.Setenv(tc.envName, tc.envValue)

assert.NoError(t, err)
}

res, err := cfgParser.ParseDynamicValue(tc.value)

assert.NoError(t, err)
assert.Equal(t, tc.expected, res)
})
}
}
59 changes: 5 additions & 54 deletions internal/template/mapper/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@ import (
"reflect"
"regexp"
"strings"
)

const (
Env = "env"
File = "file"
"github.com/sighupio/furyctl/internal/parser"
)

var (
Expand Down Expand Up @@ -127,12 +124,14 @@ func (m *Mapper) injectDynamicValuesAndPaths(
}

func (m *Mapper) injectDynamicValuesAndPathsString(value string) (string, error) {
cfgParser := parser.NewConfigParser(m.furyctlConfDir)

// If the value contains dynamic values, we need to parse them.
dynamicValues := EnvRegexp.FindAllString(value, -1)
for _, dynamicValue := range dynamicValues {
parsedDynamicValue, err := ParseDynamicValue(dynamicValue, m.furyctlConfDir)
parsedDynamicValue, err := cfgParser.ParseDynamicValue(dynamicValue)
if err != nil {
return "", err
return "", fmt.Errorf("error parsing dynamic value: %w", err)
}

value = strings.Replace(value, dynamicValue, parsedDynamicValue, 1)
Expand All @@ -147,51 +146,3 @@ func (m *Mapper) injectDynamicValuesAndPathsString(value string) (string, error)

return value, nil
}

func readValueFromFile(path string) (string, error) {
val, err := os.ReadFile(path)

return string(val), err
}

func ParseDynamicValue(val any, baseDir string) (string, error) {
strVal := fmt.Sprintf("%v", val)

spl := strings.Split(strVal, "://")

if len(spl) > 1 {
source := strings.TrimPrefix(spl[0], "{")
sourceValue := strings.TrimSuffix(spl[1], "}")

switch source {
case Env:
envVar := os.Getenv(sourceValue)

envVar = strings.TrimRight(envVar, "\n")

return envVar, nil

case File:
// If the value is a relative path, we need to convert it to an absolute path.
isRelativePath := RelativePathRegexp.MatchString(sourceValue)
if isRelativePath {
sourceValue = filepath.Clean(sourceValue)
sourceValue = filepath.Join(baseDir, sourceValue)
}

content, err := readValueFromFile(sourceValue)
if err != nil {
return "", fmt.Errorf("%w", err)
}

content = strings.TrimRight(content, "\n")

return content, nil

default:
return strVal, nil
}
}

return strVal, nil
}
Loading

0 comments on commit f7dcbd7

Please sign in to comment.