mirror of https://github.com/k3d-io/k3d
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
6.5 KiB
215 lines
6.5 KiB
4 years ago
|
/*
|
||
|
Copyright © 2020 The k3d Author(s)
|
||
|
|
||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
of this software and associated documentation files (the "Software"), to deal
|
||
|
in the Software without restriction, including without limitation the rights
|
||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
copies of the Software, and to permit persons to whom the Software is
|
||
|
furnished to do so, subject to the following conditions:
|
||
|
|
||
|
The above copyright notice and this permission notice shall be included in
|
||
|
all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
|
THE SOFTWARE.
|
||
|
*/
|
||
|
|
||
|
package config
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
|
||
|
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha1"
|
||
|
"github.com/rancher/k3d/v4/pkg/runtimes"
|
||
|
k3d "github.com/rancher/k3d/v4/pkg/types"
|
||
|
"github.com/rancher/k3d/v4/pkg/util"
|
||
|
"github.com/rancher/k3d/v4/version"
|
||
|
)
|
||
|
|
||
|
// TransformSimpleToClusterConfig transforms a simple configuration to a full-fledged cluster configuration
|
||
|
func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtime, simpleConfig conf.SimpleConfig) (*conf.ClusterConfig, error) {
|
||
|
|
||
|
// set default cluster name
|
||
|
if simpleConfig.Name == "" {
|
||
|
simpleConfig.Name = k3d.DefaultClusterName
|
||
|
}
|
||
|
|
||
|
// fetch latest image
|
||
|
if simpleConfig.Image == "latest" {
|
||
|
simpleConfig.Image = version.GetK3sVersion(true)
|
||
|
}
|
||
|
|
||
|
clusterNetwork := k3d.ClusterNetwork{}
|
||
|
if simpleConfig.Network != "" {
|
||
|
clusterNetwork.Name = simpleConfig.Network
|
||
|
clusterNetwork.External = true
|
||
|
}
|
||
|
|
||
|
// -> API
|
||
|
if simpleConfig.ExposeAPI.Host == "" {
|
||
|
simpleConfig.ExposeAPI.Host = k3d.DefaultAPIHost
|
||
|
}
|
||
|
if simpleConfig.ExposeAPI.HostIP == "" {
|
||
|
simpleConfig.ExposeAPI.HostIP = k3d.DefaultAPIHost
|
||
|
}
|
||
|
|
||
|
// FILL CLUSTER CONFIG
|
||
|
newCluster := k3d.Cluster{
|
||
|
Name: simpleConfig.Name,
|
||
|
Network: clusterNetwork,
|
||
|
Token: simpleConfig.ClusterToken,
|
||
|
ExposeAPI: simpleConfig.ExposeAPI,
|
||
|
}
|
||
|
|
||
|
// -> NODES
|
||
|
newCluster.Nodes = []*k3d.Node{}
|
||
|
|
||
|
if !simpleConfig.Options.K3dOptions.DisableLoadbalancer {
|
||
|
newCluster.ServerLoadBalancer = &k3d.Node{
|
||
|
Role: k3d.LoadBalancerRole,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************
|
||
|
* Add Nodes *
|
||
|
*************/
|
||
|
|
||
|
for i := 0; i < simpleConfig.Servers; i++ {
|
||
|
serverNode := k3d.Node{
|
||
|
Role: k3d.ServerRole,
|
||
|
Image: simpleConfig.Image,
|
||
|
Args: simpleConfig.Options.K3sOptions.ExtraServerArgs,
|
||
|
ServerOpts: k3d.ServerOpts{},
|
||
|
}
|
||
|
|
||
|
// first server node will be init node if we have more than one server specified but no external datastore
|
||
|
if i == 0 && simpleConfig.Servers > 1 {
|
||
|
serverNode.ServerOpts.IsInit = true
|
||
|
newCluster.InitNode = &serverNode
|
||
|
}
|
||
|
|
||
|
newCluster.Nodes = append(newCluster.Nodes, &serverNode)
|
||
|
}
|
||
|
|
||
|
for i := 0; i < simpleConfig.Agents; i++ {
|
||
|
agentNode := k3d.Node{
|
||
|
Role: k3d.AgentRole,
|
||
|
Image: simpleConfig.Image,
|
||
|
Args: simpleConfig.Options.K3sOptions.ExtraAgentArgs,
|
||
|
}
|
||
|
newCluster.Nodes = append(newCluster.Nodes, &agentNode)
|
||
|
}
|
||
|
|
||
|
/****************************
|
||
|
* Extra Node Configuration *
|
||
|
****************************/
|
||
|
|
||
|
// -> VOLUMES
|
||
|
nodeCount := simpleConfig.Servers + simpleConfig.Agents
|
||
|
nodeList := newCluster.Nodes
|
||
|
if !simpleConfig.Options.K3dOptions.DisableLoadbalancer {
|
||
|
nodeCount++
|
||
|
nodeList = append(nodeList, newCluster.ServerLoadBalancer)
|
||
|
}
|
||
|
for _, volumeWithNodeFilters := range simpleConfig.Volumes {
|
||
|
nodes, err := util.FilterNodes(newCluster.Nodes, volumeWithNodeFilters.NodeFilters)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
for _, node := range nodes {
|
||
|
node.Volumes = append(node.Volumes, volumeWithNodeFilters.Volume)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// -> PORTS
|
||
|
for _, portWithNodeFilters := range simpleConfig.Ports {
|
||
|
if len(portWithNodeFilters.NodeFilters) == 0 && nodeCount > 1 {
|
||
|
return nil, fmt.Errorf("Portmapping '%s' lacks a node filter, but there's more than one node", portWithNodeFilters.Port)
|
||
|
}
|
||
|
|
||
|
nodes, err := util.FilterNodes(nodeList, portWithNodeFilters.NodeFilters)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
for _, node := range nodes {
|
||
|
node.Ports = append(node.Ports, portWithNodeFilters.Port)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// -> LABELS
|
||
|
for _, labelWithNodeFilters := range simpleConfig.Labels {
|
||
|
if len(labelWithNodeFilters.NodeFilters) == 0 && nodeCount > 1 {
|
||
|
return nil, fmt.Errorf("Labelmapping '%s' lacks a node filter, but there's more than one node", labelWithNodeFilters.Label)
|
||
|
}
|
||
|
|
||
|
nodes, err := util.FilterNodes(nodeList, labelWithNodeFilters.NodeFilters)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
for _, node := range nodes {
|
||
|
if node.Labels == nil {
|
||
|
node.Labels = make(map[string]string) // ensure that the map is initialized
|
||
|
}
|
||
|
k, v := util.SplitLabelKeyValue(labelWithNodeFilters.Label)
|
||
|
node.Labels[k] = v
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// -> ENV
|
||
|
for _, envVarWithNodeFilters := range simpleConfig.Env {
|
||
|
if len(envVarWithNodeFilters.NodeFilters) == 0 && nodeCount > 1 {
|
||
|
return nil, fmt.Errorf("EnvVarMapping '%s' lacks a node filter, but there's more than one node", envVarWithNodeFilters.EnvVar)
|
||
|
}
|
||
|
|
||
|
nodes, err := util.FilterNodes(nodeList, envVarWithNodeFilters.NodeFilters)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
for _, node := range nodes {
|
||
|
node.Env = append(node.Env, envVarWithNodeFilters.EnvVar)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**************************
|
||
|
* Cluster Create Options *
|
||
|
**************************/
|
||
|
|
||
|
clusterCreateOpts := k3d.ClusterCreateOpts{
|
||
|
DisableImageVolume: simpleConfig.Options.K3dOptions.DisableImageVolume,
|
||
|
WaitForServer: simpleConfig.Options.K3dOptions.Wait,
|
||
|
Timeout: simpleConfig.Options.K3dOptions.Timeout,
|
||
|
DisableLoadBalancer: simpleConfig.Options.K3dOptions.DisableLoadbalancer,
|
||
|
K3sServerArgs: simpleConfig.Options.K3sOptions.ExtraServerArgs,
|
||
|
K3sAgentArgs: simpleConfig.Options.K3sOptions.ExtraAgentArgs,
|
||
|
}
|
||
|
|
||
|
/**********************
|
||
|
* Kubeconfig Options *
|
||
|
**********************/
|
||
|
|
||
|
// Currently, the kubeconfig options for the cluster config are the same as for the simple config
|
||
|
|
||
|
/******************************
|
||
|
* Create Full Cluster Config *
|
||
|
******************************/
|
||
|
|
||
|
clusterConfig := &conf.ClusterConfig{
|
||
|
Cluster: newCluster,
|
||
|
ClusterCreateOpts: clusterCreateOpts,
|
||
|
KubeconfigOpts: simpleConfig.Options.KubeconfigOptions,
|
||
|
}
|
||
|
|
||
|
return clusterConfig, nil
|
||
|
}
|