github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/pkg/clusterfile/decoder_test.go (about) 1 // Copyright © 2022 Alibaba Group Holding Ltd. 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 clusterfile 16 17 import ( 18 "net" 19 "os" 20 "testing" 21 22 "github.com/sealerio/sealer/types/api/constants" 23 24 "github.com/stretchr/testify/assert" 25 "k8s.io/kube-proxy/config/v1alpha1" 26 27 v1 "github.com/sealerio/sealer/types/api/v1" 28 v2 "github.com/sealerio/sealer/types/api/v2" 29 ) 30 31 const data = `apiVersion: sealer.com/v1alpha1 32 kind: Config 33 metadata: 34 name: mysql-config 35 spec: 36 path: etc/mysql.yaml 37 data: | 38 mysql-user: root 39 mysql-passwd: xxx 40 --- 41 apiVersion: sealer.io/v2 42 kind: Application 43 metadata: 44 name: my-apps 45 spec: 46 launchApps: 47 - app1 48 - app2 49 configs: 50 - name: app2 51 launch: 52 cmds: 53 - kubectl get pods -A 54 --- 55 apiVersion: sealer.io/v1 56 kind: Plugin 57 metadata: 58 name: MyHostname # Specify this plugin name,will dump in $rootfs/plugins dir. 59 spec: 60 type: HOSTNAME # fixed string,should not change this name. 61 action: PreInit # Specify which phase to run. 62 data: | 63 192.168.0.2 master-0 64 --- 65 apiVersion: sealer.io/v1 66 kind: Plugin 67 metadata: 68 name: MyShell # Specify this plugin name,will dump in $rootfs/plugins dir. 69 spec: 70 type: SHELL 71 action: PostInstall # PreInit PostInstall 72 scope: master 73 data: | 74 kubectl get nodes 75 --- 76 apiVersion: sealer.io/v2 77 kind: Cluster 78 metadata: 79 name: my-cluster 80 spec: 81 image: kubernetes:v1.19.8 82 env: 83 - key1=value1 84 - key2=value2;value3 #key2=[value2, value3] 85 ssh: 86 passwd: test123 87 pk: xxx 88 pkPasswd: xxx 89 user: root 90 port: "22" 91 hosts: 92 - ips: [ 192.168.0.2 ] 93 roles: [ master ] # add role field to specify the node role 94 env: # rewrite some nodes has different env config 95 - etcd-dir=/data/etcd 96 ssh: # rewrite ssh config if some node has different passwd... 97 user: root 98 passwd: test456 99 port: "22" 100 - ips: [ 192.168.0.3 ] 101 roles: [ node,db ] 102 --- 103 apiVersion: kubeadm.k8s.io/v1beta3 104 kind: InitConfiguration 105 localAPIEndpoint: 106 bindPort: 6443 107 nodeRegistration: 108 criSocket: /var/run/dockershim.sock 109 --- 110 apiVersion: kubeproxy.config.k8s.io/v1alpha1 111 kind: KubeProxyConfiguration 112 mode: "ipvs" 113 ipvs: 114 excludeCIDRs: 115 - "10.103.97.2/32"` 116 117 func TestDecodeClusterFile(t *testing.T) { 118 cluster := v2.Cluster{ 119 Spec: v2.ClusterSpec{ 120 Image: "kubernetes:v1.19.8", 121 DataRoot: "/var/lib/sealer/data", 122 Env: []string{"key1=value1", "key2=value2;value3", "LocalRegistryDomain=sea.hub", "LocalRegistryPort=5000", "LocalRegistryURL=sea.hub:5000", "RegistryDomain=sea.hub", "RegistryPort=5000", "RegistryURL=sea.hub:5000"}, 123 SSH: v1.SSH{ 124 User: "root", 125 Passwd: "test123", 126 Port: "22", 127 Pk: "xxx", 128 PkPasswd: "xxx", 129 }, 130 Registry: v2.Registry{ 131 LocalRegistry: &v2.LocalRegistry{ 132 RegistryConfig: v2.RegistryConfig{ 133 Domain: "sea.hub", 134 Port: 5000, 135 }, 136 HA: &defaultHA, 137 Insecure: &defaultInsecure, 138 }, 139 }, 140 Hosts: []v2.Host{ 141 { 142 IPS: []net.IP{net.IPv4(192, 168, 0, 2)}, 143 Roles: []string{"master"}, 144 Env: []string{"etcd-dir=/data/etcd"}, 145 SSH: v1.SSH{ 146 User: "root", 147 Passwd: "test456", 148 Port: "22", 149 }, 150 }, 151 { 152 IPS: []net.IP{net.IPv4(192, 168, 0, 3)}, 153 Roles: []string{"node", "db"}, 154 }, 155 }, 156 }, 157 } 158 cluster.APIVersion = "sealer.io/v2" 159 cluster.Kind = "Cluster" 160 cluster.Name = "my-cluster" 161 162 plugin1 := v1.Plugin{ 163 Spec: v1.PluginSpec{ 164 Type: "HOSTNAME", 165 Data: "192.168.0.2 master-0\n", 166 Action: "PreInit", 167 }, 168 } 169 plugin1.Name = "MyHostname" 170 plugin1.Kind = constants.PluginKind 171 plugin1.APIVersion = v1.GroupVersion.String() 172 173 plugin2 := v1.Plugin{ 174 Spec: v1.PluginSpec{ 175 Type: "SHELL", 176 Data: "kubectl get nodes\n", 177 Scope: "master", 178 Action: "PostInstall", 179 }, 180 } 181 plugin2.Name = "MyShell" 182 plugin2.Kind = "Plugin" 183 plugin2.APIVersion = "sealer.io/v1" 184 185 config := v1.Config{ 186 Spec: v1.ConfigSpec{ 187 Path: "etc/mysql.yaml", 188 Data: "mysql-user: root\nmysql-passwd: xxx\n", 189 }, 190 } 191 config.Name = "mysql-config" 192 config.Kind = "Config" 193 config.APIVersion = "sealer.com/v1alpha1" 194 195 app := &v2.Application{ 196 Spec: v2.ApplicationSpec{ 197 LaunchApps: []string{"app1", "app2"}, 198 Configs: []v2.ApplicationConfig{ 199 { 200 Name: "app2", 201 Launch: &v2.Launch{ 202 Cmds: []string{ 203 "kubectl get pods -A", 204 }, 205 }, 206 }, 207 }, 208 }, 209 } 210 app.Name = "my-apps" 211 app.Kind = constants.ApplicationKind 212 app.APIVersion = v2.GroupVersion.String() 213 214 type wanted struct { 215 cluster v2.Cluster 216 config []v1.Config 217 plugins []v1.Plugin 218 application *v2.Application 219 } 220 221 type args struct { 222 data []byte 223 wanted wanted 224 } 225 226 var tests = []struct { 227 name string 228 args args 229 }{ 230 { 231 "test decode cluster file", 232 args{ 233 data: []byte(data), 234 wanted: wanted{ 235 cluster: cluster, 236 config: []v1.Config{config}, 237 plugins: []v1.Plugin{plugin1, plugin2}, 238 application: app, 239 }, 240 }, 241 }, 242 } 243 244 f, err := os.CreateTemp("", "tmpfile-") 245 if err != nil { 246 assert.Error(t, err) 247 } 248 249 defer os.Remove(f.Name()) 250 251 if _, err = f.Write([]byte(data)); err != nil { 252 assert.Error(t, err) 253 } 254 if err = f.Close(); err != nil { 255 assert.Error(t, err) 256 } 257 258 for _, tt := range tests { 259 t.Run(tt.name, func(t *testing.T) { 260 i, err := NewClusterFile([]byte(data)) 261 if err != nil { 262 assert.Errorf(t, err, "failed to NewClusterFile by name") 263 } 264 265 assert.NotNil(t, i) 266 267 assert.Equal(t, tt.args.wanted.cluster, i.GetCluster()) 268 269 assert.Equal(t, tt.args.wanted.config, i.GetConfigs()) 270 271 assert.Equal(t, tt.args.wanted.plugins, i.GetPlugins()) 272 273 assert.Equal(t, tt.args.wanted.application, i.GetApplication()) 274 275 kubeadm := i.GetKubeadmConfig() 276 assert.NotNil(t, kubeadm) 277 278 assert.Equal(t, kubeadm.LocalAPIEndpoint.BindPort, int32(6443)) 279 assert.Equal(t, kubeadm.InitConfiguration.NodeRegistration.CRISocket, "/var/run/dockershim.sock") 280 281 assert.Equal(t, kubeadm.Mode, v1alpha1.ProxyMode("ipvs")) 282 assert.Equal(t, kubeadm.IPVS.ExcludeCIDRs, []string{"10.103.97.2/32"}) 283 }) 284 } 285 }