forked from siderolabs/talos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
apply-config.go
143 lines (120 loc) · 4.45 KB
/
apply-config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package talos
import (
"context"
"fmt"
"os"
"strings"
"time"
"github.com/spf13/cobra"
"google.golang.org/protobuf/types/known/durationpb"
"github.com/talos-systems/talos/cmd/talosctl/pkg/talos/helpers"
"github.com/talos-systems/talos/internal/pkg/tui/installer"
machineapi "github.com/talos-systems/talos/pkg/machinery/api/machine"
"github.com/talos-systems/talos/pkg/machinery/client"
"github.com/talos-systems/talos/pkg/machinery/constants"
)
var applyConfigCmdFlags struct {
helpers.Mode
certFingerprints []string
filename string
insecure bool
dryRun bool
configTryTimeout time.Duration
}
// applyConfigCmd represents the applyConfiguration command.
var applyConfigCmd = &cobra.Command{
Use: "apply-config",
Aliases: []string{"apply"},
Short: "Apply a new configuration to a node",
Long: ``,
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
var (
cfgBytes []byte
e error
)
if len(args) > 0 {
if args[0] != "config" && !strings.EqualFold(args[0], "machineconfig") {
cmd.Help() //nolint:errcheck
return fmt.Errorf("unknown positional argument %s", args[0])
} else if cmd.CalledAs() == "apply-config" {
cmd.Help() //nolint:errcheck
return fmt.Errorf("expected no positional arguments")
}
}
if applyConfigCmdFlags.filename != "" {
cfgBytes, e = os.ReadFile(applyConfigCmdFlags.filename)
if e != nil {
return fmt.Errorf("failed to read configuration from %q: %w", applyConfigCmdFlags.filename, e)
}
if len(cfgBytes) < 1 {
return fmt.Errorf("no configuration data read")
}
} else if !applyConfigCmdFlags.Interactive {
return fmt.Errorf("no filename supplied for configuration")
}
withClient := func(f func(context.Context, *client.Client) error) error {
if applyConfigCmdFlags.insecure {
return WithClientMaintenance(applyConfigCmdFlags.certFingerprints, f)
}
return WithClient(f)
}
return withClient(func(ctx context.Context, c *client.Client) error {
if applyConfigCmdFlags.Interactive {
install := installer.NewInstaller()
node := Nodes[0]
if len(Endpoints) > 0 {
return WithClientNoNodes(func(bootstrapCtx context.Context, bootstrapClient *client.Client) error {
opts := []installer.Option{}
opts = append(opts, installer.WithBootstrapNode(bootstrapCtx, bootstrapClient, Endpoints[0]), installer.WithDryRun(applyConfigCmdFlags.dryRun))
conn, err := installer.NewConnection(
ctx,
c,
node,
opts...,
)
if err != nil {
return err
}
return install.Run(conn)
})
}
conn, err := installer.NewConnection(
ctx,
c,
node,
installer.WithDryRun(applyConfigCmdFlags.dryRun),
)
if err != nil {
return err
}
return install.Run(conn)
}
resp, err := c.ApplyConfiguration(ctx, &machineapi.ApplyConfigurationRequest{
Data: cfgBytes,
Mode: applyConfigCmdFlags.Mode.Mode,
OnReboot: applyConfigCmdFlags.OnReboot,
Immediate: applyConfigCmdFlags.Immediate,
DryRun: applyConfigCmdFlags.dryRun,
TryModeTimeout: durationpb.New(applyConfigCmdFlags.configTryTimeout),
})
if err != nil {
return fmt.Errorf("error applying new configuration: %s", err)
}
helpers.PrintApplyResults(resp)
return nil
})
},
}
func init() {
applyConfigCmd.Flags().StringVarP(&applyConfigCmdFlags.filename, "file", "f", "", "the filename of the updated configuration")
applyConfigCmd.Flags().BoolVarP(&applyConfigCmdFlags.insecure, "insecure", "i", false, "apply the config using the insecure (encrypted with no auth) maintenance service")
applyConfigCmd.Flags().BoolVar(&applyConfigCmdFlags.dryRun, "dry-run", false, "check how the config change will be applied in dry-run mode")
applyConfigCmd.Flags().StringSliceVar(&applyConfigCmdFlags.certFingerprints, "cert-fingerprint", nil, "list of server certificate fingeprints to accept (defaults to no check)")
applyConfigCmd.Flags().DurationVar(&applyConfigCmdFlags.configTryTimeout, "timeout", constants.ConfigTryTimeout, "the config will be rolled back after specified timeout (if try mode is selected)")
helpers.AddModeFlags(&applyConfigCmdFlags.Mode, applyConfigCmd)
addCommand(applyConfigCmd)
}