Skip to content
This repository has been archived by the owner on Aug 19, 2023. It is now read-only.

Commit

Permalink
feat: add webconfig service
Browse files Browse the repository at this point in the history
If no configuration source is provided (on baremetal only for now), Talos will set of a simple web service to receive its configuration via an HTTP POST request, on port 80 or 443.
It also serves a simple web form for interactive submission from the browser.

Fixes siderolabs#2593

Signed-off-by: Seán C McCord <[email protected]>
  • Loading branch information
Ulexus authored and talos-bot committed Oct 31, 2020
1 parent 221b0fc commit 63daa56
Show file tree
Hide file tree
Showing 5 changed files with 344 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ package container
import (
"context"
"encoding/base64"
"errors"
"log"
"net"
"os"

"github.com/talos-systems/go-procfs/procfs"

"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/errors"
)

// Container is a platform for installing Talos via an Container image.
Expand All @@ -29,9 +29,9 @@ func (c *Container) Name() string {
func (c *Container) Configuration(context.Context) ([]byte, error) {
log.Printf("fetching machine config from: USERDATA environment variable")

s, ok := os.LookupEnv("USERDATA")
if !ok {
return nil, errors.New("missing USERDATA environment variable")
s := os.Getenv("USERDATA")
if s == "" {
return nil, errors.ErrNoConfigSource
}

decoded, err := base64.StdEncoding.DecodeString(s)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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 errors

import "errors"

// ErrNoConfigSource indicates that the platform does not have a configured source for the configuration.
var ErrNoConfigSource = errors.New("no configuration source")
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/talos-systems/go-blockdevice/blockdevice/probe"

"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/errors"
"github.com/talos-systems/talos/pkg/download"
"github.com/talos-systems/talos/pkg/machinery/constants"
)
Expand All @@ -43,7 +44,7 @@ func (m *Metal) Name() string {
func (m *Metal) Configuration(ctx context.Context) ([]byte, error) {
var option *string
if option = procfs.ProcCmdline().Get(constants.KernelParamConfig).First(); option == nil {
return nil, fmt.Errorf("no config option was found")
return nil, errors.ErrNoConfigSource
}

log.Printf("fetching machine config from: %q", *option)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub"
perrors "github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/errors"
"github.com/talos-systems/talos/internal/app/machined/pkg/system"
"github.com/talos-systems/talos/internal/app/machined/pkg/system/events"
"github.com/talos-systems/talos/internal/app/machined/pkg/system/services"
Expand All @@ -51,6 +52,7 @@ import (
"github.com/talos-systems/talos/internal/pkg/kmsg"
"github.com/talos-systems/talos/internal/pkg/kubeconfig"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/webconfig"
"github.com/talos-systems/talos/pkg/cmd"
"github.com/talos-systems/talos/pkg/conditions"
"github.com/talos-systems/talos/pkg/images"
Expand Down Expand Up @@ -428,6 +430,13 @@ func LoadConfig(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFu
defer ctxCancel()

b, e := fetchConfig(fetchCtx, r)
if errors.Is(e, perrors.ErrNoConfigSource) {
b, e = receiveConfigViaWebconfig(ctx, logger, r)
if e != nil {
return fmt.Errorf("failed to receive config via webconfig: %w", err)
}
}

if e != nil {
return e
}
Expand Down Expand Up @@ -541,6 +550,29 @@ func fetchConfig(ctx context.Context, r runtime.Runtime) (out []byte, err error)
return b, nil
}

func receiveConfigViaWebconfig(ctx context.Context, logger *log.Logger, r runtime.Runtime) ([]byte, error) {
cfgBytes, err := webconfig.Run(ctx, logger, r.State().Platform().Mode())
if err != nil {
return nil, fmt.Errorf("failed to receive config via webconfig: %w", err)
}

provider, err := configloader.NewFromBytes(cfgBytes)
if err != nil {
return nil, fmt.Errorf("failed to create config provider from webconfig bytes: %w", err)
}

if err = provider.Validate(r.State().Platform().Mode()); err != nil {
return nil, fmt.Errorf("failed to validate config received from webconfig: %w", err)
}

processedBytes, err := provider.Bytes()
if err != nil {
return nil, fmt.Errorf("failed to export validated webconfig to bytes: %w", err)
}

return processedBytes, nil
}

// ValidateConfig validates the config.
func ValidateConfig(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) error {
Expand Down
Loading

0 comments on commit 63daa56

Please sign in to comment.