Skip to content

Commit

Permalink
Create the component config.(kubernetes-sigs#245)
Browse files Browse the repository at this point in the history
Create the component config in simulator.

Signed-off-by: yanghesong <hesong.yang@foxmail.com>
  • Loading branch information
yanghesong committed Nov 16, 2022
1 parent 3c90c5e commit d3b3cbf
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 118 deletions.
136 changes: 68 additions & 68 deletions simulator/config/config.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package config

import (
"errors"
"net/url"
"os"
"strconv"
"strings"

"golang.org/x/xerrors"
"gopkg.in/yaml.v2"
"io/ioutil"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
v1beta2config "k8s.io/kube-scheduler/config/v1beta2"
"k8s.io/kubernetes/pkg/scheduler/apis/config/scheme"
"net/url"
"os"
"strconv"

"sigs.k8s.io/kube-scheduler-simulator/simulator/scheduler/config"
)

// ErrEmptyEnv represents the required environment variable don't exist.
var ErrEmptyEnv = errors.New("env is required, but empty")
// configYaml represents the value from the config file.
var configYaml = &Yaml{}

// YamlFile is the config file path.
// TODO: Config this file path by cli in main function.
const YamlFile = "./config.yml"

// Config is configuration for simulator.
type Config struct {
Expand All @@ -35,8 +38,24 @@ type Config struct {
ExternalSchedulerEnabled bool
}

// NewConfig gets some settings from environment variables.
// Yaml is the Go representation of a module configuration in the yaml
// config file.
type Yaml struct {
Port int `yaml:"port"`
EtcdURL string `yaml:"etcd-url"`
CorsAllowedOriginList []string `yaml:"cors-allowed-origin-list"`
KubeConfig string `yaml:"kube-config"`
KubeApiHost string `yaml:"kube-api-host:"`
KubeApiPort int `yaml:"kube-api-port"`
KubeSchedulerConfigPath string `yaml:"kube-scheduler-config-path"`
ExternalImportEnabled bool `yaml:"external-import-enabled"`
ExternalSchedulerEnabled bool `yaml:"external-scheduler-enabled"`
}

// NewConfig gets some settings from config file.
func NewConfig() (*Config, error) {
readConfigYaml()

port, err := getPort()
if err != nil {
return nil, xerrors.Errorf("get port: %w", err)
Expand Down Expand Up @@ -85,73 +104,64 @@ func NewConfig() (*Config, error) {
}, nil
}

// getPort gets Port from the environment variable named PORT.
func getPort() (int, error) {
p := os.Getenv("PORT")
if p == "" {
return 0, xerrors.Errorf("get PORT from env: %w", ErrEmptyEnv)
}
// ReadConfigYaml read the yaml file and set configYaml
func readConfigYaml() {
var configByte []byte
var err error

port, err := strconv.Atoi(p)
configByte, err = ioutil.ReadFile(YamlFile)
if err != nil {
return 0, xerrors.Errorf("convert PORT of string to int: %w", err)
//level.Error(logger).Log("msg", "Error reading config file", "error", err)
return
}

if err = yaml.Unmarshal(configByte, configYaml); err != nil {
return
}
}

// getPort gets port from the config file.
func getPort() (int, error) {
port := configYaml.Port

return port, nil
}

func getKubeAPIServerURL() string {
p := os.Getenv("KUBE_API_PORT")
if p == "" {
p = "3131"
}
port := configYaml.KubeApiPort

h := os.Getenv("KUBE_API_HOST")
if h == "" {
h = "127.0.0.1"
host := configYaml.KubeApiHost
if host == "" {
host = "127.0.0.1"
}
return h + ":" + p
return host + ":" + strconv.Itoa(port)
}

func getExternalSchedulerEnabled() (bool, error) {
e := os.Getenv("EXTERNAL_SCHEDULER_ENABLED")
if e == "" {
return false, nil
}
isExternalSchedulerEnabled := configYaml.ExternalSchedulerEnabled

b, err := strconv.ParseBool(e)
if err != nil {
return false, xerrors.Errorf("EXTERNAL_SCHEDULER_ENABLED is specified, but it's not bool: %s.", e)
}

return b, nil
return isExternalSchedulerEnabled, nil
}

func getEtcdURL() (string, error) {
e := os.Getenv("KUBE_SCHEDULER_SIMULATOR_ETCD_URL")
if e == "" {
return "", xerrors.Errorf("get KUBE_SCHEDULER_SIMULATOR_ETCD_URL from env: %w", ErrEmptyEnv)
}
etcdURL := configYaml.EtcdURL

return e, nil
return etcdURL, nil
}

// getCorsAllowedOriginList fetches CorsAllowedOriginList from the env named CORS_ALLOWED_ORIGIN_LIST.
// getCorsAllowedOriginList fetches CorsAllowedOriginList from the config file.
// This allowed list is applied to kube-apiserver and the simulator server.
//
// Let's say CORS_ALLOWED_ORIGIN_LIST="http://localhost:3000, http://localhost:3001, http://localhost:3002" are given.
// Let's say cors-allowed-origin-list="http://localhost:3000, http://localhost:3001, http://localhost:3002" are given.
// Then, getCorsAllowedOriginList returns []string{"http://localhost:3000", "http://localhost:3001", "http://localhost:3002"}
func getCorsAllowedOriginList() ([]string, error) {
e := os.Getenv("CORS_ALLOWED_ORIGIN_LIST")
if e == "" {
return nil, xerrors.Errorf("get CORS_ALLOWED_ORIGIN_LIST from env: %w", ErrEmptyEnv)
}
corsAllowedOriginList := configYaml.CorsAllowedOriginList

urls := parseStringListEnv(e)
if err := validateURLs(urls); err != nil {
return nil, xerrors.Errorf("validate origins in CORS_ALLOWED_ORIGIN_LIST: %w", err)
if err := validateURLs(corsAllowedOriginList); err != nil {
return nil, xerrors.Errorf("validate origins in cors-allowed-origin-list: %w", err)
}

return urls, nil
return corsAllowedOriginList, nil
}

// validateURLs checks if all URLs in slice is valid or not.
Expand All @@ -165,31 +175,21 @@ func validateURLs(urls []string) error {
return nil
}

func parseStringListEnv(e string) []string {
list := strings.Split(e, ",")
for i := range list {
// remove space
list[i] = strings.TrimSpace(list[i])
}

return list
}

// getSchedulerCfg reads KUBE_SCHEDULER_CONFIG_PATH which means initial kube-scheduler configuration
// getSchedulerCfg reads kube-scheduler-config-path which means initial kube-scheduler configuration
// and converts it into *v1beta2config.KubeSchedulerConfiguration.
// KUBE_SCHEDULER_CONFIG_PATH is not required.
// If KUBE_SCHEDULER_CONFIG_PATH is not set, the default configuration of kube-scheduler will be used.
// kube-scheduler-config-path is not required.
// If kube-scheduler-config-path is not set, the default configuration of kube-scheduler will be used.
func getSchedulerCfg() (*v1beta2config.KubeSchedulerConfiguration, error) {
e := os.Getenv("KUBE_SCHEDULER_CONFIG_PATH")
if e == "" {
kubeSchedulerConfigPath := configYaml.KubeSchedulerConfigPath
if kubeSchedulerConfigPath == "" {
dsc, err := config.DefaultSchedulerConfig()
if err != nil {
return nil, xerrors.Errorf("create default scheduler config: %w", err)
}
return dsc, nil
}

data, err := os.ReadFile(e)
data, err := os.ReadFile(kubeSchedulerConfigPath)
if err != nil {
return nil, xerrors.Errorf("read scheduler config file: %w", err)
}
Expand All @@ -205,8 +205,8 @@ func getSchedulerCfg() (*v1beta2config.KubeSchedulerConfiguration, error) {
// getExternalImportEnabled reads EXTERNAL_IMPORT_ENABLED and convert it to bool.
// This function will return `true` if `EXTERNAL_IMPORT_ENABLED` is "1".
func getExternalImportEnabled() bool {
i := os.Getenv("EXTERNAL_IMPORT_ENABLED")
return i == "1"
isExternalImportEnabled := configYaml.ExternalImportEnabled
return isExternalImportEnabled == true
}

func decodeSchedulerCfg(buf []byte) (*v1beta2config.KubeSchedulerConfiguration, error) {
Expand Down
42 changes: 0 additions & 42 deletions simulator/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,48 +118,6 @@ profiles:
}
}

func Test_parseStringListEnv(t *testing.T) {
t.Parallel()
tests := []struct {
name string
arg string
want []string
}{
{
name: "happy path: can parse the list which has multiple elements",
arg: "hoge,fuga,foo",
want: []string{
"hoge",
"fuga",
"foo",
},
},
{
name: "happy path: can parse the list which has the space between elements",
arg: "hoge, fuga, foo ",
want: []string{
"hoge",
"fuga",
"foo",
},
},
{
name: "happy path: do nothing with non-list string",
arg: "hoge",
want: []string{
"hoge",
},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
assert.Equalf(t, tt.want, parseStringListEnv(tt.arg), "parseStringListEnv(%v)", tt.arg)
})
}
}

func Test_validateURLs(t *testing.T) {
t.Parallel()
tests := []struct {
Expand Down
3 changes: 3 additions & 0 deletions simulator/docs/env-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ used to configure kube-scheduler-simulator.
Please refer [docker-compose.yml](./../../docker-compose.yml) as an example
use.

## For Simulator
This part is deprecated. Please refer to the simulator [config.yml](./../config.yml).

`PORT`: (required) This is the port number on which kube-scheduler-simulator
server is started.

Expand Down
25 changes: 17 additions & 8 deletions simulator/hack/etcd.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
#!/usr/bin/env bash

ETCD_VERSION=${ETCD_VERSION:-3.4.13}
ETCD_HOST=${ETCD_HOST:-127.0.0.1}
ETCD_PORT=${ETCD_PORT:-2379}
export KUBE_SCHEDULER_SIMULATOR_ETCD_URL="http://${ETCD_HOST}:${ETCD_PORT}"
SRC_FILE=./config.yml

load::config() {
while IFS= read -r line; do
if [[ $line == etcd-url:* ]]; then
ETCD_URL="${line#*:}"
ETCD_URL=${ETCD_URL// /}
ETCD_URL=${ETCD_URL//\"/}
fi
done <$SRC_FILE
}

kube::etcd::cleanup() {
kube::etcd::stop
Expand Down Expand Up @@ -31,13 +38,13 @@ kube::etcd::start() {
else
ETCD_LOGFILE=${ETCD_LOGFILE:-"/dev/null"}
fi
echo "etcd --advertise-client-urls ${KUBE_SCHEDULER_SIMULATOR_ETCD_URL} --data-dir ${ETCD_DIR} --listen-client-urls http://${ETCD_HOST}:${ETCD_PORT} --log-level=debug > \"${ETCD_LOGFILE}\" 2>/dev/null"
etcd --advertise-client-urls "${KUBE_SCHEDULER_SIMULATOR_ETCD_URL}" --data-dir "${ETCD_DIR}" --listen-client-urls "${KUBE_SCHEDULER_SIMULATOR_ETCD_URL}" --log-level=debug 2> "${ETCD_LOGFILE}" >/dev/null &
echo "etcd --advertise-client-urls ${ETCD_URL} --data-dir ${ETCD_DIR} --listen-client-urls ${ETCD_URL} --log-level=debug > \"${ETCD_LOGFILE}\" 2>/dev/null"
etcd --advertise-client-urls "${ETCD_URL}" --data-dir "${ETCD_DIR}" --listen-client-urls "${ETCD_URL}" --log-level=debug 2> "${ETCD_LOGFILE}" >/dev/null &
ETCD_PID=$!

echo "Waiting for etcd to come up."
kube::util::wait_for_url "${KUBE_SCHEDULER_SIMULATOR_ETCD_URL}/health" "etcd: " 0.25 80
curl -fs -X POST "${KUBE_SCHEDULER_SIMULATOR_ETCD_URL}/v3/kv/put" -d '{"key": "X3Rlc3Q=", "value": ""}'
kube::util::wait_for_url "${ETCD_URL}/health" "etcd: " 0.25 80
curl -fs -X POST "${ETCD_URL}/v3/kv/put" -d '{"key": "X3Rlc3Q=", "value": ""}'
}

kube::util::wait_for_url() {
Expand All @@ -64,3 +71,5 @@ kube::util::wait_for_url() {
echo "Timed out waiting for ${prefix} to answer at ${url}; tried ${times} waiting ${wait} between each"
exit 1
}

load::config

0 comments on commit d3b3cbf

Please sign in to comment.