github.com/oam-dev/kubevela@v1.9.11/pkg/policy/envbinding/patch_test.go (about)

     1  /*
     2   Copyright 2021. The KubeVela Authors.
     3  
     4   Licensed under the Apache License, Version 2.0 (the "License");
     5   you may not use this file except in compliance with the License.
     6   You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10   Unless required by applicable law or agreed to in writing, software
    11   distributed under the License is distributed on an "AS IS" BASIS,
    12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   See the License for the specific language governing permissions and
    14   limitations under the License.
    15  */
    16  
    17  package envbinding
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/stretchr/testify/require"
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  
    25  	"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
    26  	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
    27  	"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
    28  	"github.com/oam-dev/kubevela/pkg/oam/util"
    29  )
    30  
    31  func Test_EnvBindApp_GenerateConfiguredApplication(t *testing.T) {
    32  	testCases := map[string]struct {
    33  		baseApp     *v1beta1.Application
    34  		envName     string
    35  		envPatch    v1alpha1.EnvPatch
    36  		expectedApp *v1beta1.Application
    37  		selector    *v1alpha1.EnvSelector
    38  	}{
    39  		"normal-test": {
    40  			baseApp: baseApp,
    41  			envName: "prod",
    42  			envPatch: v1alpha1.EnvPatch{
    43  				Components: []v1alpha1.EnvComponentPatch{{
    44  					Name: "express-server",
    45  					Type: "webservice",
    46  					Properties: util.Object2RawExtension(map[string]interface{}{
    47  						"image": "busybox",
    48  					}),
    49  					Traits: []v1alpha1.EnvTraitPatch{{
    50  						Type: "ingress-1-20",
    51  						Properties: util.Object2RawExtension(map[string]interface{}{
    52  							"domain": "newTestsvc.example.com",
    53  						}),
    54  					}},
    55  				}},
    56  			},
    57  			expectedApp: &v1beta1.Application{
    58  				TypeMeta: metav1.TypeMeta{
    59  					APIVersion: "v1beta1",
    60  					Kind:       "Application",
    61  				},
    62  				ObjectMeta: metav1.ObjectMeta{
    63  					Name: "test",
    64  				},
    65  				Spec: v1beta1.ApplicationSpec{
    66  					Components: []common.ApplicationComponent{{
    67  						Name: "express-server",
    68  						Type: "webservice",
    69  						Properties: util.Object2RawExtension(map[string]interface{}{
    70  							"image": "busybox",
    71  							"port":  8000,
    72  						}),
    73  						Traits: []common.ApplicationTrait{{
    74  							Type: "ingress-1-20",
    75  							Properties: util.Object2RawExtension(map[string]interface{}{
    76  								"domain": "newTestsvc.example.com",
    77  								"http": map[string]interface{}{
    78  									"/": 8000,
    79  								},
    80  							}),
    81  						}},
    82  					}},
    83  				},
    84  			},
    85  		},
    86  		"add-component": {
    87  			baseApp: baseApp,
    88  			envName: "prod",
    89  			envPatch: v1alpha1.EnvPatch{
    90  				Components: []v1alpha1.EnvComponentPatch{{
    91  					Name: "express-server",
    92  					Type: "webservice",
    93  					Traits: []v1alpha1.EnvTraitPatch{{
    94  						Type: "labels",
    95  						Properties: util.Object2RawExtension(map[string]interface{}{
    96  							"test": "label",
    97  						}),
    98  					}},
    99  				}, {
   100  					Name: "new-server",
   101  					Type: "worker",
   102  					Properties: util.Object2RawExtension(map[string]interface{}{
   103  						"image": "busybox",
   104  						"cmd":   []string{"sleep", "1000"},
   105  					}),
   106  					Traits: []v1alpha1.EnvTraitPatch{{
   107  						Type: "labels",
   108  						Properties: util.Object2RawExtension(map[string]interface{}{
   109  							"test": "label",
   110  						}),
   111  					}},
   112  				}},
   113  			},
   114  			expectedApp: &v1beta1.Application{
   115  				TypeMeta: metav1.TypeMeta{
   116  					APIVersion: "v1beta1",
   117  					Kind:       "Application",
   118  				},
   119  				ObjectMeta: metav1.ObjectMeta{
   120  					Name: "test",
   121  				},
   122  				Spec: v1beta1.ApplicationSpec{
   123  					Components: []common.ApplicationComponent{{
   124  						Name: "express-server",
   125  						Type: "webservice",
   126  						Properties: util.Object2RawExtension(map[string]interface{}{
   127  							"image": "crccheck/hello-world",
   128  							"port":  8000,
   129  						}),
   130  						Traits: []common.ApplicationTrait{{
   131  							Type: "ingress-1-20",
   132  							Properties: util.Object2RawExtension(map[string]interface{}{
   133  								"domain": "testsvc.example.com",
   134  								"http": map[string]interface{}{
   135  									"/": 8000,
   136  								},
   137  							}),
   138  						}, {
   139  							Type: "labels",
   140  							Properties: util.Object2RawExtension(map[string]interface{}{
   141  								"test": "label",
   142  							}),
   143  						}},
   144  					}, {
   145  						Name: "new-server",
   146  						Type: "worker",
   147  						Properties: util.Object2RawExtension(map[string]interface{}{
   148  							"image": "busybox",
   149  							"cmd":   []string{"sleep", "1000"},
   150  						}),
   151  						Traits: []common.ApplicationTrait{{
   152  							Type: "labels",
   153  							Properties: util.Object2RawExtension(map[string]interface{}{
   154  								"test": "label",
   155  							}),
   156  						}},
   157  					}},
   158  				},
   159  			},
   160  		},
   161  		"disable-trait": {
   162  			baseApp: baseApp,
   163  			envName: "prod",
   164  			envPatch: v1alpha1.EnvPatch{
   165  				Components: []v1alpha1.EnvComponentPatch{{
   166  					Name: "express-server",
   167  					Type: "webservice",
   168  					Traits: []v1alpha1.EnvTraitPatch{{
   169  						Type:    "ingress-1-20",
   170  						Disable: true,
   171  					}},
   172  				}},
   173  			},
   174  			expectedApp: &v1beta1.Application{
   175  				TypeMeta: metav1.TypeMeta{
   176  					APIVersion: "v1beta1",
   177  					Kind:       "Application",
   178  				},
   179  				ObjectMeta: metav1.ObjectMeta{
   180  					Name: "test",
   181  				},
   182  				Spec: v1beta1.ApplicationSpec{
   183  					Components: []common.ApplicationComponent{{
   184  						Name: "express-server",
   185  						Type: "webservice",
   186  						Properties: util.Object2RawExtension(map[string]interface{}{
   187  							"image": "crccheck/hello-world",
   188  							"port":  8000,
   189  						}),
   190  						Traits: []common.ApplicationTrait{},
   191  					}},
   192  				},
   193  			},
   194  		},
   195  		"component-selector": {
   196  			baseApp: baseApp,
   197  			envName: "prod",
   198  			envPatch: v1alpha1.EnvPatch{
   199  				Components: []v1alpha1.EnvComponentPatch{{
   200  					Name: "new-server",
   201  					Type: "worker",
   202  					Properties: util.Object2RawExtension(map[string]interface{}{
   203  						"image": "busybox",
   204  					}),
   205  				}},
   206  			},
   207  			selector: &v1alpha1.EnvSelector{
   208  				Components: []string{"new-server"},
   209  			},
   210  			expectedApp: &v1beta1.Application{
   211  				TypeMeta: metav1.TypeMeta{
   212  					APIVersion: "v1beta1",
   213  					Kind:       "Application",
   214  				},
   215  				ObjectMeta: metav1.ObjectMeta{
   216  					Name: "test",
   217  				},
   218  				Spec: v1beta1.ApplicationSpec{
   219  					Components: []common.ApplicationComponent{{
   220  						Name: "new-server",
   221  						Type: "worker",
   222  						Properties: util.Object2RawExtension(map[string]interface{}{
   223  							"image": "busybox",
   224  						}),
   225  					}},
   226  				},
   227  			},
   228  		},
   229  		"empty-component-selector": {
   230  			baseApp: baseApp,
   231  			envName: "prod",
   232  			envPatch: v1alpha1.EnvPatch{
   233  				Components: []v1alpha1.EnvComponentPatch{{
   234  					Name: "new-server",
   235  					Type: "worker",
   236  					Properties: util.Object2RawExtension(map[string]interface{}{
   237  						"image": "busybox",
   238  					}),
   239  				}},
   240  			},
   241  			selector: &v1alpha1.EnvSelector{
   242  				Components: []string{},
   243  			},
   244  			expectedApp: &v1beta1.Application{
   245  				TypeMeta: metav1.TypeMeta{
   246  					APIVersion: "v1beta1",
   247  					Kind:       "Application",
   248  				},
   249  				ObjectMeta: metav1.ObjectMeta{
   250  					Name: "test",
   251  				},
   252  				Spec: v1beta1.ApplicationSpec{
   253  					Components: []common.ApplicationComponent{},
   254  				},
   255  			},
   256  		},
   257  		"patch-external-revision": {
   258  			baseApp: baseApp,
   259  			envName: "prod",
   260  			envPatch: v1alpha1.EnvPatch{
   261  				Components: []v1alpha1.EnvComponentPatch{{
   262  					Name:             "express-server",
   263  					Type:             "webservice",
   264  					ExternalRevision: "external-rev",
   265  				}},
   266  			},
   267  			expectedApp: &v1beta1.Application{
   268  				TypeMeta: metav1.TypeMeta{
   269  					APIVersion: "v1beta1",
   270  					Kind:       "Application",
   271  				},
   272  				ObjectMeta: metav1.ObjectMeta{
   273  					Name: "test",
   274  				},
   275  				Spec: v1beta1.ApplicationSpec{
   276  					Components: []common.ApplicationComponent{{
   277  						Name: "express-server",
   278  						Type: "webservice",
   279  						Properties: util.Object2RawExtension(map[string]interface{}{
   280  							"image": "crccheck/hello-world",
   281  							"port":  8000,
   282  						}),
   283  						ExternalRevision: "external-rev",
   284  						Traits: []common.ApplicationTrait{{
   285  							Type: "ingress-1-20",
   286  							Properties: util.Object2RawExtension(map[string]interface{}{
   287  								"domain": "testsvc.example.com",
   288  								"http": map[string]interface{}{
   289  									"/": 8000,
   290  								},
   291  							}),
   292  						}},
   293  					}},
   294  				},
   295  			},
   296  		},
   297  		"patch-all-comp": {
   298  			baseApp: &v1beta1.Application{
   299  				Spec: v1beta1.ApplicationSpec{
   300  					Components: []common.ApplicationComponent{{
   301  						Name: "express-server",
   302  						Type: "webservice",
   303  						Properties: util.Object2RawExtension(map[string]interface{}{
   304  							"image": "crccheck/hello-world",
   305  						}),
   306  						Traits: []common.ApplicationTrait{{
   307  							Type: "ingress",
   308  							Properties: util.Object2RawExtension(map[string]interface{}{
   309  								"domain": "a.example.com",
   310  							}),
   311  						}, {
   312  							Type: "ingress-1-20",
   313  							Properties: util.Object2RawExtension(map[string]interface{}{
   314  								"domain": "a-1-20.example.com",
   315  							}),
   316  						}},
   317  					}, {
   318  						Name: "express-worker",
   319  						Type: "worker",
   320  						Properties: util.Object2RawExtension(map[string]interface{}{
   321  							"image": "crccheck/hello-world",
   322  						}),
   323  					}},
   324  				},
   325  			},
   326  			envName: "prod",
   327  			envPatch: v1alpha1.EnvPatch{
   328  				Components: []v1alpha1.EnvComponentPatch{{
   329  					Name: "",
   330  					Type: "",
   331  					Properties: util.Object2RawExtension(map[string]interface{}{
   332  						"image": "busybox",
   333  					}),
   334  					Traits: []v1alpha1.EnvTraitPatch{{
   335  						Type: "ingress",
   336  						Properties: util.Object2RawExtension(map[string]interface{}{
   337  							"domain": "b.example.com",
   338  						}),
   339  					}},
   340  				}},
   341  			},
   342  			expectedApp: &v1beta1.Application{
   343  				Spec: v1beta1.ApplicationSpec{
   344  					Components: []common.ApplicationComponent{{
   345  						Name: "express-server",
   346  						Type: "webservice",
   347  						Properties: util.Object2RawExtension(map[string]interface{}{
   348  							"image": "busybox",
   349  						}),
   350  						Traits: []common.ApplicationTrait{{
   351  							Type: "ingress",
   352  							Properties: util.Object2RawExtension(map[string]interface{}{
   353  								"domain": "b.example.com",
   354  							}),
   355  						}, {
   356  							Type: "ingress-1-20",
   357  							Properties: util.Object2RawExtension(map[string]interface{}{
   358  								"domain": "a-1-20.example.com",
   359  							}),
   360  						}},
   361  					}, {
   362  						Name: "express-worker",
   363  						Type: "worker",
   364  						Properties: util.Object2RawExtension(map[string]interface{}{
   365  							"image": "busybox",
   366  						}),
   367  						Traits: []common.ApplicationTrait{{
   368  							Type: "ingress",
   369  							Properties: util.Object2RawExtension(map[string]interface{}{
   370  								"domain": "b.example.com",
   371  							}),
   372  						}},
   373  					}},
   374  				},
   375  			},
   376  		},
   377  		"patch-type-comp": {
   378  			baseApp: &v1beta1.Application{
   379  				Spec: v1beta1.ApplicationSpec{
   380  					Components: []common.ApplicationComponent{{
   381  						Name: "express-server",
   382  						Type: "webservice",
   383  						Properties: util.Object2RawExtension(map[string]interface{}{
   384  							"image": "crccheck/hello-world",
   385  						}),
   386  						Traits: []common.ApplicationTrait{{
   387  							Type: "ingress",
   388  							Properties: util.Object2RawExtension(map[string]interface{}{
   389  								"domain": "a.example.com",
   390  							}),
   391  						}, {
   392  							Type: "ingress-1-20",
   393  							Properties: util.Object2RawExtension(map[string]interface{}{
   394  								"domain": "a-1-20.example.com",
   395  							}),
   396  						}},
   397  					}, {
   398  						Name: "express-worker",
   399  						Type: "worker",
   400  						Properties: util.Object2RawExtension(map[string]interface{}{
   401  							"image": "crccheck/hello-world",
   402  						}),
   403  					}},
   404  				},
   405  			},
   406  			envName: "prod",
   407  			envPatch: v1alpha1.EnvPatch{
   408  				Components: []v1alpha1.EnvComponentPatch{{
   409  					Name: "",
   410  					Type: "webservice",
   411  					Properties: util.Object2RawExtension(map[string]interface{}{
   412  						"image": "busybox",
   413  					}),
   414  					Traits: []v1alpha1.EnvTraitPatch{{
   415  						Type: "ingress",
   416  						Properties: util.Object2RawExtension(map[string]interface{}{
   417  							"domain": "b.example.com",
   418  						}),
   419  					}},
   420  				}},
   421  			},
   422  			expectedApp: &v1beta1.Application{
   423  				Spec: v1beta1.ApplicationSpec{
   424  					Components: []common.ApplicationComponent{{
   425  						Name: "express-server",
   426  						Type: "webservice",
   427  						Properties: util.Object2RawExtension(map[string]interface{}{
   428  							"image": "busybox",
   429  						}),
   430  						Traits: []common.ApplicationTrait{{
   431  							Type: "ingress",
   432  							Properties: util.Object2RawExtension(map[string]interface{}{
   433  								"domain": "b.example.com",
   434  							}),
   435  						}, {
   436  							Type: "ingress-1-20",
   437  							Properties: util.Object2RawExtension(map[string]interface{}{
   438  								"domain": "a-1-20.example.com",
   439  							}),
   440  						}},
   441  					}, {
   442  						Name: "express-worker",
   443  						Type: "worker",
   444  						Properties: util.Object2RawExtension(map[string]interface{}{
   445  							"image": "crccheck/hello-world",
   446  						}),
   447  					}},
   448  				},
   449  			},
   450  		},
   451  		"patch-without-type-specified": {
   452  			baseApp: &v1beta1.Application{
   453  				Spec: v1beta1.ApplicationSpec{
   454  					Components: []common.ApplicationComponent{{
   455  						Name: "express-server",
   456  						Type: "webservice",
   457  						Properties: util.Object2RawExtension(map[string]interface{}{
   458  							"image": "crccheck/hello-world",
   459  						}),
   460  						Traits: []common.ApplicationTrait{{
   461  							Type: "ingress",
   462  							Properties: util.Object2RawExtension(map[string]interface{}{
   463  								"domain": "a.example.com",
   464  							}),
   465  						}, {
   466  							Type: "ingress-1-20",
   467  							Properties: util.Object2RawExtension(map[string]interface{}{
   468  								"domain": "a-1-20.example.com",
   469  							}),
   470  						}},
   471  					}, {
   472  						Name: "express-worker",
   473  						Type: "worker",
   474  						Properties: util.Object2RawExtension(map[string]interface{}{
   475  							"image": "crccheck/hello-world",
   476  						}),
   477  					}},
   478  				},
   479  			},
   480  			envName: "prod",
   481  			envPatch: v1alpha1.EnvPatch{
   482  				Components: []v1alpha1.EnvComponentPatch{{
   483  					Name: "express-worker",
   484  					Type: "",
   485  					Properties: util.Object2RawExtension(map[string]interface{}{
   486  						"image": "busybox",
   487  					}),
   488  					Traits: []v1alpha1.EnvTraitPatch{{
   489  						Type: "ingress",
   490  						Properties: util.Object2RawExtension(map[string]interface{}{
   491  							"domain": "b.example.com",
   492  						}),
   493  					}},
   494  				}},
   495  			},
   496  			expectedApp: &v1beta1.Application{
   497  				Spec: v1beta1.ApplicationSpec{
   498  					Components: []common.ApplicationComponent{{
   499  						Name: "express-server",
   500  						Type: "webservice",
   501  						Properties: util.Object2RawExtension(map[string]interface{}{
   502  							"image": "crccheck/hello-world",
   503  						}),
   504  						Traits: []common.ApplicationTrait{{
   505  							Type: "ingress",
   506  							Properties: util.Object2RawExtension(map[string]interface{}{
   507  								"domain": "a.example.com",
   508  							}),
   509  						}, {
   510  							Type: "ingress-1-20",
   511  							Properties: util.Object2RawExtension(map[string]interface{}{
   512  								"domain": "a-1-20.example.com",
   513  							}),
   514  						}},
   515  					}, {
   516  						Name: "express-worker",
   517  						Type: "worker",
   518  						Properties: util.Object2RawExtension(map[string]interface{}{
   519  							"image": "busybox",
   520  						}),
   521  						Traits: []common.ApplicationTrait{{
   522  							Type: "ingress",
   523  							Properties: util.Object2RawExtension(map[string]interface{}{
   524  								"domain": "b.example.com",
   525  							}),
   526  						}},
   527  					}},
   528  				},
   529  			},
   530  		},
   531  	}
   532  
   533  	for name, tc := range testCases {
   534  		t.Run(name, func(t *testing.T) {
   535  			app, err := PatchApplication(tc.baseApp, &tc.envPatch, tc.selector)
   536  			r := require.New(t)
   537  			r.NoError(err)
   538  			r.Equal(tc.expectedApp, app)
   539  		})
   540  	}
   541  }
   542  
   543  var baseApp = &v1beta1.Application{
   544  	TypeMeta: metav1.TypeMeta{
   545  		APIVersion: "v1beta1",
   546  		Kind:       "Application",
   547  	},
   548  	ObjectMeta: metav1.ObjectMeta{
   549  		Name: "test",
   550  	},
   551  	Spec: v1beta1.ApplicationSpec{
   552  		Components: []common.ApplicationComponent{{
   553  			Name: "express-server",
   554  			Type: "webservice",
   555  			Properties: util.Object2RawExtension(map[string]interface{}{
   556  				"image": "crccheck/hello-world",
   557  				"port":  8000,
   558  			}),
   559  			Traits: []common.ApplicationTrait{{
   560  				Type: "ingress-1-20",
   561  				Properties: util.Object2RawExtension(map[string]interface{}{
   562  					"domain": "testsvc.example.com",
   563  					"http": map[string]interface{}{
   564  						"/": 8000,
   565  					},
   566  				}),
   567  			}},
   568  		}},
   569  	},
   570  }