1
0
mirror of synced 2026-03-18 00:46:56 +00:00

Merge branch 'main' into patch-3

This commit is contained in:
lloydchang
2024-01-19 01:27:15 -08:00
committed by GitHub
528 changed files with 23323 additions and 9621 deletions

View File

@@ -27,8 +27,9 @@ import (
"time"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/hashicorp/go-cleanhttp"
"github.com/fluxcd/flux2/pkg/manifestgen"
"github.com/fluxcd/flux2/v2/pkg/manifestgen"
)
// Generate returns the install manifests as a multi-doc YAML.
@@ -54,7 +55,7 @@ func Generate(options Options, manifestsBase string) (*manifestgen.Manifest, err
} else {
// download the manifests base from GitHub
if manifestsBase == "" {
manifestsBase, err = os.MkdirTemp("", options.Namespace)
manifestsBase, err = manifestgen.MkdirTempAbs("", options.Namespace)
if err != nil {
return nil, fmt.Errorf("temp dir error: %w", err)
}
@@ -91,7 +92,7 @@ func Generate(options Options, manifestsBase string) (*manifestgen.Manifest, err
// GetLatestVersion calls the GitHub API and returns the latest released version.
func GetLatestVersion() (string, error) {
ghURL := "https://api.github.com/repos/fluxcd/flux2/releases/latest"
c := http.DefaultClient
c := cleanhttp.DefaultClient()
c.Timeout = 15 * time.Second
res, err := c.Get(ghURL)
@@ -121,7 +122,7 @@ func ExistingVersion(version string) (bool, error) {
}
ghURL := fmt.Sprintf("https://api.github.com/repos/fluxcd/flux2/releases/tags/%s", version)
c := http.DefaultClient
c := cleanhttp.DefaultClient()
c.Timeout = 15 * time.Second
res, err := c.Get(ghURL)

View File

@@ -26,10 +26,12 @@ import (
"path/filepath"
"strings"
"github.com/fluxcd/pkg/untar"
"sigs.k8s.io/kustomize/api/filesys"
"github.com/hashicorp/go-cleanhttp"
"github.com/fluxcd/flux2/pkg/manifestgen/kustomization"
"github.com/fluxcd/pkg/kustomize/filesys"
"github.com/fluxcd/pkg/tar"
"github.com/fluxcd/flux2/v2/pkg/manifestgen/kustomization"
)
func fetch(ctx context.Context, url, version, dir string) error {
@@ -44,7 +46,7 @@ func fetch(ctx context.Context, url, version, dir string) error {
}
// download
resp, err := http.DefaultClient.Do(req.WithContext(ctx))
resp, err := cleanhttp.DefaultClient().Do(req.WithContext(ctx))
if err != nil {
return fmt.Errorf("failed to download manifests.tar.gz from %s, error: %w", ghURL, err)
}
@@ -56,7 +58,7 @@ func fetch(ctx context.Context, url, version, dir string) error {
}
// extract
if _, err = untar.Untar(resp.Body, dir); err != nil {
if err = tar.Untar(resp.Body, dir, tar.WithMaxUntarSize(-1)); err != nil {
return fmt.Errorf("failed to untar manifests.tar.gz from %s, error: %w", ghURL, err)
}
@@ -71,9 +73,9 @@ func generate(base string, options Options) error {
// In such environments they normally add `.cluster.local` and `.local`
// suffixes to `no_proxy` variable in order to prevent cluster-local
// traffic from going through http proxy. Without fully specified
// domain they need to mention `notifications-controller` explicity in
// domain they need to mention `notifications-controller` explicitly in
// `no_proxy` variable after debugging http proxy logs.
options.EventsAddr = fmt.Sprintf("http://%s.%s.svc.%s/", options.NotificationController, options.Namespace, options.ClusterDomain)
options.EventsAddr = fmt.Sprintf("http://%s.%s.svc.%s./", options.NotificationController, options.Namespace, options.ClusterDomain)
}
if err := execTemplate(options, namespaceTmpl, path.Join(base, "namespace.yaml")); err != nil {
@@ -126,8 +128,12 @@ func build(base, output string) error {
return err
}
fs := filesys.MakeFsOnDisk()
if err := fs.WriteFile(output, resources); err != nil {
outputBase := filepath.Dir(strings.TrimSuffix(output, string(filepath.Separator)))
fs, err := filesys.MakeFsOnDiskSecure(outputBase)
if err != nil {
return err
}
if err = fs.WriteFile(output, resources); err != nil {
return err
}

View File

@@ -51,8 +51,6 @@ patches:
- path: node-selector.yaml
target:
kind: Deployment
patchesJson6902:
{{- range $i, $component := .Components }}
{{- if eq $component "notification-controller" }}
- target:
@@ -165,6 +163,9 @@ apiVersion: v1
kind: Namespace
metadata:
name: {{.Namespace}}
labels:
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
`
func execTemplate(obj interface{}, tmpl, filename string) error {

View File

@@ -20,20 +20,23 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/api/provider"
kustypes "sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
"github.com/fluxcd/flux2/pkg/manifestgen"
"github.com/fluxcd/pkg/kustomize/filesys"
"github.com/fluxcd/flux2/v2/pkg/manifestgen"
)
// Generate scans the given directory for Kubernetes manifests and creates a kustomization.yaml
// including all discovered manifests as resources.
// Generate scans the given directory for Kubernetes manifests and creates a
// konfig.DefaultKustomizationFileName file, including all discovered manifests
// as resources.
func Generate(options Options) (*manifestgen.Manifest, error) {
kfile := filepath.Join(options.TargetPath, konfig.DefaultKustomizationFileName())
abskfile := filepath.Join(options.BaseDir, kfile)
@@ -50,7 +53,7 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
return nil
}
if info.IsDir() {
// If a sub-directory contains an existing Kustomization file add the
// If a sub-directory contains an existing Kustomization file, add the
// directory as a resource and do not decent into it.
for _, kfilename := range konfig.RecognizedKustomizationFileNames() {
if options.FileSystem.Exists(filepath.Join(path, kfilename)) {
@@ -88,7 +91,9 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
if err != nil {
return nil, err
}
f.Close()
if err = f.Close(); err != nil {
return nil, err
}
kus := kustypes.Kustomization{
TypeMeta: kustypes.TypeMeta{
@@ -128,20 +133,40 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
}, nil
}
// kustomizeBuildMutex is a workaround for a concurrent map read and map write bug.
// TODO(stefan): https://github.com/kubernetes-sigs/kustomize/issues/3659
var kustomizeBuildMutex sync.Mutex
// Build takes a Kustomize overlays and returns the resulting manifests as multi-doc YAML.
// Build takes the path to a directory with a konfig.RecognizedKustomizationFileNames,
// builds it, and returns the resulting manifests as multi-doc YAML. It restricts the
// Kustomize file system to the parent directory of the base.
func Build(base string) ([]byte, error) {
// TODO(stefan): temporary workaround for concurrent map read and map write bug
// https://github.com/kubernetes-sigs/kustomize/issues/3659
// TODO(hidde): drop this when consumers have moved away to BuildWithRoot.
parent := filepath.Dir(strings.TrimSuffix(base, string(filepath.Separator)))
return BuildWithRoot(parent, base)
}
// BuildWithRoot takes the path to a directory with a konfig.RecognizedKustomizationFileNames,
// builds it, and returns the resulting manifests as multi-doc YAML.
// The Kustomize file system is restricted to root.
func BuildWithRoot(root, base string) ([]byte, error) {
kustomizeBuildMutex.Lock()
defer kustomizeBuildMutex.Unlock()
kfile := filepath.Join(base, konfig.DefaultKustomizationFileName())
fs, err := filesys.MakeFsOnDiskSecureBuild(root)
if err != nil {
return nil, err
}
fs := filesys.MakeFsOnDisk()
if !fs.Exists(kfile) {
return nil, fmt.Errorf("%s not found", kfile)
var kfile string
for _, f := range konfig.RecognizedKustomizationFileNames() {
if kf := filepath.Join(base, f); fs.Exists(kf) {
kfile = kf
break
}
}
if kfile == "" {
return nil, fmt.Errorf("%s not found", konfig.DefaultKustomizationFileName())
}
// TODO(hidde): work around for a bug in kustomize causing it to
@@ -161,11 +186,8 @@ func Build(base string) ([]byte, error) {
}
buildOptions := &krusty.Options{
DoLegacyResourceSort: true,
LoadRestrictions: kustypes.LoadRestrictionsNone,
AddManagedbyLabel: false,
DoPrune: false,
PluginConfig: kustypes.DisabledPluginConfig(),
LoadRestrictions: kustypes.LoadRestrictionsNone,
PluginConfig: kustypes.DisabledPluginConfig(),
}
k := krusty.MakeKustomizer(buildOptions)

View File

@@ -16,7 +16,7 @@ limitations under the License.
package kustomization
import "sigs.k8s.io/kustomize/api/filesys"
import "sigs.k8s.io/kustomize/kyaml/filesys"
type Options struct {
FileSystem filesys.FileSystem
@@ -25,6 +25,8 @@ type Options struct {
}
func MakeDefaultOptions() Options {
// TODO(hidde): switch MakeFsOnDisk to MakeFsOnDiskSecureBuild when we
// break API.
return Options{
FileSystem: filesys.MakeFsOnDisk(),
BaseDir: "",

View File

@@ -34,7 +34,7 @@ type Manifest struct {
Content string
}
// WriteFile writes the YAML content to a file inside the the root path.
// WriteFile writes the YAML content to a file inside the root path.
// If the file does not exist, WriteFile creates it with permissions perm,
// otherwise WriteFile overwrites the file, without changing permissions.
func (m *Manifest) WriteFile(rootDir string) (string, error) {

View File

@@ -18,6 +18,8 @@ package sourcesecret
import (
"crypto/elliptic"
"github.com/fluxcd/pkg/ssh"
)
type PrivateKeyAlgorithm string
@@ -31,30 +33,53 @@ const (
const (
UsernameSecretKey = "username"
PasswordSecretKey = "password"
CAFileSecretKey = "caFile"
CertFileSecretKey = "certFile"
KeyFileSecretKey = "keyFile"
CACrtSecretKey = "ca.crt"
TLSCrtSecretKey = "tls.crt"
TLSKeySecretKey = "tls.key"
PrivateKeySecretKey = "identity"
PublicKeySecretKey = "identity.pub"
KnownHostsSecretKey = "known_hosts"
BearerTokenKey = "bearerToken"
// Deprecated: Replaced by CACrtSecretKey, but kept for backwards
// compatibility with deprecated TLS flags.
CAFileSecretKey = "caFile"
// Deprecated: Replaced by TLSCrtSecretKey, but kept for backwards
// compatibility with deprecated TLS flags.
CertFileSecretKey = "certFile"
// Deprecated: Replaced by TLSKeySecretKey, but kept for backwards
// compatibility with deprecated TLS flags.
KeyFileSecretKey = "keyFile"
)
type Options struct {
Name string
Namespace string
Labels map[string]string
Registry string
SSHHostname string
PrivateKeyAlgorithm PrivateKeyAlgorithm
RSAKeyBits int
ECDSACurve elliptic.Curve
PrivateKeyPath string
Keypair *ssh.KeyPair
Username string
Password string
CAFilePath string
CertFilePath string
KeyFilePath string
CACrt []byte
TLSCrt []byte
TLSKey []byte
TargetPath string
ManifestFile string
BearerToken string
// Deprecated: Replaced by CACrt, but kept for backwards compatibility
// with deprecated TLS flags.
CAFile []byte
// Deprecated: Replaced by TLSCrt, but kept for backwards compatibility
// with deprecated TLS flags.
CertFile []byte
// Deprecated: Replaced by TLSKey, but kept for backwards compatibility
// with deprecated TLS flags.
KeyFile []byte
}
func MakeDefaultOptions() Options {
@@ -63,12 +88,12 @@ func MakeDefaultOptions() Options {
Namespace: "flux-system",
Labels: map[string]string{},
PrivateKeyAlgorithm: RSAPrivateKeyAlgorithm,
PrivateKeyPath: "",
Username: "",
Password: "",
CAFilePath: "",
CertFilePath: "",
KeyFilePath: "",
CAFile: []byte{},
CertFile: []byte{},
KeyFile: []byte{},
ManifestFile: "secret.yaml",
BearerToken: "",
}
}

View File

@@ -18,6 +18,8 @@ package sourcesecret
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"net"
"os"
@@ -31,11 +33,32 @@ import (
"github.com/fluxcd/pkg/ssh"
"github.com/fluxcd/flux2/pkg/manifestgen"
"github.com/fluxcd/flux2/v2/pkg/manifestgen"
)
const defaultSSHPort = 22
// types gotten from https://github.com/kubernetes/kubectl/blob/master/pkg/cmd/create/create_secret_docker.go#L64-L84
// DockerConfigJSON represents a local docker auth config file
// for pulling images.
type DockerConfigJSON struct {
Auths DockerConfig `json:"auths"`
}
// DockerConfig represents the config file used by the docker CLI.
// This config that represents the credentials that should be used
// when pulling images from specific image repositories.
type DockerConfig map[string]DockerConfigEntry
// DockerConfigEntry holds the user information that grant the access to docker registry
type DockerConfigEntry struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Email string `json:"email,omitempty"`
Auth string `json:"auth,omitempty"`
}
func Generate(options Options) (*manifestgen.Manifest, error) {
var err error
@@ -43,10 +66,8 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
switch {
case options.Username != "" && options.Password != "":
// noop
case len(options.PrivateKeyPath) > 0:
if keypair, err = loadKeyPair(options.PrivateKeyPath, options.Password); err != nil {
return nil, err
}
case options.Keypair != nil:
keypair = options.Keypair
case len(options.PrivateKeyAlgorithm) > 0:
if keypair, err = generateKeyPair(options); err != nil {
return nil, err
@@ -55,29 +76,20 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
var hostKey []byte
if keypair != nil {
if hostKey, err = scanHostKey(options.SSHHostname); err != nil {
if hostKey, err = ScanHostKey(options.SSHHostname); err != nil {
return nil, err
}
}
var caFile []byte
if options.CAFilePath != "" {
if caFile, err = os.ReadFile(options.CAFilePath); err != nil {
return nil, fmt.Errorf("failed to read CA file: %w", err)
var dockerCfgJson []byte
if options.Registry != "" {
dockerCfgJson, err = generateDockerConfigJson(options.Registry, options.Username, options.Password)
if err != nil {
return nil, fmt.Errorf("failed to generate json for docker config: %w", err)
}
}
var certFile, keyFile []byte
if options.CertFilePath != "" && options.KeyFilePath != "" {
if certFile, err = os.ReadFile(options.CertFilePath); err != nil {
return nil, fmt.Errorf("failed to read cert file: %w", err)
}
if keyFile, err = os.ReadFile(options.KeyFilePath); err != nil {
return nil, fmt.Errorf("failed to read key file: %w", err)
}
}
secret := buildSecret(keypair, hostKey, caFile, certFile, keyFile, options)
secret := buildSecret(keypair, hostKey, dockerCfgJson, options)
b, err := yaml.Marshal(secret)
if err != nil {
return nil, err
@@ -89,7 +101,36 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
}, nil
}
func buildSecret(keypair *ssh.KeyPair, hostKey, caFile, certFile, keyFile []byte, options Options) (secret corev1.Secret) {
func LoadKeyPairFromPath(path, password string) (*ssh.KeyPair, error) {
if path == "" {
return nil, nil
}
b, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to open private key file: %w", err)
}
return LoadKeyPair(b, password)
}
func LoadKeyPair(privateKey []byte, password string) (*ssh.KeyPair, error) {
var ppk cryptssh.Signer
var err error
if password != "" {
ppk, err = cryptssh.ParsePrivateKeyWithPassphrase(privateKey, []byte(password))
} else {
ppk, err = cryptssh.ParsePrivateKey(privateKey)
}
if err != nil {
return nil, err
}
return &ssh.KeyPair{
PublicKey: cryptssh.MarshalAuthorizedKey(ppk.PublicKey()),
PrivateKey: privateKey,
}, nil
}
func buildSecret(keypair *ssh.KeyPair, hostKey, dockerCfg []byte, options Options) (secret corev1.Secret) {
secret.TypeMeta = metav1.TypeMeta{
APIVersion: "v1",
Kind: "Secret",
@@ -101,21 +142,36 @@ func buildSecret(keypair *ssh.KeyPair, hostKey, caFile, certFile, keyFile []byte
secret.Labels = options.Labels
secret.StringData = map[string]string{}
if dockerCfg != nil {
secret.Type = corev1.SecretTypeDockerConfigJson
secret.StringData[corev1.DockerConfigJsonKey] = string(dockerCfg)
return
}
if options.Username != "" && options.Password != "" {
secret.StringData[UsernameSecretKey] = options.Username
secret.StringData[PasswordSecretKey] = options.Password
}
if caFile != nil {
secret.StringData[CAFileSecretKey] = string(caFile)
if options.BearerToken != "" {
secret.StringData[BearerTokenKey] = options.BearerToken
}
if certFile != nil && keyFile != nil {
secret.StringData[CertFileSecretKey] = string(certFile)
secret.StringData[KeyFileSecretKey] = string(keyFile)
if len(options.CACrt) != 0 {
secret.StringData[CACrtSecretKey] = string(options.CACrt)
} else if len(options.CAFile) != 0 {
secret.StringData[CAFileSecretKey] = string(options.CAFile)
}
if keypair != nil && hostKey != nil {
if len(options.TLSCrt) != 0 && len(options.TLSKey) != 0 {
secret.Type = corev1.SecretTypeTLS
secret.StringData[TLSCrtSecretKey] = string(options.TLSCrt)
secret.StringData[TLSKeySecretKey] = string(options.TLSKey)
} else if len(options.CertFile) != 0 && len(options.KeyFile) != 0 {
secret.StringData[CertFileSecretKey] = string(options.CertFile)
secret.StringData[KeyFileSecretKey] = string(options.KeyFile)
}
if keypair != nil && len(hostKey) != 0 {
secret.StringData[PrivateKeySecretKey] = string(keypair.PrivateKey)
secret.StringData[PublicKeySecretKey] = string(keypair.PublicKey)
secret.StringData[KnownHostsSecretKey] = string(hostKey)
@@ -128,29 +184,6 @@ func buildSecret(keypair *ssh.KeyPair, hostKey, caFile, certFile, keyFile []byte
return
}
func loadKeyPair(path string, password string) (*ssh.KeyPair, error) {
b, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to open private key file: %w", err)
}
var ppk cryptssh.Signer
if password != "" {
ppk, err = cryptssh.ParsePrivateKeyWithPassphrase(b, []byte(password))
} else {
ppk, err = cryptssh.ParsePrivateKey(b)
}
if err != nil {
return nil, err
}
return &ssh.KeyPair{
PublicKey: cryptssh.MarshalAuthorizedKey(ppk.PublicKey()),
PrivateKey: b,
}, nil
}
func generateKeyPair(options Options) (*ssh.KeyPair, error) {
var keyGen ssh.KeyPairGenerator
switch options.PrivateKeyAlgorithm {
@@ -170,14 +203,14 @@ func generateKeyPair(options Options) (*ssh.KeyPair, error) {
return pair, nil
}
func scanHostKey(host string) ([]byte, error) {
func ScanHostKey(host string) ([]byte, error) {
if _, _, err := net.SplitHostPort(host); err != nil {
// Assume we are dealing with a hostname without a port,
// append the default SSH port as this is required for
// host key scanning to work.
host = fmt.Sprintf("%s:%d", host, defaultSSHPort)
}
hostKey, err := ssh.ScanHostKey(host, 30*time.Second)
hostKey, err := ssh.ScanHostKey(host, 30*time.Second, []string{}, false)
if err != nil {
return nil, fmt.Errorf("SSH key scan for host %s failed, error: %w", host, err)
}
@@ -189,3 +222,19 @@ func resourceToString(data []byte) string {
data = bytes.Replace(data, []byte("status: {}\n"), []byte(""), 1)
return string(data)
}
func generateDockerConfigJson(url, username, password string) ([]byte, error) {
cred := fmt.Sprintf("%s:%s", username, password)
auth := base64.StdEncoding.EncodeToString([]byte(cred))
cfg := DockerConfigJSON{
Auths: map[string]DockerConfigEntry{
url: {
Username: username,
Password: password,
Auth: auth,
},
},
}
return json.Marshal(cfg)
}

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*
@@ -47,7 +48,7 @@ func Test_passwordLoadKeyPair(t *testing.T) {
pk, _ := os.ReadFile(tt.privateKeyPath)
ppk, _ := os.ReadFile(tt.publicKeyPath)
got, err := loadKeyPair(tt.privateKeyPath, tt.password)
got, err := LoadKeyPair(pk, tt.password)
if err != nil {
t.Errorf("loadKeyPair() error = %v", err)
return
@@ -66,24 +67,13 @@ func Test_passwordLoadKeyPair(t *testing.T) {
func Test_PasswordlessLoadKeyPair(t *testing.T) {
for algo, privateKey := range testdata.PEMBytes {
t.Run(algo, func(t *testing.T) {
f, err := os.CreateTemp("", "test-private-key-")
if err != nil {
t.Fatalf("unable to create temporary file. err: %s", err)
}
defer os.Remove(f.Name())
if _, err = f.Write(privateKey); err != nil {
t.Fatalf("unable to write private key to file. err: %s", err)
}
got, err := loadKeyPair(f.Name(), "")
got, err := LoadKeyPair(privateKey, "")
if err != nil {
t.Errorf("loadKeyPair() error = %v", err)
return
}
pk, _ := os.ReadFile(f.Name())
if !reflect.DeepEqual(got.PrivateKey, pk) {
if !reflect.DeepEqual(got.PrivateKey, privateKey) {
t.Errorf("PrivateKey %s != %s", got.PrivateKey, string(privateKey))
}

View File

@@ -32,20 +32,18 @@ type Options struct {
Secret string
TargetPath string
ManifestFile string
GitImplementation string
RecurseSubmodules bool
}
func MakeDefaultOptions() Options {
return Options{
Interval: 1 * time.Minute,
URL: "",
Name: "flux-system",
Namespace: "flux-system",
Branch: "main",
Secret: "flux-system",
ManifestFile: "gotk-sync.yaml",
TargetPath: "",
GitImplementation: "",
Interval: 1 * time.Minute,
URL: "",
Name: "flux-system",
Namespace: "flux-system",
Branch: "main",
Secret: "flux-system",
ManifestFile: "gotk-sync.yaml",
TargetPath: "",
}
}

View File

@@ -26,11 +26,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
"github.com/fluxcd/flux2/pkg/manifestgen"
"github.com/fluxcd/flux2/v2/pkg/manifestgen"
)
func Generate(options Options) (*manifestgen.Manifest, error) {
@@ -67,7 +67,6 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
SecretRef: &meta.LocalObjectReference{
Name: options.Secret,
},
GitImplementation: options.GitImplementation,
RecurseSubmodules: options.RecurseSubmodules,
},
}

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*
@@ -23,8 +24,8 @@ import (
"strings"
"testing"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
)
func TestGenerate(t *testing.T) {

38
pkg/manifestgen/tmpdir.go Normal file
View File

@@ -0,0 +1,38 @@
/*
Copyright 2022 The Flux 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.
*/
package manifestgen
import (
"fmt"
"os"
"path/filepath"
)
// MkdirTempAbs creates a tmp dir and returns the absolute path to the dir.
// This is required since certain OSes like MacOS create temporary files in
// e.g. `/private/var`, to which `/var` is a symlink.
func MkdirTempAbs(dir, pattern string) (string, error) {
tmpDir, err := os.MkdirTemp(dir, pattern)
if err != nil {
return "", err
}
tmpDir, err = filepath.EvalSymlinks(tmpDir)
if err != nil {
return "", fmt.Errorf("error evaluating symlink: %w", err)
}
return tmpDir, nil
}