mirror of
https://github.com/status-im/consul.git
synced 2025-02-21 01:48:20 +00:00
* Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
165 lines
4.3 KiB
Go
165 lines
4.3 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package cluster
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
|
|
jsonpatch "github.com/evanphx/json-patch"
|
|
"github.com/hashicorp/hcl"
|
|
"github.com/mitchellh/mapstructure"
|
|
"github.com/testcontainers/testcontainers-go"
|
|
"google.golang.org/grpc"
|
|
|
|
agentconfig "github.com/hashicorp/consul/agent/config"
|
|
"github.com/hashicorp/consul/api"
|
|
"github.com/hashicorp/consul/lib/decode"
|
|
|
|
"github.com/hashicorp/consul/test/integration/consul-container/libs/utils"
|
|
)
|
|
|
|
// Agent represent a Consul agent abstraction
|
|
type Agent interface {
|
|
GetIP() string
|
|
GetClient() *api.Client
|
|
NewClient(string, bool) (*api.Client, error)
|
|
GetName() string
|
|
GetAgentName() string
|
|
GetPartition() string
|
|
GetPod() testcontainers.Container
|
|
Logs(context.Context) (io.ReadCloser, error)
|
|
ClaimAdminPort() (int, error)
|
|
GetConfig() Config
|
|
GetInfo() AgentInfo
|
|
GetDatacenter() string
|
|
GetNetwork() string
|
|
IsServer() bool
|
|
RegisterTermination(func() error)
|
|
Terminate() error
|
|
TerminateAndRetainPod(bool) error
|
|
Upgrade(ctx context.Context, config Config) error
|
|
Exec(ctx context.Context, cmd []string) (string, error)
|
|
DataDir() string
|
|
GetGRPCConn() *grpc.ClientConn
|
|
}
|
|
|
|
// Config is a set of configurations required to create a Agent
|
|
//
|
|
// Constructed by (Builder).ToAgentConfig()
|
|
type Config struct {
|
|
// NodeName is set for the consul agent name and container name
|
|
// Equivalent to the -node command-line flag.
|
|
// If empty, a random name will be generated
|
|
NodeName string
|
|
// NodeID is used to configure node_id in agent config file
|
|
// Equivalent to the -node-id command-line flag.
|
|
// If empty, a random name will be generated
|
|
NodeID string
|
|
|
|
// ExternalDataDir is data directory to copy consul data from, if set.
|
|
// This directory contains subdirectories like raft, serf, services
|
|
ExternalDataDir string
|
|
|
|
ScratchDir string
|
|
CertVolume string
|
|
CACert string
|
|
JSON string
|
|
ConfigBuilder *ConfigBuilder
|
|
Image string
|
|
Version string
|
|
Cmd []string
|
|
LogConsumer testcontainers.LogConsumer
|
|
|
|
// service defaults
|
|
UseAPIWithTLS bool // TODO
|
|
UseGRPCWithTLS bool
|
|
|
|
ACLEnabled bool
|
|
}
|
|
|
|
func (c *Config) DockerImage() string {
|
|
return utils.DockerImage(c.Image, c.Version)
|
|
}
|
|
|
|
// Clone copies everything. It is the caller's job to replace fields that
|
|
// should be unique.
|
|
func (c Config) Clone() Config {
|
|
c2 := c
|
|
if c.Cmd != nil {
|
|
copy(c2.Cmd, c.Cmd)
|
|
}
|
|
return c2
|
|
}
|
|
|
|
type decodeTarget struct {
|
|
agentconfig.Config `mapstructure:",squash"`
|
|
}
|
|
|
|
// MutatebyAgentConfig mutates config by applying the fields in the input hclConfig
|
|
// Note that the precedence order is config > hclConfig, because user provider hclConfig
|
|
// may not work with the testing environment, e.g., data dir, agent name, etc.
|
|
// Currently only hcl config is allowed
|
|
func (c *Config) MutatebyAgentConfig(hclConfig string) error {
|
|
rawConfigJson, err := convertHcl2Json(hclConfig)
|
|
if err != nil {
|
|
return fmt.Errorf("error converting to Json: %s", err)
|
|
}
|
|
|
|
// Merge 2 json
|
|
mergedConfigJosn, err := jsonpatch.MergePatch([]byte(rawConfigJson), []byte(c.JSON))
|
|
if err != nil {
|
|
return fmt.Errorf("error merging configurations: %w", err)
|
|
}
|
|
|
|
c.JSON = string(mergedConfigJosn)
|
|
return nil
|
|
}
|
|
|
|
// TODO: refactor away
|
|
type AgentInfo struct {
|
|
CACertFile string
|
|
UseTLSForAPI bool
|
|
UseTLSForGRPC bool
|
|
DebugURI string
|
|
}
|
|
|
|
func convertHcl2Json(in string) (string, error) {
|
|
var raw map[string]interface{}
|
|
err := hcl.Decode(&raw, in)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var target decodeTarget
|
|
var md mapstructure.Metadata
|
|
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
|
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
|
// decode.HookWeakDecodeFromSlice is only necessary when reading from
|
|
// an HCL config file. In the future we could omit it when reading from
|
|
// JSON configs. It is left here for now to maintain backwards compat
|
|
// for the unlikely scenario that someone is using malformed JSON configs
|
|
// and expecting this behaviour to correct their config.
|
|
decode.HookWeakDecodeFromSlice,
|
|
decode.HookTranslateKeys,
|
|
),
|
|
Metadata: &md,
|
|
Result: &target,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if err := d.Decode(raw); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
rawjson, err := json.MarshalIndent(target, "", " ")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(rawjson), nil
|
|
}
|