AB#2064 Feat/config/dev config to config (#139)

Renamed dev-config to config, additionally changed cdbg config to yaml.
This commit is contained in:
Fabian Kammel 2022-05-13 11:56:43 +02:00 committed by GitHub
parent fde7304d78
commit 83857b142c
20 changed files with 175 additions and 189 deletions

View File

@ -14,7 +14,6 @@
#ignore build files #ignore build files
/build /build
admin.conf admin.conf
coordinatorConfig.json
coordinator-* coordinator-*
/image /image

1
.gitignore vendored
View File

@ -16,7 +16,6 @@
build build
admin.conf admin.conf
coordinatorConfig.json
coordinator-* coordinator-*
util/pcr-reader/pcrs/ util/pcr-reader/pcrs/

View File

@ -16,7 +16,7 @@ RUN git clone -b v1.0.20210914 --depth=1 https://git.zx2c4.com/wireguard-tools &
# Setup CLI # Setup CLI
RUN wg genkey | (umask 0077 && tee /privatekey) | wg pubkey > /publickey RUN wg genkey | (umask 0077 && tee /privatekey) | wg pubkey > /publickey
RUN mkdir -p /root/.config/constellation && touch /root/.config/constellation/config.json RUN mkdir -p /root/.config/constellation && touch /root/.config/constellation/constellation-conf.yaml
# Setup AWS config # Setup AWS config
RUN mkdir -p /root/.aws && echo "[default]\nregion = us-east-2" > /root/.aws/config && echo "[default]" >> /root/.aws/credentials RUN mkdir -p /root/.aws && echo "[default]\nregion = us-east-2" > /root/.aws/config && echo "[default]" >> /root/.aws/credentials

193
README.md
View File

