mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-10-01 01:36:09 -04:00
AB#2033 User-friendly wrap and reword errors
fix: readOrGenerated function signature
This commit is contained in:
parent
9441e46e4b
commit
1e11188dac
@ -1,6 +1,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/internal/config"
|
||||
"github.com/edgelesssys/constellation/internal/constants"
|
||||
@ -50,7 +52,7 @@ func configGenerate(cmd *cobra.Command, fileHandler file.Handler, provider cloud
|
||||
if flags.file == "-" {
|
||||
content, err := encoder.NewEncoder(conf).Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("encoding config content: %w", err)
|
||||
}
|
||||
_, err = cmd.OutOrStdout().Write(content)
|
||||
return err
|
||||
@ -62,7 +64,7 @@ func configGenerate(cmd *cobra.Command, fileHandler file.Handler, provider cloud
|
||||
func parseGenerateFlags(cmd *cobra.Command) (generateFlags, error) {
|
||||
file, err := cmd.Flags().GetString("file")
|
||||
if err != nil {
|
||||
return generateFlags{}, err
|
||||
return generateFlags{}, fmt.Errorf("parsing config generate flags: %w", err)
|
||||
}
|
||||
return generateFlags{
|
||||
file: file,
|
||||
|
@ -70,7 +70,7 @@ func create(cmd *cobra.Command, creator cloudCreator, fileHandler file.Handler,
|
||||
|
||||
config, err := readConfig(cmd.OutOrStdout(), fileHandler, flags.configPath, provider)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("reading and validating config: %w", err)
|
||||
}
|
||||
|
||||
if !flags.yes {
|
||||
@ -105,7 +105,7 @@ func create(cmd *cobra.Command, creator cloudCreator, fileHandler file.Handler,
|
||||
func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (createFlags, error) {
|
||||
controllerCount, err := cmd.Flags().GetInt("control-plane-nodes")
|
||||
if err != nil {
|
||||
return createFlags{}, err
|
||||
return createFlags{}, fmt.Errorf("parsing number of control-plane nodes: %w", err)
|
||||
}
|
||||
if controllerCount < constants.MinControllerCount {
|
||||
return createFlags{}, fmt.Errorf("number of control-plane nodes must be at least %d", constants.MinControllerCount)
|
||||
@ -113,7 +113,7 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
|
||||
|
||||
workerCount, err := cmd.Flags().GetInt("worker-nodes")
|
||||
if err != nil {
|
||||
return createFlags{}, err
|
||||
return createFlags{}, fmt.Errorf("parsing number of worker nodes: %w", err)
|
||||
}
|
||||
if workerCount < constants.MinWorkerCount {
|
||||
return createFlags{}, fmt.Errorf("number of worker nodes must be at least %d", constants.MinWorkerCount)
|
||||
@ -121,7 +121,7 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
|
||||
|
||||
insType, err := cmd.Flags().GetString("instance-type")
|
||||
if err != nil {
|
||||
return createFlags{}, err
|
||||
return createFlags{}, fmt.Errorf("parsing instance type argument: %w", err)
|
||||
}
|
||||
if insType == "" {
|
||||
insType = defaultInstanceType(provider)
|
||||
@ -132,7 +132,7 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
|
||||
|
||||
name, err := cmd.Flags().GetString("name")
|
||||
if err != nil {
|
||||
return createFlags{}, err
|
||||
return createFlags{}, fmt.Errorf("parsing name argument: %w", err)
|
||||
}
|
||||
if len(name) > constants.ConstellationNameLength {
|
||||
return createFlags{}, fmt.Errorf(
|
||||
@ -143,12 +143,12 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
|
||||
|
||||
yes, err := cmd.Flags().GetBool("yes")
|
||||
if err != nil {
|
||||
return createFlags{}, err
|
||||
return createFlags{}, fmt.Errorf("%w; Set '-yes' without a value to automatically confirm", err)
|
||||
}
|
||||
|
||||
configPath, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return createFlags{}, err
|
||||
return createFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
||||
}
|
||||
|
||||
return createFlags{
|
||||
@ -192,7 +192,7 @@ func checkDirClean(fileHandler file.Handler) error {
|
||||
return fmt.Errorf("file '%s' already exists in working directory, run 'constellation terminate' before creating a new one", constants.AdminConfFilename)
|
||||
}
|
||||
if _, err := fileHandler.Stat(constants.MasterSecretFilename); !errors.Is(err, fs.ErrNotExist) {
|
||||
return fmt.Errorf("file '%s' already exists in working directory, clean it up first", constants.MasterSecretFilename)
|
||||
return fmt.Errorf("file '%s' already exists in working directory. Constellation won't overwrite previous master secrets. Move it somewhere or delete it before creating a new cluster", constants.MasterSecretFilename)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -80,16 +80,16 @@ func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, ser
|
||||
var stat state.ConstellationState
|
||||
err = fileHandler.ReadJSON(constants.StateFilename, &stat)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return fmt.Errorf("nothing to initialize: %w", err)
|
||||
return fmt.Errorf("missing Constellation state file: %w. Please do 'constellation create ...' before 'constellation init'", err)
|
||||
} else if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("loading Constellation state file: %w", err)
|
||||
}
|
||||
|
||||
provider := cloudprovider.FromString(stat.CloudProvider)
|
||||
|
||||
config, err := readConfig(cmd.OutOrStdout(), fileHandler, flags.configPath, provider)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("reading and validating config: %w", err)
|
||||
}
|
||||
|
||||
var sshUsers []*ssh.UserKey
|
||||
@ -166,7 +166,7 @@ func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, ser
|
||||
|
||||
if flags.autoconfigureWG {
|
||||
if err := vpnHandler.Apply(vpnConfig); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("configuring WireGuard: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ type activationResult struct {
|
||||
func writeWGQuickFile(fileHandler file.Handler, vpnHandler vpnHandler, vpnConfig *wgquick.Config) error {
|
||||
data, err := vpnHandler.Marshal(vpnConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("marshalling VPN config: %w", err)
|
||||
}
|
||||
return fileHandler.Write(constants.WGQuickConfigFilename, data, file.OptNone)
|
||||
}
|
||||
@ -285,7 +285,7 @@ func writeRow(wr io.Writer, col1 string, col2 string) {
|
||||
func evalFlagArgs(cmd *cobra.Command, fileHandler file.Handler) (initFlags, error) {
|
||||
userPrivKeyPath, err := cmd.Flags().GetString("privatekey")
|
||||
if err != nil {
|
||||
return initFlags{}, err
|
||||
return initFlags{}, fmt.Errorf("parsing privatekey path argument: %w", err)
|
||||
}
|
||||
userPrivKey, userPubKey, err := readOrGenerateVPNKey(fileHandler, userPrivKeyPath)
|
||||
if err != nil {
|
||||
@ -293,23 +293,23 @@ func evalFlagArgs(cmd *cobra.Command, fileHandler file.Handler) (initFlags, erro
|
||||
}
|
||||
autoconfigureWG, err := cmd.Flags().GetBool("wg-autoconfig")
|
||||
if err != nil {
|
||||
return initFlags{}, err
|
||||
return initFlags{}, fmt.Errorf("parsing wg-autoconfig argument: %w", err)
|
||||
}
|
||||
masterSecretPath, err := cmd.Flags().GetString("master-secret")
|
||||
if err != nil {
|
||||
return initFlags{}, err
|
||||
return initFlags{}, fmt.Errorf("parsing master-secret path argument: %w", err)
|
||||
}
|
||||
masterSecret, err := readOrGeneratedMasterSecret(cmd.OutOrStdout(), fileHandler, masterSecretPath)
|
||||
masterSecret, err := readOrGenerateMasterSecret(cmd.OutOrStdout(), fileHandler, masterSecretPath)
|
||||
if err != nil {
|
||||
return initFlags{}, err
|
||||
return initFlags{}, fmt.Errorf("parsing or generating master mastersecret from file %s: %w", masterSecretPath, err)
|
||||
}
|
||||
autoscale, err := cmd.Flags().GetBool("autoscale")
|
||||
if err != nil {
|
||||
return initFlags{}, err
|
||||
return initFlags{}, fmt.Errorf("parsing autoscale argument: %w", err)
|
||||
}
|
||||
configPath, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return initFlags{}, err
|
||||
return initFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
||||
}
|
||||
|
||||
return initFlags{
|
||||
@ -337,17 +337,17 @@ func readOrGenerateVPNKey(fileHandler file.Handler, privKeyPath string) (privKey
|
||||
if privKeyPath == "" {
|
||||
privKeyParsed, err = wgtypes.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, fmt.Errorf("generating WireGuard private key: %w", err)
|
||||
}
|
||||
privKey = []byte(privKeyParsed.String())
|
||||
} else {
|
||||
privKey, err = fileHandler.Read(privKeyPath)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, fmt.Errorf("reading the VPN private key: %w", err)
|
||||
}
|
||||
privKeyParsed, err = wgtypes.ParseKey(string(privKey))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, fmt.Errorf("parsing the WireGuard private key: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -367,8 +367,8 @@ func ipsToEndpoints(ips []string, port string) []string {
|
||||
return endpoints
|
||||
}
|
||||
|
||||
// readOrGeneratedMasterSecret reads a base64 encoded master secret from file or generates a new 32 byte secret.
|
||||
func readOrGeneratedMasterSecret(w io.Writer, fileHandler file.Handler, filename string) ([]byte, error) {
|
||||
// readOrGenerateMasterSecret reads a base64 encoded master secret from file or generates a new 32 byte secret.
|
||||
func readOrGenerateMasterSecret(writer io.Writer, fileHandler file.Handler, filename string) ([]byte, error) {
|
||||
if filename != "" {
|
||||
// Try to read the base64 secret from file
|
||||
encodedSecret, err := fileHandler.Read(filename)
|
||||
@ -393,7 +393,7 @@ func readOrGeneratedMasterSecret(w io.Writer, fileHandler file.Handler, filename
|
||||
if err := fileHandler.Write(constants.MasterSecretFilename, []byte(base64.StdEncoding.EncodeToString(masterSecret)), file.OptNone); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Fprintf(w, "Your Constellation master secret was successfully written to ./%s\n", constants.MasterSecretFilename)
|
||||
fmt.Fprintf(writer, "Your Constellation master secret was successfully written to ./%s\n", constants.MasterSecretFilename)
|
||||
return masterSecret, nil
|
||||
}
|
||||
|
||||
|
@ -414,7 +414,7 @@ func TestReadOrGenerateVPNKey(t *testing.T) {
|
||||
assert.NotEmpty(pubK)
|
||||
}
|
||||
|
||||
func TestReadOrGeneratedMasterSecret(t *testing.T) {
|
||||
func TestReadOrGenerateMasterSecret(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
filename string
|
||||
filecontent string
|
||||
@ -484,7 +484,7 @@ func TestReadOrGeneratedMasterSecret(t *testing.T) {
|
||||
}
|
||||
|
||||
var out bytes.Buffer
|
||||
secret, err := readOrGeneratedMasterSecret(&out, fileHandler, tc.filename)
|
||||
secret, err := readOrGenerateMasterSecret(&out, fileHandler, tc.filename)
|
||||
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
|
@ -24,7 +24,7 @@ func readConfig(out io.Writer, fileHandler file.Handler, name string, provider c
|
||||
func validateConfig(out io.Writer, cnf *config.Config, provider cloudprovider.Provider) error {
|
||||
msgs, err := cnf.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("performing config validation: %w", err)
|
||||
}
|
||||
|
||||
if len(msgs) > 0 {
|
||||
@ -32,7 +32,7 @@ func validateConfig(out io.Writer, cnf *config.Config, provider cloudprovider.Pr
|
||||
for _, m := range msgs {
|
||||
fmt.Fprintln(out, "\t"+m)
|
||||
}
|
||||
return errors.New("invalid configuration")
|
||||
return errors.New("invalid configuration. Fix the invalid entries or generate a new configuration using `constellation config generate`")
|
||||
}
|
||||
|
||||
if provider != cloudprovider.Unknown && !cnf.HasProvider(provider) {
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@ -60,7 +61,7 @@ func recover(ctx context.Context, cmd *cobra.Command, fileHandler file.Handler,
|
||||
|
||||
config, err := readConfig(cmd.OutOrStdout(), fileHandler, flags.configPath, provider)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("reading and validating config: %w", err)
|
||||
}
|
||||
|
||||
validators, err := cloudcmd.NewValidators(provider, config)
|
||||
@ -89,16 +90,16 @@ func recover(ctx context.Context, cmd *cobra.Command, fileHandler file.Handler,
|
||||
func parseRecoverFlags(cmd *cobra.Command, fileHandler file.Handler) (recoverFlags, error) {
|
||||
endpoint, err := cmd.Flags().GetString("endpoint")
|
||||
if err != nil {
|
||||
return recoverFlags{}, err
|
||||
return recoverFlags{}, fmt.Errorf("parsing endpoint argument: %w", err)
|
||||
}
|
||||
endpoint, err = validateEndpoint(endpoint, constants.CoordinatorPort)
|
||||
if err != nil {
|
||||
return recoverFlags{}, err
|
||||
return recoverFlags{}, fmt.Errorf("validating endpoint argument: %w", err)
|
||||
}
|
||||
|
||||
diskUUID, err := cmd.Flags().GetString("disk-uuid")
|
||||
if err != nil {
|
||||
return recoverFlags{}, err
|
||||
return recoverFlags{}, fmt.Errorf("parsing disk-uuid argument: %w", err)
|
||||
}
|
||||
if match := diskUUIDRegexp.MatchString(diskUUID); !match {
|
||||
return recoverFlags{}, errors.New("flag '--disk-uuid' isn't a valid LUKS UUID")
|
||||
@ -107,16 +108,16 @@ func parseRecoverFlags(cmd *cobra.Command, fileHandler file.Handler) (recoverFla
|
||||
|
||||
masterSecretPath, err := cmd.Flags().GetString("master-secret")
|
||||
if err != nil {
|
||||
return recoverFlags{}, err
|
||||
return recoverFlags{}, fmt.Errorf("parsing master-secret path argument: %w", err)
|
||||
}
|
||||
masterSecret, err := readMasterSecret(fileHandler, masterSecretPath)
|
||||
if err != nil {
|
||||
return recoverFlags{}, err
|
||||
return recoverFlags{}, fmt.Errorf("reading the master secret from file %s: %w", masterSecretPath, err)
|
||||
}
|
||||
|
||||
configPath, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return recoverFlags{}, err
|
||||
return recoverFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
||||
}
|
||||
|
||||
return recoverFlags{
|
||||
|
@ -38,28 +38,28 @@ func runTerminate(cmd *cobra.Command, args []string) error {
|
||||
func terminate(cmd *cobra.Command, terminator cloudTerminator, fileHandler file.Handler) error {
|
||||
var stat state.ConstellationState
|
||||
if err := fileHandler.ReadJSON(constants.StateFilename, &stat); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("reading Constellation state: %w", err)
|
||||
}
|
||||
|
||||
cmd.Println("Terminating ...")
|
||||
|
||||
if err := terminator.Terminate(cmd.Context(), stat); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("terminating Constellation cluster: %w", err)
|
||||
}
|
||||
|
||||
cmd.Println("Your Constellation cluster was terminated successfully.")
|
||||
|
||||
var retErr error
|
||||
if err := fileHandler.Remove(constants.StateFilename); err != nil {
|
||||
retErr = multierr.Append(err, fmt.Errorf("failed to remove file '%s', please remove manually", constants.StateFilename))
|
||||
retErr = multierr.Append(err, fmt.Errorf("failed to remove file: '%s', please remove it manually", constants.StateFilename))
|
||||
}
|
||||
|
||||
if err := fileHandler.Remove(constants.AdminConfFilename); err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
retErr = multierr.Append(err, fmt.Errorf("failed to remove file '%s', please remove manually", constants.AdminConfFilename))
|
||||
retErr = multierr.Append(err, fmt.Errorf("failed to remove file: '%s', please remove it manually", constants.AdminConfFilename))
|
||||
}
|
||||
|
||||
if err := fileHandler.Remove(constants.WGQuickConfigFilename); err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
retErr = multierr.Append(err, fmt.Errorf("failed to remove file '%s', please remove manually", constants.WGQuickConfigFilename))
|
||||
retErr = multierr.Append(err, fmt.Errorf("failed to remove file: '%s', please remove it manually", constants.WGQuickConfigFilename))
|
||||
}
|
||||
|
||||
return retErr
|
||||
|
@ -51,7 +51,7 @@ func verify(ctx context.Context, cmd *cobra.Command, provider cloudprovider.Prov
|
||||
|
||||
config, err := readConfig(cmd.OutOrStdout(), fileHandler, flags.configPath, provider)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("reading and validating config: %w", err)
|
||||
}
|
||||
|
||||
validators, err := cloudcmd.NewValidators(provider, config)
|
||||
@ -83,28 +83,28 @@ func verify(ctx context.Context, cmd *cobra.Command, provider cloudprovider.Prov
|
||||
func parseVerifyFlags(cmd *cobra.Command) (verifyFlags, error) {
|
||||
ownerID, err := cmd.Flags().GetString("owner-id")
|
||||
if err != nil {
|
||||
return verifyFlags{}, err
|
||||
return verifyFlags{}, fmt.Errorf("parsing owner-id argument: %w", err)
|
||||
}
|
||||
clusterID, err := cmd.Flags().GetString("unique-id")
|
||||
if err != nil {
|
||||
return verifyFlags{}, err
|
||||
return verifyFlags{}, fmt.Errorf("parsing unique-id argument: %w", err)
|
||||
}
|
||||
if ownerID == "" && clusterID == "" {
|
||||
return verifyFlags{}, errors.New("neither owner ID nor unique ID provided to verify the cluster")
|
||||
return verifyFlags{}, errors.New("neither owner-id nor unique-id provided to verify the cluster")
|
||||
}
|
||||
|
||||
endpoint, err := cmd.Flags().GetString("node-endpoint")
|
||||
if err != nil {
|
||||
return verifyFlags{}, err
|
||||
return verifyFlags{}, fmt.Errorf("parsing node-endpoint argument: %w", err)
|
||||
}
|
||||
endpoint, err = validateEndpoint(endpoint, constants.CoordinatorPort)
|
||||
if err != nil {
|
||||
return verifyFlags{}, err
|
||||
return verifyFlags{}, fmt.Errorf("validating endpoint argument: %w", err)
|
||||
}
|
||||
|
||||
configPath, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
return verifyFlags{}, err
|
||||
return verifyFlags{}, fmt.Errorf("parsing config path argument: %w", err)
|
||||
}
|
||||
|
||||
return verifyFlags{
|
||||
|
@ -126,7 +126,7 @@ func (m *Metadata) GetInstance(ctx context.Context, providerID string) (cloudtyp
|
||||
if scaleSetErr == nil {
|
||||
return instance, nil
|
||||
}
|
||||
return cloudtypes.Instance{}, fmt.Errorf("retrieving instance given providerID %v as either single vm or scale set vm: %v; %v", providerID, singleErr, scaleSetErr)
|
||||
return cloudtypes.Instance{}, fmt.Errorf("retrieving instance given providerID %v as either single VM or scale set VM: %v; %v", providerID, singleErr, scaleSetErr)
|
||||
}
|
||||
|
||||
// SignalRole signals the constellation role via cloud provider metadata.
|
||||
|
@ -90,16 +90,18 @@ func (i *osInstaller) extractArchive(archivePath, prefix string, perm fs.FileMod
|
||||
if len(header.Name) == 0 {
|
||||
return errors.New("cannot create dir for empty path")
|
||||
}
|
||||
if err := i.fs.Mkdir(path.Join(prefix, header.Name), fs.FileMode(header.Mode)&perm); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
return fmt.Errorf("creating folder %s: %w", path.Join(prefix, header.Name), err)
|
||||
prefixedPath := path.Join(prefix, header.Name)
|
||||
if err := i.fs.Mkdir(prefixedPath, fs.FileMode(header.Mode)&perm); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
return fmt.Errorf("creating folder %q: %w", prefixedPath, err)
|
||||
}
|
||||
case tar.TypeReg:
|
||||
if len(header.Name) == 0 {
|
||||
return errors.New("cannot create file for empty path")
|
||||
}
|
||||
out, err := i.fs.OpenFile(path.Join(prefix, header.Name), os.O_WRONLY|os.O_CREATE, fs.FileMode(header.Mode))
|
||||
prefixedPath := path.Join(prefix, header.Name)
|
||||
out, err := i.fs.OpenFile(prefixedPath, os.O_WRONLY|os.O_CREATE, fs.FileMode(header.Mode))
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating file %s for writing: %w", path.Join(prefix, header.Name), err)
|
||||
return fmt.Errorf("creating file %q for writing: %w", prefixedPath, err)
|
||||
}
|
||||
defer out.Close()
|
||||
if _, err := io.Copy(out, tarReader); err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user