diff --git a/images/agent/config/config.go b/images/agent/config/config.go index 85a77bd2..f2c804eb 100644 --- a/images/agent/config/config.go +++ b/images/agent/config/config.go @@ -57,8 +57,7 @@ func NewConfig() (*Options, error) { machId, err := getMachineId() if err != nil { - return nil, fmt.Errorf("[NewConfig] required %s env variable is not specified, error: %w", - MachineID, err) + return nil, fmt.Errorf("[NewConfig] unable to get %s, error: %w", MachineID, err) } opts.MachineId = machId @@ -74,10 +73,15 @@ func NewConfig() (*Options, error) { } func getMachineId() (string, error) { - id, err := os.ReadFile("/host-root/etc/machine-id") - if err != nil { - return "", err + id := os.Getenv(MachineID) + if id == "" { + byteId, err := os.ReadFile("/host-root/etc/machine-id") + if err != nil { + return "", err + } + + id = string(byteId) } - return string(id), nil + return id, nil } diff --git a/images/agent/config/config_test.go b/images/agent/config/config_test.go index e6a1d054..8885fda6 100644 --- a/images/agent/config/config_test.go +++ b/images/agent/config/config_test.go @@ -25,7 +25,6 @@ import ( func TestNewConfig(t *testing.T) { t.Run("AllValuesSet_ReturnsNoError", func(t *testing.T) { - machineIdFile := "./host-root/etc/machine-id" expNodeName := "test-node" expMetricsPort := ":0000" expMachineId := "test-id" @@ -38,34 +37,9 @@ func TestNewConfig(t *testing.T) { if err != nil { t.Error(err) } + err = os.Setenv(MachineID, expMachineId) defer os.Clearenv() - err = os.MkdirAll("./host-root/etc", 0750) - if err != nil { - t.Error(err) - } - - file, err := os.Create(machineIdFile) - if err != nil { - t.Error(err) - } - defer func() { - err = file.Close() - if err != nil { - t.Error(err) - } - - err = os.RemoveAll("./host-root") - if err != nil { - t.Error(err) - } - }() - - _, err = file.Write([]byte(expMachineId)) - if err != nil { - t.Error(err) - } - opts, err := NewConfig() if assert.NoError(t, err) { @@ -114,8 +88,8 @@ func TestNewConfig(t *testing.T) { t.Run("MachineIdNotSet_ReturnsError", func(t *testing.T) { expMetricsPort := ":0000" expNodeName := "test-node" - expErrorMsg := fmt.Sprintf("[NewConfig] required %s env variable is not specified, error: %s", - MachineID, "open host-root/etc/machine-id: no such file or directory") + expErrorMsg := fmt.Sprintf("[NewConfig] unable to get %s, error: %s", + MachineID, "open /host-root/etc/machine-id: no such file or directory") err := os.Setenv(MetricsPort, expMetricsPort) if err != nil { @@ -132,7 +106,6 @@ func TestNewConfig(t *testing.T) { }) t.Run("MetricsPortNotSet_ReturnsDefaultPort", func(t *testing.T) { - machineIdFile := "./host-root/etc/machine-id" expNodeName := "test-node" expMetricsPort := ":8080" expMachineId := "test-id" @@ -141,33 +114,12 @@ func TestNewConfig(t *testing.T) { if err != nil { t.Error(err) } - defer os.Clearenv() - - err = os.MkdirAll("./host-root/etc", 0750) + err = os.Setenv(MachineID, expMachineId) if err != nil { t.Error(err) } - file, err := os.Create(machineIdFile) - if err != nil { - t.Error(err) - } - defer func() { - err = file.Close() - if err != nil { - t.Error(err) - } - - err = os.RemoveAll("./host-root") - if err != nil { - t.Error(err) - } - }() - - _, err = file.Write([]byte(expMachineId)) - if err != nil { - t.Error(err) - } + defer os.Clearenv() opts, err := NewConfig() diff --git a/images/agent/go.mod b/images/agent/go.mod index 9f140fef..497e58ea 100644 --- a/images/agent/go.mod +++ b/images/agent/go.mod @@ -3,16 +3,17 @@ module sds-node-configurator go 1.20 require ( - github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 github.com/go-logr/logr v1.3.0 github.com/onsi/ginkgo/v2 v2.11.0 github.com/onsi/gomega v1.27.10 + github.com/prometheus/client_golang v1.17.0 github.com/stretchr/testify v1.8.4 k8s.io/api v0.28.4 k8s.io/apiextensions-apiserver v0.28.4 k8s.io/apimachinery v0.28.4 k8s.io/client-go v0.28.4 k8s.io/klog/v2 v2.110.1 + k8s.io/utils v0.0.0-20231127182322-b307cd553661 sigs.k8s.io/controller-runtime v0.16.3 ) @@ -31,7 +32,6 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -41,14 +41,12 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.17.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect @@ -69,7 +67,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/component-base v0.28.4 // indirect k8s.io/kube-openapi v0.0.0-20231129212854-f0671cc7e66a // indirect - k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/images/agent/go.sum b/images/agent/go.sum index c078a1eb..922b8639 100644 --- a/images/agent/go.sum +++ b/images/agent/go.sum @@ -1,54 +1,30 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= -github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= -github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= @@ -56,60 +32,34 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -118,8 +68,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -133,93 +81,61 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= -github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -228,136 +144,71 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= -golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc= -gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo= -k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4= k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= -k8s.io/apiextensions-apiserver v0.27.2 h1:iwhyoeS4xj9Y7v8YExhUwbVuBhMr3Q4bd/laClBV6Bo= -k8s.io/apiextensions-apiserver v0.27.2/go.mod h1:Oz9UdvGguL3ULgRdY9QMUzL2RZImotgxvGjdWRq6ZXQ= k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU= k8s.io/apiextensions-apiserver v0.28.4/go.mod h1:pgQIZ1U8eJSMQcENew/0ShUTlePcSGFq6dxSxf2mwPM= -k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg= -k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= -k8s.io/client-go v0.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE= -k8s.io/client-go v0.27.2/go.mod h1:tY0gVmUsHrAmjzHX9zs7eCjxcBsf8IiNe7KQ52biTcQ= k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= -k8s.io/component-base v0.27.2 h1:neju+7s/r5O4x4/txeUONNTS9r1HsPbyoPBAtHsDCpo= -k8s.io/component-base v0.27.2/go.mod h1:5UPk7EjfgrfgRIuDBFtsEFAe4DAvP3U+M8RTzoSJkpo= k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo= k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/kube-openapi v0.0.0-20231129212854-f0671cc7e66a h1:ZeIPbyHHqahGIbeyLJJjAUhnxCKqXaDY+n89Ms8szyA= k8s.io/kube-openapi v0.0.0-20231129212854-f0671cc7e66a/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= -k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.15.0 h1:ML+5Adt3qZnMSYxZ7gAverBLNPSMQEibtzAgp0UPojU= -sigs.k8s.io/controller-runtime v0.15.0/go.mod h1:7ngYvp1MLT+9GeZ+6lH3LOlcHkp/+tzA/fmHa4iq9kk= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/images/agent/internal/const.go b/images/agent/internal/const.go index c0fcb609..4cdf0748 100644 --- a/images/agent/internal/const.go +++ b/images/agent/internal/const.go @@ -22,7 +22,6 @@ const ( LoopDeviceType = "loop" LVMDeviceType = "lvm" LVMFSType = "LVM2_member" - AvailableBlockDevice = "available_block_device" SdsNodeConfigurator = "storage.deckhouse.io/sds-node-configurator" LVMVGHealthOperational = "Operational" LVMVGHealthNonOperational = "NonOperational" diff --git a/images/agent/pkg/controller/block_device_test.go b/images/agent/pkg/controller/block_device_test.go index f9e22621..86e40681 100644 --- a/images/agent/pkg/controller/block_device_test.go +++ b/images/agent/pkg/controller/block_device_test.go @@ -17,15 +17,16 @@ limitations under the License. package controller import ( + "fmt" + "k8s.io/apimachinery/pkg/api/resource" "sds-node-configurator/api/v1alpha1" "sds-node-configurator/internal" - "sds-node-configurator/pkg/utils" "testing" "github.com/stretchr/testify/assert" ) -func TestGetCandidates(t *testing.T) { +func TestBlockDeviceCtrl(t *testing.T) { t.Run("CheckConsumable", func(t *testing.T) { t.Run("Good device returns true", func(t *testing.T) { goodDevice := internal.Device{ @@ -35,7 +36,7 @@ func TestGetCandidates(t *testing.T) { HotPlug: false, Model: "", Serial: "", - Size: 0, + Size: resource.Quantity{}, Type: "", Wwn: "", KName: "", @@ -50,63 +51,20 @@ func TestGetCandidates(t *testing.T) { t.Run("Bad devices return false", func(t *testing.T) { badDevices := internal.Devices{BlockDevices: []internal.Device{ - {Name: internal.DRBDName + "badName", + { MountPoint: "", - PartUUID: "", - HotPlug: false, - Model: "", - Serial: "", - Size: 0, - Type: "", - Wwn: "", - KName: "", - PkName: "", + HotPlug: true, FSType: "", - Rota: false}, + }, { - Name: "goodName", - MountPoint: "badMountPoint", - PartUUID: "", + MountPoint: "bad", HotPlug: false, - Model: "", - Serial: "", - Size: 0, - Type: "", - Wwn: "", - KName: "", - PkName: "", FSType: "", - Rota: false, }, { - Name: "goodName", MountPoint: "", - PartUUID: "", HotPlug: false, - Model: "", - Serial: "", - Size: 0, - Type: "", - Wwn: "", - KName: "", - PkName: "", - FSType: "badFSType", - Rota: false, - }, - { - Name: "goodName", - MountPoint: "", - PartUUID: "", - HotPlug: true, - Model: "", - Serial: "", - Size: 0, - Type: "", - Wwn: "", - KName: "", - PkName: "", - FSType: "", - Rota: false, + FSType: "bad", }, }} @@ -123,7 +81,7 @@ func TestGetCandidates(t *testing.T) { NodeName: nodeName, Wwn: "ZX128ZX128ZX128", Path: "/dev/sda", - Size: 4294967296, + Size: resource.Quantity{}, Model: "HARD-DRIVE", } @@ -135,7 +93,7 @@ func TestGetCandidates(t *testing.T) { t.Run("CheckTag", func(t *testing.T) { t.Run("Have tag_Returns true and tag", func(t *testing.T) { expectedName := "testName" - tags := "storage.deckhouse.io/enabled=true,storage.deckhouse.io/watcherLVMVGCtrlName=" + expectedName + tags := fmt.Sprintf("storage.deckhouse.io/enabled=true,storage.deckhouse.io/lvmVolumeGroupName=%s", expectedName) shouldBeTrue, actualName := CheckTag(tags) if assert.True(t, shouldBeTrue) { @@ -155,17 +113,15 @@ func TestGetCandidates(t *testing.T) { t.Run("hasValidSize", func(t *testing.T) { sizes := []string{"2G", "1G", "1.5G", "0.9G", "100M"} - expected := []bool{true, true, true, false, false, false} + expected := []bool{true, true, true, false, false} for i, size := range sizes { - b, err := utils.QuantityToBytes(size) - if err != nil { - panic(err) - } - - valid, err := hasValidSize(b) + s, err := resource.ParseQuantity(size) if assert.NoError(t, err) { - assert.Equal(t, expected[i], valid) + valid, err := hasValidSize(s) + if assert.NoError(t, err) { + assert.Equal(t, expected[i], valid) + } } } }) @@ -183,7 +139,7 @@ func TestGetCandidates(t *testing.T) { Wwn: "testWWN", Serial: "testSERIAL", Path: "testPATH", - Size: 0, + Size: resource.Quantity{}, Rota: false, Model: "testMODEL", Name: "testNAME", @@ -205,7 +161,7 @@ func TestGetCandidates(t *testing.T) { Wwn: "testWWN2", Serial: "testSERIAL2", Path: "testPATH2", - Size: 0, + Size: resource.Quantity{}, Rota: true, Model: "testMODEL2", Name: "testNAME", @@ -217,7 +173,7 @@ func TestGetCandidates(t *testing.T) { MachineId: "testMACHINE2", }, } - resourse := v1alpha1.BlockDevice{ + blockDevice := v1alpha1.BlockDevice{ Status: v1alpha1.BlockDeviceStatus{ Type: "testTYPE", FsType: "testFS", @@ -230,7 +186,7 @@ func TestGetCandidates(t *testing.T) { Wwn: "testWWN", Serial: "testSERIAL", Path: "testPATH", - Size: "testSIZE", + Size: "0", Model: "testMODEL", Rota: false, HotPlug: false, @@ -240,7 +196,7 @@ func TestGetCandidates(t *testing.T) { expected := []bool{false, true} for i, candidate := range candidates { - actual := hasBlockDeviceDiff(resourse.Status, candidate) + actual := hasBlockDeviceDiff(blockDevice.Status, candidate) assert.Equal(t, expected[i], actual) } }) diff --git a/images/agent/pkg/controller/controller_reconcile_test.go b/images/agent/pkg/controller/controller_reconcile_test.go index 26850c2c..3ba06a2e 100644 --- a/images/agent/pkg/controller/controller_reconcile_test.go +++ b/images/agent/pkg/controller/controller_reconcile_test.go @@ -18,8 +18,10 @@ package controller_test import ( "context" + "k8s.io/apimachinery/pkg/api/resource" "sds-node-configurator/internal" "sds-node-configurator/pkg/controller" + "sds-node-configurator/pkg/monitoring" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -29,9 +31,10 @@ import ( var _ = Describe("Storage Controller", func() { var ( - ctx = context.Background() - deviceName = "/dev/sda" - candidate = internal.BlockDeviceCandidate{ + ctx = context.Background() + testMetrics = monitoring.GetMetrics("") + deviceName = "/dev/sda" + candidate = internal.BlockDeviceCandidate{ NodeName: "test-node", Consumable: true, PVUuid: "123", @@ -41,7 +44,7 @@ var _ = Describe("Storage Controller", func() { Wwn: "WW12345678", Serial: "test", Path: deviceName, - Size: 0, + Size: resource.Quantity{}, Rota: false, Model: "", Name: "/dev/sda", @@ -57,7 +60,7 @@ var _ = Describe("Storage Controller", func() { cl := NewFakeClient() It("CreateAPIBlockDevice", func() { - blockDevice, err := controller.CreateAPIBlockDevice(ctx, cl, candidate) + blockDevice, err := controller.CreateAPIBlockDevice(ctx, cl, testMetrics, candidate) Expect(err).NotTo(HaveOccurred()) Expect(blockDevice.Status.NodeName).To(Equal(candidate.NodeName)) Expect(blockDevice.Status.Consumable).To(Equal(candidate.Consumable)) @@ -68,7 +71,7 @@ var _ = Describe("Storage Controller", func() { Expect(blockDevice.Status.Wwn).To(Equal(candidate.Wwn)) Expect(blockDevice.Status.Serial).To(Equal(candidate.Serial)) Expect(blockDevice.Status.Path).To(Equal(candidate.Path)) - Expect(blockDevice.Status.Size).To(Equal(candidate.Size)) + Expect(blockDevice.Status.Size).To(Equal(candidate.Size.String())) Expect(blockDevice.Status.Rota).To(Equal(candidate.Rota)) Expect(blockDevice.Status.Model).To(Equal(candidate.Model)) Expect(blockDevice.Status.Type).To(Equal(candidate.Type)) @@ -77,7 +80,7 @@ var _ = Describe("Storage Controller", func() { }) It("GetAPIBlockDevices", func() { - listDevice, err := controller.GetAPIBlockDevices(ctx, cl) + listDevice, err := controller.GetAPIBlockDevices(ctx, cl, testMetrics) Expect(err).NotTo(HaveOccurred()) Expect(listDevice).NotTo(BeNil()) Expect(len(listDevice)).To(Equal(1)) @@ -98,7 +101,7 @@ var _ = Describe("Storage Controller", func() { Wwn: "WW12345678", Serial: "test", Path: deviceName, - Size: 0, + Size: resource.Quantity{}, Rota: false, Model: "", Name: "/dev/sda", @@ -110,7 +113,7 @@ var _ = Describe("Storage Controller", func() { MachineId: "1234", } - resources, err := controller.GetAPIBlockDevices(ctx, cl) + resources, err := controller.GetAPIBlockDevices(ctx, cl, testMetrics) Expect(err).NotTo(HaveOccurred()) Expect(resources).NotTo(BeNil()) Expect(len(resources)).To(Equal(1)) @@ -119,10 +122,10 @@ var _ = Describe("Storage Controller", func() { Expect(oldResource).NotTo(BeNil()) Expect(oldResource.Status.NodeName).To(Equal(candidate.NodeName)) - err = controller.UpdateAPIBlockDevice(ctx, cl, oldResource, newCandidate) + err = controller.UpdateAPIBlockDevice(ctx, cl, testMetrics, oldResource, newCandidate) Expect(err).NotTo(HaveOccurred()) - resources, err = controller.GetAPIBlockDevices(ctx, cl) + resources, err = controller.GetAPIBlockDevices(ctx, cl, testMetrics) Expect(err).NotTo(HaveOccurred()) Expect(resources).NotTo(BeNil()) Expect(len(resources)).To(Equal(1)) @@ -135,10 +138,10 @@ var _ = Describe("Storage Controller", func() { }) It("DeleteAPIBlockDevice", func() { - err := controller.DeleteAPIBlockDevice(ctx, cl, deviceName) + err := controller.DeleteAPIBlockDevice(ctx, cl, testMetrics, deviceName) Expect(err).NotTo(HaveOccurred()) - devices, err := controller.GetAPIBlockDevices(context.Background(), cl) + devices, err := controller.GetAPIBlockDevices(context.Background(), cl, testMetrics) for name := range devices { Expect(name).NotTo(Equal(deviceName)) } diff --git a/images/agent/pkg/controller/discover_lvm_volume_group_test.go b/images/agent/pkg/controller/discover_lvm_volume_group_test.go index 24a7c50c..25a78344 100644 --- a/images/agent/pkg/controller/discover_lvm_volume_group_test.go +++ b/images/agent/pkg/controller/discover_lvm_volume_group_test.go @@ -5,7 +5,7 @@ Licensed 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 + 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, @@ -18,10 +18,12 @@ package controller import ( "context" + "k8s.io/apimachinery/pkg/api/resource" "reflect" "sds-node-configurator/api/v1alpha1" "sds-node-configurator/internal" "sds-node-configurator/pkg/logger" + "sds-node-configurator/pkg/monitoring" "testing" "github.com/stretchr/testify/assert" @@ -100,11 +102,16 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { }) t.Run("getUsedSizeMiB_returns_usedSize_in_M", func(t *testing.T) { + size, err := resource.ParseQuantity("2G") + if err != nil { + t.Error(err) + } + lv := internal.LVData{ - LVSize: "2048K", + LVSize: size, DataPercent: "50", } - expected := "1M" + expected := "97656250Ki" actual, err := getUsedSizeMiB(lv) if assert.NoError(t, err) { @@ -246,17 +253,23 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { VGUuid: vgUuid, } + size10G, err := resource.ParseQuantity("10G") + size1G, err := resource.ParseQuantity("1G") + if err != nil { + t.Error(err) + } + pvs := []internal.PVData{ { PVName: "test_pv1", - PVSize: "pv_size1", + PVSize: size10G, PVUuid: "pv_uuid1", VGName: vgName, VGUuid: vgUuid, }, { PVName: "test_pv2", - PVSize: "pv_size2", + PVSize: size1G, PVUuid: "pv_uuid2", VGUuid: vgUuid, VGName: vgName, @@ -268,7 +281,7 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "block_device1"}, Status: v1alpha1.BlockDeviceStatus{ Path: "test_pv1", - Size: "dev_size1", + Size: "10G", VGUuid: vgUuid, ActualVGNameOnTheNode: vgName, }, @@ -277,7 +290,7 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "block_device2"}, Status: v1alpha1.BlockDeviceStatus{ Path: "test_pv2", - Size: "dev_size2", + Size: "1G", VGUuid: vgUuid, ActualVGNameOnTheNode: vgName, }, @@ -288,15 +301,15 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { nodeName: { { Path: "test_pv1", - PVSize: "pv_size1", - DevSize: "dev_size1", + PVSize: size10G, + DevSize: size10G, PVUuid: "pv_uuid1", BlockDevice: "block_device1", }, { Path: "test_pv2", - PVSize: "pv_size2", - DevSize: "dev_size2", + PVSize: size1G, + DevSize: size1G, PVUuid: "pv_uuid2", BlockDevice: "block_device2", }, @@ -341,36 +354,22 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { assert.Equal(t, 2, len(sorted)) }) - t.Run("getAllocatedSizeMiB_returns_allocatedSize", func(t *testing.T) { - vg := internal.VGData{ - VGFree: "1024.00K", - VGSize: "2048.00K", - } - expected := "1M" - - actual, err := getAllocatedSizeMiB(vg) - - if assert.NoError(t, err) { - assert.Equal(t, expected, actual) - } - }) - t.Run("getVgType_returns_shared", func(t *testing.T) { vg := internal.VGData{VGShared: "shared"} expected := "Shared" - acutal := getVgType(vg) + actual := getVgType(vg) - assert.Equal(t, expected, acutal) + assert.Equal(t, expected, actual) }) t.Run("getVgType_returns_local", func(t *testing.T) { vg := internal.VGData{VGShared: ""} expected := "Local" - acutal := getVgType(vg) + actual := getVgType(vg) - assert.Equal(t, expected, acutal) + assert.Equal(t, expected, actual) }) t.Run("getSpecThinPools_returns_LVName_LVSize_map", func(t *testing.T) { @@ -381,22 +380,28 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { vg := internal.VGData{VGName: vgName, VGUuid: vgUuid} + firstSize, err := resource.ParseQuantity("1G") + secondSize, err := resource.ParseQuantity("2G") + if err != nil { + t.Error(err) + } + thinPools := map[string][]internal.LVData{ vgName + vgUuid: { { LVName: "first", - LVSize: "first_size", + LVSize: firstSize, }, { LVName: "second", - LVSize: "second_size", + LVSize: secondSize, }, }, } - expected := map[string]string{ - "first": "first_size", - "second": "second_size", + expected := map[string]resource.Quantity{ + "first": firstSize, + "second": secondSize, } actual := getSpecThinPools(thinPools, vg) @@ -404,27 +409,35 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { assert.Equal(t, expected, actual) }) - t.Run("CreateLVMVolumeGroup", func(t *testing.T) { + t.Run("CreateLVMVolumeGroup_creates_expected", func(t *testing.T) { const ( LVMVGName = "test_lvm" ActualVGNameOnTheNode = "test-vg" Type = "local" - AllocatedSize = "10G" + AllocatedSize = "9765625Ki" Health = internal.LVMVGHealthOperational Message = "No problems detected" - VGSize = "10G" + VGSize = "9765625Ki" VGUuid = "test_uuid" ) + size10G, err := resource.ParseQuantity("10G") + size1G, err := resource.ParseQuantity("1G") + if err != nil { + t.Error(err) + } + var ( cl = NewFakeClient() ctx = context.Background() + testLogger = logger.Logger{} + testMetrics = monitoring.GetMetrics("") blockDevicesNames = []string{"first", "second"} - specThinPools = map[string]string{"first": "first_size"} + specThinPools = map[string]resource.Quantity{"first": size10G} statusThinPools = []internal.LVMVGStatusThinPool{ { Name: "first_status_pool", - ActualSize: "10G", + ActualSize: size10G, UsedSize: "4G", }, } @@ -432,8 +445,8 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { "test-node-1": { { Path: "test/path", - PVSize: "1G", - DevSize: "1G", + PVSize: size1G, + DevSize: size1G, PVUuid: "test-pv-uuid", BlockDevice: "test-device", }, @@ -447,11 +460,11 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { BlockDevicesNames: blockDevicesNames, SpecThinPools: specThinPools, Type: Type, - AllocatedSize: AllocatedSize, + AllocatedSize: size10G, Health: Health, Message: Message, StatusThinPools: statusThinPools, - VGSize: VGSize, + VGSize: size10G, VGUuid: VGUuid, Nodes: nodes, } @@ -483,7 +496,7 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { }, } - created, err := CreateLVMVolumeGroup(ctx, cl, candidate) + created, err := CreateLVMVolumeGroup(ctx, testLogger, testMetrics, cl, candidate) if assert.NoError(t, err) { assert.Equal(t, &expected, created) } @@ -494,22 +507,30 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { LVMVGName = "test_lvm" ActualVGNameOnTheNode = "test-vg" Type = "local" - AllocatedSize = "10G" + AllocatedSize = "9765625Ki" Health = internal.LVMVGHealthOperational Message = "No problems detected" - VGSize = "10G" + VGSize = "9765625Ki" VGUuid = "test_uuid" ) + size10G, err := resource.ParseQuantity("10G") + size1G, err := resource.ParseQuantity("1G") + if err != nil { + t.Error(err) + } + var ( cl = NewFakeClient() + testMetrics = monitoring.GetMetrics("") + testLogger = logger.Logger{} ctx = context.Background() blockDevicesNames = []string{"first", "second"} - specThinPools = map[string]string{"first": "first_size"} + specThinPools = map[string]resource.Quantity{"first": size10G} statusThinPools = []internal.LVMVGStatusThinPool{ { Name: "first_status_pool", - ActualSize: "10G", + ActualSize: size10G, UsedSize: "4G", }, } @@ -517,8 +538,8 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { "test-node-1": { { Path: "test/path", - PVSize: "1G", - DevSize: "1G", + PVSize: size1G, + DevSize: size1G, PVUuid: "test-pv-uuid", BlockDevice: "test-device", }, @@ -532,11 +553,11 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { BlockDevicesNames: blockDevicesNames, SpecThinPools: specThinPools, Type: Type, - AllocatedSize: AllocatedSize, + AllocatedSize: size10G, Health: Health, Message: Message, StatusThinPools: statusThinPools, - VGSize: VGSize, + VGSize: size10G, VGUuid: VGUuid, Nodes: nodes, } @@ -570,9 +591,9 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { }, } - created, err := CreateLVMVolumeGroup(ctx, cl, candidate) + created, err := CreateLVMVolumeGroup(ctx, testLogger, testMetrics, cl, candidate) if assert.NoError(t, err) && assert.NotNil(t, created) { - actual, err := GetAPILVMVolumeGroups(ctx, cl) + actual, err := GetAPILVMVolumeGroups(ctx, cl, testMetrics) if assert.NoError(t, err) && assert.Equal(t, 1, len(actual)) { assert.Equal(t, expected, actual) } @@ -584,22 +605,28 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { LVMVGName = "test_lvm" ActualVGNameOnTheNode = "test-vg" Type = "local" - AllocatedSize = "10G" Health = internal.LVMVGHealthOperational Message = "No problems detected" - VGSize = "10G" VGUuid = "test_uuid" ) + size10G, err := resource.ParseQuantity("10G") + size1G, err := resource.ParseQuantity("1G") + if err != nil { + t.Error(err) + } + var ( cl = NewFakeClient() ctx = context.Background() + testMetrics = monitoring.GetMetrics("") + testLogger = logger.Logger{} blockDevicesNames = []string{"first", "second"} - specThinPools = map[string]string{"first": "first_size"} + specThinPools = map[string]resource.Quantity{"first": size10G} statusThinPools = []internal.LVMVGStatusThinPool{ { Name: "first_status_pool", - ActualSize: "10G", + ActualSize: size10G, UsedSize: "4G", }, } @@ -607,8 +634,8 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { "test-node-1": { { Path: "test/path", - PVSize: "1G", - DevSize: "1G", + PVSize: size1G, + DevSize: size1G, PVUuid: "test-pv-uuid", BlockDevice: "test-device", }, @@ -622,22 +649,22 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { BlockDevicesNames: blockDevicesNames, SpecThinPools: specThinPools, Type: Type, - AllocatedSize: AllocatedSize, + AllocatedSize: size10G, Health: Health, Message: Message, StatusThinPools: statusThinPools, - VGSize: VGSize, + VGSize: size10G, VGUuid: VGUuid, Nodes: nodes, } - created, err := CreateLVMVolumeGroup(ctx, cl, candidate) + created, err := CreateLVMVolumeGroup(ctx, testLogger, testMetrics, cl, candidate) if assert.NoError(t, err) && assert.NotNil(t, created) { - actual, err := GetAPILVMVolumeGroups(ctx, cl) + actual, err := GetAPILVMVolumeGroups(ctx, cl, testMetrics) if assert.NoError(t, err) && assert.Equal(t, 1, len(actual)) { - err := DeleteLVMVolumeGroup(ctx, cl, LVMVGName) + err := DeleteLVMVolumeGroup(ctx, cl, testMetrics, LVMVGName) if assert.NoError(t, err) { - actual, err := GetAPILVMVolumeGroups(ctx, cl) + actual, err := GetAPILVMVolumeGroups(ctx, cl, testMetrics) if assert.NoError(t, err) { assert.Equal(t, 0, len(actual)) } @@ -651,22 +678,30 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { LVMVGName = "test_lvm" ActualVGNameOnTheNode = "test-vg" Type = "local" - AllocatedSize = "10G" + AllocatedSize = "9765625Ki" Health = internal.LVMVGHealthOperational Message = "No problems detected" - VGSize = "10G" + VGSize = "9765625Ki" VGUuid = "test_uuid" ) + size10G, err := resource.ParseQuantity("10G") + size1G, err := resource.ParseQuantity("1G") + if err != nil { + t.Error(err) + } + var ( cl = NewFakeClient() ctx = context.Background() + testMetrics = monitoring.GetMetrics("") + testLogger = logger.Logger{} BlockDevicesNames = []string{"first", "second"} - SpecThinPools = map[string]string{"first": "first_size"} + SpecThinPools = map[string]resource.Quantity{"first": size1G} StatusThinPools = []internal.LVMVGStatusThinPool{ { Name: "first_status_pool", - ActualSize: "10G", + ActualSize: size10G, UsedSize: "4G", }, } @@ -674,8 +709,8 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { "test-node-1": { { Path: "test/path", - PVSize: "1G", - DevSize: "1G", + PVSize: size1G, + DevSize: size1G, PVUuid: "test-pv-uuid", BlockDevice: "test-device", }, @@ -685,15 +720,15 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { "test-node-1": { { Path: "test/path", - PVSize: "1G", - DevSize: "1G", + PVSize: size1G, + DevSize: size1G, PVUuid: "test-pv-uuid", BlockDevice: "test-device", }, { Path: "test/path2", - PVSize: "1G", - DevSize: "1G", + PVSize: size1G, + DevSize: size1G, PVUuid: "test-pv-uuid2", BlockDevice: "test-device2", }, @@ -707,11 +742,11 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { BlockDevicesNames: BlockDevicesNames, SpecThinPools: SpecThinPools, Type: Type, - AllocatedSize: AllocatedSize, + AllocatedSize: size10G, Health: Health, Message: Message, StatusThinPools: StatusThinPools, - VGSize: VGSize, + VGSize: size10G, VGUuid: VGUuid, Nodes: oldNodes, } @@ -722,11 +757,11 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { BlockDevicesNames: BlockDevicesNames, SpecThinPools: SpecThinPools, Type: Type, - AllocatedSize: AllocatedSize, + AllocatedSize: size10G, Health: Health, Message: Message, StatusThinPools: StatusThinPools, - VGSize: VGSize, + VGSize: size10G, VGUuid: VGUuid, Nodes: newNodes, } @@ -758,12 +793,12 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { }, } - created, err := CreateLVMVolumeGroup(ctx, cl, oldCandidate) + created, err := CreateLVMVolumeGroup(ctx, testLogger, testMetrics, cl, oldCandidate) if assert.NoError(t, err) { - err := UpdateLVMVolumeGroupByCandidate(ctx, cl, *created, newCandidate) + err := UpdateLVMVolumeGroupByCandidate(ctx, cl, testMetrics, *created, newCandidate) if assert.NoError(t, err) { - lmvs, err := GetAPILVMVolumeGroups(ctx, cl) + lmvs, err := GetAPILVMVolumeGroups(ctx, cl, testMetrics) if assert.NoError(t, err) { actual := lmvs[LVMVGName] assert.Equal(t, expected, actual) @@ -773,61 +808,75 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { }) t.Run("deepEqual_specThinPools_returnsTrue", func(t *testing.T) { + size10G, err := resource.ParseQuantity("10G") + size1G, err := resource.ParseQuantity("1G") + if err != nil { + t.Error(err) + } + var ( - specThinPools = map[string]string{ - "first": "first_size", - "second": "second_size", + specThinPools = map[string]resource.Quantity{ + "first": size10G, + "second": size1G, } ) candidate := internal.LVMVolumeGroupCandidate{ SpecThinPools: specThinPools, } - resource := v1alpha1.LvmVolumeGroup{ + lvmVolumeGroup := v1alpha1.LvmVolumeGroup{ Spec: v1alpha1.LvmVolumeGroupSpec{ ThinPools: convertSpecThinPools(specThinPools), }, } - assert.True(t, reflect.DeepEqual(convertSpecThinPools(candidate.SpecThinPools), resource.Spec.ThinPools)) + assert.True(t, reflect.DeepEqual(convertSpecThinPools(candidate.SpecThinPools), lvmVolumeGroup.Spec.ThinPools)) }) t.Run("deepEqual_specThinPools_returnsFalse", func(t *testing.T) { + size10G, err := resource.ParseQuantity("10G") + size1G, err := resource.ParseQuantity("1G") + size2G, err := resource.ParseQuantity("2G") + size3G, err := resource.ParseQuantity("3G") + if err != nil { + t.Error(err) + } + var ( - specThinPools = map[string]string{ - "first": "first_size", - "second": "second_size", + specThinPools = map[string]resource.Quantity{ + "first": size10G, + "second": size1G, } - anotherSpecThinPools = map[string]string{ - "third": "third_size", - "second": "second_size", + anotherSpecThinPools = map[string]resource.Quantity{ + "third": size2G, + "second": size3G, } ) candidate := internal.LVMVolumeGroupCandidate{ SpecThinPools: specThinPools, } - resource := v1alpha1.LvmVolumeGroup{ + lvmVolumeGroup := v1alpha1.LvmVolumeGroup{ Spec: v1alpha1.LvmVolumeGroupSpec{ ThinPools: convertSpecThinPools(anotherSpecThinPools), }, } - assert.False(t, reflect.DeepEqual(convertSpecThinPools(candidate.SpecThinPools), resource.Spec.ThinPools)) + assert.False(t, reflect.DeepEqual(convertSpecThinPools(candidate.SpecThinPools), lvmVolumeGroup.Spec.ThinPools)) }) t.Run("filterResourcesByNode_returns_current_node_resources", func(t *testing.T) { var ( - ctx = context.Background() - cl = NewFakeClient() - logger, _ = logger.NewLogger(logger.InfoLevel) - currentNode = "test_node" - firstBDName = "first_device" - secondBDName = "second_device" - firstLVName = "first_lv" - secondLVName = "second_lv" - blockDevices = map[string]v1alpha1.BlockDevice{ + ctx = context.Background() + cl = NewFakeClient() + testLogger, _ = logger.NewLogger(logger.InfoLevel) + currentNode = "test_node" + firstBDName = "first_device" + secondBDName = "second_device" + firstLVName = "first_lv" + secondLVName = "second_lv" + blockDevices = map[string]v1alpha1.BlockDevice{ firstBDName: { ObjectMeta: metav1.ObjectMeta{ Name: firstBDName, @@ -874,7 +923,7 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { }, } - actual := filterResourcesByNode(ctx, cl, logger, lvs, blockDevices, currentNode) + actual := filterResourcesByNode(ctx, cl, *testLogger, lvs, blockDevices, currentNode) assert.Equal(t, expected, actual) }) @@ -883,7 +932,7 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { var ( ctx = context.Background() cl = NewFakeClient() - logger, _ = logger.NewLogger(logger.InfoLevel) + testLogger = logger.Logger{} currentNode = "test_node" anotherNode = "another_node" firstBDName = "first_device" @@ -927,45 +976,51 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { } ) - actual := filterResourcesByNode(ctx, cl, logger, lvs, blockDevices, currentNode) + actual := filterResourcesByNode(ctx, cl, testLogger, lvs, blockDevices, currentNode) assert.Equal(t, 0, len(actual)) }) t.Run("hasLVMVolumeGroupDiff", func(t *testing.T) { t.Run("should_return_false", func(t *testing.T) { + size10G, err := resource.ParseQuantity("10G") + size1G, err := resource.ParseQuantity("1G") + size13G, err := resource.ParseQuantity("13G") + if err != nil { + t.Error(err) + } + var ( + testLogger = logger.Logger{} blockDevicesNames = []string{ "first", "second", } - specThinPools = map[string]string{ - "first": "first_size", - "second": "second_size", + specThinPools = map[string]resource.Quantity{ + "first": size10G, + "second": size1G, } specType = "type" - allocatedSize = "10G" health = internal.LVMVGHealthOperational message = "all good" statusThinPools = []internal.LVMVGStatusThinPool{ { Name: "first", - ActualSize: "10G", + ActualSize: size10G, UsedSize: "2G", }, { Name: "second", - ActualSize: "10G", + ActualSize: size10G, UsedSize: "2G", }, } - vgSize = "10G" - nodes = map[string][]internal.LVMVGDevice{ + nodes = map[string][]internal.LVMVGDevice{ "test_node": { { Path: "/test/ds", - PVSize: "1G", - DevSize: "13G", + PVSize: size1G, + DevSize: size13G, PVUuid: "testUUID", BlockDevice: "something", }, @@ -976,41 +1031,49 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { BlockDevicesNames: blockDevicesNames, SpecThinPools: specThinPools, Type: specType, - AllocatedSize: allocatedSize, + AllocatedSize: size10G, Health: health, Message: message, StatusThinPools: statusThinPools, - VGSize: vgSize, + VGSize: size10G, Nodes: nodes, } - resource := v1alpha1.LvmVolumeGroup{ + lvmVolumeGroup := v1alpha1.LvmVolumeGroup{ Spec: v1alpha1.LvmVolumeGroupSpec{ BlockDeviceNames: blockDevicesNames, ThinPools: convertSpecThinPools(specThinPools), Type: specType, }, Status: v1alpha1.LvmVolumeGroupStatus{ - AllocatedSize: allocatedSize, + AllocatedSize: "9765625Ki", Health: health, Message: message, Nodes: convertLVMVGNodes(nodes), ThinPools: convertStatusThinPools(statusThinPools), - VGSize: vgSize, + VGSize: "9765625Ki", }, } - assert.False(t, hasLVMVolumeGroupDiff(resource, candidate)) + + assert.False(t, hasLVMVolumeGroupDiff(testLogger, lvmVolumeGroup, candidate)) }) t.Run("should_return_true", func(t *testing.T) { + size10G, err := resource.ParseQuantity("10G") + size1G, err := resource.ParseQuantity("1G") + size13G, err := resource.ParseQuantity("13G") + if err != nil { + t.Error(err) + } + var ( blockDevicesNames = []string{ "first", "second", } - specThinPools = map[string]string{ - "first": "first_size", - "second": "second_size", + specThinPools = map[string]resource.Quantity{ + "first": size10G, + "second": size1G, } specType = "type" allocatedSize = "10G" @@ -1019,12 +1082,12 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { statusThinPools = []internal.LVMVGStatusThinPool{ { Name: "first", - ActualSize: "10G", + ActualSize: size10G, UsedSize: "2G", }, { Name: "second", - ActualSize: "10G", + ActualSize: size10G, UsedSize: "2G", }, } @@ -1033,15 +1096,15 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { "test_node": { { Path: "/test/ds", - PVSize: "1G", - DevSize: "13G", + PVSize: size1G, + DevSize: size13G, PVUuid: "testUUID", BlockDevice: "something", }, { Path: "/test/ds2", - PVSize: "1G", - DevSize: "13G", + PVSize: size1G, + DevSize: size13G, PVUuid: "testUUID2", BlockDevice: "something2", }, @@ -1052,15 +1115,15 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { BlockDevicesNames: blockDevicesNames, SpecThinPools: specThinPools, Type: specType, - AllocatedSize: allocatedSize, + AllocatedSize: size10G, Health: health, Message: "NewMessage", StatusThinPools: statusThinPools, - VGSize: vgSize, + VGSize: size10G, Nodes: nodes, } - resource := v1alpha1.LvmVolumeGroup{ + lvmVolumeGroup := v1alpha1.LvmVolumeGroup{ Spec: v1alpha1.LvmVolumeGroupSpec{ BlockDeviceNames: blockDevicesNames, ThinPools: convertSpecThinPools(specThinPools), @@ -1076,7 +1139,7 @@ func TestLVMVolumeGroupDiscover(t *testing.T) { }, } - assert.True(t, hasLVMVolumeGroupDiff(resource, candidate)) + assert.True(t, hasLVMVolumeGroupDiff(logger.Logger{}, lvmVolumeGroup, candidate)) }) }) } diff --git a/images/agent/pkg/controller/lvm_volume_group_test.go b/images/agent/pkg/controller/lvm_volume_group_test.go index 6b8bed7c..9331ccf1 100644 --- a/images/agent/pkg/controller/lvm_volume_group_test.go +++ b/images/agent/pkg/controller/lvm_volume_group_test.go @@ -18,6 +18,7 @@ package controller import ( "encoding/json" + "k8s.io/apimachinery/pkg/api/resource" "sds-node-configurator/api/v1alpha1" "testing" @@ -28,76 +29,77 @@ import ( func TestLvmVolumeGroupAPIObjects(t *testing.T) { t.Run("Unmarshal_LvmVolumeGroup_json_to_struct", func(t *testing.T) { js := `{ - "apiVersion": "storage.deckhouse.io/v1alpha1", - "kind": "LvmVolumeGroup", - "metadata": { - "name": "lvg-test-1" - }, - "spec": { - "actualVGNameOnTheNode": "testVGname", - "blockDeviceNames": [ - "test-bd", - "test-bd2" - ], - "thinPools": [ - { - "name": "test-name", - "size": "10G" - }, - { - "name": "test-name2", - "size": "1G" - } - ], - "type": "local" - }, - "status": { - "allocatedSize": "20G", - "health": "operational", - "message": "all-good", - "nodes": [ - { - "devices": [ - { - "blockDevice": "test/BD", - "devSize": "1G", - "path": "test/path1", - "pvSize": "1G", - "pvUUID": "testPV1" - }, - { - "blockDevice": "test/BD2", - "devSize": "1G", - "path": "test/path2", - "pvSize": "2G", - "pvUUID": "testPV2" - } - ], - "name": "node1" - }, - { - "devices": [ - { - "blockDevice": "test/DB3", - "devSize": "2G", - "path": "test/path3", - "pvSize": "3G", - "pvUUID": "testPV3" - } - ], - "name": "node2" - } - ], - "thinPools": [ + "apiVersion": "storage.deckhouse.io/v1alpha1", + "kind": "LvmVolumeGroup", + "metadata": { + "name": "lvg-test-1" + }, + "spec": { + "actualVGNameOnTheNode": "testVGname", + "blockDeviceNames": [ + "test-bd", + "test-bd2" + ], + "thinPools": [ + { + "name": "test-name", + "size": "10G" + }, + { + "name": "test-name2", + "size": "1G" + } + ], + "type": "local" + }, + "status": { + "allocatedSize": "20G", + "health": "operational", + "message": "all-good", + "nodes": [ + { + "devices": [ + { + "blockDevice": "test/BD", + "devSize": "1G", + "path": "test/path1", + "pvSize": "1G", + "pvUUID": "testPV1" + }, + { + "blockDevice": "test/BD2", + "devSize": "1G", + "path": "test/path2", + "pvSize": "2G", + "pvUUID": "testPV2" + } + ], + "name": "node1" + }, + { + "devices": [ + { + "blockDevice": "test/DB3", + "devSize": "2G", + "path": "test/path3", + "pvSize": "3G", + "pvUUID": "testPV3" + } + ], + "name": "node2" + } + ], + "thinPools": [ { - "name": "test-name", - "actualSize": "1G" - } + "name": "test-name", + "actualSize": "1G" + } ], - "vgSize": "test-vg-size", - "vgUUID": "test-vg-uuid" - } + "vgSize": "test-vg-size", + "vgUUID": "test-vg-uuid" + } }` + expected := v1alpha1.LvmVolumeGroup{ TypeMeta: metav1.TypeMeta{ Kind: "LvmVolumeGroup", @@ -113,11 +115,11 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { ThinPools: []v1alpha1.SpecThinPool{ { Name: "test-name", - Size: "10G", + Size: *convertSize("10G", t), }, { Name: "test-name2", - Size: "1G", + Size: *convertSize("1G", t), }, }, }, @@ -130,7 +132,7 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { ThinPools: []v1alpha1.StatusThinPool{ { Name: "test-name", - ActualSize: "1G", + ActualSize: *convertSize("1G", t), }, }, Nodes: []v1alpha1.LvmVolumeGroupNode{ @@ -140,14 +142,14 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { { Path: "test/path1", PVSize: "1G", - DevSize: "1G", + DevSize: *convertSize("1G", t), PVUuid: "testPV1", BlockDevice: "test/BD", }, { Path: "test/path2", PVSize: "2G", - DevSize: "1G", + DevSize: *convertSize("1G", t), PVUuid: "testPV2", BlockDevice: "test/BD2", }, @@ -159,7 +161,7 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { { Path: "test/path3", PVSize: "3G", - DevSize: "2G", + DevSize: *convertSize("2G", t), PVUuid: "testPV3", BlockDevice: "test/DB3", }, @@ -179,77 +181,77 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { t.Run("Marshal_LvmVolumeGroup_struct_to_json", func(t *testing.T) { expected := `{ - "apiVersion": "storage.deckhouse.io/v1alpha1", - "kind": "LvmVolumeGroup", - "metadata": { - "creationTimestamp": null, - "name": "lvg-test-1" - }, - "spec": { - "actualVGNameOnTheNode": "testVGname", - "blockDeviceNames": [ - "test-bd", - "test-bd2" - ], - "thinPools": [ - { - "name": "test-name", - "size": "10G" - }, - { - "name": "test-name2", - "size": "1G" - } - ], - "type": "local" - }, - "status": { - "allocatedSize": "20G", - "health": "operational", - "message": "all-good", - "nodes": [ - { - "devices": [ - { - "blockDevice": "test/BD", - "devSize": "1G", - "path": "test/path1", - "pvSize": "1G", - "pvUUID": "testPV1" - }, - { - "blockDevice": "test/BD2", - "devSize": "1G", - "path": "test/path2", - "pvSize": "2G", - "pvUUID": "testPV2" - } - ], - "name": "node1" - }, - { - "devices": [ - { - "blockDevice": "test/DB3", - "devSize": "2G", - "path": "test/path3", - "pvSize": "3G", - "pvUUID": "testPV3" - } - ], - "name": "node2" - } - ], - "thinPools": [ - { - "name": "test-name", - "actualSize": "1G", + "apiVersion": "storage.deckhouse.io/v1alpha1", + "kind": "LvmVolumeGroup", + "metadata": { + "creationTimestamp": null, + "name": "lvg-test-1" + }, + "spec": { + "actualVGNameOnTheNode": "testVGname", + "blockDeviceNames": [ + "test-bd", + "test-bd2" + ], + "thinPools": [ + { + "name": "test-name", + "size": "10G" + }, + { + "name": "test-name2", + "size": "1G" + } + ], + "type": "local" + }, + "status": { + "allocatedSize": "20G", + "health": "operational", + "message": "all-good", + "nodes": [ + { + "devices": [ + { + "blockDevice": "test/BD", + "devSize": "1G", + "path": "test/path1", + "pvSize": "1G", + "pvUUID": "testPV1" + }, + { + "blockDevice": "test/BD2", + "devSize": "1G", + "path": "test/path2", + "pvSize": "2G", + "pvUUID": "testPV2" + } + ], + "name": "node1" + }, + { + "devices": [ + { + "blockDevice": "test/DB3", + "devSize": "2G", + "path": "test/path3", + "pvSize": "3G", + "pvUUID": "testPV3" + } + ], + "name": "node2" + } + ], + "thinPools": [ + { + "name": "test-name", + "actualSize": "1G", "usedSize": "500M" - } - ], - "vgSize": "test-vg-size", - "vgUUID": "test-vg-uuid" - } + } + ], + "vgSize": "test-vg-size", + "vgUUID": "test-vg-uuid" + } }` testObj := v1alpha1.LvmVolumeGroup{ ObjectMeta: metav1.ObjectMeta{ @@ -266,11 +268,11 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { ThinPools: []v1alpha1.SpecThinPool{ { Name: "test-name", - Size: "10G", + Size: *convertSize("10G", t), }, { Name: "test-name2", - Size: "1G", + Size: *convertSize("1G", t), }, }, Type: "local", @@ -284,14 +286,14 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { Devices: []v1alpha1.LvmVolumeGroupDevice{ { BlockDevice: "test/BD", - DevSize: "1G", + DevSize: *convertSize("1G", t), PVSize: "1G", PVUuid: "testPV1", Path: "test/path1", }, { BlockDevice: "test/BD2", - DevSize: "1G", + DevSize: *convertSize("1G", t), PVSize: "2G", PVUuid: "testPV2", Path: "test/path2", @@ -303,7 +305,7 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { Devices: []v1alpha1.LvmVolumeGroupDevice{ { BlockDevice: "test/DB3", - DevSize: "2G", + DevSize: *convertSize("2G", t), PVSize: "3G", PVUuid: "testPV3", Path: "test/path3", @@ -315,7 +317,7 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { ThinPools: []v1alpha1.StatusThinPool{ { Name: "test-name", - ActualSize: "1G", + ActualSize: *convertSize("1G", t), UsedSize: "500M", }, }, @@ -331,3 +333,12 @@ func TestLvmVolumeGroupAPIObjects(t *testing.T) { } }) } + +func convertSize(size string, t *testing.T) *resource.Quantity { + sizeQTB, err := resource.ParseQuantity(size) + if err != nil { + t.Error(err) + } + + return &sizeQTB +} diff --git a/images/agent/pkg/controller/watcher_lvm_volume_group.go b/images/agent/pkg/controller/watcher_lvm_volume_group.go index 384822e5..63d01797 100644 --- a/images/agent/pkg/controller/watcher_lvm_volume_group.go +++ b/images/agent/pkg/controller/watcher_lvm_volume_group.go @@ -199,7 +199,7 @@ func ReconcileLVMVG( log.Error(err, fmt.Sprintf("[ReconcileLVMVG] error getLVMVolumeGroup, objectname: %s", objectName)) return true, err } - validation, status, err := ValidationLVMGroup(ctx, cl, metrics, group, objectNameSpace, nodeName) + validation, status, err := ValidateLVMGroup(ctx, cl, metrics, group, objectNameSpace, nodeName) if group == nil { err = errors.New("nil pointer detected") @@ -207,15 +207,15 @@ func ReconcileLVMVG( return true, err } - if status.Health == NoOperational { + if status.Health == NonOperational { health := status.Health var message string if err != nil { message = err.Error() } - log.Error(err, fmt.Sprintf("[ReconcileLVMVG] ValidationLVMGroup, resource name: %s, message: %s", group.Name, message)) - err = updateLVMVolumeGroupStatus(ctx, cl, metrics, group.Name, group.Namespace, message, health) + log.Error(err, fmt.Sprintf("[ReconcileLVMVG] ValidateLVMGroup, resource name: %s, message: %s", group.Name, message)) + err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, group.Name, group.Namespace, message, health) if err != nil { log.Error(err, fmt.Sprintf("[ReconcileLVMVG] error update LVMVolumeGroup %s", group.Name)) return true, err @@ -291,14 +291,14 @@ func ReconcileLVMVG( } log.Info("[ReconcileLVMVG] validation and choosing the type of operation") - extendPVs, shrinkPVs, err := ValidationTypeLVMGroup(ctx, cl, metrics, group, log) + extendPVs, shrinkPVs, err := ValidateTypeLVMGroup(ctx, cl, metrics, group, log) if err != nil { - log.Error(err, fmt.Sprintf("[ReconcileLVMVG] error ValidationTypeLVMGroup, name: %s", group.Name)) + log.Error(err, fmt.Sprintf("[ReconcileLVMVG] error ValidateTypeLVMGroup, name: %s", group.Name)) return true, err } if err == nil && extendPVs == nil && shrinkPVs == nil { - log.Warning("[ReconcileLVMVG] ValidationTypeLVMGroup FAIL") + log.Warning("[ReconcileLVMVG] ValidateTypeLVMGroup FAIL") //todo retry and send message } @@ -373,7 +373,7 @@ func ReconcileLVMVG( log.Debug(fmt.Sprintf("[ReconcileLVMVG] exec command: %s", command)) if err != nil { log.Error(errors.New("check size error"), fmt.Sprintf("[ReconcileLVMVG] devSize <= pvSize, block device: %s", d.BlockDevice)) - err = updateLVMVolumeGroupStatus(ctx, cl, metrics, group.Name, group.Namespace, "devSize <= pvSize", NoOperational) + err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, group.Name, group.Namespace, "devSize <= pvSize", NonOperational) if err != nil { log.Error(err, fmt.Sprintf("[ReconcileLVMVG] error update LVMVolumeGroup %s", group.Name)) } @@ -411,7 +411,7 @@ func ReconcileLVMVG( if err != nil { log.Error(err, fmt.Sprintf("[ReconcileLVMVG] error CreateLV, thin pool: %s", pool.Name)) metrics.UtilsCommandsErrorsCount(watcherLVMVGCtrlName, "lvcreate").Inc() - if err = updateLVMVolumeGroupStatus(ctx, cl, metrics, group.Name, group.Namespace, err.Error(), NoOperational); err != nil { + if err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, group.Name, group.Namespace, err.Error(), NonOperational); err != nil { log.Error(err, fmt.Sprintf("[ReconcileLVMVG] unable to update LVMVolumeGroupStatus, resource name: %s", group.Name)) } return true, err @@ -486,7 +486,7 @@ func ReconcileLVMVG( err := CreateVGComplex(ctx, cl, metrics, group, log) if err != nil { log.Error(err, fmt.Sprintf("[ReconcileLVMVG] unable to CreateVGComplex for resource, name: %s", group.Name)) - if err = updateLVMVolumeGroupStatus(ctx, cl, metrics, group.Name, group.Namespace, err.Error(), NoOperational); err != nil { + if err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, group.Name, group.Namespace, err.Error(), NonOperational); err != nil { log.Error(err, fmt.Sprintf("[ReconcileLVMVG] unable to update LVMVolumeGroupStatus, resource name: %s", group.Name)) } @@ -503,7 +503,7 @@ func ReconcileLVMVG( if err != nil { metrics.UtilsCommandsErrorsCount(watcherLVMVGCtrlName, "lvcreate").Inc() log.Error(err, fmt.Sprintf("[ReconcileLVMVG] error CreateLV, thin pool: %s", v.Name)) - if err = updateLVMVolumeGroupStatus(ctx, cl, metrics, group.Name, group.Namespace, err.Error(), NoOperational); err != nil { + if err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, group.Name, group.Namespace, err.Error(), NonOperational); err != nil { log.Error(err, fmt.Sprintf("[ReconcileLVMVG] unable to update LVMVolumeGroupStatus, resource name: %s", group.Name)) } return true, err @@ -513,7 +513,7 @@ func ReconcileLVMVG( } log.Info("[ReconcileLVMVG] reconcile loop end") - err = updateLVMVolumeGroupStatus(ctx, cl, metrics, group.Name, group.Namespace, "", Operational) + err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, group.Name, group.Namespace, "", Operational) if err != nil { log.Error(err, fmt.Sprintf("[ReconcileLVMVG] error update LVMVolumeGroup %s", group.Name)) return true, err diff --git a/images/agent/pkg/controller/watcher_lvm_volume_group_constants.go b/images/agent/pkg/controller/watcher_lvm_volume_group_constants.go index 677ca3c4..747114f5 100644 --- a/images/agent/pkg/controller/watcher_lvm_volume_group_constants.go +++ b/images/agent/pkg/controller/watcher_lvm_volume_group_constants.go @@ -22,12 +22,11 @@ const ( Failed = "Failed" - NoOperational = "NonOperational" - Operational = "Operational" + NonOperational = "NonOperational" + Operational = "Operational" - delAnnotation = "storage.deckhouse.io/sds-delete-vg" - nameSpaceEvent = "default" - LvmVolumeGroupKind = "LvmVolumeGroup" + delAnnotation = "storage.deckhouse.io/sds-delete-vg" + nameSpaceEvent = "default" EventActionDeleting = "Deleting" EventReasonDeleting = "Deleting" diff --git a/images/agent/pkg/controller/watcher_lvm_volume_group_func.go b/images/agent/pkg/controller/watcher_lvm_volume_group_func.go index f38a26dd..53d1a0d5 100644 --- a/images/agent/pkg/controller/watcher_lvm_volume_group_func.go +++ b/images/agent/pkg/controller/watcher_lvm_volume_group_func.go @@ -54,7 +54,7 @@ func getLVMVolumeGroup(ctx context.Context, cl client.Client, metrics monitoring return obj, nil } -func updateLVMVolumeGroupStatus(ctx context.Context, cl client.Client, metrics monitoring.Metrics, name, namespace, message, health string) error { +func updateLVMVolumeGroupHealthStatus(ctx context.Context, cl client.Client, metrics monitoring.Metrics, name, namespace, message, health string) error { obj := &v1alpha1.LvmVolumeGroup{} start := time.Now() @@ -108,10 +108,10 @@ func getBlockDevice(ctx context.Context, cl client.Client, metrics monitoring.Me return obj, nil } -func ValidationLVMGroup(ctx context.Context, cl client.Client, metrics monitoring.Metrics, lvmVolumeGroup *v1alpha1.LvmVolumeGroup, namespace, nodeName string) (bool, *StatusLVMVolumeGroup, error) { +func ValidateLVMGroup(ctx context.Context, cl client.Client, metrics monitoring.Metrics, lvmVolumeGroup *v1alpha1.LvmVolumeGroup, namespace, nodeName string) (bool, *StatusLVMVolumeGroup, error) { status := StatusLVMVolumeGroup{} if lvmVolumeGroup == nil { - return false, nil, errors.New("lvmVolumeGroup in empty") + return false, nil, errors.New("lvmVolumeGroup is nil") } membership := 0 @@ -119,7 +119,7 @@ func ValidationLVMGroup(ctx context.Context, cl client.Client, metrics monitorin for _, blockDev := range lvmVolumeGroup.Spec.BlockDeviceNames { device, err := getBlockDevice(ctx, cl, metrics, namespace, blockDev) if err != nil { - status.Health = NoOperational + status.Health = NonOperational return false, &status, err } if device.Status.NodeName == nodeName { @@ -131,38 +131,46 @@ func ValidationLVMGroup(ctx context.Context, cl client.Client, metrics monitorin return true, &status, nil } - // TODO devices not affiliated ? - if membership != len(lvmVolumeGroup.Spec.BlockDeviceNames) { - status.Health = NoOperational + if membership > 0 { + status.Health = NonOperational status.Phase = Failed - status.Message = "one or some devices not affiliated this node" + status.Message = "selected block devices are from different nodes for local LVMVolumeGroup" return false, &status, nil } - if len(lvmVolumeGroup.Spec.BlockDeviceNames)-membership == len(lvmVolumeGroup.Spec.BlockDeviceNames) { - status.Health = NoOperational + if membership == 0 { + status.Health = NonOperational status.Phase = Failed - status.Message = "no one devices not affiliated this node" + status.Message = "selected block devices not affiliated to current Watcher's node" return false, &status, nil } } if lvmVolumeGroup.Spec.Type == Shared { - if len(lvmVolumeGroup.Spec.BlockDeviceNames) > 1 { - status.Health = NoOperational + if len(lvmVolumeGroup.Spec.BlockDeviceNames) != 1 { + status.Health = NonOperational status.Phase = Failed - status.Message = "LVMVolumeGroup Type != shared" + status.Message = "several block devices are selected for the shared LVMVolumeGroup" return false, &status, errors.New(status.Message) } - if len(lvmVolumeGroup.Spec.BlockDeviceNames) == 1 && (len(lvmVolumeGroup.Spec.BlockDeviceNames)-membership) == 0 { + singleBD := lvmVolumeGroup.Spec.BlockDeviceNames[0] + bd, err := getBlockDevice(ctx, cl, metrics, namespace, singleBD) + if err != nil { + status.Health = NonOperational + status.Phase = Failed + status.Message = "selected unknown block device for the shared LVMVolumeGroup" + return false, &status, err + } + + if bd.Status.NodeName == nodeName { return true, &status, nil } } return false, &status, nil } -func ValidationTypeLVMGroup(ctx context.Context, cl client.Client, metrics monitoring.Metrics, lvmVolumeGroup *v1alpha1.LvmVolumeGroup, l logger.Logger) (extendPV, shrinkPV []string, err error) { +func ValidateTypeLVMGroup(ctx context.Context, cl client.Client, metrics monitoring.Metrics, lvmVolumeGroup *v1alpha1.LvmVolumeGroup, l logger.Logger) (extendPV, shrinkPV []string, err error) { pvs, cmdStr, _, err := utils.GetAllPVs() l.Debug(fmt.Sprintf("GetAllPVs exec cmd: %s", cmdStr)) if err != nil { @@ -346,32 +354,31 @@ func ExistVG(vgName string, log logger.Logger, metrics monitoring.Metrics) (bool return false, nil } -func ConsumableAllDevices(ctx context.Context, cl client.Client, metrics monitoring.Metrics, group *v1alpha1.LvmVolumeGroup) (bool, error) { +func ValidateConsumableDevices(ctx context.Context, cl client.Client, metrics monitoring.Metrics, group *v1alpha1.LvmVolumeGroup) (bool, error) { if group == nil { - return false, fmt.Errorf("group is empty") + return false, fmt.Errorf("lvmVolumeGroup is nil") } - countConsumable := 0 + for _, device := range group.Spec.BlockDeviceNames { d, err := getBlockDevice(ctx, cl, metrics, group.Namespace, device) if err != nil { return false, err } - if d.Status.Consumable == true { - countConsumable++ + + if d.Status.Consumable == false { + return false, nil } } - if len(group.Spec.BlockDeviceNames) == countConsumable { - return true, nil - } + return true, nil } func GetPathsConsumableDevicesFromLVMVG(ctx context.Context, cl client.Client, mertics monitoring.Metrics, group *v1alpha1.LvmVolumeGroup) ([]string, error) { if group == nil { - return nil, fmt.Errorf("group is empty") + return nil, fmt.Errorf("lvmVolumeGroup is nil") } - var paths []string + var paths []string for _, device := range group.Spec.BlockDeviceNames { d, err := getBlockDevice(ctx, cl, mertics, group.Namespace, device) paths = append(paths, d.Status.Path) @@ -379,6 +386,7 @@ func GetPathsConsumableDevicesFromLVMVG(ctx context.Context, cl client.Client, m return nil, err } } + return paths, nil } @@ -410,12 +418,12 @@ func ExtendVGComplex(metrics monitoring.Metrics, extendPVs []string, VGName stri } func CreateVGComplex(ctx context.Context, cl client.Client, metrics monitoring.Metrics, group *v1alpha1.LvmVolumeGroup, l logger.Logger) error { - AllConsumable, err := ConsumableAllDevices(ctx, cl, metrics, group) + allDevicesConsumable, err := ValidateConsumableDevices(ctx, cl, metrics, group) if err != nil { - l.Error(err, " error ConsumableAllDevices") + l.Error(err, " error ValidateConsumableDevices") return err } - if !AllConsumable { + if !allDevicesConsumable { l.Error(err, " error not all devices is consumable") return err } diff --git a/images/agent/pkg/controller/watcher_lvm_volume_group_test.go b/images/agent/pkg/controller/watcher_lvm_volume_group_test.go new file mode 100644 index 00000000..5ee7fa81 --- /dev/null +++ b/images/agent/pkg/controller/watcher_lvm_volume_group_test.go @@ -0,0 +1,1114 @@ +package controller + +import ( + "context" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sds-node-configurator/api/v1alpha1" + "sds-node-configurator/pkg/monitoring" + "testing" +) + +func TestWatcherLVMVolumeGroupCtrl(t *testing.T) { + cl := NewFakeClient() + ctx := context.Background() + metrics := monitoring.GetMetrics("") + namespace := "test" + + t.Run("getLVMVolumeGroup_lvg_exists_returns_correct", func(t *testing.T) { + const name = "test_name" + testObj := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + + err := cl.Create(ctx, testObj) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testObj) + if err != nil { + t.Error(err) + } + }() + } + + actual, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, name) + + if assert.NoError(t, err) { + assert.NotNil(t, actual) + assert.Equal(t, name, actual.Name) + assert.Equal(t, namespace, actual.Namespace) + } + }) + + t.Run("getLVMVolumeGroup_lvg_doesnt_exist_returns_nil", func(t *testing.T) { + const name = "test_name" + testObj := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + + err := cl.Create(ctx, testObj) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testObj) + if err != nil { + t.Error(err) + } + }() + } + + actual, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, "another-name") + + if assert.EqualError(t, err, "lvmvolumegroups.storage.deckhouse.io \"another-name\" not found") { + assert.Nil(t, actual) + } + }) + + t.Run("updateLVMVolumeGroupHealthStatus_new_old_health_is_operational_doesnt_update_returns_nil", func(t *testing.T) { + const ( + name = "test_name" + message = "All good" + ) + testObj := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Status: v1alpha1.LvmVolumeGroupStatus{ + Health: Operational, + Message: message, + }, + } + + err := cl.Create(ctx, testObj) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testObj) + if err != nil { + t.Error(err) + } + }() + } + + oldLvg, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, name) + if assert.NoError(t, err) { + assert.Equal(t, name, oldLvg.Name) + assert.Equal(t, Operational, oldLvg.Status.Health) + assert.Equal(t, message, oldLvg.Status.Message) + } + + err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, name, namespace, "new message", Operational) + assert.Nil(t, err) + + updatedLvg, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, name) + if assert.NoError(t, err) { + assert.Equal(t, name, updatedLvg.Name) + assert.Equal(t, Operational, updatedLvg.Status.Health) + assert.Equal(t, message, updatedLvg.Status.Message) + } + }) + + t.Run("updateLVMVolumeGroupHealthStatus_new_old_health_and_messages_are_the_same_doesnt_updates_returns_nil", func(t *testing.T) { + const ( + name = "test_name" + message = "All bad" + ) + testObj := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Status: v1alpha1.LvmVolumeGroupStatus{ + Health: NonOperational, + Message: message, + }, + } + + err := cl.Create(ctx, testObj) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testObj) + if err != nil { + t.Error(err) + } + }() + } + + oldLvg, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, name) + if assert.NoError(t, err) { + assert.Equal(t, name, oldLvg.Name) + assert.Equal(t, NonOperational, oldLvg.Status.Health) + assert.Equal(t, message, oldLvg.Status.Message) + } + + err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, name, namespace, message, NonOperational) + assert.Nil(t, err) + + updatedLvg, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, name) + if assert.NoError(t, err) { + assert.Equal(t, name, updatedLvg.Name) + assert.Equal(t, NonOperational, updatedLvg.Status.Health) + assert.Equal(t, message, updatedLvg.Status.Message) + } + }) + + t.Run("updateLVMVolumeGroupHealthStatus_new_old_health_are_nonoperational_different_messages_are_updates_message_returns_nil", func(t *testing.T) { + const ( + name = "test_name" + oldMessage = "All bad1" + newMessage = "All bad2" + ) + testObj := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Status: v1alpha1.LvmVolumeGroupStatus{ + Health: NonOperational, + Message: oldMessage, + }, + } + + err := cl.Create(ctx, testObj) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testObj) + if err != nil { + t.Error(err) + } + }() + } + + oldLvg, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, name) + if assert.NoError(t, err) { + assert.Equal(t, name, oldLvg.Name) + assert.Equal(t, NonOperational, oldLvg.Status.Health) + assert.Equal(t, oldMessage, oldLvg.Status.Message) + } + + err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, name, namespace, newMessage, NonOperational) + assert.Nil(t, err) + + updatedLvg, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, name) + if assert.NoError(t, err) { + assert.Equal(t, name, updatedLvg.Name) + assert.Equal(t, NonOperational, updatedLvg.Status.Health) + assert.Equal(t, newMessage, updatedLvg.Status.Message) + } + }) + + t.Run("updateLVMVolumeGroupHealthStatus_old_health_is_nonoperational_new_health_is_operational_updates_health_and_message_returns_nil", func(t *testing.T) { + const ( + name = "test_name" + oldMessage = "All bad" + newMessage = "All good" + ) + testObj := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Status: v1alpha1.LvmVolumeGroupStatus{ + Health: NonOperational, + Message: oldMessage, + }, + } + + err := cl.Create(ctx, testObj) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testObj) + if err != nil { + t.Error(err) + } + }() + } + + oldLvg, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, name) + if assert.NoError(t, err) { + assert.Equal(t, name, oldLvg.Name) + assert.Equal(t, NonOperational, oldLvg.Status.Health) + assert.Equal(t, oldMessage, oldLvg.Status.Message) + } + + err = updateLVMVolumeGroupHealthStatus(ctx, cl, metrics, name, namespace, newMessage, Operational) + assert.Nil(t, err) + + updatedLvg, err := getLVMVolumeGroup(ctx, cl, metrics, namespace, name) + if assert.NoError(t, err) { + assert.Equal(t, name, updatedLvg.Name) + assert.Equal(t, Operational, updatedLvg.Status.Health) + assert.Equal(t, newMessage, updatedLvg.Status.Message) + } + }) + + t.Run("getBlockDevice_bd_exists_returns_correct_one", func(t *testing.T) { + const name = "test_name" + + testObj := &v1alpha1.BlockDevice{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + + err := cl.Create(ctx, testObj) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testObj) + if err != nil { + t.Error(err) + } + }() + } + + bd, err := getBlockDevice(ctx, cl, metrics, namespace, name) + if assert.NoError(t, err) { + assert.Equal(t, name, bd.Name) + assert.Equal(t, namespace, bd.Namespace) + } + }) + + t.Run("getBlockDevice_bd_doesnt_exists_returns_nil", func(t *testing.T) { + const name = "test_name" + + testObj := &v1alpha1.BlockDevice{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + } + + err := cl.Create(ctx, testObj) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testObj) + if err != nil { + t.Error(err) + } + }() + } + + bd, err := getBlockDevice(ctx, cl, metrics, namespace, "another-name") + if assert.EqualError(t, err, "blockdevices.storage.deckhouse.io \"another-name\" not found") { + assert.Nil(t, bd) + } + }) + + t.Run("ValidateLVMGroup_lvg_is_nil_returns_error", func(t *testing.T) { + valid, obj, err := ValidateLVMGroup(ctx, cl, metrics, nil, "test_ns", "test_node") + assert.False(t, valid) + assert.Nil(t, obj) + assert.EqualError(t, err, "lvmVolumeGroup is nil") + }) + + t.Run("ValidateLVMGroup_type_local_selected_absent_bds_validation_fails", func(t *testing.T) { + const name = "test_name" + + testObj := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{"test_bd"}, + Type: Local, + }, + } + + err := cl.Create(ctx, testObj) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testObj) + if err != nil { + t.Error(err) + } + }() + } + + valid, status, err := ValidateLVMGroup(ctx, cl, metrics, testObj, namespace, "test_node") + assert.False(t, valid) + if assert.NotNil(t, status) { + assert.Equal(t, NonOperational, status.Health) + } + assert.EqualError(t, err, "blockdevices.storage.deckhouse.io \"test_bd\" not found") + }) + + t.Run("ValidateLVMGroup_type_local_selected_bds_from_different_nodes_validation_fails", func(t *testing.T) { + const ( + name = "test_name" + firstBd = "first" + secondBd = "second" + testNode = "test_node" + ) + + bds := &v1alpha1.BlockDeviceList{ + Items: []v1alpha1.BlockDevice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: firstBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: secondBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: "another_node", + }, + }, + }, + } + + var err error + for _, bd := range bds.Items { + err = cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + if err == nil { + defer func() { + for _, bd := range bds.Items { + err = cl.Delete(ctx, &bd) + if err != nil { + t.Error(err) + } + } + }() + } + + testLvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{firstBd, secondBd}, + Type: Local, + }, + } + + err = cl.Create(ctx, testLvg) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testLvg) + if err != nil { + t.Error(err) + } + }() + } + + valid, status, err := ValidateLVMGroup(ctx, cl, metrics, testLvg, namespace, testNode) + assert.False(t, valid) + if assert.NotNil(t, status) { + assert.Equal(t, NonOperational, status.Health) + assert.Equal(t, "selected block devices are from different nodes for local LVMVolumeGroup", status.Message) + } + assert.Nil(t, err) + }) + + t.Run("ValidateLVMGroup_type_local_no_bds_affiliated_to_the_node_validation_fails", func(t *testing.T) { + const ( + name = "test_name" + firstBd = "first" + secondBd = "second" + testNode = "test_node" + ) + + bds := &v1alpha1.BlockDeviceList{ + Items: []v1alpha1.BlockDevice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: firstBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: secondBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + }, + }, + }, + } + + var err error + for _, bd := range bds.Items { + err = cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + if err == nil { + defer func() { + for _, bd := range bds.Items { + err = cl.Delete(ctx, &bd) + if err != nil { + t.Error(err) + } + } + }() + } + + testLvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{firstBd, secondBd}, + Type: Local, + }, + } + + err = cl.Create(ctx, testLvg) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testLvg) + if err != nil { + t.Error(err) + } + }() + } + + valid, status, err := ValidateLVMGroup(ctx, cl, metrics, testLvg, namespace, "another-node") + assert.False(t, valid) + if assert.NotNil(t, status) { + assert.Equal(t, NonOperational, status.Health) + assert.Equal(t, "selected block devices not affiliated to current Watcher's node", status.Message) + } + assert.Nil(t, err) + }) + + t.Run("ValidateLVMGroup_type_local_validation_passes", func(t *testing.T) { + const ( + name = "test_name" + firstBd = "first" + secondBd = "second" + testNode = "test_node" + ) + + bds := &v1alpha1.BlockDeviceList{ + Items: []v1alpha1.BlockDevice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: firstBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: secondBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + }, + }, + }, + } + + var err error + for _, bd := range bds.Items { + err = cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + if err == nil { + defer func() { + for _, bd := range bds.Items { + err = cl.Delete(ctx, &bd) + if err != nil { + t.Error(err) + } + } + }() + } + + testLvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{firstBd, secondBd}, + Type: Local, + }, + } + + err = cl.Create(ctx, testLvg) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testLvg) + if err != nil { + t.Error(err) + } + }() + } + + valid, status, err := ValidateLVMGroup(ctx, cl, metrics, testLvg, namespace, testNode) + assert.True(t, valid) + if assert.NotNil(t, status) { + assert.Equal(t, "", status.Health) + assert.Equal(t, "", status.Message) + } + assert.Nil(t, err) + }) + + t.Run("ValidateLVMGroup_type_shared_selected_several_bds_validation_fails", func(t *testing.T) { + const ( + name = "test_name" + firstBd = "first" + secondBd = "second" + testNode = "test_node" + ) + + bds := &v1alpha1.BlockDeviceList{ + Items: []v1alpha1.BlockDevice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: firstBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: secondBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: "another_node", + }, + }, + }, + } + + var err error + for _, bd := range bds.Items { + err = cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + if err == nil { + defer func() { + for _, bd := range bds.Items { + err = cl.Delete(ctx, &bd) + if err != nil { + t.Error(err) + } + } + }() + } + + testLvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{firstBd, secondBd}, + Type: Shared, + }, + } + + err = cl.Create(ctx, testLvg) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testLvg) + if err != nil { + t.Error(err) + } + }() + } + + valid, status, err := ValidateLVMGroup(ctx, cl, metrics, testLvg, namespace, testNode) + assert.False(t, valid) + if assert.NotNil(t, status) { + assert.Equal(t, NonOperational, status.Health) + assert.Equal(t, "several block devices are selected for the shared LVMVolumeGroup", status.Message) + } + assert.EqualError(t, err, "several block devices are selected for the shared LVMVolumeGroup") + }) + + t.Run("ValidateLVMGroup_type_shared_selected_absent_bd_validation_fails", func(t *testing.T) { + const ( + name = "test_name" + firstBd = "first" + testNode = "test_node" + ) + + bds := &v1alpha1.BlockDeviceList{ + Items: []v1alpha1.BlockDevice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: firstBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + }, + }, + }, + } + + var err error + for _, bd := range bds.Items { + err = cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + if err == nil { + defer func() { + for _, bd := range bds.Items { + err = cl.Delete(ctx, &bd) + if err != nil { + t.Error(err) + } + } + }() + } + + testLvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{"absent_bd"}, + Type: Shared, + }, + } + + err = cl.Create(ctx, testLvg) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testLvg) + if err != nil { + t.Error(err) + } + }() + } + + valid, status, err := ValidateLVMGroup(ctx, cl, metrics, testLvg, namespace, testNode) + assert.False(t, valid) + if assert.NotNil(t, status) { + assert.Equal(t, NonOperational, status.Health) + assert.Equal(t, "selected unknown block device for the shared LVMVolumeGroup", status.Message) + } + assert.EqualError(t, err, "blockdevices.storage.deckhouse.io \"absent_bd\" not found") + }) + + t.Run("ValidateLVMGroup_type_shared_validation_passes", func(t *testing.T) { + const ( + name = "test_name" + firstBd = "first" + testNode = "test_node" + ) + + bds := &v1alpha1.BlockDeviceList{ + Items: []v1alpha1.BlockDevice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: firstBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + }, + }, + }, + } + + var err error + for _, bd := range bds.Items { + err = cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + if err == nil { + defer func() { + for _, bd := range bds.Items { + err = cl.Delete(ctx, &bd) + if err != nil { + t.Error(err) + } + } + }() + } + + testLvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{firstBd}, + Type: Shared, + }, + } + + err = cl.Create(ctx, testLvg) + if err != nil { + t.Error(err) + } else { + defer func() { + err = cl.Delete(ctx, testLvg) + if err != nil { + t.Error(err) + } + }() + } + + valid, status, err := ValidateLVMGroup(ctx, cl, metrics, testLvg, namespace, testNode) + assert.True(t, valid) + if assert.NotNil(t, status) { + assert.Equal(t, "", status.Health) + assert.Equal(t, "", status.Message) + } + assert.Nil(t, err) + }) + + t.Run("CreateEventLVMVolumeGroup_creates_event", func(t *testing.T) { + const ( + name = "test_name" + nodeName = "test_node" + ) + + testLvg := &v1alpha1.LvmVolumeGroup{ + TypeMeta: metav1.TypeMeta{ + Kind: "test_kind", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + UID: "test_UUID", + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{"absent_bd"}, + Type: Local, + }, + } + + err := CreateEventLVMVolumeGroup(ctx, cl, metrics, EventReasonDeleting, EventActionDeleting, nodeName, testLvg) + if assert.NoError(t, err) { + events := &v1.EventList{} + err = cl.List(ctx, events) + if err != nil { + t.Error(err) + } + + if assert.Equal(t, 1, len(events.Items)) { + event := events.Items[0] + + assert.Equal(t, testLvg.Name+"-", event.GenerateName) + assert.Equal(t, nameSpaceEvent, event.Namespace) + assert.Equal(t, EventReasonDeleting, event.Reason) + assert.Equal(t, testLvg.Name, event.InvolvedObject.Name) + assert.Equal(t, testLvg.Kind, event.InvolvedObject.Kind) + assert.Equal(t, testLvg.UID, event.InvolvedObject.UID) + assert.Equal(t, "apiextensions.k8s.io/v1", event.InvolvedObject.APIVersion) + assert.Equal(t, v1.EventTypeNormal, event.Type) + assert.Equal(t, EventActionDeleting, event.Action) + assert.Equal(t, nodeName, event.ReportingInstance) + assert.Equal(t, watcherLVMVGCtrlName, event.ReportingController) + assert.Equal(t, "Event Message", event.Message) + + err = cl.Delete(ctx, &event) + if err != nil { + t.Error(err) + } + } + } + }) + + t.Run("ValidateConsumableDevices_validation_passes", func(t *testing.T) { + const ( + name = "test_name" + firstBd = "first" + secondBd = "second" + testNode = "test_node" + ) + + bds := &v1alpha1.BlockDeviceList{ + Items: []v1alpha1.BlockDevice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: firstBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + Consumable: true, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: secondBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + Consumable: true, + }, + }, + }, + } + + var err error + for _, bd := range bds.Items { + err = cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + if err == nil { + defer func() { + for _, bd := range bds.Items { + err = cl.Delete(ctx, &bd) + if err != nil { + t.Error(err) + } + } + }() + } + + testLvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{firstBd, secondBd}, + Type: Shared, + }, + } + + passed, err := ValidateConsumableDevices(ctx, cl, metrics, testLvg) + if assert.NoError(t, err) { + assert.True(t, passed) + } + }) + + t.Run("ValidateConsumableDevices_validation_fails", func(t *testing.T) { + const ( + name = "test_name" + firstBd = "first" + secondBd = "second" + testNode = "test_node" + ) + + bds := &v1alpha1.BlockDeviceList{ + Items: []v1alpha1.BlockDevice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: firstBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + Consumable: false, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: secondBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + Consumable: true, + }, + }, + }, + } + + var err error + for _, bd := range bds.Items { + err = cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + if err == nil { + defer func() { + for _, bd := range bds.Items { + err = cl.Delete(ctx, &bd) + if err != nil { + t.Error(err) + } + } + }() + } + + testLvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{firstBd, secondBd}, + Type: Shared, + }, + } + + passed, err := ValidateConsumableDevices(ctx, cl, metrics, testLvg) + if assert.NoError(t, err) { + assert.False(t, passed) + } + }) + + t.Run("ValidateConsumableDevices_lvg_is_nil_validation_fails", func(t *testing.T) { + passed, err := ValidateConsumableDevices(ctx, cl, metrics, nil) + if assert.EqualError(t, err, "lvmVolumeGroup is nil") { + assert.False(t, passed) + } + }) + + t.Run("GetPathsConsumableDevicesFromLVMVG_lvg_is_nil_returns_error", func(t *testing.T) { + paths, err := GetPathsConsumableDevicesFromLVMVG(ctx, cl, metrics, nil) + + if assert.EqualError(t, err, "lvmVolumeGroup is nil") { + assert.Nil(t, paths) + } + }) + + t.Run("GetPathsConsumableDevicesFromLVMVG_lvg_is_nil_returns_error", func(t *testing.T) { + const ( + name = "test_name" + firstBd = "first" + secondBd = "second" + testNode = "test_node" + firstPath = "first_path" + secondPath = "second_path" + ) + + bds := &v1alpha1.BlockDeviceList{ + Items: []v1alpha1.BlockDevice{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: firstBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + Consumable: false, + Path: firstPath, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: secondBd, + Namespace: namespace, + }, + Status: v1alpha1.BlockDeviceStatus{ + NodeName: testNode, + Consumable: true, + Path: secondPath, + }, + }, + }, + } + + var err error + for _, bd := range bds.Items { + err = cl.Create(ctx, &bd) + if err != nil { + t.Error(err) + } + } + + if err == nil { + defer func() { + for _, bd := range bds.Items { + err = cl.Delete(ctx, &bd) + if err != nil { + t.Error(err) + } + } + }() + } + + testLvg := &v1alpha1.LvmVolumeGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha1.LvmVolumeGroupSpec{ + BlockDeviceNames: []string{firstBd, secondBd}, + Type: Shared, + }, + } + + expected := []string{firstPath, secondPath} + + actual, err := GetPathsConsumableDevicesFromLVMVG(ctx, cl, metrics, testLvg) + if assert.NoError(t, err) { + assert.ElementsMatch(t, expected, actual) + } + + }) +} diff --git a/images/agent/pkg/utils/commands_test.go b/images/agent/pkg/utils/commands_test.go index 541e6bb4..981c4c20 100644 --- a/images/agent/pkg/utils/commands_test.go +++ b/images/agent/pkg/utils/commands_test.go @@ -17,6 +17,7 @@ limitations under the License. package utils import ( + "k8s.io/apimachinery/pkg/api/resource" "sds-node-configurator/internal" "testing" @@ -59,6 +60,12 @@ func TestCommands(t *testing.T) { } ] }` + + size30G, err := resource.ParseQuantity("30G") + size1M, err := resource.ParseQuantity("1M") + if err != nil { + t.Error(err) + } expectedDevices := internal.Devices{BlockDevices: []internal.Device{ { Name: "/dev/vda", @@ -67,7 +74,7 @@ func TestCommands(t *testing.T) { HotPlug: false, Model: "", Serial: "", - Size: "30G", + Size: size30G, Type: "disk", Wwn: "", KName: "/dev/vda", @@ -82,7 +89,7 @@ func TestCommands(t *testing.T) { HotPlug: false, Model: "", Serial: "", - Size: "1M", + Size: size1M, Type: "part", Wwn: "", KName: "/dev/vda1", @@ -142,13 +149,17 @@ func TestCommands(t *testing.T) { "report": [ { "pv": [ - {"pv_name":"/dev/vdb", "vg_name":"vgtest", "pv_fmt":"lvm2", "pv_attr":"a--", "pv_size":"1020.00m", + {"pv_name":"/dev/vdb", "vg_name":"vgtest", "pv_fmt":"lvm2", "pv_attr":"a--", "pv_size":"10G", "pv_free":"1020.00m", "pv_used":"0 ", "pv_uuid":"BmuLLu-9ZSf-eqpf-qR3H-23rQ-fIl7-Ouyl5X", "vg_tags":"", "vg_uuid":"JnCFQZ-TTfE-Ed2C-nKoH-yzPH-4fMA-CKwIv7"} ] } ] }` + size10G, err := resource.ParseQuantity("10G") + if err != nil { + t.Error(err) + } expectedPVs := internal.PV{PV: []internal.PVData{ { PVName: "/dev/vdb", @@ -157,7 +168,7 @@ func TestCommands(t *testing.T) { PVUuid: "BmuLLu-9ZSf-eqpf-qR3H-23rQ-fIl7-Ouyl5X", VGTags: "", VGUuid: "JnCFQZ-TTfE-Ed2C-nKoH-yzPH-4fMA-CKwIv7", - PVSize: "1020.00m", + PVSize: size10G, }, }} @@ -191,20 +202,24 @@ func TestCommands(t *testing.T) { { "vg": [ {"vg_name":"test-vg", "pv_count":"1", "lv_count":"0", "snap_count":"0", "vg_attr":"wz--n-", -"vg_size":"<2.00g", "vg_free":"<2.00g", "vg_uuid":"P14t8J-nfUE-hryT-LiTv-JdFD-Wqxg-R8taCa", +"vg_size":"2G", "vg_free":"2G", "vg_uuid":"P14t8J-nfUE-hryT-LiTv-JdFD-Wqxg-R8taCa", "vg_tags":"test-tag", "vg_shared":"test-shared"} ] } ] }` + size2G, err := resource.ParseQuantity("2G") + if err != nil { + t.Error(err) + } expectedVGs := internal.VG{VG: []internal.VGData{ { VGName: "test-vg", VGUuid: "P14t8J-nfUE-hryT-LiTv-JdFD-Wqxg-R8taCa", VGTags: "test-tag", - VGSize: "<2.00g", + VGSize: size2G, VGShared: "test-shared", - VGFree: "<2.00g", + VGFree: size2G, }, }} @@ -253,7 +268,7 @@ func TestCommands(t *testing.T) { "report": [ { "lv": [ - {"lv_name":"mythinpool", "vg_name":"test", "lv_attr":"twi---tzp-", "lv_size":"1.00g", "pool_lv":"", "origin":"", "data_percent":"", "metadata_percent":"", "move_pv":"", "mirror_log":"", "copy_percent":"", "convert_lv":""} + {"lv_name":"mythinpool", "vg_name":"test", "lv_attr":"twi---tzp-", "lv_size":"1G", "pool_lv":"", "origin":"", "data_percent":"", "metadata_percent":"", "move_pv":"", "mirror_log":"", "copy_percent":"", "convert_lv":""} ] } ]