Skip to content

Commit d233cf6

Browse files
lucafrancescatoadamjensenbot
authored andcommitted
liqoctl install: accept provided parameters for Kind and Kubeadm providers
1 parent 6c45ffb commit d233cf6

File tree

13 files changed

+301
-39
lines changed

13 files changed

+301
-39
lines changed

cmd/liqo-controller-manager/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func main() {
127127
"https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement")
128128

129129
// Resource sharing parameters
130-
flag.Var(&clusterLabels, "cluster-labels",
130+
flag.Var(&clusterLabels, consts.ClusterLabelsParameter,
131131
"The set of labels which characterizes the local cluster when exposed remotely as a virtual node")
132132
resourceSharingPercentage := argsutils.Percentage{Val: 50}
133133
flag.Var(&resourceSharingPercentage, "resource-sharing-percentage",

cmd/liqoctl/cmd/install.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ func newInstallCommand(ctx context.Context) *cobra.Command {
4040
installCmd.PersistentFlags().BoolP("only-output-values", "", false, "Generate a values file for further customization")
4141
installCmd.PersistentFlags().StringP("dump-values-path", "", "./values.yaml", "Path for the output value file")
4242
installCmd.PersistentFlags().BoolP("dry-run", "", false, "Simulate an install")
43-
installCmd.PersistentFlags().BoolP("enable-lan-discovery", "", false, "Enable LAN discovery")
44-
installCmd.PersistentFlags().StringP("cluster-labels", "", "",
43+
installCmd.PersistentFlags().BoolP(liqoconst.EnableLanDiscoveryParameter, "", false, "Enable LAN discovery")
44+
installCmd.PersistentFlags().StringP(liqoconst.ClusterLabelsParameter, "", "",
4545
"Cluster Labels to append to Liqo Cluster, supports '='.(e.g. --cluster-labels key1=value1,key2=value2)")
4646
installCmd.PersistentFlags().BoolP("disable-endpoint-check", "", false,
4747
"Disable the check that the current kubeconfig context contains the same endpoint retrieved from the cloud provider (AKS, EKS, GKE)")
4848
installCmd.PersistentFlags().String("chart-path", installutils.LiqoChartFullName,
4949
"Specify a path to get the Liqo chart, instead of installing the chart from the official repository")
50-
installCmd.PersistentFlags().StringP("cluster-name", "n", "", "Name to assign to the Liqo cluster")
51-
installCmd.PersistentFlags().Bool("generate-name", false, "Generate a random Docker-like name for the cluster")
52-
installCmd.PersistentFlags().String("reserved-subnets", "", "In order to prevent IP conflicting between locally used private subnets in your "+
53-
"infrastructure and private subnets belonging to remote clusters "+
50+
installCmd.PersistentFlags().StringP(liqoconst.ClusterNameParameter, "n", "", "Name to assign to the Liqo cluster")
51+
installCmd.PersistentFlags().Bool(liqoconst.GenerateNameParameter, false, "Generate a random Docker-like name for the cluster")
52+
installCmd.PersistentFlags().String(liqoconst.ReservedSubnetsParameter, "", "In order to prevent IP conflicting between "+
53+
"locally used private subnets in your infrastructure and private subnets belonging to remote clusters "+
5454
"you need tell liqo the subnets used in your cluster. E.g if your cluster nodes belong to the 192.168.2.0/24 subnet then "+
5555
"you should add that subnet to the reservedSubnets. PodCIDR and serviceCIDR used in the local cluster are automatically "+
5656
"added to the reserved list. (e.g. --reserved-subnets 192.168.2.0/24,192.168.4.0/24)")

pkg/consts/parameters.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ package consts
1717
const (
1818
// ClusterNameParameter is the name of the parameter specifying the cluster name.
1919
ClusterNameParameter = "cluster-name"
20+
// ClusterLabelsParameter is the name of the parameter specifying the cluster labels.
21+
ClusterLabelsParameter = "cluster-labels"
22+
// ReservedSubnetsParameter is the name of the parameter specifying the cluster's reserved subnets.
23+
ReservedSubnetsParameter = "reserved-subnets"
24+
// EnableLanDiscoveryParameter is the name of the parameter specifying whether the lan discovery is enabled.
25+
EnableLanDiscoveryParameter = "enable-lan-discovery"
26+
// GenerateNameParameter is the name of the parameter specifying whether to generate a random name for the cluster.
27+
GenerateNameParameter = "generate-name"
2028

2129
// AuthServiceAddressOverrideParameter is the name of the parameter overriding
2230
// the automatically detected authentication service address.
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
// Copyright 2019-2022 The Liqo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package install
16+
17+
import (
18+
"fmt"
19+
"testing"
20+
21+
. "github.com/onsi/ginkgo"
22+
. "github.com/onsi/ginkgo/extensions/table"
23+
. "github.com/onsi/gomega"
24+
"github.com/spf13/cobra"
25+
26+
installutils "github.com/liqotech/liqo/pkg/liqoctl/install/utils"
27+
argsutils "github.com/liqotech/liqo/pkg/utils/args"
28+
)
29+
30+
// This recursive function takes a map and a list of keys and visits a tree of nested maps
31+
// using the keys in the order provided. At each iteration, if the number of non-visited keys
32+
// is 1, the function returns the value associated to the last key, else if it is greater
33+
// than 1, the function expects the value to be a map and a new recursive iteration happens.
34+
// In case the key is not found, an empty string is returned.
35+
// In case no keys are provided, an error is returned.
36+
// Example:
37+
// m := map[string]interface{}{
38+
// "first": map[string]interface{}{
39+
// "second": map[string]interface{}{
40+
// "third": "value",
41+
// },
42+
// },
43+
// }
44+
// ValueFor(m, "first", "second", "third") // returns "value", nil
45+
// ValueFor(m, "first", "second") // returns map[string]interface{}{ "third": "value" }, nil
46+
// ValueFor(m, "first", "third") // returns "", nil
47+
// ValueFor(m) // returns nil, "At least one key is required"
48+
func ValueFor(m map[string]interface{}, keys ...string) (val interface{}, err error) {
49+
var ok bool
50+
if len(keys) == 0 {
51+
return nil, fmt.Errorf("At least one key is required")
52+
} else if val, ok = m[keys[0]]; !ok {
53+
return "", nil
54+
} else if len(keys) == 1 {
55+
return val, nil
56+
} else if m, ok = val.(map[string]interface{}); !ok {
57+
return nil, fmt.Errorf("The value for key %s is not map (expected to be a map)", keys[0])
58+
} else {
59+
return ValueFor(m, keys[1:]...)
60+
}
61+
}
62+
63+
func TestInstallCommand(t *testing.T) {
64+
RegisterFailHandler(Fail)
65+
RunSpecs(t, "Test Install Command")
66+
}
67+
68+
var _ = Describe("Test the install command works as expected", func() {
69+
type testCase struct {
70+
provider string
71+
parameters []string
72+
providerValue string
73+
regionValue string
74+
customLabelValue string
75+
clusterNameValue string
76+
enableAdvertisementValue bool
77+
enableDiscoveryValue bool
78+
reservedSubnetsValue []interface{}
79+
}
80+
81+
DescribeTable("An install command is issued",
82+
func(tc testCase) {
83+
cmd := &cobra.Command{}
84+
cmd.PersistentFlags().Bool("enable-lan-discovery", false, "")
85+
cmd.PersistentFlags().String("cluster-labels", "", "")
86+
cmd.PersistentFlags().String("cluster-name", "default-cluster-name", "")
87+
cmd.PersistentFlags().String("reserved-subnets", "", "")
88+
cmd.PersistentFlags().Bool("generate-name", false, "")
89+
cmd.SetArgs(tc.parameters)
90+
Expect(cmd.Execute()).To(Succeed())
91+
92+
providerInstance := getProviderInstance(tc.provider)
93+
Expect(providerInstance).NotTo(BeNil())
94+
err := providerInstance.PreValidateGenericCommandArguments(cmd.Flags())
95+
Expect(err).ToNot(HaveOccurred())
96+
err = providerInstance.ValidateCommandArguments(cmd.Flags())
97+
Expect(err).ToNot(HaveOccurred())
98+
err = providerInstance.PostValidateGenericCommandArguments("")
99+
Expect(err).ToNot(HaveOccurred())
100+
101+
// Chart values
102+
chartValues := map[string]interface{}{
103+
"discovery": map[string]interface{}{
104+
"config": map[string]interface{}{
105+
"clusterLabels": map[string]interface{}{},
106+
"clusterName": "",
107+
"enableAdvertisement": false,
108+
"enableDiscovery": false,
109+
},
110+
},
111+
"networkManager": map[string]interface{}{
112+
"config": map[string]interface{}{
113+
"reservedSubnets": []interface{}{},
114+
},
115+
},
116+
}
117+
118+
// Common values
119+
enableLanDiscovery, err := cmd.Flags().GetBool("enable-lan-discovery")
120+
Expect(err).ToNot(HaveOccurred())
121+
clusterLabels, err := cmd.Flags().GetString("cluster-labels")
122+
Expect(err).ToNot(HaveOccurred())
123+
clusterLabelsVar := argsutils.StringMap{}
124+
err = clusterLabelsVar.Set(clusterLabels)
125+
Expect(err).ToNot(HaveOccurred())
126+
clusterLabelsMap := installutils.GetInterfaceMap(clusterLabelsVar.StringMap)
127+
commonValues := map[string]interface{}{
128+
"discovery": map[string]interface{}{
129+
"config": map[string]interface{}{
130+
"clusterLabels": clusterLabelsMap,
131+
"enableAdvertisement": enableLanDiscovery,
132+
"enableDiscovery": enableLanDiscovery,
133+
},
134+
},
135+
}
136+
137+
// Provider values
138+
providerValues := make(map[string]interface{})
139+
providerInstance.UpdateChartValues(providerValues)
140+
141+
// Merged values
142+
values, err := generateValues(chartValues, commonValues, providerValues)
143+
Expect(err).ToNot(HaveOccurred())
144+
145+
// Test values over expected ones
146+
Expect(ValueFor(values, "discovery", "config", "clusterLabels", "liqo.io/provider")).To(Equal(tc.providerValue))
147+
Expect(ValueFor(values, "discovery", "config", "clusterName")).To(Equal(tc.clusterNameValue))
148+
Expect(ValueFor(values, "discovery", "config", "clusterLabels", "topology.liqo.io/region")).To(Equal(tc.regionValue))
149+
Expect(ValueFor(values, "discovery", "config", "clusterLabels", "liqo.io/my-label")).To(Equal(tc.customLabelValue))
150+
Expect(ValueFor(values, "discovery", "config", "enableAdvertisement")).To(Equal(tc.enableAdvertisementValue))
151+
Expect(ValueFor(values, "discovery", "config", "enableDiscovery")).To(Equal(tc.enableDiscoveryValue))
152+
Expect(ValueFor(values, "networkManager", "config", "reservedSubnets")).To(Equal(tc.reservedSubnetsValue))
153+
},
154+
Entry("Install Kind cluster with default parameters", testCase{
155+
"kind",
156+
[]string{},
157+
"kind",
158+
"",
159+
"",
160+
"default-cluster-name",
161+
true,
162+
true,
163+
[]interface{}{},
164+
}),
165+
Entry("Install Kind cluster with one cluster labels' key-value pair", testCase{
166+
"kind",
167+
[]string{"--cluster-labels=topology.liqo.io/region=eu-east"},
168+
"kind",
169+
"eu-east",
170+
"",
171+
"default-cluster-name",
172+
true,
173+
true,
174+
[]interface{}{},
175+
}),
176+
Entry("Install Kind cluster with cluster labels, auto-discovery disabled, cluster name and reserved subnets", testCase{
177+
"kind",
178+
[]string{
179+
"--cluster-labels=topology.liqo.io/region=eu-east,liqo.io/my-label=custom,liqo.io/provider=provider-1",
180+
"--enable-lan-discovery=false",
181+
"--cluster-name=cluster-1",
182+
"--reserved-subnets=10.20.30.0/24,10.20.31.0/24",
183+
},
184+
"provider-1",
185+
"eu-east",
186+
"custom",
187+
"cluster-1",
188+
false,
189+
false,
190+
[]interface{}{"10.20.30.0/24", "10.20.31.0/24"},
191+
}),
192+
Entry("Install Kubeadm cluster with default parameters", testCase{
193+
"kubeadm",
194+
[]string{},
195+
"kubeadm",
196+
"",
197+
"",
198+
"default-cluster-name",
199+
false,
200+
false,
201+
[]interface{}{},
202+
}),
203+
Entry("Install Kubeadm cluster with cluster labels, cluster name and reserved subnets", testCase{
204+
"kubeadm",
205+
[]string{
206+
"--cluster-labels=topology.liqo.io/region=eu-east,liqo.io/my-label=custom,liqo.io/provider=provider-1",
207+
"--cluster-name=cluster-1",
208+
"--reserved-subnets=10.20.30.0/24,10.20.31.0/24",
209+
},
210+
"provider-1",
211+
"eu-east",
212+
"custom",
213+
"cluster-1",
214+
false,
215+
false,
216+
[]interface{}{"10.20.30.0/24", "10.20.31.0/24"},
217+
}),
218+
)
219+
})

pkg/liqoctl/install/kind/provider.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,16 @@ func (k *Kind) UpdateChartValues(values map[string]interface{}) {
5757
"reservedSubnets": installutils.GetInterfaceSlice(k.ReservedSubnets),
5858
},
5959
}
60+
if k.LanDiscovery == nil {
61+
lanDiscovery := true
62+
k.LanDiscovery = &lanDiscovery
63+
}
6064
values["discovery"] = map[string]interface{}{
6165
"config": map[string]interface{}{
6266
"clusterLabels": installutils.GetInterfaceMap(k.ClusterLabels),
6367
"clusterName": k.ClusterName,
64-
"enableAdvertisement": true,
65-
"enableDiscovery": true,
68+
"enableAdvertisement": *k.LanDiscovery,
69+
"enableDiscovery": *k.LanDiscovery,
6670
},
6771
}
6872
}

pkg/liqoctl/install/provider/args.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
flag "github.com/spf13/pflag"
2222

23+
"github.com/liqotech/liqo/pkg/consts"
2324
installutils "github.com/liqotech/liqo/pkg/liqoctl/install/utils"
2425
argsutils "github.com/liqotech/liqo/pkg/utils/args"
2526
)
@@ -83,11 +84,7 @@ func ValidateCommonArguments(providerName string, flags *flag.FlagSet) (*CommonA
8384
if err != nil {
8485
return nil, err
8586
}
86-
clusterLabels, err := flags.GetString("cluster-labels")
87-
if err != nil {
88-
return nil, err
89-
}
90-
lanDiscovery, err := flags.GetBool("enable-lan-discovery")
87+
lanDiscovery, err := flags.GetBool(consts.EnableLanDiscoveryParameter)
9188
if err != nil {
9289
return nil, err
9390
}
@@ -111,7 +108,7 @@ func ValidateCommonArguments(providerName string, flags *flag.FlagSet) (*CommonA
111108
if err != nil {
112109
return nil, err
113110
}
114-
commonValues, err := parseCommonValues(providerName, clusterLabels, chartPath, version, resourceSharingPercentage,
111+
commonValues, err := parseCommonValues(providerName, chartPath, version, resourceSharingPercentage,
115112
lanDiscovery, enableHa, float64(ifaceMTU), float64(listeningPort))
116113
if err != nil {
117114
return nil, err
@@ -130,12 +127,8 @@ func ValidateCommonArguments(providerName string, flags *flag.FlagSet) (*CommonA
130127
}, nil
131128
}
132129

133-
func parseCommonValues(providerName, clusterLabels, chartPath, version, resourceSharingPercentage string,
130+
func parseCommonValues(providerName, chartPath, version, resourceSharingPercentage string,
134131
lanDiscovery, enableHa bool, mtu, port float64) (map[string]interface{}, error) {
135-
clusterLabelsVar := argsutils.StringMap{}
136-
if err := clusterLabelsVar.Set(clusterLabels); err != nil {
137-
return map[string]interface{}{}, err
138-
}
139132

140133
// If the chartPath is different from the official repo, we force the tag parameter in order to set the correct
141134
// prefix for the images.
@@ -164,7 +157,6 @@ func parseCommonValues(providerName, clusterLabels, chartPath, version, resource
164157
"tag": tag,
165158
"discovery": map[string]interface{}{
166159
"config": map[string]interface{}{
167-
"clusterLabels": installutils.GetInterfaceMap(clusterLabelsVar.StringMap),
168160
"enableDiscovery": lanDiscovery,
169161
"enableAdvertisement": lanDiscovery,
170162
},

pkg/liqoctl/install/provider/args_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ var _ = Describe("Args", func() {
4545
When("mtu is set to zero, falling back to default value for each provider", func() {
4646
It("should return the right mtu in the configuration map", func() {
4747
for _, provider := range Providers {
48-
config, err := parseCommonValues(provider, "", "", "", "", false, false, 0, 0)
48+
config, err := parseCommonValues(provider, "", "", "", false, false, 0, 0)
4949
Expect(err).NotTo(HaveOccurred())
5050
netConfig := config["networkConfig"].(map[string]interface{})
5151
Expect(netConfig["mtu"]).To(BeNumerically("==", providersDefaultMTU[provider]))
@@ -55,7 +55,7 @@ var _ = Describe("Args", func() {
5555

5656
When("the provider does not exist", func() {
5757
It("should return an error", func() {
58-
_, err := parseCommonValues("notExisting", "", "", "", "", false, false, 0, 0)
58+
_, err := parseCommonValues("notExisting", "", "", "", false, false, 0, 0)
5959
Expect(err).To(HaveOccurred())
6060
Expect(err).To(MatchError(fmt.Errorf("mtu for provider notExisting not found")))
6161
})
@@ -64,7 +64,7 @@ var _ = Describe("Args", func() {
6464
When("the mtu is set by the user", func() {
6565
It("should set the mtu", func() {
6666
var mtu float64 = 1340
67-
config, err := parseCommonValues("eks", "", "", "", "", false, false, mtu, 0)
67+
config, err := parseCommonValues("eks", "", "", "", false, false, mtu, 0)
6868
Expect(err).NotTo(HaveOccurred())
6969
netConfig := config["networkConfig"].(map[string]interface{})
7070
Expect(netConfig["mtu"]).To(BeNumerically("==", mtu))

0 commit comments

Comments
 (0)