talm

Форк
0
/
init.go 
198 строк · 5.6 Кб
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4

5
package commands
6

7
import (
8
	"fmt"
9
	"os"
10
	"path/filepath"
11
	"strings"
12
	"time"
13

14
	"github.com/aenix-io/talm/pkg/generated"
15
	"github.com/spf13/cobra"
16
	"gopkg.in/yaml.v3"
17

18
	"github.com/siderolabs/talos/cmd/talosctl/cmd/mgmt/gen"
19
	"github.com/siderolabs/talos/pkg/machinery/config"
20
	"github.com/siderolabs/talos/pkg/machinery/config/generate"
21
	"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets"
22
)
23

24
var initCmdFlags struct {
25
	force        bool
26
	preset       string
27
	talosVersion string
28
}
29

30
// initCmd represents the `init` command.
31
var initCmd = &cobra.Command{
32
	Use:   "init",
33
	Short: "Initialize a new project and generate default values",
34
	Long:  ``,
35
	Args:  cobra.NoArgs,
36
	PreRunE: func(cmd *cobra.Command, args []string) error {
37
		if !cmd.Flags().Changed("talos-version") {
38
			initCmdFlags.talosVersion = Config.TemplateOptions.TalosVersion
39
		}
40
		return nil
41
	},
42
	RunE: func(cmd *cobra.Command, args []string) error {
43
		var (
44
			secretsBundle   *secrets.Bundle
45
			versionContract *config.VersionContract
46
			err             error
47
		)
48

49
		if initCmdFlags.talosVersion != "" {
50
			versionContract, err = config.ParseContractFromVersion(initCmdFlags.talosVersion)
51
			if err != nil {
52
				return fmt.Errorf("invalid talos-version: %w", err)
53
			}
54
		}
55

56
		secretsBundle, err = secrets.NewBundle(secrets.NewFixedClock(time.Now()),
57
			versionContract,
58
		)
59
		if err != nil {
60
			return fmt.Errorf("failed to create secrets bundle: %w", err)
61
		}
62
		var genOptions []generate.Option //nolint:prealloc
63
		if !isValidPreset(initCmdFlags.preset) {
64
			return fmt.Errorf("invalid preset: %s. Valid presets are: %s", initCmdFlags.preset, generated.AvailablePresets)
65
		}
66
		if initCmdFlags.talosVersion != "" {
67
			var versionContract *config.VersionContract
68

69
			versionContract, err = config.ParseContractFromVersion(initCmdFlags.talosVersion)
70
			if err != nil {
71
				return fmt.Errorf("invalid talos-version: %w", err)
72
			}
73

74
			genOptions = append(genOptions, generate.WithVersionContract(versionContract))
75
		}
76
		genOptions = append(genOptions, generate.WithSecretsBundle(secretsBundle))
77

78
		err = writeSecretsBundleToFile(secretsBundle)
79
		if err != nil {
80
			return err
81
		}
82

83
		// Clalculate cluster name from directory
84
		absolutePath, err := filepath.Abs(Config.RootDir)
85
		if err != nil {
86
			return err
87
		}
88
		clusterName := filepath.Base(absolutePath)
89

90
		configBundle, err := gen.GenerateConfigBundle(genOptions, clusterName, "https://192.168.0.1:6443", "", []string{}, []string{}, []string{})
91
		configBundle.TalosConfig().Contexts[clusterName].Endpoints = []string{"127.0.0.1"}
92
		if err != nil {
93
			return err
94
		}
95

96
		data, err := yaml.Marshal(configBundle.TalosConfig())
97
		if err != nil {
98
			return fmt.Errorf("failed to marshal config: %+v", err)
99
		}
100

101
		talosconfigFile := filepath.Join(Config.RootDir, "talosconfig")
102
		if err = writeToDestination(data, talosconfigFile, 0o644); err != nil {
103
			return err
104
		}
105

106
		for path, content := range generated.PresetFiles {
107
			parts := strings.SplitN(path, "/", 2)
108
			chartName := parts[0]
109
			// Write preset files
110
			if chartName == initCmdFlags.preset {
111
				file := filepath.Join(Config.RootDir, filepath.Join(parts[1:]...))
112
				if parts[len(parts)-1] == "Chart.yaml" {
113
					writeToDestination([]byte(fmt.Sprintf(content, clusterName, Config.InitOptions.Version)), file, 0o644)
114
				} else {
115
					err = writeToDestination([]byte(content), file, 0o644)
116
				}
117
				if err != nil {
118
					return err
119
				}
120
			}
121
			// Write library chart
122
			if chartName == "talm" {
123
				file := filepath.Join(Config.RootDir, filepath.Join("charts", path))
124
				if parts[len(parts)-1] == "Chart.yaml" {
125
					writeToDestination([]byte(fmt.Sprintf(content, "talm", Config.InitOptions.Version)), file, 0o644)
126
				} else {
127
					err = writeToDestination([]byte(content), file, 0o644)
128
				}
129
				if err != nil {
130
					return err
131
				}
132
			}
133
		}
134

135
		return nil
136

137
	},
138
}
139

140
func writeSecretsBundleToFile(bundle *secrets.Bundle) error {
141
	bundleBytes, err := yaml.Marshal(bundle)
142
	if err != nil {
143
		return err
144
	}
145

146
	secretsFile := filepath.Join(Config.RootDir, "secrets.yaml")
147
	if err = validateFileExists(secretsFile); err != nil {
148
		return err
149
	}
150

151
	return writeToDestination(bundleBytes, secretsFile, 0o644)
152
}
153

154
func init() {
155
	initCmd.Flags().StringVar(&initCmdFlags.talosVersion, "talos-version", "", "the desired Talos version to generate config for (backwards compatibility, e.g. v0.8)")
156
	initCmd.Flags().StringVarP(&initCmdFlags.preset, "preset", "p", "generic", "specify preset to generate files")
157
	initCmd.Flags().BoolVar(&initCmdFlags.force, "force", false, "will overwrite existing files")
158

159
	addCommand(initCmd)
160
}
161

162
func isValidPreset(preset string) bool {
163
	for _, validPreset := range generated.AvailablePresets {
164
		if preset == validPreset {
165
			return true
166
		}
167
	}
168
	return false
169
}
170

171
func validateFileExists(file string) error {
172
	if !initCmdFlags.force {
173
		if _, err := os.Stat(file); err == nil {
174
			return fmt.Errorf("file %q already exists, use --force to overwrite", file)
175
		}
176
	}
177

178
	return nil
179
}
180

181
func writeToDestination(data []byte, destination string, permissions os.FileMode) error {
182
	if err := validateFileExists(destination); err != nil {
183
		return err
184
	}
185

186
	parentDir := filepath.Dir(destination)
187

188
	// Create dir path, ignoring "already exists" messages
189
	if err := os.MkdirAll(parentDir, os.ModePerm); err != nil {
190
		return fmt.Errorf("failed to create output dir: %w", err)
191
	}
192

193
	err := os.WriteFile(destination, data, permissions)
194

195
	fmt.Fprintf(os.Stderr, "Created %s\n", destination)
196

197
	return err
198
}
199

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.