diff --git a/README.md b/README.md index 22c8bdcfe..4d964b90f 100644 --- a/README.md +++ b/README.md @@ -93,12 +93,61 @@ go install github.com/edgelesssys/constellation/debugd/cdbg ## debugd & cdbg usage -With `cdbg` installed in your path: +With `cdbg` and `yq` installed in your path: -0. (optional) Run `constellation config generate` to create a new default configuration -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 +0. Write the configuration file for cdbg `cdbg-conf.yaml`: + ```yaml + cdbg: + authorizedKeys: + - user: my-username + pubkey: ssh-rsa AAAAB…LJuM= + coordinatorPath: "./coordinator" + systemdUnits: + - name: some-custom.service + contents: |- + [Unit] + Description=… + ``` +1. Run `constellation config generate` to create a new default configuration +2. Locate the latest debugd images for [GCP](#debugd-gcp-image) and [Azure](#debugd-azure-image) +3. Modify the `constellation-conf.yaml` to use an image with the debugd already included and add required firewall rules: + ```shell-session + # Set timestamp from cloud provider image name + export TIMESTAMP=01234 + + yq -i \ + ".provider.azureConfig.image = \"/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/CONSTELLATION-IMAGES/providers/Microsoft.Compute/galleries/Constellation/images/constellation-coreos-debugd/versions/0.0.${TIMESTAMP}\"" \ + constellation-conf.yaml + + yq -i \ + ".provider.gcpConfig.image = \"projects/constellation-images/global/images/constellation-coreos-debugd-${TIMESTAMP}\"" \ + constellation-conf.yaml + + yq -i \ + ".provider.azureConfig.networkSecurityGroupInput.ingress += { + \"name\": \"debugd\", + \"description\": \"debugd default port\", + \"protocol\": \"tcp\", + \"iprange\": \"0.0.0.0/0\", + \"fromport\": 4000, + \"toport\": 0 + }" \ + constellation-conf.yaml + + yq -i \ + ".provider.gcpConfig.firewallInput.ingress += { + \"name\": \"debugd\", + \"description\": \"debugd default port\", + \"protocol\": \"tcp\", + \"iprange\": \"0.0.0.0/0\", + \"fromport\": 4000, + \"toport\": 0 + }" \ + constellation-conf.yaml + ``` +4. Run `constellation create […]` +5. Run `cdbg deploy` +6. Run `constellation init […]` as usual ### debugd GCP image @@ -117,98 +166,6 @@ az sig image-version list --resource-group constellation-images --gallery-name C ``` Choose the newest debugd image and copy the full URI. -## debugd Configuration - -You should first locate the newest debugd image for your cloud provider ([GCP](#debugd-gcp-image), [Azure](#debugd-azure-image)). - -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: -```yaml -cdbg: - authorizedKeys: - - user: my-username - pubkey: ssh-rsa AAAAB…LJuM= - coordinatorPath: "/path/to/coordinator" - systemdUnits: - - name: some-custom.service - contents: |- - [Unit] - Description=… -provider: - # Add Azure image - 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: - - name: coordinator - description: Coordinator default port - protocol: tcp - iprange: 0.0.0.0/0 - fromport: 9000 - toport: 0 - - name: wireguard - description: WireGuard default port - protocol: udp - iprange: 0.0.0.0/0 - fromport: 51820 - toport: 0 - - name: ssh - description: SSH - protocol: tcp - iprange: 0.0.0.0/0 - fromport: 22 - toport: 0 - - name: nodeport - description: NodePort - protocol: tcp - iprange: 0.0.0.0/0 - fromport: 30000 - toport: 32767 - # Add debug port - - name: debugd - description: debugd default port - protocol: tcp - iprange: 0.0.0.0/0 - fromport: 4000 - toport: 0 - gcpConfig: - # Add GCP image - image: projects/constellation-images/global/images/constellation-coreos-debugd-TIMESTAMP - firewallInput: - ingress: - - name: coordinator - description: Coordinator default port - protocol: tcp - iprange: "" - fromport: 9000 - toport: 0 - - name: wireguard - description: WireGuard default port - protocol: udp - iprange: "" - fromport: 51820 - toport: 0 - - name: ssh - description: SSH - protocol: tcp - iprange: "" - fromport: 22 - toport: 0 - - name: nodeport - description: NodePort - protocol: tcp - iprange: "" - fromport: 30000 - toport: 32767 - # Add debugd port - - name: debugd - description: debugd default port - protocol: tcp - iprange: "" - fromport: 4000 - toport: 0 -``` - # Local image testing with QEMU To build our images we use the [CoreOS-Assembler (COSA)](https://github.com/edgelesssys/constellation-coreos-assembler). diff --git a/debugd/cdbg/cmd/deploy.go b/debugd/cdbg/cmd/deploy.go index 0e063a626..febbef002 100644 --- a/debugd/cdbg/cmd/deploy.go +++ b/debugd/cdbg/cmd/deploy.go @@ -16,6 +16,7 @@ import ( depl "github.com/edgelesssys/constellation/debugd/debugd/deploy" pb "github.com/edgelesssys/constellation/debugd/service" "github.com/edgelesssys/constellation/debugd/ssh" + configc "github.com/edgelesssys/constellation/internal/config" "github.com/edgelesssys/constellation/internal/constants" statec "github.com/edgelesssys/constellation/internal/state" "github.com/spf13/afero" @@ -32,7 +33,7 @@ Uses config provided by --config and reads constellation config from its default 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.`, RunE: runDeploy, - 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", + Example: "cdbg deploy\ncdbg 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 { @@ -41,21 +42,25 @@ func runDeploy(cmd *cobra.Command, args []string) error { return err } fileHandler := file.NewHandler(afero.NewOsFs()) - config, err := config.FromFile(fileHandler, configName) + debugConfig, err := config.FromFile(fileHandler, configName) + if err != nil { + return err + } + constellationConfig, err := configc.FromFile(fileHandler, constants.ConfigFilename) if err != nil { return err } - return deploy(cmd, fileHandler, config, coordinator.NewFileStreamer(afero.NewOsFs())) + return deploy(cmd, fileHandler, constellationConfig, debugConfig, coordinator.NewFileStreamer(afero.NewOsFs())) } -func deploy(cmd *cobra.Command, fileHandler file.Handler, config *config.CDBGConfig, reader fileToStreamReader) error { +func deploy(cmd *cobra.Command, fileHandler file.Handler, constellationConfig *configc.Config, debugConfig *config.CDBGConfig, reader fileToStreamReader) error { overrideCoordinatorPath, err := cmd.Flags().GetString("coordinator") if err != nil { return err } if len(overrideCoordinatorPath) > 0 { - config.ConstellationDebugConfig.CoordinatorPath = overrideCoordinatorPath + debugConfig.ConstellationDebugConfig.CoordinatorPath = overrideCoordinatorPath } overrideIPs, err := cmd.Flags().GetStringSlice("ips") @@ -74,7 +79,7 @@ func deploy(cmd *cobra.Command, fileHandler file.Handler, config *config.CDBGCon } else if err != nil { return fmt.Errorf("loading statefile failed: %w", err) } - ips, err = getIPsFromConfig(stat, *config) + ips, err = getIPsFromConfig(stat, *constellationConfig) if err != nil { return err } @@ -83,10 +88,10 @@ func deploy(cmd *cobra.Command, fileHandler file.Handler, config *config.CDBGCon for _, ip := range ips { input := deployOnEndpointInput{ debugdEndpoint: net.JoinHostPort(ip, debugd.DebugdPort), - coordinatorPath: config.ConstellationDebugConfig.CoordinatorPath, + coordinatorPath: debugConfig.ConstellationDebugConfig.CoordinatorPath, reader: reader, - authorizedKeys: config.ConstellationDebugConfig.AuthorizedKeys, - systemdUnits: config.ConstellationDebugConfig.SystemdUnits, + authorizedKeys: debugConfig.ConstellationDebugConfig.AuthorizedKeys, + systemdUnits: debugConfig.ConstellationDebugConfig.SystemdUnits, } if err := deployOnEndpoint(cmd.Context(), input); err != nil { return err @@ -166,8 +171,8 @@ func deployOnEndpoint(ctx context.Context, in deployOnEndpointInput) error { return nil } -func getIPsFromConfig(stat statec.ConstellationState, config config.CDBGConfig) ([]string, error) { - coordinators, nodes, err := state.GetScalingGroupsFromConfig(stat, &config.Config) +func getIPsFromConfig(stat statec.ConstellationState, config configc.Config) ([]string, error) { + coordinators, nodes, err := state.GetScalingGroupsFromConfig(stat, &config) if err != nil { return nil, err } diff --git a/debugd/cdbg/cmd/root.go b/debugd/cdbg/cmd/root.go index 2eead5ec8..48833f8a2 100644 --- a/debugd/cdbg/cmd/root.go +++ b/debugd/cdbg/cmd/root.go @@ -22,5 +22,5 @@ func Execute() { } func init() { - rootCmd.PersistentFlags().String("config", constants.ConfigFilename, "debugd config file") + rootCmd.PersistentFlags().String("config", constants.DebugdConfigFilename, "debugd config file") } diff --git a/debugd/cdbg/config/config.go b/debugd/cdbg/config/config.go index 0c429ebea..c5a097a90 100644 --- a/debugd/cdbg/config/config.go +++ b/debugd/cdbg/config/config.go @@ -1,18 +1,18 @@ package config import ( + "errors" "fmt" + "io/fs" "github.com/edgelesssys/constellation/cli/file" "github.com/edgelesssys/constellation/debugd/debugd/deploy" "github.com/edgelesssys/constellation/debugd/ssh" - configc "github.com/edgelesssys/constellation/internal/config" ) -// CDBGConfig describes the constellation-cli config file and extends it with a new field "cdbg". +// CDBGConfig describes the constellation-cli config file. type CDBGConfig struct { ConstellationDebugConfig ConstellationDebugdConfig `yaml:"cdbg"` - configc.Config } // ConstellationDebugdConfig is the cdbg specific configuration. @@ -22,27 +22,13 @@ type ConstellationDebugdConfig struct { SystemdUnits []deploy.SystemdUnit `yaml:"systemdUnits,omitempty"` } -// Default returns a struct with the default config. -func Default() *CDBGConfig { - return &CDBGConfig{ - ConstellationDebugConfig: ConstellationDebugdConfig{ - AuthorizedKeys: []ssh.SSHKey{}, - CoordinatorPath: "coordinator", - SystemdUnits: []deploy.SystemdUnit{}, - }, - Config: *configc.Default(), - } -} - -// FromFile returns a default config that has been merged with a config file. -// If name is empty, the defaults are returned. +// FromFile reads a debug configuration. func FromFile(fileHandler file.Handler, name string) (*CDBGConfig, error) { - conf := Default() - if name == "" { - return conf, nil - } - + conf := &CDBGConfig{} if err := fileHandler.ReadYAML(name, conf); err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil, fmt.Errorf("unable to find %s - consult the README on how to setup cdbg", name) + } return nil, fmt.Errorf("could not load config from file %s: %w", name, err) } return conf, nil diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 5e36621b7..82a78a917 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -27,6 +27,7 @@ const ( StateFilename = "constellation-state.json" ConfigFilename = "constellation-conf.yaml" + DebugdConfigFilename = "cdbg-conf.yaml" AdminConfFilename = "constellation-admin.conf" MasterSecretFilename = "constellation-mastersecret.base64" WGQuickConfigFilename = "wg0.conf"