@ -95,12 +95,12 @@ go install github.com/edgelesssys/constellation/debugd/cdbg
With `cdbg` installed in your path: With `cdbg` installed in your path:
1. Run `constellation --dev-config /path/to/dev-config create […]` while specifying a cloud-provider image with the debugd already included. See [Configuration](#debugd-configuration) for a dev-config with a custom image and firewall rules to allow incoming connection on the debugd default port 4000. 0. (optional) Run `constellation config generate` to create a new default configuration
2. Run `cdbg deploy --dev-config /path/to/dev-config` 1. Run `constellation create […]` while specifying a cloud-provider image with the debugd already included. See [Configuration](#debugd-configuration) for a config with a custom image and firewall rules to allow incoming connection on the debugd default port 4000.
2. Run `cdbg deploy`
3. Run `constellation init […]` as usual 3. Run `constellation init […]` as usual
### debugd GCP image ### debugd GCP image
For GCP, run the following command to get a list of all constellation images, sorted by their creation date: For GCP, run the following command to get a list of all constellation images, sorted by their creation date:
@ -121,109 +121,92 @@ Choose the newest debugd image and copy the full URI.
You should first locate the newest debugd image for your cloud provider ([GCP](#debugd-gcp-image), [Azure](#debugd-azure-image)). You should first locate the newest debugd image for your cloud provider ([GCP](#debugd-gcp-image), [Azure](#debugd-azure-image)).
This tool uses the dev-config file from `constellation-coordinator` and extends it with more fields. This tool uses the config file from `constellation` and extends it with more fields.
See this example on what the possible settings are and how to setup the constellation cli to use a cloud-provider image and firewall rules with support for debugd: See this example on what the possible settings are and how to setup the constellation cli to use a cloud-provider image and firewall rules with support for debugd:
```json ```yaml
{ cdbg:
"cdbg":{ authorizedKeys:
"authorized_keys":[ - user: my-username
{ pubkey: ssh-rsa AAAAB…LJuM=
"user":"my-username", coordinatorPath: "/path/to/coordinator"
"pubkey":"ssh-rsa AAAAB…LJuM=" systemdUnits:
} - name: some-custom.service
], contents: |-
"coordinator_path":"/path/to/coordinator", [Unit]
"systemd_units":[ Description=…
{ provider:
"name":"some-custom.service", # Add Azure image
"contents":"[Unit]\nDescription=…" azureConfig:
} image: /subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/CONSTELLATION-IMAGES/providers/Microsoft.Compute/galleries/Constellation/images/constellation-coreos/versions/0.0.TIMESTAMP
] networkSecurityGroupInput:
}, ingress:
"provider": { - name: coordinator
"gcpConfig": { description: Coordinator default port
"image": "projects/constellation-images/global/images/constellation-coreos-debugd-TIMESTAMP", protocol: tcp
"firewallInput": { iprange: 0.0.0.0/0
"ingress": [ fromport: 9000
{ toport: 0
"name": "coordinator", - name: wireguard
"description": "Coordinator default port", description: WireGuard default port
"protocol": "tcp", protocol: udp
"fromport": 9000 iprange: 0.0.0.0/0
}, fromport: 51820
{ toport: 0
"name": "wireguard", - name: ssh
"description": "WireGuard default port", description: SSH
"protocol": "udp", protocol: tcp
"fromport": 51820 iprange: 0.0.0.0/0
}, fromport: 22
{ toport: 0
"name": "ssh", - name: nodeport
"description": "SSH", description: NodePort
"protocol": "tcp", protocol: tcp
"fromport": 22 iprange: 0.0.0.0/0
}, fromport: 30000
{ toport: 32767
"name": "nodeport", # Add debug port
"description": "NodePort", - name: debugd
"protocol": "tcp", description: debugd default port
"fromport": 30000, protocol: tcp
"toport": 32767 iprange: 0.0.0.0/0
}, fromport: 4000
{ toport: 0
"name": "debugd", gcpConfig:
"description": "debugd default port", # Add GCP image
"protocol": "tcp", image: projects/constellation-images/global/images/constellation-coreos-debugd-TIMESTAMP
"fromport": 4000 firewallInput:
} ingress:
] - name: coordinator
} description: Coordinator default port
}, protocol: tcp
"azureConfig": { iprange: ""
"image": "/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/CONSTELLATION-IMAGES/providers/Microsoft.Compute/galleries/Constellation/images/constellation-coreos-debugd/versions/0.0.TIMESTAMP", fromport: 9000
"networkSecurityGroupInput": { toport: 0
"ingress": [ - name: wireguard
{ description: WireGuard default port
"name": "coordinator", protocol: udp
"description": "Coordinator default port", iprange: ""
"protocol": "tcp", fromport: 51820
"iprange": "0.0.0.0/0", toport: 0
"fromport": 9000 - name: ssh
}, description: SSH
{ protocol: tcp
"name": "wireguard", iprange: ""
"description": "WireGuard default port", fromport: 22
"protocol": "udp", toport: 0
"iprange": "0.0.0.0/0", - name: nodeport
"fromport": 51820 description: NodePort
}, protocol: tcp
{ iprange: ""
"name": "ssh", fromport: 30000
"description": "SSH", toport: 32767
"protocol": "tcp", # Add debugd port
"iprange": "0.0.0.0/0", - name: debugd
"fromport": 22 description: debugd default port
}, protocol: tcp
{ iprange: ""
"name": "nodeport", fromport: 4000
"description": "NodePort", toport: 0
"protocol": "tcp",
"iprange": "0.0.0.0/0",
"fromport": 30000,
"toport": 32767
},
{
"name": "debugd",
"description": "debugd default port",
"protocol": "tcp",
"iprange": "0.0.0.0/0",
"fromport": 4000
}
]
}
}
}
}
``` ```
# Local image testing with QEMU # Local image testing with QEMU

View File

@ -68,7 +68,7 @@ func create(cmd *cobra.Command, creator cloudCreator, fileHandler file.Handler,
return err return err
} }
config, err := config.FromFile(fileHandler, flags.devConfigPath) config, err := config.FromFile(fileHandler, flags.configPath)
if err != nil { if err != nil {
return err return err
} }
@ -146,7 +146,7 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
return createFlags{}, err return createFlags{}, err
} }
devConfigPath, err := cmd.Flags().GetString("dev-config") configPath, err := cmd.Flags().GetString("config")
if err != nil { if err != nil {
return createFlags{}, err return createFlags{}, err
} }
@ -156,7 +156,7 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
workerCount: workerCount, workerCount: workerCount,
insType: insType, insType: insType,
name: name, name: name,
devConfigPath: devConfigPath, configPath: configPath,
yes: yes, yes: yes,
}, nil }, nil
} }
@ -167,7 +167,7 @@ type createFlags struct {
workerCount int workerCount int
insType string insType string
name string name string
devConfigPath string configPath string
yes bool yes bool
} }

