blob: 5586114992762e4fca1ba64a4ef58a41a275a450 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"encoding/json"
"io/ioutil"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/apache/apisix-ingress-controller/pkg/types"
)
func TestNewConfigFromFile(t *testing.T) {
cfg := &Config{
LogLevel: "warn",
LogOutput: "stdout",
LogRotateOutputPath: "",
LogRotationMaxSize: 100,
LogRotationMaxAge: 0,
LogRotationMaxBackups: 0,
HTTPListen: ":9090",
HTTPSListen: ":9443",
IngressPublishService: "",
IngressStatusAddress: []string{},
CertFilePath: "/etc/webhook/certs/cert.pem",
KeyFilePath: "/etc/webhook/certs/key.pem",
EnableProfiling: true,
ApisixResourceSyncInterval: types.TimeDuration{Duration: 200 * time.Second},
Kubernetes: KubernetesConfig{
ResyncInterval: types.TimeDuration{Duration: time.Hour},
Kubeconfig: "/path/to/foo/baz",
AppNamespaces: []string{""},
ElectionID: "my-election-id",
IngressClass: IngressClass,
IngressVersion: IngressNetworkingV1,
APIVersion: DefaultAPIVersion,
},
APISIX: APISIXConfig{
DefaultClusterName: "default",
DefaultClusterBaseURL: "http://127.0.0.1:8080/apisix",
DefaultClusterAdminKey: "123456",
},
}
jsonData, err := json.Marshal(cfg)
assert.Nil(t, err, "failed to marshal config to json: %s", err)
tmpJSON, err := ioutil.TempFile("/tmp", "config-*.json")
assert.Nil(t, err, "failed to create temporary json configuration file: ", err)
defer os.Remove(tmpJSON.Name())
_, err = tmpJSON.Write(jsonData)
assert.Nil(t, err, "failed to write json data: ", err)
tmpJSON.Close()
newCfg, err := NewConfigFromFile(tmpJSON.Name())
assert.Nil(t, err, "failed to new config from file: ", err)
assert.Nil(t, newCfg.Validate(), "failed to validate config")
assert.Equal(t, cfg, newCfg, "bad configuration")
// We constructs yaml data manually instead of using yaml.Marshal since
// types.TimeDuration doesn't have a `yaml:",inline"` tag, if we add it,
// error ",inline needs a struct value field" will be reported.
// I don't know why.
yamlData := `
log_level: warn
log_output: stdout
http_listen: :9090
https_listen: :9443
ingress_publish_service: ""
ingress_status_address: []
enable_profiling: true
apisix-resource-sync-interval: 200s
kubernetes:
kubeconfig: /path/to/foo/baz
resync_interval: 1h0m0s
election_id: my-election-id
ingress_class: apisix
ingress_version: networking/v1
api_version: apisix.apache.org/v2
apisix:
default_cluster_base_url: http://127.0.0.1:8080/apisix
default_cluster_admin_key: "123456"
`
tmpYAML, err := ioutil.TempFile("/tmp", "config-*.yaml")
assert.Nil(t, err, "failed to create temporary yaml configuration file: ", err)
defer os.Remove(tmpYAML.Name())
_, err = tmpYAML.Write([]byte(yamlData))
assert.Nil(t, err, "failed to write yaml data: ", err)
tmpYAML.Close()
newCfg, err = NewConfigFromFile(tmpYAML.Name())
assert.Nil(t, err, "failed to new config from file: ", err)
assert.Nil(t, newCfg.Validate(), "failed to validate config")
assert.Equal(t, cfg, newCfg, "bad configuration")
}
func TestConfigWithEnvVar(t *testing.T) {
cfg := &Config{
LogLevel: "warn",
LogOutput: "stdout",
LogRotateOutputPath: "",
LogRotationMaxSize: 100,
LogRotationMaxAge: 0,
LogRotationMaxBackups: 0,
HTTPListen: ":9090",
HTTPSListen: ":9443",
IngressPublishService: "",
IngressStatusAddress: []string{},
CertFilePath: "/etc/webhook/certs/cert.pem",
KeyFilePath: "/etc/webhook/certs/key.pem",
EnableProfiling: true,
ApisixResourceSyncInterval: types.TimeDuration{Duration: 200 * time.Second},
Kubernetes: KubernetesConfig{
ResyncInterval: types.TimeDuration{Duration: time.Hour},
Kubeconfig: "",
AppNamespaces: []string{""},
ElectionID: "my-election-id",
IngressClass: IngressClass,
IngressVersion: IngressNetworkingV1,
APIVersion: DefaultAPIVersion,
},
APISIX: APISIXConfig{
DefaultClusterName: "default",
DefaultClusterBaseURL: "http://127.0.0.1:8080/apisix",
DefaultClusterAdminKey: "123456",
},
}
defaultClusterBaseURLEnvName := "DEFAULT_CLUSTER_BASE_URL"
defaultClusterAdminKeyEnvName := "DEFAULT_CLUSTER_ADMIN_KEY"
kubeconfigEnvName := "KUBECONFIG"
err := os.Setenv(defaultClusterBaseURLEnvName, "http://127.0.0.1:8080/apisix")
assert.Nil(t, err, "failed to set env variable: ", err)
_ = os.Setenv(defaultClusterAdminKeyEnvName, "123456")
_ = os.Setenv(kubeconfigEnvName, "")
jsonData := `
{
"log_level": "warn",
"log_output": "stdout",
"http_listen": ":9090",
"https_listen": ":9443",
"ingress_publish_service": "",
"ingress_status_address": [],
"enable_profiling": true,
"apisix-resource-sync-interval": "200s",
"kubernetes": {
"kubeconfig": "{{.KUBECONFIG}}",
"resync_interval": "1h0m0s",
"election_id": "my-election-id",
"ingress_class": "apisix",
"ingress_version": "networking/v1"
},
"apisix": {
"default_cluster_base_url": "{{.DEFAULT_CLUSTER_BASE_URL}}",
"default_cluster_admin_key": "{{.DEFAULT_CLUSTER_ADMIN_KEY}}"
}
}
`
tmpJSON, err := ioutil.TempFile("/tmp", "config-*.json")
assert.Nil(t, err, "failed to create temporary json configuration file: ", err)
defer os.Remove(tmpJSON.Name())
_, err = tmpJSON.Write([]byte(jsonData))
assert.Nil(t, err, "failed to write json data: ", err)
tmpJSON.Close()
newCfg, err := NewConfigFromFile(tmpJSON.Name())
assert.Nil(t, err, "failed to new config from file: ", err)
assert.Nil(t, newCfg.Validate(), "failed to validate config")
assert.Equal(t, cfg, newCfg, "bad configuration")
yamlData := `
log_level: warn
log_output: stdout
http_listen: :9090
https_listen: :9443
ingress_publish_service: ""
ingress_status_address: []
enable_profiling: true
apisix-resource-sync-interval: 200s
kubernetes:
resync_interval: 1h0m0s
kubeconfig: "{{.KUBECONFIG}}"
election_id: my-election-id
ingress_class: apisix
ingress_version: networking/v1
apisix:
default_cluster_base_url: {{.DEFAULT_CLUSTER_BASE_URL}}
default_cluster_admin_key: "{{.DEFAULT_CLUSTER_ADMIN_KEY}}"
`
tmpYAML, err := ioutil.TempFile("/tmp", "config-*.yaml")
assert.Nil(t, err, "failed to create temporary yaml configuration file: ", err)
defer os.Remove(tmpYAML.Name())
_, err = tmpYAML.Write([]byte(yamlData))
assert.Nil(t, err, "failed to write yaml data: ", err)
tmpYAML.Close()
newCfg, err = NewConfigFromFile(tmpYAML.Name())
assert.Nil(t, err, "failed to new config from file: ", err)
assert.Nil(t, newCfg.Validate(), "failed to validate config")
assert.Equal(t, cfg, newCfg, "bad configuration")
_ = os.Unsetenv(defaultClusterBaseURLEnvName)
_, err = NewConfigFromFile(tmpJSON.Name())
assert.NotNil(t, err, "should failed because env variable missing")
_, err = NewConfigFromFile(tmpYAML.Name())
assert.NotNil(t, err, "should failed because env variable missing")
}
func TestConfigDefaultValue(t *testing.T) {
yamlData := `
apisix:
default_cluster_base_url: http://127.0.0.1:8080/apisix
`
tmpYAML, err := ioutil.TempFile("/tmp", "config-*.yaml")
assert.Nil(t, err, "failed to create temporary yaml configuration file: ", err)
defer os.Remove(tmpYAML.Name())
_, err = tmpYAML.Write([]byte(yamlData))
assert.Nil(t, err, "failed to write yaml data: ", err)
tmpYAML.Close()
newCfg, err := NewConfigFromFile(tmpYAML.Name())
assert.Nil(t, err, "failed to new config from file: ", err)
assert.Nil(t, newCfg.Validate(), "failed to validate config")
defaultCfg := NewDefaultConfig()
defaultCfg.APISIX.DefaultClusterBaseURL = "http://127.0.0.1:8080/apisix"
defaultCfg.APISIX.DefaultClusterName = "default"
assert.Equal(t, defaultCfg, newCfg, "bad configuration")
}
func TestConfigInvalidation(t *testing.T) {
yamlData := ``
tmpYAML, err := ioutil.TempFile("/tmp", "config-*.yaml")
assert.Nil(t, err, "failed to create temporary yaml configuration file: ", err)
defer os.Remove(tmpYAML.Name())
_, err = tmpYAML.Write([]byte(yamlData))
assert.Nil(t, err, "failed to write yaml data: ", err)
tmpYAML.Close()
newCfg, err := NewConfigFromFile(tmpYAML.Name())
assert.Nil(t, err, "failed to new config from file: ", err)
err = newCfg.Validate()
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "apisix base url is required", "bad error: ", err)
yamlData = `
kubernetes:
resync_interval: 15s
apisix:
default_cluster_base_url: http://127.0.0.1:1234/apisix
`
tmpYAML, err = ioutil.TempFile("/tmp", "config-*.yaml")
assert.Nil(t, err, "failed to create temporary yaml configuration file: ", err)
defer os.Remove(tmpYAML.Name())
_, err = tmpYAML.Write([]byte(yamlData))
assert.Nil(t, err, "failed to write yaml data: ", err)
tmpYAML.Close()
newCfg, err = NewConfigFromFile(tmpYAML.Name())
assert.Nil(t, err, "failed to new config from file: ", err)
err = newCfg.Validate()
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "controller resync interval too small", "bad error: ", err)
}