github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/kubeblocks/config_test.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package kubeblocks
    21  
    22  import (
    23  	"bytes"
    24  	"strings"
    25  
    26  	. "github.com/onsi/ginkgo/v2"
    27  	. "github.com/onsi/gomega"
    28  
    29  	"helm.sh/helm/v3/pkg/cli/values"
    30  	appsv1 "k8s.io/api/apps/v1"
    31  	corev1 "k8s.io/api/core/v1"
    32  	"k8s.io/cli-runtime/pkg/genericiooptions"
    33  	clientfake "k8s.io/client-go/rest/fake"
    34  	cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
    35  
    36  	"github.com/1aal/kubeblocks/pkg/cli/printer"
    37  	"github.com/1aal/kubeblocks/pkg/cli/testing"
    38  	"github.com/1aal/kubeblocks/pkg/cli/types"
    39  	"github.com/1aal/kubeblocks/pkg/cli/util/helm"
    40  	"github.com/1aal/kubeblocks/version"
    41  )
    42  
    43  var _ = Describe("backupconfig", func() {
    44  	var streams genericiooptions.IOStreams
    45  	var tf *cmdtesting.TestFactory
    46  	var o *InstallOptions
    47  	var out *bytes.Buffer
    48  
    49  	mockDeploy := func() *appsv1.Deployment {
    50  		deploy := &appsv1.Deployment{}
    51  		deploy.SetLabels(map[string]string{
    52  			"app.kubernetes.io/name":    types.KubeBlocksChartName,
    53  			"app.kubernetes.io/version": "0.3.0",
    54  		})
    55  		deploy.Spec.Template.Spec.Containers = []corev1.Container{
    56  			{
    57  				Name: "kb",
    58  				Env: []corev1.EnvVar{
    59  					{
    60  						Name:  "CM_NAMESPACE",
    61  						Value: "default",
    62  					},
    63  				},
    64  			},
    65  		}
    66  		return deploy
    67  	}
    68  
    69  	mockHelmConfig := func(release string, opt *Options) (map[string]interface{}, error) {
    70  		values := map[string]interface{}{
    71  			"updateStrategy": map[string]interface{}{
    72  				"rollingUpdate": map[string]interface{}{
    73  					"maxSurge":       1,
    74  					"maxUnavailable": "40%",
    75  				},
    76  				"type": "RollingUpdate",
    77  			},
    78  			"podDisruptionBudget": map[string]interface{}{
    79  				"minAvailable": 1,
    80  			},
    81  			"loggerSettings": map[string]interface{}{
    82  				"developmentMode": false,
    83  				"encoder":         "console",
    84  				"timeEncoding":    "iso8601",
    85  			},
    86  			"cloudProvider": map[string]interface{}{
    87  				"accessKey": "testAK",
    88  			},
    89  			"priorityClassName": nil,
    90  			"nameOverride":      "",
    91  			"fullnameOverride":  "",
    92  			"dnsPolicy":         "ClusterFirst",
    93  			"replicaCount":      1,
    94  			"hostNetwork":       false,
    95  			"keepAddons":        false,
    96  		}
    97  		for _, key := range sensitiveValues {
    98  			sp := strings.Split(key, ".")
    99  			rootKey := sp[0]
   100  			if node, ok := values[rootKey]; ok {
   101  				encryptNodeData(values, node, sp, 0)
   102  			}
   103  		}
   104  		return values, nil
   105  	}
   106  
   107  	BeforeEach(func() {
   108  		streams, _, out, _ = genericiooptions.NewTestIOStreams()
   109  		tf = cmdtesting.NewTestFactory().WithNamespace(testing.Namespace)
   110  		tf.Client = &clientfake.RESTClient{}
   111  		// use a fake URL to test
   112  		types.KubeBlocksChartName = testing.KubeBlocksChartName
   113  		types.KubeBlocksChartURL = testing.KubeBlocksChartURL
   114  		o = &InstallOptions{
   115  			Options: Options{
   116  				IOStreams: streams,
   117  				HelmCfg:   helm.NewFakeConfig(testing.Namespace),
   118  				Namespace: "default",
   119  				Client:    testing.FakeClientSet(mockDeploy()),
   120  				Dynamic:   testing.FakeDynamicClient(),
   121  			},
   122  			Version:   version.DefaultKubeBlocksVersion,
   123  			ValueOpts: values.Options{Values: []string{"snapshot-controller.enabled=true"}},
   124  		}
   125  	})
   126  
   127  	AfterEach(func() {
   128  		tf.Cleanup()
   129  	})
   130  
   131  	It("run config cmd", func() {
   132  		cmd := NewConfigCmd(tf, streams)
   133  		Expect(cmd).ShouldNot(BeNil())
   134  		Expect(o.PreCheck()).Should(HaveOccurred())
   135  	})
   136  
   137  	It("pruningConfigResults test, and expected success", func() {
   138  		configs := map[string]interface{}{
   139  			"key1": "value1",
   140  			"key2": "value2",
   141  			"key3": "value3",
   142  		}
   143  		tests := []struct {
   144  			configs       map[string]interface{}
   145  			showAllConfig bool
   146  			filterConfig  string
   147  			keyWhiteList  []string
   148  			results       map[string]interface{}
   149  		}{
   150  			{
   151  				configs,
   152  				true,
   153  				"",
   154  				keyWhiteList,
   155  				configs,
   156  			}, {
   157  				configs,
   158  				false,
   159  				"key1",
   160  				keyWhiteList,
   161  				map[string]interface{}{
   162  					"key1": "value1",
   163  				},
   164  			}, {
   165  				configs,
   166  				false,
   167  				"",
   168  				[]string{"key2"},
   169  				map[string]interface{}{
   170  					"key2": "value2",
   171  				},
   172  			}, {
   173  				configs,
   174  				false,
   175  				"",
   176  				[]string{},
   177  				map[string]interface{}{},
   178  			}}
   179  		Eventually(func(g Gomega) {
   180  			for _, t := range tests {
   181  				showAllConfig = t.showAllConfig
   182  				filterConfig = t.filterConfig
   183  				keyWhiteList = t.keyWhiteList
   184  				g.Expect(pruningConfigResults(t.configs)).Should(Equal(t.results))
   185  			}
   186  		}).Should(Succeed())
   187  	})
   188  
   189  	Context("run describe config cmd", func() {
   190  		var output printer.Format
   191  
   192  		It("describe-config --output table/wide", func() {
   193  			output = printer.Table
   194  			err := describeConfig(o, output, mockHelmConfig)
   195  			Expect(err).Should(Succeed())
   196  			expect := `KEY                                VALUE                                   
   197  cloudProvider.accessKey            "******"                                
   198  dnsPolicy                          "ClusterFirst"                          
   199  fullnameOverride                   ""                                      
   200  hostNetwork                        false                                   
   201  keepAddons                         false                                   
   202  loggerSettings.developmentMode     false                                   
   203  loggerSettings.encoder             "console"                               
   204  loggerSettings.timeEncoding        "iso8601"                               
   205  nameOverride                       ""                                      
   206  podDisruptionBudget.minAvailable   1                                       
   207  priorityClassName                  <nil>                                   
   208  replicaCount                       1                                       
   209  updateStrategy.rollingUpdate       {"maxSurge":1,"maxUnavailable":"40%"}   
   210  updateStrategy.type                "RollingUpdate"                         
   211  `
   212  			Expect(out.String()).Should(Equal(expect))
   213  		})
   214  
   215  		It("describe-config --output json", func() {
   216  			output = printer.JSON
   217  			expect := `{
   218    "cloudProvider": {
   219      "accessKey": "******"
   220    },
   221    "dnsPolicy": "ClusterFirst",
   222    "fullnameOverride": "",
   223    "hostNetwork": false,
   224    "keepAddons": false,
   225    "loggerSettings": {
   226      "developmentMode": false,
   227      "encoder": "console",
   228      "timeEncoding": "iso8601"
   229    },
   230    "nameOverride": "",
   231    "podDisruptionBudget": {
   232      "minAvailable": 1
   233    },
   234    "priorityClassName": null,
   235    "replicaCount": 1,
   236    "updateStrategy": {
   237      "rollingUpdate": {
   238        "maxSurge": 1,
   239        "maxUnavailable": "40%"
   240      },
   241      "type": "RollingUpdate"
   242    }
   243  }
   244  `
   245  			err := describeConfig(o, output, mockHelmConfig)
   246  			Expect(err).Should(Succeed())
   247  			Expect(out.String()).Should(Equal(expect))
   248  		})
   249  
   250  		It("describe-config --output yaml", func() {
   251  			output = printer.YAML
   252  			expect := `cloudProvider:
   253    accessKey: '******'
   254  dnsPolicy: ClusterFirst
   255  fullnameOverride: ""
   256  hostNetwork: false
   257  keepAddons: false
   258  loggerSettings:
   259    developmentMode: false
   260    encoder: console
   261    timeEncoding: iso8601
   262  nameOverride: ""
   263  podDisruptionBudget:
   264    minAvailable: 1
   265  priorityClassName: null
   266  replicaCount: 1
   267  updateStrategy:
   268    rollingUpdate:
   269      maxSurge: 1
   270      maxUnavailable: 40%
   271    type: RollingUpdate
   272  `
   273  			err := describeConfig(o, output, mockHelmConfig)
   274  			Expect(err).Should(Succeed())
   275  			Expect(out.String()).Should(Equal(expect))
   276  		})
   277  	})
   278  })