|
13 | 13 | package framework |
14 | 14 |
|
15 | 15 | import ( |
16 | | - "bytes" |
17 | 16 | _ "embed" |
18 | 17 | "encoding/json" |
19 | 18 | "fmt" |
| 19 | + "github.com/gavv/httpexpect/v2" |
| 20 | + "net/http" |
| 21 | + "net/url" |
20 | 22 | "os" |
| 23 | + "strings" |
21 | 24 | "text/template" |
22 | | - "time" |
23 | 25 |
|
24 | | - "github.com/api7/gopkg/pkg/log" |
25 | 26 | "github.com/google/uuid" |
26 | 27 | . "github.com/onsi/gomega" |
27 | | - "golang.org/x/net/html" |
28 | | - "helm.sh/helm/v3/pkg/action" |
29 | | - "helm.sh/helm/v3/pkg/chart/loader" |
30 | | - "helm.sh/helm/v3/pkg/cli" |
31 | | - "helm.sh/helm/v3/pkg/kube" |
32 | | - "k8s.io/apimachinery/pkg/util/yaml" |
33 | 28 |
|
34 | 29 | v1 "github.com/apache/apisix-ingress-controller/api/dashboard/v1" |
35 | 30 | ) |
36 | 31 |
|
37 | 32 | var ( |
38 | | - API7EELicense string |
39 | | - |
40 | 33 | valuesTemplate *template.Template |
41 | | - |
42 | | - dashboardVersion string |
| 34 | + _db string |
43 | 35 | ) |
44 | 36 |
|
45 | 37 | func init() { |
46 | | - API7EELicense = os.Getenv("API7_EE_LICENSE") |
47 | | - if API7EELicense == "" { |
48 | | - panic("env {API7_EE_LICENSE} is required") |
| 38 | + _db = os.Getenv("DB") |
| 39 | + if _db == "" { |
| 40 | + _db = postgres |
49 | 41 | } |
50 | | - |
51 | | - dashboardVersion = os.Getenv("DASHBOARD_VERSION") |
52 | | - if dashboardVersion == "" { |
53 | | - dashboardVersion = "dev" |
54 | | - } |
55 | | - |
56 | 42 | tmpl, err := template.New("values.yaml").Parse(` |
57 | 43 | dashboard: |
58 | 44 | image: |
@@ -258,116 +244,54 @@ api_usage: |
258 | 244 | valuesTemplate = tmpl |
259 | 245 | } |
260 | 246 |
|
261 | | -type responseCreateGateway struct { |
262 | | - Value responseCreateGatewayValue `json:"value"` |
263 | | - ErrorMsg string `json:"error_msg"` |
264 | | -} |
| 247 | +// DatabaseConfig is the database related configuration entrypoint. |
| 248 | +type DatabaseConfig struct { |
| 249 | + DSN string `json:"dsn" yaml:"dsn" mapstructure:"dsn"` |
265 | 250 |
|
266 | | -type responseCreateGatewayValue struct { |
267 | | - ID string `json:"id"` |
268 | | - TokenPlainText string `json:"token_plain_text"` |
269 | | - Key string `json:"key"` |
| 251 | + MaxOpenConns int `json:"max_open_conns" yaml:"max_open_conns" mapstructure:"max_open_conns"` |
| 252 | + MaxIdleConns int `json:"max_idle_conns" yaml:"max_idle_conns" mapstructure:"max_idle_conns"` |
270 | 253 | } |
271 | 254 |
|
272 | | -func (f *Framework) deploy() { |
273 | | - debug := func(format string, v ...any) { |
274 | | - log.Infof(format, v...) |
275 | | - } |
276 | | - |
277 | | - kubeConfigPath := os.Getenv("KUBECONFIG") |
278 | | - actionConfig := new(action.Configuration) |
279 | | - |
280 | | - err := actionConfig.Init( |
281 | | - kube.GetConfig(kubeConfigPath, "", f.kubectlOpts.Namespace), |
282 | | - f.kubectlOpts.Namespace, |
283 | | - "memory", |
284 | | - debug, |
285 | | - ) |
286 | | - f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "init helm action config") |
287 | | - |
288 | | - install := action.NewInstall(actionConfig) |
289 | | - install.Namespace = f.kubectlOpts.Namespace |
290 | | - install.ReleaseName = "api7ee3" |
291 | | - |
292 | | - chartPath, err := install.LocateChart("api7/api7ee3", cli.New()) |
293 | | - f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "locate helm chart") |
294 | | - |
295 | | - chart, err := loader.Load(chartPath) |
296 | | - f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "load helm chart") |
297 | | - |
298 | | - buf := bytes.NewBuffer(nil) |
299 | | - _ = valuesTemplate.Execute(buf, map[string]any{ |
300 | | - "DB": _db, |
301 | | - "DSN": getDSN(), |
302 | | - "Tag": dashboardVersion, |
303 | | - }) |
304 | | - |
305 | | - var v map[string]any |
306 | | - err = yaml.Unmarshal(buf.Bytes(), &v) |
307 | | - f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "unmarshal values") |
308 | | - _, err = install.Run(chart, v) |
309 | | - f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "install dashboard") |
310 | | - |
311 | | - err = f.ensureService("api7ee3-dashboard", _namespace, 1) |
312 | | - f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "ensuring dashboard service") |
313 | | - |
314 | | - err = f.ensureService("api7-postgresql", _namespace, 1) |
315 | | - f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "ensuring postgres service") |
316 | | - |
317 | | - err = f.ensureService("api7-prometheus-server", _namespace, 1) |
318 | | - f.GomegaT.Expect(err).ShouldNot(HaveOccurred(), "ensuring prometheus-server service") |
| 255 | +type LogOptions struct { |
| 256 | + // Level is the minimum logging level that a logging message should have |
| 257 | + // to output itself. |
| 258 | + Level string `json:"level" yaml:"level"` |
| 259 | + // Output defines the destination file path to output logging messages. |
| 260 | + // Two keywords "stderr" and "stdout" can be specified so that message will |
| 261 | + // be written to stderr or stdout. |
| 262 | + Output string `json:"output" yaml:"output"` |
319 | 263 | } |
320 | 264 |
|
321 | | -func (f *Framework) initDashboard() { |
322 | | - f.deletePods("app.kubernetes.io/name=api7ee3") |
323 | | - time.Sleep(5 * time.Second) |
| 265 | +func (conf *DatabaseConfig) GetType() string { |
| 266 | + parts := strings.SplitN(conf.DSN, "://", 2) |
| 267 | + if len(parts) > 1 { |
| 268 | + return parts[0] |
| 269 | + } |
| 270 | + return "" |
324 | 271 | } |
325 | 272 |
|
326 | | -// ParseHTML will parse the doc from login page and generate a map contains id and action. |
327 | | -func (f *Framework) ParseHTML(doc *html.Node) map[string]string { |
328 | | - var fu func(*html.Node) |
329 | | - htmlMap := make(map[string]string) |
330 | | - fu = func(n *html.Node) { |
331 | | - var ( |
332 | | - name string |
333 | | - value string |
334 | | - ) |
335 | | - for _, attr := range n.Attr { |
336 | | - if attr.Key == "id" || attr.Key == "name" { |
337 | | - name = attr.Val |
338 | | - } |
339 | | - if attr.Key == "action" || attr.Key == "value" { |
340 | | - value = attr.Val |
341 | | - } |
342 | | - |
343 | | - htmlMap[name] = value |
344 | | - } |
345 | | - |
346 | | - for c := n.FirstChild; c != nil; c = c.NextSibling { |
347 | | - fu(c) |
348 | | - } |
| 273 | +//nolint:unused |
| 274 | +func getDSN() string { |
| 275 | + switch _db { |
| 276 | + case postgres: |
| 277 | + return postgresDSN |
| 278 | + case oceanbase: |
| 279 | + return oceanbaseDSN |
| 280 | + case mysql: |
| 281 | + return mysqlDSN |
349 | 282 | } |
350 | | - fu(doc) |
351 | | - |
352 | | - return htmlMap |
| 283 | + panic("unknown database") |
353 | 284 | } |
354 | 285 |
|
355 | | -func (f *Framework) GetTokenFromDashboard(gatewayGroupID string) (string, error) { |
356 | | - respExp := f.DashboardHTTPClient(). |
357 | | - POST("/api/gateway_groups/"+gatewayGroupID+"/instance_token"). |
358 | | - WithHeader("Content-Type", "application/json"). |
359 | | - WithBasicAuth("admin", "admin"). |
360 | | - Expect() |
| 286 | +type responseCreateGateway struct { |
| 287 | + Value responseCreateGatewayValue `json:"value"` |
| 288 | + ErrorMsg string `json:"error_msg"` |
| 289 | +} |
361 | 290 |
|
362 | | - respExp.Status(200).Body().Contains("token_plain_text") |
363 | | - body := respExp.Body().Raw() |
364 | | - // unmarshal into responseCreateGateway |
365 | | - var response responseCreateGateway |
366 | | - err := json.Unmarshal([]byte(body), &response) |
367 | | - if err != nil { |
368 | | - return "", err |
369 | | - } |
370 | | - return response.Value.TokenPlainText, nil |
| 291 | +type responseCreateGatewayValue struct { |
| 292 | + ID string `json:"id"` |
| 293 | + TokenPlainText string `json:"token_plain_text"` |
| 294 | + Key string `json:"key"` |
371 | 295 | } |
372 | 296 |
|
373 | 297 | func (f *Framework) GetDataplaneCertificates(gatewayGroupID string) *v1.DataplaneCertificate { |
@@ -461,3 +385,66 @@ func (f *Framework) CreateNewGatewayGroupWithIngressE() (string, error) { |
461 | 385 | } |
462 | 386 | return response.Value.ID, nil |
463 | 387 | } |
| 388 | + |
| 389 | +func (f *Framework) setDpManagerEndpoints() { |
| 390 | + payload := []byte(fmt.Sprintf(`{"control_plane_address":["%s"]}`, DPManagerTLSEndpoint)) |
| 391 | + |
| 392 | + respExp := f.DashboardHTTPClient(). |
| 393 | + PUT("/api/system_settings"). |
| 394 | + WithBasicAuth("admin", "admin"). |
| 395 | + WithHeader("Content-Type", "application/json"). |
| 396 | + WithBytes(payload). |
| 397 | + Expect() |
| 398 | + |
| 399 | + respExp.Raw() |
| 400 | + f.Logf("set dp manager endpoints response: %s", respExp.Body().Raw()) |
| 401 | + |
| 402 | + respExp.Status(200). |
| 403 | + Body().Contains("control_plane_address") |
| 404 | +} |
| 405 | + |
| 406 | +func (f *Framework) GetDashboardEndpoint() string { |
| 407 | + return f.dashboardHTTPTunnel.Endpoint() |
| 408 | +} |
| 409 | + |
| 410 | +func (f *Framework) GetDashboardEndpointHTTPS() string { |
| 411 | + return f.dashboardHTTPSTunnel.Endpoint() |
| 412 | +} |
| 413 | + |
| 414 | +func (f *Framework) DashboardHTTPClient() *httpexpect.Expect { |
| 415 | + u := url.URL{ |
| 416 | + Scheme: "http", |
| 417 | + Host: f.GetDashboardEndpoint(), |
| 418 | + } |
| 419 | + return httpexpect.WithConfig(httpexpect.Config{ |
| 420 | + BaseURL: u.String(), |
| 421 | + Client: &http.Client{ |
| 422 | + Transport: &http.Transport{}, |
| 423 | + CheckRedirect: func(req *http.Request, via []*http.Request) error { |
| 424 | + return http.ErrUseLastResponse |
| 425 | + }, |
| 426 | + }, |
| 427 | + Reporter: httpexpect.NewAssertReporter( |
| 428 | + httpexpect.NewAssertReporter(f.GinkgoT), |
| 429 | + ), |
| 430 | + }) |
| 431 | +} |
| 432 | + |
| 433 | +func (f *Framework) DashboardHTTPSClient() *httpexpect.Expect { |
| 434 | + u := url.URL{ |
| 435 | + Scheme: "https", |
| 436 | + Host: f.GetDashboardEndpointHTTPS(), |
| 437 | + } |
| 438 | + return httpexpect.WithConfig(httpexpect.Config{ |
| 439 | + BaseURL: u.String(), |
| 440 | + Client: &http.Client{ |
| 441 | + Transport: &http.Transport{}, |
| 442 | + CheckRedirect: func(req *http.Request, via []*http.Request) error { |
| 443 | + return http.ErrUseLastResponse |
| 444 | + }, |
| 445 | + }, |
| 446 | + Reporter: httpexpect.NewAssertReporter( |
| 447 | + httpexpect.NewAssertReporter(f.GinkgoT), |
| 448 | + ), |
| 449 | + }) |
| 450 | +} |
0 commit comments