crossplane

Форк
0
/
context_test.go 
301 строка · 7.7 Кб
1
/*
2
Copyright 2023 The Crossplane 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 upbound
18

19
import (
20
	"fmt"
21
	"net/url"
22
	"path/filepath"
23
	"testing"
24

25
	"github.com/alecthomas/kong"
26
	"github.com/google/go-cmp/cmp"
27
	"github.com/google/go-cmp/cmp/cmpopts"
28
	"github.com/spf13/afero"
29

30
	"github.com/crossplane/crossplane-runtime/pkg/errors"
31
	"github.com/crossplane/crossplane-runtime/pkg/test"
32

33
	"github.com/crossplane/crossplane/internal/xpkg/upbound/config"
34
)
35

36
var (
37
	defaultConfigJSON = `{
38
		"upbound": {
39
		  "default": "default",
40
		  "profiles": {
41
			"default": {
42
			  "id": "someone@upbound.io",
43
			  "type": "user",
44
			  "session": "a token"
45
			}
46
		  }
47
		}
48
	  }
49
	`
50
	baseConfigJSON = `{
51
		"upbound": {
52
		  "default": "default",
53
		  "profiles": {
54
			"default": {
55
			  "id": "someone@upbound.io",
56
			  "type": "user",
57
			  "session": "a token",
58
			  "base": {
59
				"UP_DOMAIN": "https://local.upbound.io",
60
				"UP_ACCOUNT": "my-org",
61
				"UP_INSECURE_SKIP_TLS_VERIFY": "true"
62
			  }
63
			},
64
			"cool-profile": {
65
				"id": "someone@upbound.io",
66
				"type": "user",
67
				"session": "a token",
68
				"base": {
69
				  "UP_DOMAIN": "https://local.upbound.io",
70
				  "UP_ACCOUNT": "my-org",
71
				  "UP_INSECURE_SKIP_TLS_VERIFY": "true"
72
				}
73
			  }
74
		  }
75
		}
76
	  }
77
	`
78
)
79

80
func withConfig(config string) Option {
81
	return func(ctx *Context) {
82
		// establish fs and create config.json
83
		fs := afero.NewMemMapFs()
84
		fs.MkdirAll(filepath.Dir("/.up/"), 0755)
85
		f, _ := fs.Create("/.up/config.json")
86

87
		f.WriteString(config)
88

89
		ctx.fs = fs
90
	}
91
}
92

93
func withFS(fs afero.Fs) Option {
94
	return func(ctx *Context) {
95
		ctx.fs = fs
96
	}
97
}
98

99
func withPath(p string) Option {
100
	return func(ctx *Context) {
101
		ctx.cfgPath = p
102
	}
103
}
104

105
func withURL(uri string) *url.URL {
106
	u, _ := url.Parse(uri)
107
	return u
108
}
109

110
func TestNewFromFlags(t *testing.T) {
111
	type args struct {
112
		flags []string
113
		opts  []Option
114
	}
115
	type want struct {
116
		err error
117
		c   *Context
118
	}
119

120
	cases := map[string]struct {
121
		reason string
122
		args   args
123
		want   want
124
	}{
125
		"NoPreExistingProfile": {
126
			reason: "We should successfully return a Context if a pre-existing profile does not exist.",
127
			args: args{
128
				flags: []string{},
129
				opts: []Option{
130
					withFS(afero.NewMemMapFs()),
131
				},
132
			},
133
			want: want{
134
				c: &Context{
135
					Account:          "",
136
					APIEndpoint:      withURL("https://api.upbound.io"),
137
					Cfg:              &config.Config{},
138
					Domain:           withURL("https://upbound.io"),
139
					Profile:          config.Profile{},
140
					RegistryEndpoint: withURL("https://xpkg.upbound.io"),
141
				},
142
			},
143
		},
144
		"ErrorSuppliedNotExist": {
145
			reason: "We should return an error if profile is supplied and it does not exist.",
146
			args: args{
147
				flags: []string{
148
					"--profile=not-here",
149
				},
150
			},
151
			want: want{
152
				err: errors.Errorf(errProfileNotFoundFmt, "not-here"),
153
			},
154
		},
155
		"SuppliedNotExistAllowEmpty": {
156
			reason: "We should successfully return a Context if a supplied profile does not exist and.",
157
			args: args{
158
				flags: []string{
159
					"--profile=not-here",
160
				},
161
				opts: []Option{
162
					withFS(afero.NewMemMapFs()),
163
					AllowMissingProfile(),
164
				},
165
			},
166
			want: want{
167
				c: &Context{
168
					ProfileName:      "not-here",
169
					Account:          "",
170
					APIEndpoint:      withURL("https://api.upbound.io"),
171
					Cfg:              &config.Config{},
172
					Domain:           withURL("https://upbound.io"),
173
					Profile:          config.Profile{},
174
					RegistryEndpoint: withURL("https://xpkg.upbound.io"),
175
				},
176
			},
177
		},
178
		"PreExistingProfileNoBaseConfig": {
179
			reason: "We should successfully return a Context if a pre-existing profile exists, but does not have a base config",
180
			args: args{
181
				flags: []string{},
182
				opts: []Option{
183
					withConfig(defaultConfigJSON),
184
					withPath("/.up/config.json"),
185
				},
186
			},
187
			want: want{
188
				c: &Context{
189
					ProfileName:           "default",
190
					Account:               "",
191
					APIEndpoint:           withURL("https://api.upbound.io"),
192
					Domain:                withURL("https://upbound.io"),
193
					InsecureSkipTLSVerify: false,
194
					Profile: config.Profile{
195
						ID:      "someone@upbound.io",
196
						Type:    config.UserProfileType,
197
						Session: "a token",
198
						Account: "",
199
					},
200
					RegistryEndpoint: withURL("https://xpkg.upbound.io"),
201
					Token:            "",
202
				},
203
			},
204
		},
205
		"PreExistingProfileBaseConfigSetProfile": {
206
			reason: "We should return a Context that includes the persisted Profile from base config",
207
			args: args{
208
				flags: []string{},
209
				opts: []Option{
210
					withConfig(baseConfigJSON),
211
					withPath("/.up/config.json"),
212
				},
213
			},
214
			want: want{
215
				c: &Context{
216
					ProfileName:           "default",
217
					Account:               "my-org",
218
					APIEndpoint:           withURL("https://api.local.upbound.io"),
219
					Domain:                withURL("https://local.upbound.io"),
220
					InsecureSkipTLSVerify: true,
221
					Profile: config.Profile{
222
						ID:      "someone@upbound.io",
223
						Type:    config.UserProfileType,
224
						Session: "a token",
225
						Account: "",
226
						BaseConfig: map[string]string{
227
							"UP_ACCOUNT":                  "my-org",
228
							"UP_DOMAIN":                   "https://local.upbound.io",
229
							"UP_INSECURE_SKIP_TLS_VERIFY": "true",
230
						},
231
					},
232
					RegistryEndpoint: withURL("https://xpkg.local.upbound.io"),
233
					Token:            "",
234
				},
235
			},
236
		},
237
		"PreExistingBaseConfigOverrideThroughFlags": {
238
			reason: "We should return a Context that includes the persisted Profile from base config overridden based on flags",
239
			args: args{
240
				flags: []string{
241
					"--profile=cool-profile",
242
					"--account=not-my-org",
243
					fmt.Sprintf("--domain=%s", withURL("http://a.domain.org")),
244
					fmt.Sprintf("--override-api-endpoint=%s", withURL("http://not.a.url")),
245
				},
246
				opts: []Option{
247
					withConfig(baseConfigJSON),
248
					withPath("/.up/config.json"),
249
				},
250
			},
251
			want: want{
252
				c: &Context{
253
					ProfileName:           "cool-profile",
254
					Account:               "not-my-org",
255
					APIEndpoint:           withURL("http://not.a.url"),
256
					Domain:                withURL("http://a.domain.org"),
257
					InsecureSkipTLSVerify: true,
258
					Profile: config.Profile{
259
						ID:      "someone@upbound.io",
260
						Type:    config.UserProfileType,
261
						Session: "a token",
262
						Account: "",
263
						BaseConfig: map[string]string{
264
							"UP_ACCOUNT":                  "my-org",
265
							"UP_DOMAIN":                   "https://local.upbound.io",
266
							"UP_INSECURE_SKIP_TLS_VERIFY": "true",
267
						},
268
					},
269
					RegistryEndpoint: withURL("http://xpkg.a.domain.org"),
270
					Token:            "",
271
				},
272
			},
273
		},
274
	}
275

276
	for name, tc := range cases {
277
		t.Run(name, func(t *testing.T) {
278
			flags := Flags{}
279
			parser, _ := kong.New(&flags)
280
			parser.Parse(tc.args.flags)
281

282
			c, err := NewFromFlags(flags, tc.args.opts...)
283

284
			if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
285
				t.Errorf("\n%s\nNewFromFlags(...): -want error, +got error:\n%s", tc.reason, diff)
286
			}
287

288
			if diff := cmp.Diff(tc.want.c, c,
289
				cmpopts.IgnoreUnexported(Context{}),
290
				// NOTE(tnthornton): we're not concerned about the FSSource's
291
				// internal components.
292
				cmpopts.IgnoreFields(Context{}, "CfgSrc"),
293
				// NOTE(tnthornton) we're not concerned about the Cfg's
294
				// internal components.
295
				cmpopts.IgnoreFields(Context{}, "Cfg"),
296
			); diff != "" {
297
				t.Errorf("\n%s\nNewFromFlags(...): -want error, +got error:\n%s", tc.reason, diff)
298
			}
299
		})
300
	}
301
}
302

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.