View File

@ -57,7 +57,7 @@ func TestCreate(t *testing.T) {
controllerCountFlag *int controllerCountFlag *int
workerCountFlag *int workerCountFlag *int
insTypeFlag string insTypeFlag string
devConfigFlag string configFlag string
nameFlag string nameFlag string
stdin string stdin string
wantErr bool wantErr bool
@ -187,14 +187,14 @@ func TestCreate(t *testing.T) {
yesFlag: true, yesFlag: true,
wantErr: true, wantErr: true,
}, },
"dev config does not exist": { "config does not exist": {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() }, setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
creator: &stubCloudCreator{}, creator: &stubCloudCreator{},
provider: cloudprovider.GCP, provider: cloudprovider.GCP,
controllerCountFlag: intPtr(1), controllerCountFlag: intPtr(1),
workerCountFlag: intPtr(1), workerCountFlag: intPtr(1),
yesFlag: true, yesFlag: true,
devConfigFlag: "dev-config.json", configFlag: constants.ConfigFilename,
wantErr: true, wantErr: true,
}, },
"create error": { "create error": {
@ -229,15 +229,15 @@ func TestCreate(t *testing.T) {
cmd.SetOut(&bytes.Buffer{}) cmd.SetOut(&bytes.Buffer{})
cmd.SetErr(&bytes.Buffer{}) cmd.SetErr(&bytes.Buffer{})
cmd.SetIn(bytes.NewBufferString(tc.stdin)) cmd.SetIn(bytes.NewBufferString(tc.stdin))
cmd.Flags().String("dev-config", "", "") // register persisten flag manually cmd.Flags().String("config", "", "") // register persisten flag manually
if tc.yesFlag { if tc.yesFlag {
require.NoError(cmd.Flags().Set("yes", "true")) require.NoError(cmd.Flags().Set("yes", "true"))
} }
if tc.nameFlag != "" { if tc.nameFlag != "" {
require.NoError(cmd.Flags().Set("name", tc.nameFlag)) require.NoError(cmd.Flags().Set("name", tc.nameFlag))
} }
if tc.devConfigFlag != "" { if tc.configFlag != "" {
require.NoError(cmd.Flags().Set("dev-config", tc.devConfigFlag)) require.NoError(cmd.Flags().Set("config", tc.configFlag))
} }
if tc.controllerCountFlag != nil { if tc.controllerCountFlag != nil {
require.NoError(cmd.Flags().Set("control-plane-nodes", strconv.Itoa(*tc.controllerCountFlag))) require.NoError(cmd.Flags().Set("control-plane-nodes", strconv.Itoa(*tc.controllerCountFlag)))

View File

@ -72,7 +72,7 @@ func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, ser
return err return err
} }
config, err := config.FromFile(fileHandler, flags.devConfigPath) config, err := config.FromFile(fileHandler, flags.configPath)
if err != nil { if err != nil {
return err return err
} }
@ -290,13 +290,13 @@ func evalFlagArgs(cmd *cobra.Command, fileHandler file.Handler) (initFlags, erro
if err != nil { if err != nil {
return initFlags{}, err return initFlags{}, err
} }
devConfigPath, err := cmd.Flags().GetString("dev-config") configPath, err := cmd.Flags().GetString("config")
if err != nil { if err != nil {
return initFlags{}, err return initFlags{}, err
} }
return initFlags{ return initFlags{
devConfigPath: devConfigPath, configPath: configPath,
userPrivKey: userPrivKey, userPrivKey: userPrivKey,
userPubKey: userPubKey, userPubKey: userPubKey,
autoconfigureWG: autoconfigureWG, autoconfigureWG: autoconfigureWG,
@ -307,7 +307,7 @@ func evalFlagArgs(cmd *cobra.Command, fileHandler file.Handler) (initFlags, erro
// initFlags are the resulting values of flag preprocessing. // initFlags are the resulting values of flag preprocessing.
type initFlags struct { type initFlags struct {
devConfigPath string configPath string
userPrivKey []byte userPrivKey []byte
userPubKey []byte userPubKey []byte
masterSecret []byte masterSecret []byte

View File

@ -296,7 +296,7 @@ func TestInitialize(t *testing.T) {
cmd.SetOut(&out) cmd.SetOut(&out)
var errOut bytes.Buffer var errOut bytes.Buffer
cmd.SetErr(&errOut) cmd.SetErr(&errOut)
cmd.Flags().String("dev-config", "", "") // register persisten flag manually cmd.Flags().String("config", "", "") // register persisten flag manually
fs := afero.NewMemMapFs() fs := afero.NewMemMapFs()
fileHandler := file.NewHandler(fs) fileHandler := file.NewHandler(fs)
require.NoError(fileHandler.WriteJSON(constants.StateFilename, tc.existingState, file.OptNone)) require.NoError(fileHandler.WriteJSON(constants.StateFilename, tc.existingState, file.OptNone))
@ -603,7 +603,7 @@ func TestAutoscaleFlag(t *testing.T) {
cmd.SetOut(&out) cmd.SetOut(&out)
var errOut bytes.Buffer var errOut bytes.Buffer
cmd.SetErr(&errOut) cmd.SetErr(&errOut)
cmd.Flags().String("dev-config", "", "") // register persisten flag manually cmd.Flags().String("config", "", "") // register persisten flag manually
fs := afero.NewMemMapFs() fs := afero.NewMemMapFs()
fileHandler := file.NewHandler(fs) fileHandler := file.NewHandler(fs)
vpnHandler := stubVPNHandler{} vpnHandler := stubVPNHandler{}

View File

@ -51,7 +51,7 @@ func recover(ctx context.Context, cmd *cobra.Command, fileHandler file.Handler,
return err return err
} }
config, err := config.FromFile(fileHandler, flags.devConfigPath) config, err := config.FromFile(fileHandler, flags.configPath)
if err != nil { if err != nil {
return err return err
} }
@ -112,24 +112,24 @@ func parseRecoverFlags(cmd *cobra.Command, fileHandler file.Handler) (recoverFla
return recoverFlags{}, err return recoverFlags{}, err
} }
devConfigPath, err := cmd.Flags().GetString("dev-config") configPath, err := cmd.Flags().GetString("config")
if err != nil { if err != nil {
return recoverFlags{}, err return recoverFlags{}, err
} }
return recoverFlags{ return recoverFlags{
endpoint: endpoint, endpoint: endpoint,
diskUUID: diskUUID, diskUUID: diskUUID,
masterSecret: masterSecret, masterSecret: masterSecret,
devConfigPath: devConfigPath, configPath: configPath,
}, nil }, nil
} }
type recoverFlags struct { type recoverFlags struct {
endpoint string endpoint string
diskUUID string diskUUID string
masterSecret []byte masterSecret []byte
devConfigPath string configPath string
} }
// readMasterSecret reads a base64 encoded master secret from file. // readMasterSecret reads a base64 encoded master secret from file.

View File

@ -50,7 +50,7 @@ func TestRecover(t *testing.T) {
endpointFlag string endpointFlag string
diskUUIDFlag string diskUUIDFlag string
masterSecretFlag string masterSecretFlag string
devConfigFlag string configFlag string
stateless bool stateless bool
wantErr bool wantErr bool
wantKey []byte wantKey []byte
@ -95,16 +95,16 @@ func TestRecover(t *testing.T) {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() }, setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
wantErr: true, wantErr: true,
}, },
"missing dev-config": { "missing config": {
setupFs: func(require *require.Assertions) afero.Fs { setupFs: func(require *require.Assertions) afero.Fs {
fs := afero.NewMemMapFs() fs := afero.NewMemMapFs()
require.NoError(afero.WriteFile(fs, "constellation-mastersecret.base64", []byte("Y29uc3RlbGxhdGlvbi1tYXN0ZXItc2VjcmV0LWxlbmc="), 0o777)) require.NoError(afero.WriteFile(fs, "constellation-mastersecret.base64", []byte("Y29uc3RlbGxhdGlvbi1tYXN0ZXItc2VjcmV0LWxlbmc="), 0o777))
return fs return fs
}, },
endpointFlag: "192.0.2.1", endpointFlag: "192.0.2.1",
diskUUIDFlag: "00000000-0000-0000-0000-000000000000", diskUUIDFlag: "00000000-0000-0000-0000-000000000000",
devConfigFlag: "nonexistent-dev-config", configFlag: "nonexistent-config",
wantErr: true, wantErr: true,
}, },
"missing state": { "missing state": {
setupFs: func(require *require.Assertions) afero.Fs { setupFs: func(require *require.Assertions) afero.Fs {
@ -161,7 +161,7 @@ func TestRecover(t *testing.T) {
require := require.New(t) require := require.New(t)
cmd := newRecoverCmd() cmd := newRecoverCmd()
cmd.Flags().String("dev-config", "", "") // register persisten flag manually cmd.Flags().String("config", "", "") // register persisten flag manually
out := &bytes.Buffer{} out := &bytes.Buffer{}
cmd.SetOut(out) cmd.SetOut(out)
cmd.SetErr(&bytes.Buffer{}) cmd.SetErr(&bytes.Buffer{})
@ -174,8 +174,8 @@ func TestRecover(t *testing.T) {
if tc.masterSecretFlag != "" { if tc.masterSecretFlag != "" {
require.NoError(cmd.Flags().Set("master-secret", tc.masterSecretFlag)) require.NoError(cmd.Flags().Set("master-secret", tc.masterSecretFlag))
} }
if tc.devConfigFlag != "" { if tc.configFlag != "" {
require.NoError(cmd.Flags().Set("dev-config", tc.devConfigFlag)) require.NoError(cmd.Flags().Set("config", tc.configFlag))
} }
fileHandler := file.NewHandler(tc.setupFs(require)) fileHandler := file.NewHandler(tc.setupFs(require))
if !tc.stateless { if !tc.stateless {
@ -229,13 +229,13 @@ func TestParseRecoverFlags(t *testing.T) {
"all args set": { "all args set": {
args: []string{ args: []string{
"-e", "192.0.2.1:2", "--disk-uuid", "12345678-1234-1234-1234-123456789012", "-e", "192.0.2.1:2", "--disk-uuid", "12345678-1234-1234-1234-123456789012",
"--master-secret", "constellation-mastersecret.base64", "--dev-config", "dev-config-path", "--master-secret", "constellation-mastersecret.base64", "--config", "config-path",
}, },
wantFlags: recoverFlags{ wantFlags: recoverFlags{
endpoint: "192.0.2.1:2", endpoint: "192.0.2.1:2",
diskUUID: "12345678-1234-1234-1234-123456789012", diskUUID: "12345678-1234-1234-1234-123456789012",
masterSecret: []byte("constellation-master-secret-leng"), masterSecret: []byte("constellation-master-secret-leng"),
devConfigPath: "dev-config-path", configPath: "config-path",
}, },
}, },
"uppercase disk-uuid is converted to lowercase": { "uppercase disk-uuid is converted to lowercase": {
@ -256,7 +256,7 @@ func TestParseRecoverFlags(t *testing.T) {
fs := afero.NewMemMapFs() fs := afero.NewMemMapFs()
require.NoError(afero.WriteFile(fs, "constellation-mastersecret.base64", []byte("Y29uc3RlbGxhdGlvbi1tYXN0ZXItc2VjcmV0LWxlbmc="), 0o777)) require.NoError(afero.WriteFile(fs, "constellation-mastersecret.base64", []byte("Y29uc3RlbGxhdGlvbi1tYXN0ZXItc2VjcmV0LWxlbmc="), 0o777))
cmd := newRecoverCmd() cmd := newRecoverCmd()
cmd.Flags().String("dev-config", "", "") // register persistent flag manually cmd.Flags().String("config", "", "") // register persistent flag manually
require.NoError(cmd.ParseFlags(tc.args)) require.NoError(cmd.ParseFlags(tc.args))
flags, err := parseRecoverFlags(cmd, file.NewHandler(fs)) flags, err := parseRecoverFlags(cmd, file.NewHandler(fs))

View File

@ -6,6 +6,7 @@ import (
"os" "os"
"os/signal" "os/signal"
"github.com/edgelesssys/constellation/internal/constants"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -29,8 +30,8 @@ func NewRootCmd() *cobra.Command {
// Set output of cmd.Print to stdout. (By default, it's stderr.) // Set output of cmd.Print to stdout. (By default, it's stderr.)
rootCmd.SetOut(os.Stdout) rootCmd.SetOut(os.Stdout)
rootCmd.PersistentFlags().String("dev-config", "", "use settings from a development config") rootCmd.PersistentFlags().String("config", constants.ConfigFilename, "use settings from a config")
must(rootCmd.MarkPersistentFlagFilename("dev-config", "json")) must(rootCmd.MarkPersistentFlagFilename("config", "json"))
rootCmd.AddCommand(newCreateCmd()) rootCmd.AddCommand(newCreateCmd())
rootCmd.AddCommand(newInitCmd()) rootCmd.AddCommand(newInitCmd())

View File

@ -49,7 +49,7 @@ func verify(ctx context.Context, cmd *cobra.Command, provider cloudprovider.Prov
return err return err
} }
config, err := config.FromFile(fileHandler, flags.devConfigPath) config, err := config.FromFile(fileHandler, flags.configPath)
if err != nil { if err != nil {
return err return err
} }
@ -102,24 +102,24 @@ func parseVerifyFlags(cmd *cobra.Command) (verifyFlags, error) {
return verifyFlags{}, err return verifyFlags{}, err
} }
devConfigPath, err := cmd.Flags().GetString("dev-config") configPath, err := cmd.Flags().GetString("config")
if err != nil { if err != nil {
return verifyFlags{}, err return verifyFlags{}, err
} }
return verifyFlags{ return verifyFlags{
endpoint: endpoint, endpoint: endpoint,
devConfigPath: devConfigPath, configPath: configPath,
ownerID: ownerID, ownerID: ownerID,
clusterID: clusterID, clusterID: clusterID,
}, nil }, nil
} }
type verifyFlags struct { type verifyFlags struct {
endpoint string endpoint string
ownerID string ownerID string
clusterID string clusterID string
devConfigPath string configPath string
} }
// verifyCompletion handels the completion of CLI arguments. It is frequently called // verifyCompletion handels the completion of CLI arguments. It is frequently called

View File

@ -53,7 +53,7 @@ func TestVerify(t *testing.T) {
provider cloudprovider.Provider provider cloudprovider.Provider
protoClient protoClient protoClient protoClient
nodeEndpointFlag string nodeEndpointFlag string
devConfigFlag string configFlag string
ownerIDFlag string ownerIDFlag string
clusterIDFlag string clusterIDFlag string
wantErr bool wantErr bool
@ -93,12 +93,12 @@ func TestVerify(t *testing.T) {
nodeEndpointFlag: "192.0.2.1:1234", nodeEndpointFlag: "192.0.2.1:1234",
wantErr: true, wantErr: true,
}, },
"dev config file not existing": { "config file not existing": {
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() }, setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
provider: cloudprovider.GCP, provider: cloudprovider.GCP,
ownerIDFlag: zeroBase64, ownerIDFlag: zeroBase64,
nodeEndpointFlag: "192.0.2.1:1234", nodeEndpointFlag: "192.0.2.1:1234",
devConfigFlag: "./file", configFlag: "./file",
wantErr: true, wantErr: true,
}, },
"error protoClient Connect": { "error protoClient Connect": {
@ -133,12 +133,12 @@ func TestVerify(t *testing.T) {
require := require.New(t) require := require.New(t)
cmd := newVerifyCmd() cmd := newVerifyCmd()
cmd.Flags().String("dev-config", "", "") // register persisten flag manually cmd.Flags().String("config", "", "") // register persisten flag manually
out := &bytes.Buffer{} out := &bytes.Buffer{}
cmd.SetOut(out) cmd.SetOut(out)
cmd.SetErr(&bytes.Buffer{}) cmd.SetErr(&bytes.Buffer{})
if tc.devConfigFlag != "" { if tc.configFlag != "" {
require.NoError(cmd.Flags().Set("dev-config", tc.devConfigFlag)) require.NoError(cmd.Flags().Set("config", tc.configFlag))
} }
if tc.ownerIDFlag != "" { if tc.ownerIDFlag != "" {
require.NoError(cmd.Flags().Set("owner-id", tc.ownerIDFlag)) require.NoError(cmd.Flags().Set("owner-id", tc.ownerIDFlag))

View File

@ -28,20 +28,20 @@ var deployCmd = &cobra.Command{
Use: "deploy", Use: "deploy",
Short: "Deploys a self-compiled coordinator binary and SSH keys on the current constellation", Short: "Deploys a self-compiled coordinator binary and SSH keys on the current constellation",
Long: `Deploys a self-compiled coordinator binary and SSH keys on the current constellation. Long: `Deploys a self-compiled coordinator binary and SSH keys on the current constellation.
Uses dev-config provided by --dev-config and reads constellation config from its default location. Uses config provided by --config and reads constellation config from its default location.
If required, you can override the IP addresses that are used for a deployment by specifying "--ips" and a list of IP addresses. If required, you can override the IP addresses that are used for a deployment by specifying "--ips" and a list of IP addresses.
Specifying --coordinator will upload the coordinator from the specified path.`, Specifying --coordinator will upload the coordinator from the specified path.`,
RunE: runDeploy, RunE: runDeploy,
Example: "cdbg deploy --dev-config /path/to/dev-config\ncdbg deploy --coordinator /path/to/coordinator --ips 192.0.2.1,192.0.2.2,192.0.2.3 --dev-config /path/to/dev-config", Example: "cdbg deploy --config /path/to/config\ncdbg deploy --coordinator /path/to/coordinator --ips 192.0.2.1,192.0.2.2,192.0.2.3 --config /path/to/config",
} }
func runDeploy(cmd *cobra.Command, args []string) error { func runDeploy(cmd *cobra.Command, args []string) error {
devConfigName, err := cmd.Flags().GetString("dev-config") configName, err := cmd.Flags().GetString("config")
if err != nil { if err != nil {
return err return err
} }
fileHandler := file.NewHandler(afero.NewOsFs()) fileHandler := file.NewHandler(afero.NewOsFs())
config, err := config.FromFile(fileHandler, devConfigName) config, err := config.FromFile(fileHandler, configName)
if err != nil { if err != nil {
return err return err
} }
@ -178,7 +178,7 @@ func init() {
rootCmd.AddCommand(deployCmd) rootCmd.AddCommand(deployCmd)
deployCmd.Flags().StringSlice("ips", nil, "override the ips that the coordinator will be uploaded to (defaults to ips from constellation config)") deployCmd.Flags().StringSlice("ips", nil, "override the ips that the coordinator will be uploaded to (defaults to ips from constellation config)")
deployCmd.Flags().String("coordinator", "", "override the path to the coordinator binary uploaded to instances (defaults to path set in dev-config)") deployCmd.Flags().String("coordinator", "", "override the path to the coordinator binary uploaded to instances (defaults to path set in config)")
} }
type fileToStreamReader interface { type fileToStreamReader interface {

View File

@ -3,6 +3,7 @@ package cmd
import ( import (
"os" "os"
"github.com/edgelesssys/constellation/internal/constants"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -21,6 +22,5 @@ func Execute() {
} }
func init() { func init() {
rootCmd.PersistentFlags().String("dev-config", "", "debugd config file (required)") rootCmd.PersistentFlags().String("config", constants.ConfigFilename, "debugd config file")
_ = rootCmd.MarkPersistentFlagRequired("dev-config")
} }

View File

@ -11,15 +11,15 @@ import (
// CDBGConfig describes the constellation-cli config file and extends it with a new field "cdbg". // CDBGConfig describes the constellation-cli config file and extends it with a new field "cdbg".
type CDBGConfig struct { type CDBGConfig struct {
ConstellationDebugConfig ConstellationDebugdConfig `json:"cdbg"` ConstellationDebugConfig ConstellationDebugdConfig `yaml:"cdbg"`
configc.Config `` configc.Config
} }
// ConstellationDebugdConfig is the cdbg specific configuration. // ConstellationDebugdConfig is the cdbg specific configuration.
type ConstellationDebugdConfig struct { type ConstellationDebugdConfig struct {
AuthorizedKeys []ssh.SSHKey `json:"authorized_keys"` AuthorizedKeys []ssh.SSHKey `yaml:"authorizedKeys"`
CoordinatorPath string `json:"coordinator_path"` CoordinatorPath string `yaml:"coordinatorPath"`
SystemdUnits []deploy.SystemdUnit `json:"systemd_units,omitempty"` SystemdUnits []deploy.SystemdUnit `yaml:"systemdUnits,omitempty"`
} }
// Default returns a struct with the default config. // Default returns a struct with the default config.
@ -42,7 +42,7 @@ func FromFile(fileHandler file.Handler, name string) (*CDBGConfig, error) {
return conf, nil return conf, nil
} }
if err := fileHandler.ReadJSON(name, conf); err != nil { if err := fileHandler.ReadYAML(name, conf); err != nil {
return nil, fmt.Errorf("could not load config from file %s: %w", name, err) return nil, fmt.Errorf("could not load config from file %s: %w", name, err)
} }
return conf, nil return conf, nil

View File

@ -34,8 +34,8 @@ type ServiceManagerRequest struct {
// SystemdUnit describes a systemd service file including the unit name and contents. // SystemdUnit describes a systemd service file including the unit name and contents.
type SystemdUnit struct { type SystemdUnit struct {
Name string `json:"name"` Name string `yaml:"name"`
Contents string `json:"contents"` Contents string `yaml:"contents"`
} }
// ServiceManager receives ServiceManagerRequests and units via channels and performs the requests / creates the unit files. // ServiceManager receives ServiceManagerRequests and units via channels and performs the requests / creates the unit files.

View File

@ -2,6 +2,6 @@ package ssh
// SSHKey describes a public ssh key. // SSHKey describes a public ssh key.
type SSHKey struct { type SSHKey struct {
Username string `json:"user"` Username string `yaml:"user"`
KeyValue string `json:"pubkey"` KeyValue string `yaml:"pubkey"`
} }

View File

@ -1,7 +1,9 @@
package config package config
import ( import (
"errors"
"fmt" "fmt"
"io/fs"
"strconv" "strconv"
azureClient "github.com/edgelesssys/constellation/cli/azure/client" azureClient "github.com/edgelesssys/constellation/cli/azure/client"
@ -214,6 +216,9 @@ func FromFile(fileHandler file.Handler, name string) (*Config, error) {
} }
if err := fileHandler.ReadYAML(name, conf); err != nil { if err := fileHandler.ReadYAML(name, conf); err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil, fmt.Errorf("unable to find %s - use `constellation config generate` to generate it first", constants.ConfigFilename)
}
return nil, fmt.Errorf("could not load config from file %s: %w", name, err) return nil, fmt.Errorf("could not load config from file %s: %w", name, err)
} }
return conf, nil return conf, nil

View File

@ -6,6 +6,7 @@ import (
"github.com/edgelesssys/constellation/cli/cloud/cloudtypes" "github.com/edgelesssys/constellation/cli/cloud/cloudtypes"
"github.com/edgelesssys/constellation/cli/file" "github.com/edgelesssys/constellation/cli/file"
"github.com/edgelesssys/constellation/cli/gcp/client" "github.com/edgelesssys/constellation/cli/gcp/client"
"github.com/edgelesssys/constellation/internal/constants"
"github.com/spf13/afero" "github.com/spf13/afero"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -40,8 +41,6 @@ func TestFromFile(t *testing.T) {
}, },
} }
configName := "config.json"
testCases := map[string]struct { testCases := map[string]struct {
from *Config from *Config
configName string configName string
@ -50,12 +49,12 @@ func TestFromFile(t *testing.T) {
}{ }{
"overwrite fields": { "overwrite fields": {
from: &Config{CoordinatorPort: proto.String("1000")}, from: &Config{CoordinatorPort: proto.String("1000")},
configName: configName, configName: constants.ConfigFilename,
wantResultMutator: func(c *Config) { c.CoordinatorPort = proto.String("1000") }, wantResultMutator: func(c *Config) { c.CoordinatorPort = proto.String("1000") },
}, },
"overwrite slices": { "overwrite slices": {
from: &Config{Provider: someProviderConfig}, from: &Config{Provider: someProviderConfig},
configName: configName, configName: constants.ConfigFilename,
wantResultMutator: func(c *Config) { c.Provider = someProviderConfig }, wantResultMutator: func(c *Config) { c.Provider = someProviderConfig },
}, },
"default with empty name": { "default with empty name": {
@ -77,7 +76,7 @@ func TestFromFile(t *testing.T) {
require := require.New(t) require := require.New(t)
fileHandler := file.NewHandler(afero.NewMemMapFs()) fileHandler := file.NewHandler(afero.NewMemMapFs())
require.NoError(fileHandler.WriteYAML(configName, tc.from, file.OptNone)) require.NoError(fileHandler.WriteYAML(constants.ConfigFilename, tc.from, file.OptNone))
result, err := FromFile(fileHandler, tc.configName) result, err := FromFile(fileHandler, tc.configName)