diff --git a/hack/validate-imports/validate-imports.go b/hack/validate-imports/validate-imports.go index 17b70c426e3..4b8ddbcd7d6 100644 --- a/hack/validate-imports/validate-imports.go +++ b/hack/validate-imports/validate-imports.go @@ -22,7 +22,8 @@ func validateUnderscoreImport(path string) error { switch path { case "net/http/pprof", - "github.com/Azure/ARO-RP/pkg/util/scheme": + "github.com/Azure/ARO-RP/pkg/util/scheme", + "embed": return nil } diff --git a/pkg/operator/controllers/muo/bindata.go b/pkg/operator/controllers/muo/bindata.go deleted file mode 100644 index 0c52731e808..00000000000 --- a/pkg/operator/controllers/muo/bindata.go +++ /dev/null @@ -1,589 +0,0 @@ -// Code generated for package muo by go-bindata DO NOT EDIT. (@generated) -// sources: -// staticresources/cluster_role.yaml -// staticresources/cluster_rolebinding.yaml -// staticresources/config.yaml -// staticresources/custom_resource_definition.yaml -// staticresources/deployment.yaml -// staticresources/managed_upgrade_role.yaml -// staticresources/managed_upgrade_rolebinding.yaml -// staticresources/monitoring_reader_role.yaml -// staticresources/monitoring_reader_rolebinding.yaml -// staticresources/namespace.yaml -// staticresources/prometheus_role.yaml -// staticresources/prometheus_rolebinding.yaml -// staticresources/pullsecret_reader_role.yaml -// staticresources/pullsecret_reader_rolebinding.yaml -// staticresources/service_account.yaml -// staticresources/trusted_ca_bundle_configmap.yaml -package muo - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" -) - -func bindataRead(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) - clErr := gz.Close() - - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - if clErr != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindataFileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -// Name return file name -func (fi bindataFileInfo) Name() string { - return fi.name -} - -// Size return file size -func (fi bindataFileInfo) Size() int64 { - return fi.size -} - -// Mode return file mode -func (fi bindataFileInfo) Mode() os.FileMode { - return fi.mode -} - -// Mode return file modify time -func (fi bindataFileInfo) ModTime() time.Time { - return fi.modTime -} - -// IsDir return file whether a directory -func (fi bindataFileInfo) IsDir() bool { - return fi.mode&os.ModeDir != 0 -} - -// Sys return file is sys mode -func (fi bindataFileInfo) Sys() interface{} { - return nil -} - -var _cluster_roleYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x54\xc1\x8e\xd4\x30\x0c\xbd\xf7\x2b\xa2\xbd\xac\x84\x34\x1d\x71\x43\xbd\x72\xe0\x8e\x10\x77\x4f\xe2\xe9\x58\x9b\xc6\x91\xed\x14\xb1\x5f\x8f\xa6\xc9\xae\x0a\x9d\x32\xbb\x48\x9c\xe2\xbe\xda\x7e\x2f\xcf\x6e\x21\xd3\x77\x14\x25\x4e\x83\x93\x13\xf8\x1e\x8a\x5d\x58\xe8\x19\x8c\x38\xf5\x4f\x9f\xb4\x27\x3e\xce\x1f\xbb\x27\x4a\x61\x70\x9f\x63\x51\x43\xf9\xca\x11\xbb\x09\x0d\x02\x18\x0c\x9d\x73\x5e\x70\x29\xf8\x46\x13\xaa\xc1\x94\x07\x97\x4a\x8c\x9d\x73\x09\x26\x1c\xdc\x04\x09\x46\x0c\x87\x92\x47\x81\x80\x07\xce\x28\x60\x2c\x9d\x94\x88\x3a\x74\x07\x07\x99\xbe\x08\x97\xac\xd7\x76\x07\xf7\xf0\xd0\x39\x27\xa8\x5c\xc4\x63\xc3\x32\x07\x7d\x0d\x8e\x67\x4a\x10\xe9\x19\xe5\x8a\xcd\x28\xa7\x96\xb5\x48\xc1\x25\x0c\x18\xb1\x85\x23\xda\x72\x46\xd2\x1a\x64\x30\x7f\x59\xa2\x92\xc3\x4b\xc1\x8f\x05\x7c\x93\x18\x9c\x31\x59\x95\x93\x38\xe0\x1f\x22\x36\x74\x3b\x9d\x9b\x1f\x7d\xf3\xa7\xe7\x8c\x49\x2f\x74\xb6\x9e\x78\xcb\xd9\xb2\x3d\xa7\x33\x8d\xba\x86\x6e\xbc\x3e\xaa\x81\x95\xff\x6f\x4e\xa5\xbb\xa3\xdc\xd7\xbd\x99\xeb\xaa\xe9\x1a\x7b\x59\x85\x7b\x0e\xbe\x47\xd3\x04\xfe\x42\x09\xef\x88\x6a\x59\xfa\xdb\x03\xda\xfb\x2d\xdb\xe3\xaf\xd6\x14\xa9\xdf\xd2\x9b\xc4\xd4\x92\xcc\x1c\xff\x71\xa3\x5e\xed\xec\x3d\x0b\xf2\xf5\x98\xb6\x6c\x5a\x4e\xea\x85\xb2\xb5\x69\xac\x88\x1e\x3f\x3c\xde\xb8\x10\x27\x32\x16\x4a\xe3\xdf\xdb\xa2\xcc\xe4\xb1\x65\xef\x1b\xb9\x9a\xe0\xce\x9c\x37\x0a\x32\x47\xf2\x3f\x6f\xfe\x14\x02\xa9\x94\xe5\x2a\xa7\x12\xc6\xcd\x00\x77\x9c\xfb\x15\x00\x00\xff\xff\xa3\xcc\x1c\xe4\xfa\x04\x00\x00") - -func cluster_roleYamlBytes() ([]byte, error) { - return bindataRead( - _cluster_roleYaml, - "cluster_role.yaml", - ) -} - -func cluster_roleYaml() (*asset, error) { - bytes, err := cluster_roleYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "cluster_role.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _cluster_rolebindingYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x90\xbd\x6e\xc3\x30\x0c\x84\x77\x3d\x85\x5e\x40\x2e\xba\x15\xda\xda\x0e\xdd\x5d\x20\x3b\x2d\xd1\x36\x63\x9b\x14\x28\xca\x43\x9e\x3e\x08\x3c\x06\xf9\xd9\x3f\xdc\x77\x77\x0b\x71\x8e\xfe\x77\x6d\xd5\x50\x7b\x59\xf1\x87\x38\x13\x4f\x0e\x0a\x9d\x50\x2b\x09\x47\xaf\x03\xa4\x0e\x9a\xcd\xa2\x74\x01\x23\xe1\x6e\xf9\xaa\x1d\xc9\xc7\xfe\xe9\x36\x34\xc8\x60\x10\x9d\xf7\x0c\x1b\x46\xbf\x01\xc3\x84\x39\xb4\x32\x29\x64\x0c\x52\x50\xc1\x44\x5d\x6d\xc3\x19\x93\xd5\xe8\x82\x3f\xc4\xff\xa8\x3b\x25\xfc\x4e\x49\x1a\xdb\xeb\x84\x03\xa8\x05\x12\x46\x2f\x05\xb9\xce\x34\x5a\x78\xc8\xab\xac\xd8\xe3\x78\xeb\x76\xb7\xf4\x1d\x1b\x14\xfa\x53\x69\xe5\xc9\x07\xee\x1a\x00\x00\xff\xff\xc4\x6f\x81\xf4\x43\x01\x00\x00") - -func cluster_rolebindingYamlBytes() ([]byte, error) { - return bindataRead( - _cluster_rolebindingYaml, - "cluster_rolebinding.yaml", - ) -} - -func cluster_rolebindingYaml() (*asset, error) { - bytes, err := cluster_rolebindingYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "cluster_rolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _configYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x52\xdd\x6a\x1b\x3d\x10\xbd\xf7\x53\xe8\x05\xf6\xe3\x73\x7f\xa0\xd5\x5d\xd8\x10\x28\x24\x76\x08\x69\x7b\x3d\x48\x27\xbb\xc2\xda\x91\x18\x8d\xec\xa6\xf4\xe1\x8b\xd7\xbb\x8e\xd3\x6c\xab\xcb\xf3\x33\xe7\x68\x18\xca\xe1\x1b\xa4\x84\xc4\xd6\xec\xd7\xab\x5d\x60\x6f\x4d\x9b\xf8\x29\x74\x77\x94\x57\x03\x94\x3c\x29\xd9\x95\x31\x4c\x03\xac\x19\x88\xa9\x83\x6f\x6a\xee\x84\x3c\x9a\x94\x21\xa4\x49\x1a\x37\x9a\x26\x5d\xc9\xe4\x60\x4d\xca\xe0\xd2\x87\x27\x6d\xfe\x66\x5b\xcd\xd3\x4f\xf6\xff\x9e\x69\x88\xd6\xfc\x5a\x19\x33\x43\x77\xa3\x53\xec\x08\x19\x53\x52\x95\xe3\xe8\xdb\x6d\x7b\x75\x3b\x61\x31\x39\x8a\xa7\xd2\x9b\xc5\x92\xe7\x6e\xc7\x77\x20\x75\xfd\x17\x56\xc8\x9e\xa2\x35\xeb\x11\x1e\x28\xb0\x82\x89\x1d\xe6\x24\x97\x58\x25\xc5\xfb\x48\x8c\xc7\x70\x1c\xfb\xf9\xff\x89\x0a\x1d\x27\x81\xbf\x8a\x10\x2d\xb3\xfe\xb5\xa3\x95\xa0\xc1\x51\xbc\xa0\x1b\xd3\xc6\x5a\x14\xb2\x9d\x3e\x7f\x9d\x0e\xfc\x0f\x16\x63\x79\x3f\x2a\xa6\x9f\x7c\x0f\xec\xd3\x61\x1e\xe9\x11\xe9\xf9\x51\x42\x77\xdc\x8f\x79\x3f\xb7\xd3\x30\x60\x5b\xd5\x9a\xf5\xbb\x13\xc4\xc9\xe3\x5a\x28\xb0\xfd\x53\xf1\xe1\xe3\x84\xe0\x47\x86\x53\xf8\xcd\x2c\x3d\xfd\xf8\xd3\x48\x17\x47\x11\x6f\xbc\x53\x5e\x0f\x8a\xda\xb7\x3d\xdc\xce\xbe\x5e\xcf\x9b\x15\x34\xe6\x5e\xd2\x00\xed\x51\xcb\x43\x8d\xb8\xa1\x10\xab\xa0\x9c\xe9\x96\x98\x93\x3e\x40\x25\x60\x8f\xaf\xd9\x93\x5e\xb0\x37\xb1\x82\xf5\x54\xf1\x65\x73\x53\xd8\x66\xbe\xba\x8b\xb4\x97\xf3\x8b\xa9\xeb\x02\x77\x0b\x8c\xc0\xf7\x74\xbc\x4f\xd9\x41\x73\x24\x87\x05\xd1\x7c\xad\x65\x81\xab\x05\xd2\x1c\x92\xec\x62\x22\xdf\x0c\x89\x83\x26\x59\xce\xca\x21\x23\x06\xc6\xd2\x18\xfa\x59\x05\xe7\x9e\xbf\x03\x00\x00\xff\xff\x6c\x17\x59\x7b\x97\x03\x00\x00") - -func configYamlBytes() ([]byte, error) { - return bindataRead( - _configYaml, - "config.yaml", - ) -} - -func configYaml() (*asset, error) { - bytes, err := configYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "config.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _custom_resource_definitionYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x59\x4b\x8f\xdb\x38\x12\xbe\xfb\x57\x14\x66\x0f\xd9\x05\x62\x75\x67\x73\x59\xf8\x96\x71\x6f\x30\xc1\xce\x24\x8d\x74\x4f\x2e\x83\xc1\xa2\x2c\x96\x2c\x4e\x53\xa4\x96\x0f\x77\x3c\x8b\xfd\xef\x8b\xa2\x28\xcb\x92\xa9\xb6\x1b\xc9\x3c\x78\x13\x1f\xf5\xae\xaf\x8a\xd4\x72\xb9\x5c\x60\x2b\x3f\x91\x75\xd2\xe8\x15\x60\x2b\xe9\xb3\x27\xcd\x5f\xae\x78\xf8\x87\x2b\xa4\xb9\xda\xbd\x5a\x3c\x48\x2d\x56\xb0\x0e\xce\x9b\xe6\x23\x39\x13\x6c\x49\x37\x54\x49\x2d\xbd\x34\x7a\xd1\x90\x47\x81\x1e\x57\x0b\x00\xd4\xda\x78\xe4\x69\xc7\x9f\x00\xa5\xd1\xde\x1a\xa5\xc8\x2e\xb7\xa4\x8b\x87\xb0\xa1\x4d\x90\x4a\x90\x8d\xc4\x7b\xd6\xbb\xeb\xe2\x75\x71\xbd\x00\x28\x2d\xc5\xe3\xf7\xb2\x21\xe7\xb1\x69\x57\xa0\x83\x52\x0b\x00\x8d\x0d\xad\x20\xb4\x5b\x8b\x82\x4a\xa3\x2b\xb9\x75\x45\xfa\x2c\x1a\xd4\xb8\x25\x51\x98\x96\xb4\xab\x65\xe5\x0b\x69\x16\xae\xa5\x92\xa5\xd8\x5a\x13\xda\xc3\xd1\xfc\xde\x8e\x7e\x12\xba\x53\xf8\xc7\x6e\xff\x3a\xb2\x8a\xf3\x4a\x3a\xff\xaf\xd3\xb5\xef\xa5\xf3\x71\xbd\x55\xc1\xa2\x9a\x0a\x19\x97\x5c\x6d\xac\x7f\x3f\xb0\x58\xf6\x9b\xba\x55\xa9\xb7\x41\xa1\x9d\x1c\x5d\x00\xb8\xd2\xb4\xb4\x82\x78\xb2\xc5\x92\xc4\x02\x20\x59\x2d\x52\x5a\x02\x0a\x11\xfd\x80\xea\xd6\x4a\xed\xc9\xae\x8d\x0a\x8d\x3e\xf0\xf9\xc5\x19\x7d\x8b\xbe\x5e\x41\xc1\x06\x29\x04\x39\x69\x49\x14\x89\x4a\xdc\xd5\x5b\x37\xad\xfd\x7b\xbc\xe6\xf7\x2c\x82\xf3\x56\xea\x6d\x86\xa8\x47\x1f\x5c\x51\x4b\xe7\x8d\xdd\xff\x74\xfd\x73\xd1\xd6\xe8\x68\x44\xf7\x78\xe6\xb9\xd4\x4a\xa3\x3b\x05\x1d\x7f\xf1\xe9\x11\x69\xe7\x71\xfb\x75\x48\x77\xeb\x53\xe2\xc3\xd4\x97\x51\xb7\x84\x6e\x62\xed\xd1\xd4\x97\x51\x6f\xc8\xb9\xc1\x0e\x1d\xf9\xf1\xdc\x09\xfd\x6e\xd3\xee\x15\xaa\xb6\xc6\x57\x5d\x18\x96\x35\x35\xb8\x4a\x27\x38\x3f\xde\xdc\xbe\xfb\xf4\xfa\x6e\x34\x0d\x1c\x25\xa5\x95\xad\x8f\x99\x3b\xca\x04\x90\x0e\x7c\x4d\xd0\x9d\x80\xca\xd8\xf8\x39\xce\x07\x78\x73\xfb\xee\x40\xab\xb5\xa6\x25\xeb\x65\x9f\x17\xdd\x38\x42\xa5\xa3\xd9\x09\xe7\x17\x2c\x5c\xb7\x0b\x04\xc3\x11\x75\xcc\x53\xf0\x92\x48\xfa\x80\xa9\xc0\xd7\xd2\x81\xa5\xd6\x92\x23\xdd\x01\xd4\x88\x30\xf0\x26\xd4\x60\x36\xbf\x50\xe9\x0b\xb8\x23\xcb\x64\x38\x6d\x83\x12\x8c\x62\x3b\xb2\x1e\x2c\x95\x66\xab\xe5\xaf\x07\xda\x0e\xbc\x89\x4c\x15\x7a\x4a\x28\x30\x8c\x98\x8e\x1a\x15\xec\x50\x05\x7a\x09\xa8\x05\x34\xb8\x07\x4b\xcc\x05\x82\x3e\xa2\x17\xb7\xb8\x02\x7e\x30\x96\x40\xea\xca\xac\xa0\xf6\xbe\x75\xab\xab\xab\xad\xf4\x3d\x1a\x97\xa6\x69\x82\x96\x7e\x7f\x15\x81\x55\x6e\x82\x37\xd6\x5d\x09\xda\x91\xba\x72\x72\xbb\x44\x5b\xd6\xd2\x53\xe9\x83\xa5\x2b\x6c\xe5\x32\x8a\xae\x63\xa0\x14\x8d\xf8\x8b\x4d\xf8\xed\x5e\x8c\x64\x3d\x89\x8e\x6e\x44\x20\x7c\xc2\x03\x0c\x86\xec\x73\x4c\x47\x3b\x2d\x06\x43\xf3\x14\x5b\xe7\xe3\x3f\xef\xee\xa1\x67\x1d\x9d\x31\xb5\x7e\xb4\xfb\x70\xd0\x0d\x2e\x60\x83\x49\x5d\x91\xed\x9c\x58\x59\xd3\x44\x9a\xa4\x45\x6b\xa4\xf6\xf1\xa3\x54\x92\xf4\xd4\xfc\x2e\x6c\x1a\xe9\xd9\xef\xff\x09\xe4\x3c\xfb\xaa\x80\x75\x2c\x51\xb0\xe1\xa8\x14\xe8\x49\x14\xf0\x4e\xc3\x1a\x1b\x52\x6b\x74\xf4\x9b\x3b\x80\x2d\xed\x96\x6c\xd8\xcb\x5c\x70\x5c\x5d\xa7\x9b\x3b\xab\x1d\x2d\xf4\x15\x6f\xc6\x5f\xa3\x5c\xbd\x6b\xa9\x1c\xe5\x4d\x02\xff\x08\x7a\xc4\xf9\x70\x5a\x00\x87\xc1\xa1\x9c\xd2\x1a\x1e\xa5\x16\xe6\x31\x4e\x55\x96\xe8\xd7\x7e\x66\x74\x24\x9f\xe8\x3c\x6e\x6f\xbe\x7d\x6b\xb8\xa5\xb0\x28\x63\xdd\x37\xc1\x4f\xf7\x4c\x14\xb9\xaf\x09\x1a\xfc\x2c\x9b\xd0\xc0\xd6\x62\x49\xd0\x92\x95\x46\xf0\x87\xf6\x24\x38\x2b\x11\xb4\x61\xe1\x6a\xe3\x08\x04\xd3\x3e\xa1\x09\x1c\xbb\x1b\x65\xca\x07\x12\xb0\xd9\x03\xc2\xad\x11\x70\x23\x9d\x0d\x91\x11\x7c\x1b\xc4\x96\xfc\x4b\xd8\x50\xc5\x51\xe1\x6b\xf4\x1d\x29\x3e\x58\xb1\xd0\xa2\xc8\x50\xfd\x81\xd0\x05\x36\xa5\xd4\xd0\x48\x1d\x3c\x27\x76\x94\x59\xea\x28\x33\x96\x25\xb5\xbe\xcf\x7a\x26\x76\x1d\xcd\x27\x75\x2e\x39\x78\x94\xe8\x08\xa4\x87\x47\xa9\x14\x78\x2b\xb7\x5b\xb2\x9d\x04\x49\x20\xac\x3c\x75\x68\x4b\x9f\x5b\x2a\x3d\x89\xf7\x46\x0c\x36\xcd\x90\x54\xd8\xba\x9c\xfc\x95\xb1\x0d\xfa\x15\xa3\xd7\xeb\xbf\x9f\xac\x26\x15\x56\x70\x7d\xb2\xd4\x05\x25\x83\xde\x96\xec\x62\x2a\x7f\x8b\xa5\xf4\xfb\x8f\xe4\xc8\xee\x22\x00\x9f\xf1\x31\xc7\xa7\xac\xf6\x20\x2b\x70\x25\x2a\x86\x92\xd0\x32\x46\xd3\x67\x6f\x93\x73\xb9\xc0\xf4\x94\x19\x5f\x7a\xd2\x19\x6d\x93\x0b\xfb\x98\x75\x1e\xad\x77\x6c\x79\x4d\x24\x62\x5b\x95\x53\x66\x63\x8c\x22\x9c\xd2\x4b\x99\x72\xa1\x02\xc7\xb9\xf5\xa1\x25\x7d\xc7\x3d\x27\x58\x52\x34\x34\x45\xc3\x98\xcf\x93\x68\xc6\x1a\xb5\x26\x95\x5b\x9a\x70\x5f\x77\x3b\x21\x38\x12\xd1\x4e\x49\xf3\x5c\x70\xcd\x82\x4f\x3f\x64\x83\x5b\xba\x80\xe9\x3b\xde\x07\x96\x2a\xb2\xa4\x4b\xfa\x3a\xcc\x77\xb9\x4e\x20\xcb\xbe\xef\x06\x4c\x05\x87\xe6\x7e\xd6\xd0\x67\x39\xcf\x60\xec\x61\xe9\x0c\x44\xed\x5b\x2e\x23\x42\x96\xdc\x19\xc4\x20\x58\xab\xe0\x3c\xd9\x04\xab\x16\x64\xd3\x2a\x6a\xfa\x7e\x04\xbc\xc9\xc8\x18\x1c\x31\x98\xb5\x64\x39\x2d\x39\xfc\xfb\x08\x8e\x5d\x0d\x57\xbe\x48\xf4\xe4\x28\xe9\xd0\x9c\x8a\xb8\x84\x0f\x77\x37\x99\xd9\x37\x1f\x3f\xcc\xe8\x9f\x35\x4e\x92\xe1\xcd\x39\x9c\x3e\x4e\x81\x51\xe6\x81\xcf\x61\xd2\x2c\x47\xae\xe0\xa7\x19\xb7\xcc\x96\x8e\xc9\x96\x94\x79\x93\xd9\xa3\x6b\x44\x3f\x75\xd0\xe9\xa2\x42\x1b\xfb\xf1\x8b\x4b\x6d\xdc\x3d\x2a\xb6\x66\xc3\x60\x75\x59\xb5\x9d\x87\x84\x74\x1f\x38\x5b\x2d\x63\xf3\x5b\x1a\x2b\xfa\x13\xcc\x90\x76\x64\xf7\xa3\x6b\xe8\xf1\x90\x9e\x9a\x2c\x04\xe5\xd4\xfc\x2e\x51\x3d\x65\x32\x47\xfe\x1c\xd0\x01\x94\x86\xd3\xc3\x13\xbb\x35\xbf\x63\x28\x55\xdc\xc8\x2d\xb3\x21\xd5\x8d\x33\x08\x13\x9f\x29\xd2\x6d\x6a\x8e\xd5\x18\x5c\x0f\xdb\x53\xf7\x4b\x9e\x95\x3d\x4c\x83\xd4\xce\xa3\x2e\xc9\xe5\xda\x03\x78\xca\xbc\x19\x6e\x43\x64\x24\xea\xb5\x09\x8e\x1c\x54\x92\x94\x70\xa9\x2b\x89\x07\x36\x73\x06\x88\x46\xa8\x69\x88\x36\xd4\x3d\x59\x90\xba\x54\x41\x70\x7d\xed\x7b\xcd\x39\xa1\xcf\x3b\xad\xb7\xe6\x79\xd7\x65\xf4\x5c\xa7\x63\x11\x1c\x0e\xb7\xb6\x83\x6b\xe6\xa5\x82\x67\x84\x42\xb2\xc5\xb9\x80\xe8\x86\x42\xe7\x6f\xad\xd9\x3c\x57\x93\xef\xd1\x75\x10\xd7\x41\xf4\xc1\x71\x8f\xe8\xa0\xac\x89\xfb\xcd\x3f\x48\x9b\x7b\x8b\xda\xc9\xfe\x85\xed\x2b\xa8\xe4\x3b\x82\xdd\xbd\xcc\xe8\xa7\x05\xed\x81\x33\xf6\xe7\xda\xf8\x9a\xec\x1f\x60\x87\xf4\x30\xf2\x0c\xe5\xbf\x0b\x0d\x6a\xb0\x84\x02\x37\x8a\x7a\x02\x7d\x79\xe7\xd4\x11\xe4\x51\xaa\x7c\x7f\x33\x0c\xdc\x98\xe0\xa3\x1f\x7a\xbb\x9d\x8d\xeb\x0b\x75\xea\xde\x92\x9e\xa1\xd2\x5f\x37\x56\x52\xf5\xb7\x74\xf0\xf0\x54\x73\x70\xec\x0b\xf7\x9b\xc8\x19\xab\xff\x33\x43\xef\xee\xd0\x31\xfc\x29\x40\x21\x57\xfb\xcf\xc9\xcf\x31\x6f\xaa\x41\xec\x97\x9c\x2a\x3c\x73\x6f\x03\xbd\x84\xb7\xa8\x1c\xbd\x3c\x13\x3c\x3f\xea\x07\x6d\x1e\x73\x77\x9b\x67\xab\x90\xef\x5f\x67\x15\x88\xbd\xec\x50\xcc\x07\x35\xbe\x5c\x96\x7c\x67\x77\x3c\x96\xe3\x57\xd8\xdc\x86\x93\x6e\xee\x54\x8c\x6c\x1b\x3f\xde\x82\xd6\xe2\x3e\xbb\x23\x3e\x5f\x5f\xd4\x18\xc4\x56\xab\xaf\xc5\x87\x8a\xdb\x39\xff\xb8\x09\x6e\xad\x29\xc9\xcd\xe9\x94\xef\xdd\x7b\x6d\xdf\xd3\xe3\xec\xda\x2d\x69\x31\x6f\xee\x65\xaa\xf9\xe7\x77\x64\x2e\xc4\xfd\x86\xb7\x28\xd5\xec\xf2\x59\x9f\x9f\xcd\xff\xaf\xd6\xd2\x3d\x79\x6d\x9c\xb8\xed\x26\x5d\xcf\x77\xc3\x05\x32\xc2\xcc\x7c\xf7\x7a\x91\x08\x8f\xc6\x3e\x90\x5d\xff\x9e\x8d\x6c\xc7\xf2\xee\x77\xb2\xf2\x53\xd9\xbb\x1c\xfd\xf5\x39\x25\x3a\x93\x91\x73\xb9\x98\x3d\x74\x32\xd9\x5d\xaa\x56\xe0\x6d\x48\x7f\xd6\xbc\xb1\x5c\xeb\x8f\x66\xc2\xe6\xf0\x08\xde\xcb\x9d\x20\x1d\xfe\xfb\xbf\xc5\x80\xee\xfd\x23\xdd\xfb\xe9\x8f\xc1\x6f\xbe\x89\x1f\xfd\xdf\xbe\xf8\x79\x74\x81\x80\x9f\x7e\x5e\x74\x8c\x49\x7c\xea\x7f\xd5\xf1\xe4\xff\x03\x00\x00\xff\xff\x30\x3b\x1c\x49\x70\x1d\x00\x00") - -func custom_resource_definitionYamlBytes() ([]byte, error) { - return bindataRead( - _custom_resource_definitionYaml, - "custom_resource_definition.yaml", - ) -} - -func custom_resource_definitionYaml() (*asset, error) { - bytes, err := custom_resource_definitionYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "custom_resource_definition.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _deploymentYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x55\x4d\x6f\xe3\x36\x10\xbd\xfb\x57\x0c\xd2\xb3\xa2\x24\x68\x2f\xbc\x19\x1b\xb7\x5d\xa0\x8e\x0d\xc7\x68\x8f\xc5\x98\x1c\x49\x84\xf9\x55\x72\xe8\x8d\xfe\x7d\x21\xc9\x71\x64\x39\xc6\x1a\x05\x8a\xf5\xc9\x98\x37\x7c\xf3\xf8\x38\x33\xc2\xa0\xff\xa4\x98\xb4\x77\x02\x30\x84\x54\x1e\x1e\x67\x7b\xed\x94\x80\x67\x0a\xc6\xb7\x96\x1c\xcf\x2c\x31\x2a\x64\x14\x33\x00\x87\x96\x04\x58\x74\x58\x93\x2a\x72\xa8\x23\x2a\x2a\x7c\xa0\x88\xec\xe3\x31\x21\x05\x94\x24\xc0\x07\x72\xa9\xd1\x15\x17\x57\xf3\x53\x20\xd9\xd1\x46\x0a\x46\x4b\x4c\x02\x1e\x67\x00\x89\x0c\x49\xf6\xb1\x43\x00\x2c\xb2\x6c\xfe\xc0\x1d\x99\x34\x04\x6e\x50\xc1\x64\x83\x41\xa6\x23\xc3\xe8\x02\xdd\xcf\x9c\x91\xdd\x40\x07\xf0\x2e\xb4\xff\x4f\xf1\xa0\x25\xcd\xa5\xf4\xd9\xf1\xcb\xf7\x0f\x03\x60\x55\x69\xa7\xb9\x1d\xd5\xf4\x8a\xe6\x17\xd1\xce\x89\x7f\xb2\x8e\xa4\x9e\x73\xd4\xae\x7e\x95\x0d\xa9\x6c\xb4\xab\xbf\xd6\xce\x9f\xc2\x8b\x37\x92\x99\xbb\x57\x1b\x9d\x1c\x38\x5f\x8f\xde\x6d\x29\xda\x74\x0e\x17\x83\x95\x8b\xb7\x10\x29\x75\x6f\x3e\xc1\xbb\x8c\x3d\xb5\xa2\xe7\x29\xa2\x37\x74\xbf\xcf\x3b\x8a\x8e\x98\xd2\xbd\xf6\xa5\xc5\xc4\x14\x27\x67\x00\xde\xef\x2a\xe0\xab\xbb\x00\x0f\x68\x32\x5d\x14\xea\x4a\xdd\xdd\x1d\x83\xec\x4d\x47\x30\x16\x54\x00\x55\x15\x49\x16\xf0\xe2\x8f\x1e\xd0\x89\xe2\x76\x8d\x63\x9a\xc1\xb3\xff\xc2\x72\xf0\x26\x5b\x1a\x69\x93\xde\x55\xba\x5e\x62\x18\x5f\x4b\x51\x85\xd9\xf0\xd2\x2b\x12\xf0\xf3\xd3\xc3\x08\xd2\x4c\x97\x6f\xd1\xd7\x97\x58\xec\xb2\x53\x86\xee\x65\xe4\x89\x47\x01\xb9\x11\xc0\x26\x15\x1f\x59\x81\xec\x28\x6b\xe8\x5b\x8e\x39\x31\xa9\x8f\xac\xd9\x6d\xb8\xf4\x8e\x51\x3b\x8a\x23\x69\xc5\x2d\xb3\x30\xfc\x7e\x82\x0d\x05\x83\x92\x80\x1b\x9d\xe0\x9b\xe6\x06\xb8\x21\xd8\x65\x6d\x18\xb4\xc5\x9a\x7a\xb2\xb3\x23\xdb\x21\xd5\x18\xa8\x89\xfb\xa9\x47\x49\x0a\xbc\x03\xd5\xef\x1b\xd8\xb5\x50\x36\x28\xf7\x65\x4d\xae\x2b\xf9\x51\xfa\x64\x41\x3b\x76\xb6\x2b\x23\xe0\xb7\xc5\xcb\x62\x33\xdf\x2e\x9e\x47\x90\xf4\xd6\xa2\x53\x63\xdb\x8b\x5b\xee\xd5\x53\xae\xb3\x31\x6b\x6f\xb4\x6c\x05\xcc\xcd\x37\x6c\xd3\xd9\x88\x26\x9f\xa3\x9c\x76\x75\x37\xb9\x94\xf8\xa2\xd7\x65\xc8\x02\x9e\x1e\xec\x24\x6c\xc9\xfa\xd8\x0a\x78\x7c\x78\x58\xea\x33\xcc\x68\xab\xaf\xd0\xfc\x72\x95\xe6\x69\x42\x43\xee\x30\xed\xb8\xe1\x69\xff\x9a\x6f\xbf\xfc\xfe\xf7\xcb\x7c\xb9\x78\x5d\xcf\xbf\x2c\x26\x74\xfd\xb8\xfe\x1a\xbd\xbd\x9c\xd8\x4a\x93\x51\x1b\xaa\x2e\x91\x23\xb6\xee\x1b\xf6\x7d\xd9\xde\x9f\xbe\x04\x9f\xca\x58\xaf\x9e\x7b\x11\xff\x6f\xfd\x4f\x4b\xaf\xd6\x5d\xb3\xac\x36\x3f\xde\x84\x33\x25\x9f\x89\x10\x70\x77\xad\x65\xef\x46\xf9\xc3\x86\x5a\x76\x9f\xa3\x34\x69\xf8\x2e\x36\x68\x2a\x89\x65\x19\xf6\xba\x94\x58\xf4\x3b\xa1\xa4\x37\x8e\x28\x99\x54\x79\xbe\x57\xbe\xbf\x59\xa0\xef\x77\x54\x2b\x67\xda\x3e\x8f\x66\xff\x06\x00\x00\xff\xff\xb7\xcc\xef\x39\x4b\x08\x00\x00") - -func deploymentYamlBytes() ([]byte, error) { - return bindataRead( - _deploymentYaml, - "deployment.yaml", - ) -} - -func deploymentYaml() (*asset, error) { - bytes, err := deploymentYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "deployment.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _managed_upgrade_roleYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x8f\xb1\x6e\x03\x21\x10\x44\xfb\xfb\x0a\xe4\x1e\x5b\xe9\x22\x7e\x20\x7d\x8a\xf4\x6b\x18\x9f\x57\xe6\xd8\xd5\x02\x17\xc5\x5f\x1f\xf9\x7c\x27\xd9\x89\xa2\x54\xbc\x19\x8d\xe0\x41\xca\x1f\xb0\xca\x52\x82\xb3\x23\xc5\x3d\xf5\x76\x16\xe3\x2b\x35\x96\xb2\xbf\xbc\xd6\x3d\xcb\x61\x7e\x19\x2e\x5c\x52\x70\xef\x92\x31\x4c\x68\x94\xa8\x51\x18\x9c\x2b\x34\x21\xb8\x89\x0a\x8d\x48\xbe\xeb\x68\x94\xe0\x45\x61\xd4\xc4\xd6\x41\x55\x8a\x08\x4e\x14\xa5\x9e\xf9\xd4\xfc\x9f\x7b\xeb\x19\x35\x0c\xde\x91\xf2\x9b\x49\xd7\x7a\x7b\xc4\xbb\xdd\x6e\x70\xce\x50\xa5\x5b\xc4\xda\x45\x29\x27\x1e\x27\xd2\xba\xc4\x8a\x68\x68\x1b\xdb\xcc\x11\xcf\xe1\x70\xe2\x42\x99\xaf\xb0\x5b\x3f\xc3\x8e\xdb\x45\x06\x6a\x58\x30\x21\x63\xc5\x11\x6d\x39\x33\xd7\x3b\x74\x4d\xdb\xec\x93\x5a\x3c\xff\xb6\x24\x5d\x5c\x7e\x78\x26\x68\x96\xaf\x09\x65\x95\x7b\xc8\xcf\x4a\xde\x19\x34\x73\xa4\x7a\xff\xc7\x83\xe2\xff\x32\xdf\x01\x00\x00\xff\xff\x4e\x92\x80\x9e\xc9\x01\x00\x00") - -func managed_upgrade_roleYamlBytes() ([]byte, error) { - return bindataRead( - _managed_upgrade_roleYaml, - "managed_upgrade_role.yaml", - ) -} - -func managed_upgrade_roleYaml() (*asset, error) { - bytes, err := managed_upgrade_roleYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "managed_upgrade_role.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _managed_upgrade_rolebindingYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x8e\x31\xce\xc2\x30\x0c\x46\xf7\x9c\x22\x17\x48\x7f\xfd\x1b\xca\x06\x47\x28\x12\xbb\x9b\xb8\xad\x69\x6b\x47\x8e\xd3\x81\xd3\x23\xa4\x4a\x4c\x88\x85\xfd\x7d\xdf\x7b\x50\xe8\x86\x5a\x49\x38\x7a\x1d\x20\x75\xd0\x6c\x16\xa5\x07\x18\x09\x77\xcb\xa9\x76\x24\x7f\xfb\xbf\x5b\x88\x73\xf4\xbd\xac\x78\x21\xce\xc4\x93\xdb\xd0\x20\x83\x41\x74\xde\x33\x6c\x18\xfd\x06\x0c\x13\xe6\xd0\xca\xa4\x90\x31\x48\x41\x05\x13\x3d\x80\x5a\x20\x61\xf4\x52\x90\xeb\x4c\xa3\x85\x8f\xbc\xca\x8a\x3d\x8e\xaf\xe7\xb7\xf7\xbb\xa6\xb6\xe1\x8e\xc9\x6a\x74\xe1\xd8\x5d\x51\x77\x4a\x78\x4e\x49\x1a\xdb\xef\x43\x9f\x01\x00\x00\xff\xff\x45\xec\x1c\xea\x3f\x01\x00\x00") - -func managed_upgrade_rolebindingYamlBytes() ([]byte, error) { - return bindataRead( - _managed_upgrade_rolebindingYaml, - "managed_upgrade_rolebinding.yaml", - ) -} - -func managed_upgrade_rolebindingYaml() (*asset, error) { - bytes, err := managed_upgrade_rolebindingYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "managed_upgrade_rolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _monitoring_reader_roleYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8e\xbf\x4e\xc3\x40\x0c\xc6\xf7\x7b\x0a\xab\x7b\x82\xd8\xd0\xbd\x00\x3b\x03\xbb\x7b\x71\x13\xab\x39\xfb\x64\xfb\x82\xc4\xd3\xa3\x86\x80\x40\x5d\x3a\xd9\xdf\x1f\x7d\xfa\x61\xe3\x77\x32\x67\x95\x0c\x76\xc6\x32\x62\x8f\x45\x8d\x3f\x31\x58\x65\xbc\xbe\xf8\xc8\xfa\xb4\x3d\xa7\x2b\xcb\x94\xe1\x4d\x57\x4a\x95\x02\x27\x0c\xcc\x09\x40\xb0\x52\x86\xda\x75\xa8\x2a\x1c\x6a\x2c\xf3\x60\x84\x13\xd9\x91\x7a\xc3\x42\x19\xb4\x91\xf8\xc2\x97\xf8\x53\x4c\xd6\x57\xf2\x9c\x06\xc0\xc6\xaf\xa6\xbd\xf9\x6d\x73\x80\xd3\x29\x01\x18\xb9\x76\x2b\x74\x78\x45\xe5\xc2\x73\xc5\xe6\xbb\x74\xb2\x8d\x0b\x61\x29\xda\x25\x7e\xbc\x62\x14\xff\xf2\x9b\xd8\xc8\xce\xc7\xc8\x4c\xb1\xdf\x95\xfd\xfb\xf9\xc0\x28\xcb\x3d\x80\x69\x0f\x1a\x7f\x99\x47\xd6\x7b\xa0\xbd\xf3\xd8\xfe\x57\x00\x00\x00\xff\xff\xfb\x3d\x00\x65\x66\x01\x00\x00") - -func monitoring_reader_roleYamlBytes() ([]byte, error) { - return bindataRead( - _monitoring_reader_roleYaml, - "monitoring_reader_role.yaml", - ) -} - -func monitoring_reader_roleYaml() (*asset, error) { - bytes, err := monitoring_reader_roleYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "monitoring_reader_role.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _monitoring_reader_rolebindingYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x8e\x31\x4e\x83\x31\x0c\x46\xf7\x9c\x22\x17\xc8\x8f\xd8\x50\x36\x38\x42\x91\xd8\xdd\xe4\x6b\x6a\xda\xd8\x91\xe3\x74\xe0\xf4\x08\xa9\x52\x59\x7e\x75\xf6\x7b\xcf\x1f\x0d\xfe\x82\x4d\x56\xc9\xd1\x8e\x54\x36\x5a\x7e\x56\xe3\x1f\x72\x56\xd9\x2e\x6f\x73\x63\x7d\xb9\xbd\x86\x0b\x4b\xcd\xf1\xa0\x57\x7c\xb0\x54\x96\x16\x3a\x9c\x2a\x39\xe5\x10\xa3\x50\x47\x8e\x7d\x69\xea\x2a\xec\x6a\x2c\x2d\x19\xa8\xc2\xee\xd7\x39\xa8\x20\x47\x1d\x90\x79\xe6\x93\xff\x03\x83\xe9\x15\x07\x9c\xfe\x42\x8f\x37\x4f\xaa\x73\x1d\xbf\x51\x7c\xe6\x90\xee\xd2\x27\xec\xc6\x05\xef\xa5\xe8\x12\x7f\xe8\x24\xd4\x50\xd3\x1a\xcd\xa8\x22\xe9\x80\x91\xeb\xfe\xae\x3d\xfe\x37\x00\x00\xff\xff\xd9\xce\xa4\x95\x2b\x01\x00\x00") - -func monitoring_reader_rolebindingYamlBytes() ([]byte, error) { - return bindataRead( - _monitoring_reader_rolebindingYaml, - "monitoring_reader_rolebinding.yaml", - ) -} - -func monitoring_reader_rolebindingYaml() (*asset, error) { - bytes, err := monitoring_reader_rolebindingYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "monitoring_reader_rolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _namespaceYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\xcb\x31\x0e\x42\x21\x0c\x06\xe0\x9d\x53\x34\xec\x68\x5c\x39\x84\xa3\x7b\x7d\xfc\x3e\x1b\xa1\x25\xa5\xcf\xf3\x1b\x27\x17\x0f\xf0\xbd\x44\x5b\xa5\x2b\x0f\xac\xc9\x1b\x12\x4f\xb9\xc1\x97\x98\x56\x7a\x5f\xd2\x40\x70\xe3\xe0\x9a\x88\x94\x07\x2a\xd9\x84\xae\xa7\x3c\xa2\x0c\x56\xde\xd1\xca\x31\x77\xe7\x86\x62\x13\xce\x61\x9e\x88\x3a\xdf\xd1\xd7\x17\xd1\x0f\x9c\xc4\xce\x5b\x3f\x56\xc0\xcb\x30\x95\x30\x17\xdd\x2b\xe5\xf0\x03\x39\x11\xb1\xaa\x05\x87\x98\xfe\xa3\x6a\x0d\x65\xa1\x63\x0b\xf3\x4a\x39\xa7\x4f\x00\x00\x00\xff\xff\x91\x84\xdf\xfb\xbc\x00\x00\x00") - -func namespaceYamlBytes() ([]byte, error) { - return bindataRead( - _namespaceYaml, - "namespace.yaml", - ) -} - -func namespaceYaml() (*asset, error) { - bytes, err := namespaceYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "namespace.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _prometheus_roleYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\x8c\x31\x6e\xc3\x30\x0c\x45\x77\x9d\x82\xc8\x2e\x17\xdd\x02\x5d\xa0\x7b\x87\xee\x8c\xc4\xda\x84\x6d\x91\x20\x29\x17\xe8\xe9\x83\xc4\x9e\xf8\xde\x03\xf1\x51\xf9\x87\xcc\x59\x7a\x01\x7b\x60\x9d\x70\xc4\x22\xc6\xff\x18\x2c\x7d\x5a\xef\x3e\xb1\x7c\x1c\x9f\x69\xe5\xde\x0a\x7c\xcb\x46\x69\xa7\xc0\x86\x81\x25\x01\x74\xdc\xa9\x80\x9a\xec\x14\x0b\x0d\xcf\xeb\xdd\xaf\xec\x8a\x95\x0a\x88\x52\xf7\x85\x7f\x23\xef\xd8\x71\xa6\x96\x87\xce\x86\x8d\xb2\x28\x19\x86\x58\xb2\xb1\x91\x97\x94\x01\x95\xbf\x4c\x86\xfa\x6b\x3a\xc3\xed\x96\x00\x8c\x5c\x86\x55\xba\x9a\x93\x1d\x5c\xc9\xdf\x42\xbd\xa9\x70\x8f\xd3\x54\xda\x0b\x0e\xb2\xc7\xf5\x3c\x53\xbc\xef\xc6\x7e\xc2\x1f\x46\x5d\xd2\x33\x00\x00\xff\xff\xab\xd8\x23\x94\xf5\x00\x00\x00") - -func prometheus_roleYamlBytes() ([]byte, error) { - return bindataRead( - _prometheus_roleYaml, - "prometheus_role.yaml", - ) -} - -func prometheus_roleYaml() (*asset, error) { - bytes, err := prometheus_roleYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "prometheus_role.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _prometheus_rolebindingYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x8f\x31\x6e\x03\x31\x0c\x04\x7b\xbd\x42\x1f\xd0\x05\xe9\x0c\x75\xc9\x13\x1c\x20\x3d\x2d\xad\xef\x98\xf3\x91\x02\x49\xb9\xc8\xeb\x03\x03\x06\x52\xa5\x48\xbb\x58\xcc\xee\xd0\xe0\x4f\x98\xb3\x4a\xcd\x76\xa1\xb6\xd0\x8c\x4d\x8d\xbf\x29\x58\x65\xd9\x4f\xbe\xb0\xbe\xdc\x5f\xd3\xce\xd2\x6b\x3e\xeb\x0d\xef\x2c\x9d\x65\x4d\x07\x82\x3a\x05\xd5\x94\xb3\xd0\x81\x9a\x87\xe9\x81\xd8\x30\xbd\xec\x27\x7f\xc6\x3e\xa8\xa1\x66\x1d\x10\xdf\xf8\x1a\xe5\x20\xa1\x15\xbd\xcc\xb1\x1a\x75\x14\x1d\x30\x0a\xb5\x64\x7a\xc3\x19\xd7\x07\xef\x77\xed\x2f\xb8\xcf\xcb\x17\x5a\x78\x4d\xe5\xd9\xfe\x80\xdd\xb9\xe1\xad\x35\x9d\x12\xff\x3d\xa5\xc2\xa1\xf6\xf0\xfa\x09\x00\x00\xff\xff\xdf\x2c\x62\x3f\x13\x01\x00\x00") - -func prometheus_rolebindingYamlBytes() ([]byte, error) { - return bindataRead( - _prometheus_rolebindingYaml, - "prometheus_rolebinding.yaml", - ) -} - -func prometheus_rolebindingYaml() (*asset, error) { - bytes, err := prometheus_rolebindingYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "prometheus_rolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _pullsecret_reader_roleYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\x8c\xb1\x6a\xc5\x30\x0c\x45\x77\x7d\x85\x78\xbb\x53\xba\x15\xff\x40\xf7\x0e\xdd\xf5\x1c\x25\x11\x71\x2c\x23\xc9\x29\xf4\xeb\x4b\x5f\x32\xdd\xcb\x39\x70\xa8\xcb\x37\x9b\x8b\xb6\x8c\xf6\xa4\x32\xd1\x88\x4d\x4d\x7e\x29\x44\xdb\xb4\x7f\xf8\x24\xfa\x76\xbe\xc3\x2e\x6d\xce\xf8\xa5\x95\xe1\xe0\xa0\x99\x82\x32\x20\x36\x3a\x38\xe3\x31\x34\xf5\x51\xab\x73\x31\x8e\x64\x4c\x33\xdb\x6d\xbd\x53\xe1\x8c\xda\xb9\xf9\x26\x4b\xa4\xa2\x6d\x91\x15\x6c\x54\xf6\x0c\x09\xa9\xcb\xa7\xe9\xe8\xfe\xdf\x4b\xf8\x78\x00\xa2\xb1\xeb\xb0\xc2\x37\xbb\xba\x0e\x88\x27\xdb\xf3\x86\x2b\xc7\x6b\xab\xf8\x75\x7e\x28\xca\x06\x7f\x01\x00\x00\xff\xff\xb2\xe9\x84\x3f\xd2\x00\x00\x00") - -func pullsecret_reader_roleYamlBytes() ([]byte, error) { - return bindataRead( - _pullsecret_reader_roleYaml, - "pullsecret_reader_role.yaml", - ) -} - -func pullsecret_reader_roleYaml() (*asset, error) { - bytes, err := pullsecret_reader_roleYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "pullsecret_reader_role.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _pullsecret_reader_rolebindingYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x8e\x31\x6e\x03\x31\x0c\x04\x7b\xbd\x42\x1f\xd0\x05\xe9\x02\x75\xc9\x13\x1c\x20\x3d\x4d\xed\x9d\x19\xdf\x91\x02\x45\xb9\xc8\xeb\x83\x00\x06\x5c\x19\xa9\x77\x67\x76\xa9\xcb\x17\x7c\x88\x69\xcd\x7e\x26\x5e\x68\xc6\xc5\x5c\x7e\x28\xc4\x74\xb9\xbe\x8d\x45\xec\xe5\xf6\x9a\xae\xa2\xad\xe6\x93\xed\xf8\x10\x6d\xa2\x5b\x3a\x10\xd4\x28\xa8\xa6\x9c\x95\x0e\xd4\x7c\x4c\x2b\x7d\xee\xfb\x00\x3b\xa2\x38\xa8\xc1\xef\xe9\xe8\xc4\xa8\xd9\x3a\x74\x5c\x64\x8d\xc2\xa6\xab\x6c\xc9\x6d\xc7\x09\xeb\x9f\xe4\x31\xf1\x8f\x71\xcc\xf3\x37\x38\x46\x4d\xe5\x0e\x7d\xc2\x6f\xc2\x78\x67\xb6\xa9\xf1\xc0\x49\x69\x43\x2b\xb3\x6f\x4e\x0d\xc5\x3a\x9c\xc2\x9e\x7e\x7a\xda\xff\x0d\x00\x00\xff\xff\x43\xf5\x74\xa0\x27\x01\x00\x00") - -func pullsecret_reader_rolebindingYamlBytes() ([]byte, error) { - return bindataRead( - _pullsecret_reader_rolebindingYaml, - "pullsecret_reader_rolebinding.yaml", - ) -} - -func pullsecret_reader_rolebindingYaml() (*asset, error) { - bytes, err := pullsecret_reader_rolebindingYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "pullsecret_reader_rolebinding.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _service_accountYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xca\xb1\x0d\x02\x31\x0c\x05\xd0\x3e\x53\x78\x81\x14\xb4\xe9\x98\x01\x89\xfe\x2b\xf9\x1c\x11\x8a\x6d\x39\xbe\x9b\x9f\x86\x96\xfe\xc1\xe7\x93\xb1\xa7\x69\x93\xeb\x56\x3e\x53\x47\x93\x07\xe3\x9a\x9d\xf7\xde\xed\xd4\x2c\x8b\x89\x81\x44\x2b\x22\x8a\xc5\x26\x0b\x8a\x83\xa3\x9e\x7e\x04\x06\xab\x39\x03\x69\xf1\x03\xdb\xd1\xd9\xc4\x9c\xba\xdf\xf3\x95\xf5\xaf\xff\x06\x00\x00\xff\xff\xfc\xc6\x66\xb9\x7f\x00\x00\x00") - -func service_accountYamlBytes() ([]byte, error) { - return bindataRead( - _service_accountYaml, - "service_account.yaml", - ) -} - -func service_accountYaml() (*asset, error) { - bytes, err := service_accountYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "service_account.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _trusted_ca_bundle_configmapYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x44\xcd\xbd\x12\xc2\x20\x10\xc4\xf1\x9e\xa7\xb8\x49\x4f\x1c\x5b\x5a\x6b\x5b\xfb\x0b\x6c\xe2\x69\x38\x18\x38\x7c\x7e\xc7\x8f\xd1\x7e\xff\xbf\xe5\x2a\x17\xb4\x2e\x45\x03\x3d\x8e\xee\x2e\x9a\x02\x9d\x8a\xae\xb2\x9d\xb9\xba\x0c\xe3\xc4\xc6\xc1\x11\x29\x67\xf4\xca\x11\x81\x4a\x85\xf6\xab\xac\xe6\x33\x2b\x6f\x48\x7e\xd4\xad\x71\x82\x2f\x15\x8d\xad\xb4\xef\x3e\x90\xb5\xd1\x0d\xc9\x47\xf6\xcb\xd0\xb4\xc3\x11\xed\xbc\x60\xef\x2f\x93\x28\xbe\xbf\xe6\x9f\x38\x4b\x39\x88\xde\x10\xcd\xff\xd3\x4f\x19\x68\xb2\x36\x30\xb9\x67\x00\x00\x00\xff\xff\x96\x4c\x4f\xe4\xb5\x00\x00\x00") - -func trusted_ca_bundle_configmapYamlBytes() ([]byte, error) { - return bindataRead( - _trusted_ca_bundle_configmapYaml, - "trusted_ca_bundle_configmap.yaml", - ) -} - -func trusted_ca_bundle_configmapYaml() (*asset, error) { - bytes, err := trusted_ca_bundle_configmapYamlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "trusted_ca_bundle_configmap.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// MustAsset is like Asset but panics when Asset would return an error. -// It simplifies safe initialization of global variables. -func MustAsset(name string) []byte { - a, err := Asset(name) - if err != nil { - panic("asset: Asset(" + name + "): " + err.Error()) - } - - return a -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "cluster_role.yaml": cluster_roleYaml, - "cluster_rolebinding.yaml": cluster_rolebindingYaml, - "config.yaml": configYaml, - "custom_resource_definition.yaml": custom_resource_definitionYaml, - "deployment.yaml": deploymentYaml, - "managed_upgrade_role.yaml": managed_upgrade_roleYaml, - "managed_upgrade_rolebinding.yaml": managed_upgrade_rolebindingYaml, - "monitoring_reader_role.yaml": monitoring_reader_roleYaml, - "monitoring_reader_rolebinding.yaml": monitoring_reader_rolebindingYaml, - "namespace.yaml": namespaceYaml, - "prometheus_role.yaml": prometheus_roleYaml, - "prometheus_rolebinding.yaml": prometheus_rolebindingYaml, - "pullsecret_reader_role.yaml": pullsecret_reader_roleYaml, - "pullsecret_reader_rolebinding.yaml": pullsecret_reader_rolebindingYaml, - "service_account.yaml": service_accountYaml, - "trusted_ca_bundle_configmap.yaml": trusted_ca_bundle_configmapYaml, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for childName := range node.Children { - rv = append(rv, childName) - } - return rv, nil -} - -type bintree struct { - Func func() (*asset, error) - Children map[string]*bintree -} - -var _bintree = &bintree{nil, map[string]*bintree{ - "cluster_role.yaml": {cluster_roleYaml, map[string]*bintree{}}, - "cluster_rolebinding.yaml": {cluster_rolebindingYaml, map[string]*bintree{}}, - "config.yaml": {configYaml, map[string]*bintree{}}, - "custom_resource_definition.yaml": {custom_resource_definitionYaml, map[string]*bintree{}}, - "deployment.yaml": {deploymentYaml, map[string]*bintree{}}, - "managed_upgrade_role.yaml": {managed_upgrade_roleYaml, map[string]*bintree{}}, - "managed_upgrade_rolebinding.yaml": {managed_upgrade_rolebindingYaml, map[string]*bintree{}}, - "monitoring_reader_role.yaml": {monitoring_reader_roleYaml, map[string]*bintree{}}, - "monitoring_reader_rolebinding.yaml": {monitoring_reader_rolebindingYaml, map[string]*bintree{}}, - "namespace.yaml": {namespaceYaml, map[string]*bintree{}}, - "prometheus_role.yaml": {prometheus_roleYaml, map[string]*bintree{}}, - "prometheus_rolebinding.yaml": {prometheus_rolebindingYaml, map[string]*bintree{}}, - "pullsecret_reader_role.yaml": {pullsecret_reader_roleYaml, map[string]*bintree{}}, - "pullsecret_reader_rolebinding.yaml": {pullsecret_reader_rolebindingYaml, map[string]*bintree{}}, - "service_account.yaml": {service_accountYaml, map[string]*bintree{}}, - "trusted_ca_bundle_configmap.yaml": {trusted_ca_bundle_configmapYaml, map[string]*bintree{}}, -}} - -// RestoreAsset restores an asset under the given directory -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil -} - -// RestoreAssets restores an asset under the given directory recursively -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - // File - if err != nil { - return RestoreAsset(dir, name) - } - // Dir - for _, child := range children { - err = RestoreAssets(dir, filepath.Join(name, child)) - if err != nil { - return err - } - } - return nil -} - -func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) -} diff --git a/pkg/operator/controllers/muo/deploy.go b/pkg/operator/controllers/muo/deploy.go deleted file mode 100644 index 0aa0643b973..00000000000 --- a/pkg/operator/controllers/muo/deploy.go +++ /dev/null @@ -1,174 +0,0 @@ -package muo - -// Copyright (c) Microsoft Corporation. -// Licensed under the Apache License 2.0. - -import ( - "context" - "errors" - "strings" - - "github.com/ghodss/yaml" - "github.com/ugorji/go/codec" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - kruntime "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/scheme" - - "github.com/Azure/ARO-RP/pkg/api" - arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1" - "github.com/Azure/ARO-RP/pkg/operator/controllers/muo/config" - "github.com/Azure/ARO-RP/pkg/util/dynamichelper" - "github.com/Azure/ARO-RP/pkg/util/ready" -) - -type muoConfig struct { - api.MissingFields - ConfigManager struct { - api.MissingFields - Source string `json:"source,omitempty"` - OcmBaseUrl string `json:"ocmBaseUrl,omitempty"` - LocalConfigName string `json:"localConfigName,omitempty"` - } `json:"configManager,omitempty"` -} - -type Deployer interface { - CreateOrUpdate(context.Context, *arov1alpha1.Cluster, *config.MUODeploymentConfig) error - Remove(context.Context) error - IsReady(ctx context.Context) (bool, error) - Resources(*config.MUODeploymentConfig) ([]kruntime.Object, error) -} - -type deployer struct { - kubernetescli kubernetes.Interface - dh dynamichelper.Interface - - jsonHandle *codec.JsonHandle -} - -func newDeployer(kubernetescli kubernetes.Interface, dh dynamichelper.Interface) Deployer { - return &deployer{ - kubernetescli: kubernetescli, - dh: dh, - - jsonHandle: new(codec.JsonHandle), - } -} - -func (o *deployer) Resources(config *config.MUODeploymentConfig) ([]kruntime.Object, error) { - results := []kruntime.Object{} - for _, assetName := range AssetNames() { - b, err := Asset(assetName) - if err != nil { - return nil, err - } - - obj, _, err := scheme.Codecs.UniversalDeserializer().Decode(b, nil, nil) - if err != nil { - return nil, err - } - - // set the image for the deployments - if d, ok := obj.(*appsv1.Deployment); ok { - for i := range d.Spec.Template.Spec.Containers { - d.Spec.Template.Spec.Containers[i].Image = config.Pullspec - } - } - - if cm, ok := obj.(*corev1.ConfigMap); ok { - if cm.Name == "managed-upgrade-operator-config" && cm.Namespace == "openshift-managed-upgrade-operator" { - // read the config.yaml from the MUO ConfigMap which stores defaults - configDataJSON, err := yaml.YAMLToJSON([]byte(cm.Data["config.yaml"])) - if err != nil { - return nil, err - } - - var configData muoConfig - err = codec.NewDecoderBytes(configDataJSON, o.jsonHandle).Decode(&configData) - if err != nil { - return nil, err - } - - if config.EnableConnected { - configData.ConfigManager.Source = "OCM" - configData.ConfigManager.OcmBaseUrl = config.OCMBaseURL - configData.ConfigManager.LocalConfigName = "" - } else { - configData.ConfigManager.Source = "LOCAL" - configData.ConfigManager.LocalConfigName = "managed-upgrade-config" - configData.ConfigManager.OcmBaseUrl = "" - } - - // Write the yaml back into the ConfigMap - var b []byte - err = codec.NewEncoderBytes(&b, o.jsonHandle).Encode(configData) - if err != nil { - return nil, err - } - - cmYaml, err := yaml.JSONToYAML(b) - if err != nil { - return nil, err - } - cm.Data["config.yaml"] = string(cmYaml) - } - } - - results = append(results, obj) - } - - return results, nil -} - -func (o *deployer) CreateOrUpdate(ctx context.Context, cluster *arov1alpha1.Cluster, config *config.MUODeploymentConfig) error { - resources, err := o.Resources(config) - if err != nil { - return err - } - - err = dynamichelper.SetControllerReferences(resources, cluster) - if err != nil { - return err - } - - err = dynamichelper.Prepare(resources) - if err != nil { - return err - } - - return o.dh.Ensure(ctx, resources...) -} - -func (o *deployer) Remove(ctx context.Context) error { - resources, err := o.Resources(&config.MUODeploymentConfig{}) - if err != nil { - return err - } - - var errs []error - for _, obj := range resources { - // delete any deployments we have - if d, ok := obj.(*appsv1.Deployment); ok { - err := o.dh.EnsureDeleted(ctx, "Deployment", d.Namespace, d.Name) - // Don't error out because then we might delete some resources and not others - if err != nil { - errs = append(errs, err) - } - } - } - - if len(errs) != 0 { - errContent := []string{"error removing MUO:"} - for _, err := range errs { - errContent = append(errContent, err.Error()) - } - return errors.New(strings.Join(errContent, "\n")) - } - - return nil -} - -func (o *deployer) IsReady(ctx context.Context) (bool, error) { - return ready.CheckDeploymentIsReady(ctx, o.kubernetescli.AppsV1().Deployments("openshift-managed-upgrade-operator"), "managed-upgrade-operator")() -} diff --git a/pkg/operator/controllers/muo/deploy_test.go b/pkg/operator/controllers/muo/deploy_test.go deleted file mode 100644 index ef6916ca36e..00000000000 --- a/pkg/operator/controllers/muo/deploy_test.go +++ /dev/null @@ -1,350 +0,0 @@ -package muo - -// Copyright (c) Microsoft Corporation. -// Licensed under the Apache License 2.0. - -import ( - "context" - "errors" - "strings" - "testing" - - "github.com/go-test/deep" - "github.com/golang/mock/gomock" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - kruntime "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/fake" - - arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1" - "github.com/Azure/ARO-RP/pkg/operator/controllers/muo/config" - mock_dynamichelper "github.com/Azure/ARO-RP/pkg/util/mocks/dynamichelper" -) - -func TestDeployCreateOrUpdateCorrectKinds(t *testing.T) { - controller := gomock.NewController(t) - defer controller.Finish() - - setPullSpec := "MyMUOPullSpec" - cluster := &arov1alpha1.Cluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: arov1alpha1.SingletonClusterName, - }, - } - - k8scli := fake.NewSimpleClientset() - dh := mock_dynamichelper.NewMockInterface(controller) - - // When the DynamicHelper is called, count the number of objects it creates - // and capture any deployments so that we can check the pullspec - var deployments []*appsv1.Deployment - deployedObjects := make(map[string]int) - check := func(ctx context.Context, objs ...kruntime.Object) error { - m := meta.NewAccessor() - for _, i := range objs { - kind, err := m.Kind(i) - if err != nil { - return err - } - if d, ok := i.(*appsv1.Deployment); ok { - deployments = append(deployments, d) - } - deployedObjects[kind] = deployedObjects[kind] + 1 - } - return nil - } - dh.EXPECT().Ensure(gomock.Any(), gomock.Any()).Do(check).Return(nil) - - deployer := newDeployer(k8scli, dh) - err := deployer.CreateOrUpdate(context.Background(), cluster, &config.MUODeploymentConfig{Pullspec: setPullSpec}) - if err != nil { - t.Error(err) - } - - // We expect these numbers of resources to be created - expectedKinds := map[string]int{ - "ClusterRole": 1, - "ConfigMap": 2, - "ClusterRoleBinding": 1, - "CustomResourceDefinition": 1, - "Deployment": 1, - "Namespace": 1, - "Role": 4, - "RoleBinding": 4, - "ServiceAccount": 1, - } - errs := deep.Equal(deployedObjects, expectedKinds) - for _, e := range errs { - t.Error(e) - } - - // Ensure we have set the pullspec set on the containers - for _, d := range deployments { - for _, c := range d.Spec.Template.Spec.Containers { - if c.Image != setPullSpec { - t.Errorf("expected %s, got %s for pullspec", setPullSpec, c.Image) - } - } - } -} - -func TestDeployCreateOrUpdateSetsOwnerReferences(t *testing.T) { - controller := gomock.NewController(t) - defer controller.Finish() - - setPullSpec := "MyMUOPullSpec" - cluster := &arov1alpha1.Cluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: arov1alpha1.SingletonClusterName, - }, - } - - k8scli := fake.NewSimpleClientset() - dh := mock_dynamichelper.NewMockInterface(controller) - - // the OwnerReference that we expect to be set on each object we Ensure - pointerToTrueForSomeReason := bool(true) - expectedOwner := metav1.OwnerReference{ - APIVersion: "aro.openshift.io/v1alpha1", - Kind: "Cluster", - Name: arov1alpha1.SingletonClusterName, - UID: cluster.UID, - BlockOwnerDeletion: &pointerToTrueForSomeReason, - Controller: &pointerToTrueForSomeReason, - } - - // save the list of OwnerReferences on each of the Ensured objects - var ownerReferences [][]metav1.OwnerReference - check := func(ctx context.Context, objs ...kruntime.Object) error { - for _, i := range objs { - obj, err := meta.Accessor(i) - if err != nil { - return err - } - ownerReferences = append(ownerReferences, obj.GetOwnerReferences()) - } - return nil - } - dh.EXPECT().Ensure(gomock.Any(), gomock.Any()).Do(check).Return(nil) - - deployer := newDeployer(k8scli, dh) - err := deployer.CreateOrUpdate(context.Background(), cluster, &config.MUODeploymentConfig{Pullspec: setPullSpec}) - if err != nil { - t.Error(err) - } - - // Check that each list of OwnerReferences contains our controller - for _, references := range ownerReferences { - errs := deep.Equal([]metav1.OwnerReference{expectedOwner}, references) - for _, e := range errs { - t.Error(e) - } - } -} - -func TestDeployDelete(t *testing.T) { - controller := gomock.NewController(t) - defer controller.Finish() - - k8scli := fake.NewSimpleClientset() - dh := mock_dynamichelper.NewMockInterface(controller) - dh.EXPECT().EnsureDeleted(gomock.Any(), "Deployment", "openshift-managed-upgrade-operator", "managed-upgrade-operator").Return(nil) - - deployer := newDeployer(k8scli, dh) - err := deployer.Remove(context.Background()) - if err != nil { - t.Error(err) - } -} - -func TestDeployDeleteFailure(t *testing.T) { - controller := gomock.NewController(t) - defer controller.Finish() - - k8scli := fake.NewSimpleClientset() - dh := mock_dynamichelper.NewMockInterface(controller) - dh.EXPECT().EnsureDeleted(gomock.Any(), "Deployment", "openshift-managed-upgrade-operator", "managed-upgrade-operator").Return(errors.New("fail")) - - deployer := newDeployer(k8scli, dh) - err := deployer.Remove(context.Background()) - if err == nil { - t.Error(err) - } - if err.Error() != "error removing MUO:\nfail" { - t.Error(err) - } -} - -func TestDeployIsReady(t *testing.T) { - specReplicas := int32(1) - k8scli := fake.NewSimpleClientset(&appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "managed-upgrade-operator", - Namespace: "openshift-managed-upgrade-operator", - Generation: 1234, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &specReplicas, - }, - Status: appsv1.DeploymentStatus{ - ObservedGeneration: 1234, - Replicas: 1, - ReadyReplicas: 1, - UpdatedReplicas: 1, - AvailableReplicas: 1, - UnavailableReplicas: 0, - }, - }) - - deployer := newDeployer(k8scli, nil) - ready, err := deployer.IsReady(context.Background()) - if err != nil { - t.Error(err) - } - if !ready { - t.Error("deployment is not seen as ready") - } -} - -func TestDeployIsReadyMissing(t *testing.T) { - k8scli := fake.NewSimpleClientset() - deployer := newDeployer(k8scli, nil) - ready, err := deployer.IsReady(context.Background()) - if err != nil { - t.Error(err) - } - if ready { - t.Error("deployment is wrongly seen as ready") - } -} - -func TestDeployConfig(t *testing.T) { - controller := gomock.NewController(t) - defer controller.Finish() - - cluster := &arov1alpha1.Cluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: arov1alpha1.SingletonClusterName, - }, - } - - tests := []struct { - name string - deploymentConfig *config.MUODeploymentConfig - expected []string - }{ - { - name: "local", - deploymentConfig: &config.MUODeploymentConfig{EnableConnected: false}, - expected: []string{ - "configManager:", - " localConfigName: managed-upgrade-config", - " source: LOCAL", - " watchInterval: 1", - "healthCheck:", - " ignoredCriticals:", - " - PrometheusRuleFailures", - " - CannotRetrieveUpdates", - " - FluentdNodeDown", - " ignoredNamespaces:", - " - openshift-logging", - " - openshift-redhat-marketplace", - " - openshift-operators", - " - openshift-user-workload-monitoring", - " - openshift-pipelines", - " - openshift-azure-logging", - "maintenance:", - " controlPlaneTime: 90", - " ignoredAlerts:", - " controlPlaneCriticals:", - " - ClusterOperatorDown", - " - ClusterOperatorDegraded", - "nodeDrain:", - " expectedNodeDrainTime: 8", - " timeOut: 45", - "scale:", - " timeOut: 30", - "upgradeWindow:", - " delayTrigger: 30", - " timeOut: 120", - "", - }, - }, - { - name: "connected", - deploymentConfig: &config.MUODeploymentConfig{EnableConnected: true, OCMBaseURL: "https://example.com"}, - expected: []string{ - "configManager:", - " ocmBaseUrl: https://example.com", - " source: OCM", - " watchInterval: 1", - "healthCheck:", - " ignoredCriticals:", - " - PrometheusRuleFailures", - " - CannotRetrieveUpdates", - " - FluentdNodeDown", - " ignoredNamespaces:", - " - openshift-logging", - " - openshift-redhat-marketplace", - " - openshift-operators", - " - openshift-user-workload-monitoring", - " - openshift-pipelines", - " - openshift-azure-logging", - "maintenance:", - " controlPlaneTime: 90", - " ignoredAlerts:", - " controlPlaneCriticals:", - " - ClusterOperatorDown", - " - ClusterOperatorDegraded", - "nodeDrain:", - " expectedNodeDrainTime: 8", - " timeOut: 45", - "scale:", - " timeOut: 30", - "upgradeWindow:", - " delayTrigger: 30", - " timeOut: 120", - "", - }, - }, - } - for _, tt := range tests { - k8scli := fake.NewSimpleClientset() - dh := mock_dynamichelper.NewMockInterface(controller) - - // When the DynamicHelper is called, capture configmaps to inspect them - var configs []*corev1.ConfigMap - check := func(ctx context.Context, objs ...kruntime.Object) error { - for _, i := range objs { - if cm, ok := i.(*corev1.ConfigMap); ok { - configs = append(configs, cm) - } - } - return nil - } - dh.EXPECT().Ensure(gomock.Any(), gomock.Any()).Do(check).Return(nil) - - deployer := newDeployer(k8scli, dh) - err := deployer.CreateOrUpdate(context.Background(), cluster, tt.deploymentConfig) - if err != nil { - t.Error(err) - } - - foundConfig := false - for _, cms := range configs { - if cms.Name == "managed-upgrade-operator-config" && cms.Namespace == "openshift-managed-upgrade-operator" { - foundConfig = true - errs := deep.Equal(tt.expected, strings.Split(cms.Data["config.yaml"], "\n")) - for _, e := range errs { - t.Error(e) - } - } - } - - if !foundConfig { - t.Error("MUO config was not found") - } - } -} diff --git a/pkg/operator/controllers/muo/generate.go b/pkg/operator/controllers/muo/generate.go deleted file mode 100644 index 2d682e94cbb..00000000000 --- a/pkg/operator/controllers/muo/generate.go +++ /dev/null @@ -1,12 +0,0 @@ -package muo - -// Copyright (c) Microsoft Corporation. -// Licensed under the Apache License 2.0. - -// bindata for the above yaml files -//go:generate go run ../../../../vendor/github.com/go-bindata/go-bindata/go-bindata -nometadata -pkg muo -prefix staticresources/ -o bindata.go staticresources/... -//go:generate gofmt -s -l -w bindata.go - -//go:generate rm -rf ../../mocks/$GOPACKAGE -//go:generate go run ../../../../vendor/github.com/golang/mock/mockgen -destination=../../mocks/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/operator/controllers/$GOPACKAGE Deployer -//go:generate go run ../../../../vendor/golang.org/x/tools/cmd/goimports -local=github.com/Azure/ARO-RP -e -w ../../mocks/$GOPACKAGE/$GOPACKAGE.go diff --git a/pkg/operator/controllers/muo/muo_controller.go b/pkg/operator/controllers/muo/muo_controller.go index 9cef6d5a0f0..21771ab1fea 100644 --- a/pkg/operator/controllers/muo/muo_controller.go +++ b/pkg/operator/controllers/muo/muo_controller.go @@ -5,6 +5,7 @@ package muo import ( "context" + "embed" "fmt" "strings" "time" @@ -23,6 +24,7 @@ import ( arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1" aroclient "github.com/Azure/ARO-RP/pkg/operator/clientset/versioned" "github.com/Azure/ARO-RP/pkg/operator/controllers/muo/config" + "github.com/Azure/ARO-RP/pkg/util/deployer" "github.com/Azure/ARO-RP/pkg/util/dynamichelper" "github.com/Azure/ARO-RP/pkg/util/pullsecret" "github.com/Azure/ARO-RP/pkg/util/version" @@ -41,6 +43,9 @@ const ( pullSecretOCMKey = "cloud.openshift.com" ) +//go:embed staticresources +var staticFiles embed.FS + var pullSecretName = types.NamespacedName{Name: "pull-secret", Namespace: "openshift-config"} type MUODeploymentConfig struct { @@ -52,7 +57,7 @@ type MUODeploymentConfig struct { type Reconciler struct { arocli aroclient.Interface kubernetescli kubernetes.Interface - deployer Deployer + deployer deployer.Deployer readinessPollTime time.Duration readinessTimeout time.Duration @@ -62,7 +67,7 @@ func NewReconciler(arocli aroclient.Interface, kubernetescli kubernetes.Interfac return &Reconciler{ arocli: arocli, kubernetescli: kubernetescli, - deployer: newDeployer(kubernetescli, dh), + deployer: deployer.NewDeployer(kubernetescli, dh, staticFiles, "staticresources"), readinessPollTime: 10 * time.Second, readinessTimeout: 5 * time.Minute, @@ -138,13 +143,13 @@ func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl. defer cancel() err := wait.PollImmediateUntil(r.readinessPollTime, func() (bool, error) { - return r.deployer.IsReady(ctx) + return r.deployer.IsReady(ctx, "openshift-managed-upgrade-operator", "managed-upgrade-operator") }, timeoutCtx.Done()) if err != nil { return reconcile.Result{}, fmt.Errorf("managed Upgrade Operator deployment timed out on Ready: %w", err) } } else if strings.EqualFold(managed, "false") { - err := r.deployer.Remove(ctx) + err := r.deployer.Remove(ctx, config.MUODeploymentConfig{}) if err != nil { return reconcile.Result{}, err } @@ -162,7 +167,7 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error { builder := ctrl.NewControllerManagedBy(mgr). For(&arov1alpha1.Cluster{}, builder.WithPredicates(aroClusterPredicate)) - resources, err := r.deployer.Resources(&config.MUODeploymentConfig{}) + resources, err := r.deployer.Template(&config.MUODeploymentConfig{}, staticFiles) if err != nil { return err } diff --git a/pkg/operator/controllers/muo/muo_controller_test.go b/pkg/operator/controllers/muo/muo_controller_test.go index e8811949647..da15032b213 100644 --- a/pkg/operator/controllers/muo/muo_controller_test.go +++ b/pkg/operator/controllers/muo/muo_controller_test.go @@ -18,13 +18,13 @@ import ( arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1" arofake "github.com/Azure/ARO-RP/pkg/operator/clientset/versioned/fake" "github.com/Azure/ARO-RP/pkg/operator/controllers/muo/config" - mock_muo "github.com/Azure/ARO-RP/pkg/operator/mocks/muo" + mock_deployer "github.com/Azure/ARO-RP/pkg/util/mocks/deployer" ) func TestMUOReconciler(t *testing.T) { tests := []struct { name string - mocks func(*mock_muo.MockDeployer, *arov1alpha1.Cluster) + mocks func(*mock_deployer.MockDeployer, *arov1alpha1.Cluster) flags arov1alpha1.OperatorFlags // connected MUO -- cluster pullsecret pullsecret string @@ -46,12 +46,12 @@ func TestMUOReconciler(t *testing.T) { controllerManaged: "true", controllerPullSpec: "wonderfulPullspec", }, - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { expectedConfig := &config.MUODeploymentConfig{ Pullspec: "wonderfulPullspec", } md.EXPECT().CreateOrUpdate(gomock.Any(), cluster, expectedConfig).Return(nil) - md.EXPECT().IsReady(gomock.Any()).Return(true, nil) + md.EXPECT().IsReady(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, { @@ -60,12 +60,12 @@ func TestMUOReconciler(t *testing.T) { controllerEnabled: "true", controllerManaged: "true", }, - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { expectedConfig := &config.MUODeploymentConfig{ Pullspec: "acrtest.example.com/managed-upgrade-operator:aro-b1", } md.EXPECT().CreateOrUpdate(gomock.Any(), cluster, expectedConfig).Return(nil) - md.EXPECT().IsReady(gomock.Any()).Return(true, nil) + md.EXPECT().IsReady(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, { @@ -76,13 +76,13 @@ func TestMUOReconciler(t *testing.T) { controllerAllowOCM: "true", controllerPullSpec: "wonderfulPullspec", }, - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { expectedConfig := &config.MUODeploymentConfig{ Pullspec: "wonderfulPullspec", EnableConnected: false, } md.EXPECT().CreateOrUpdate(gomock.Any(), cluster, expectedConfig).Return(nil) - md.EXPECT().IsReady(gomock.Any()).Return(true, nil) + md.EXPECT().IsReady(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, { @@ -94,13 +94,13 @@ func TestMUOReconciler(t *testing.T) { controllerPullSpec: "wonderfulPullspec", }, pullsecret: "{\"auths\": {}}", - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { expectedConfig := &config.MUODeploymentConfig{ Pullspec: "wonderfulPullspec", EnableConnected: false, } md.EXPECT().CreateOrUpdate(gomock.Any(), cluster, expectedConfig).Return(nil) - md.EXPECT().IsReady(gomock.Any()).Return(true, nil) + md.EXPECT().IsReady(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, { @@ -112,13 +112,13 @@ func TestMUOReconciler(t *testing.T) { controllerPullSpec: "wonderfulPullspec", }, pullsecret: "i'm a little json, short and stout", - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { expectedConfig := &config.MUODeploymentConfig{ Pullspec: "wonderfulPullspec", EnableConnected: false, } md.EXPECT().CreateOrUpdate(gomock.Any(), cluster, expectedConfig).Return(nil) - md.EXPECT().IsReady(gomock.Any()).Return(true, nil) + md.EXPECT().IsReady(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, { @@ -130,14 +130,14 @@ func TestMUOReconciler(t *testing.T) { controllerPullSpec: "wonderfulPullspec", }, pullsecret: "{\"auths\": {\"" + pullSecretOCMKey + "\": {\"auth\": \"secret value\"}}}", - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { expectedConfig := &config.MUODeploymentConfig{ Pullspec: "wonderfulPullspec", EnableConnected: true, OCMBaseURL: "https://api.openshift.com", } md.EXPECT().CreateOrUpdate(gomock.Any(), cluster, expectedConfig).Return(nil) - md.EXPECT().IsReady(gomock.Any()).Return(true, nil) + md.EXPECT().IsReady(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, { @@ -150,14 +150,14 @@ func TestMUOReconciler(t *testing.T) { controllerPullSpec: "wonderfulPullspec", }, pullsecret: "{\"auths\": {\"" + pullSecretOCMKey + "\": {\"auth\": \"secret value\"}}}", - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { expectedConfig := &config.MUODeploymentConfig{ Pullspec: "wonderfulPullspec", EnableConnected: true, OCMBaseURL: "https://example.com", } md.EXPECT().CreateOrUpdate(gomock.Any(), cluster, expectedConfig).Return(nil) - md.EXPECT().IsReady(gomock.Any()).Return(true, nil) + md.EXPECT().IsReady(gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil) }, }, { @@ -167,12 +167,12 @@ func TestMUOReconciler(t *testing.T) { controllerManaged: "true", controllerPullSpec: "wonderfulPullspec", }, - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { expectedConfig := &config.MUODeploymentConfig{ Pullspec: "wonderfulPullspec", } md.EXPECT().CreateOrUpdate(gomock.Any(), cluster, expectedConfig).Return(nil) - md.EXPECT().IsReady(gomock.Any()).Return(false, nil) + md.EXPECT().IsReady(gomock.Any(), gomock.Any(), gomock.Any()).Return(false, nil) }, wantErr: "managed Upgrade Operator deployment timed out on Ready: timed out waiting for the condition", }, @@ -183,7 +183,7 @@ func TestMUOReconciler(t *testing.T) { controllerManaged: "true", controllerPullSpec: "wonderfulPullspec", }, - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { md.EXPECT().CreateOrUpdate(gomock.Any(), cluster, gomock.AssignableToTypeOf(&config.MUODeploymentConfig{})).Return(errors.New("failed ensure")) }, wantErr: "failed ensure", @@ -195,8 +195,8 @@ func TestMUOReconciler(t *testing.T) { controllerManaged: "false", controllerPullSpec: "wonderfulPullspec", }, - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { - md.EXPECT().Remove(gomock.Any()).Return(nil) + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { + md.EXPECT().Remove(gomock.Any(), gomock.Any()).Return(nil) }, }, { @@ -206,8 +206,8 @@ func TestMUOReconciler(t *testing.T) { controllerManaged: "false", controllerPullSpec: "wonderfulPullspec", }, - mocks: func(md *mock_muo.MockDeployer, cluster *arov1alpha1.Cluster) { - md.EXPECT().Remove(gomock.Any()).Return(errors.New("failed delete")) + mocks: func(md *mock_deployer.MockDeployer, cluster *arov1alpha1.Cluster) { + md.EXPECT().Remove(gomock.Any(), gomock.Any()).Return(errors.New("failed delete")) }, wantErr: "failed delete", }, @@ -236,7 +236,7 @@ func TestMUOReconciler(t *testing.T) { } arocli := arofake.NewSimpleClientset(cluster) kubecli := fake.NewSimpleClientset() - deployer := mock_muo.NewMockDeployer(controller) + deployer := mock_deployer.NewMockDeployer(controller) if tt.pullsecret != "" { _, err := kubecli.CoreV1().Secrets(pullSecretName.Namespace).Create(context.Background(), diff --git a/pkg/operator/controllers/muo/staticresources/config.yaml b/pkg/operator/controllers/muo/staticresources/config.yaml index 228bdb61758..5b08f203207 100644 --- a/pkg/operator/controllers/muo/staticresources/config.yaml +++ b/pkg/operator/controllers/muo/staticresources/config.yaml @@ -6,8 +6,9 @@ metadata: data: config.yaml: | configManager: - source: LOCAL - localConfigName: managed-upgrade-config + source: {{ if .EnableConnected }}OCM{{ else }}LOCAL{{ end }} + {{ if .EnableConnected }}ocmBaseUrl: {{.OCMBaseURL}}{{end}} + {{ if not .EnableConnected }}localConfigName: managed-upgrade-config{{end}} watchInterval: 1 maintenance: controlPlaneTime: 90 diff --git a/pkg/operator/controllers/muo/staticresources/deployment.yaml b/pkg/operator/controllers/muo/staticresources/deployment.yaml index 19e682ca818..142bc823534 100644 --- a/pkg/operator/controllers/muo/staticresources/deployment.yaml +++ b/pkg/operator/controllers/muo/staticresources/deployment.yaml @@ -40,7 +40,7 @@ spec: - name: managed-upgrade-operator # Replace this with the built image name # This will get replaced on deploy by /hack/generate-operator-bundle.py - image: GENERATED + image: "{{ .Pullspec }}" command: - managed-upgrade-operator imagePullPolicy: Always diff --git a/pkg/operator/controllers/muo/template_test.go b/pkg/operator/controllers/muo/template_test.go new file mode 100644 index 00000000000..68c23234388 --- /dev/null +++ b/pkg/operator/controllers/muo/template_test.go @@ -0,0 +1,170 @@ +package muo + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "context" + _ "embed" + "testing" + + "github.com/ghodss/yaml" + "github.com/go-test/deep" + "github.com/golang/mock/gomock" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/fake" + + arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1" + "github.com/Azure/ARO-RP/pkg/operator/controllers/muo/config" + "github.com/Azure/ARO-RP/pkg/util/deployer" + mock_dynamichelper "github.com/Azure/ARO-RP/pkg/util/mocks/dynamichelper" +) + +//go:embed test_files/local.yaml +var expectedLocalConfig []byte + +//go:embed test_files/connected.yaml +var expectedConnectedConfig []byte + +func TestDeployCreateOrUpdateCorrectKinds(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + setPullSpec := "MyMUOPullSpec" + cluster := &arov1alpha1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: arov1alpha1.SingletonClusterName, + }, + } + + k8scli := fake.NewSimpleClientset() + dh := mock_dynamichelper.NewMockInterface(controller) + + // When the DynamicHelper is called, count the number of objects it creates + // and capture any deployments so that we can check the pullspec + var deployments []*appsv1.Deployment + deployedObjects := make(map[string]int) + check := func(ctx context.Context, objs ...kruntime.Object) error { + m := meta.NewAccessor() + for _, i := range objs { + kind, err := m.Kind(i) + if err != nil { + return err + } + if d, ok := i.(*appsv1.Deployment); ok { + deployments = append(deployments, d) + } + deployedObjects[kind] = deployedObjects[kind] + 1 + } + return nil + } + dh.EXPECT().Ensure(gomock.Any(), gomock.Any()).Do(check).Return(nil) + + deployer := deployer.NewDeployer(k8scli, dh, staticFiles, "staticresources") + err := deployer.CreateOrUpdate(context.Background(), cluster, &config.MUODeploymentConfig{Pullspec: setPullSpec}) + if err != nil { + t.Error(err) + } + + // We expect these numbers of resources to be created + expectedKinds := map[string]int{ + "ClusterRole": 1, + "ConfigMap": 2, + "ClusterRoleBinding": 1, + "CustomResourceDefinition": 1, + "Deployment": 1, + "Namespace": 1, + "Role": 4, + "RoleBinding": 4, + "ServiceAccount": 1, + } + errs := deep.Equal(deployedObjects, expectedKinds) + for _, e := range errs { + t.Error(e) + } + + // Ensure we have set the pullspec set on the containers + for _, d := range deployments { + for _, c := range d.Spec.Template.Spec.Containers { + if c.Image != setPullSpec { + t.Errorf("expected %s, got %s for pullspec", setPullSpec, c.Image) + } + } + } +} + +func TestDeployConfig(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + cluster := &arov1alpha1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: arov1alpha1.SingletonClusterName, + }, + } + + tests := []struct { + name string + deploymentConfig *config.MUODeploymentConfig + expected []byte + }{ + { + name: "local", + deploymentConfig: &config.MUODeploymentConfig{EnableConnected: false}, + expected: expectedLocalConfig, + }, + { + name: "connected", + deploymentConfig: &config.MUODeploymentConfig{EnableConnected: true, OCMBaseURL: "https://example.com"}, + expected: expectedConnectedConfig, + }, + } + for _, tt := range tests { + k8scli := fake.NewSimpleClientset() + dh := mock_dynamichelper.NewMockInterface(controller) + + // When the DynamicHelper is called, capture configmaps to inspect them + var configs []*corev1.ConfigMap + check := func(ctx context.Context, objs ...kruntime.Object) error { + for _, i := range objs { + if cm, ok := i.(*corev1.ConfigMap); ok { + configs = append(configs, cm) + } + } + return nil + } + dh.EXPECT().Ensure(gomock.Any(), gomock.Any()).Do(check).Return(nil) + + deployer := deployer.NewDeployer(k8scli, dh, staticFiles, "staticresources") + err := deployer.CreateOrUpdate(context.Background(), cluster, tt.deploymentConfig) + if err != nil { + t.Error(err) + } + + foundConfig := false + for _, cms := range configs { + if cms.Name == "managed-upgrade-operator-config" && cms.Namespace == "openshift-managed-upgrade-operator" { + foundConfig = true + + expectedMap := make(map[string]interface{}) + yaml.Unmarshal(tt.expected, &expectedMap) + + resultMap := make(map[string]interface{}) + yaml.Unmarshal([]byte(cms.Data["config.yaml"]), &resultMap) + + err := deep.Equal(expectedMap, resultMap) + if err != nil { + t.Error(err) + } + } + } + + if !foundConfig { + t.Error("MUO config was not found") + } + } +} diff --git a/pkg/operator/controllers/muo/test_files/connected.yaml b/pkg/operator/controllers/muo/test_files/connected.yaml new file mode 100644 index 00000000000..971a4eee2b7 --- /dev/null +++ b/pkg/operator/controllers/muo/test_files/connected.yaml @@ -0,0 +1,30 @@ +configManager: + ocmBaseUrl: https://example.com + source: OCM + watchInterval: 1 +healthCheck: + ignoredCriticals: + - PrometheusRuleFailures + - CannotRetrieveUpdates + - FluentdNodeDown + ignoredNamespaces: + - openshift-logging + - openshift-redhat-marketplace + - openshift-operators + - openshift-user-workload-monitoring + - openshift-pipelines + - openshift-azure-logging +maintenance: + controlPlaneTime: 90 + ignoredAlerts: + controlPlaneCriticals: + - ClusterOperatorDown + - ClusterOperatorDegraded +nodeDrain: + expectedNodeDrainTime: 8 + timeOut: 45 +scale: + timeOut: 30 +upgradeWindow: + delayTrigger: 30 + timeOut: 120 diff --git a/pkg/operator/controllers/muo/test_files/local.yaml b/pkg/operator/controllers/muo/test_files/local.yaml new file mode 100644 index 00000000000..60d956178dc --- /dev/null +++ b/pkg/operator/controllers/muo/test_files/local.yaml @@ -0,0 +1,30 @@ +configManager: + localConfigName: managed-upgrade-config + source: LOCAL + watchInterval: 1 +healthCheck: + ignoredCriticals: + - PrometheusRuleFailures + - CannotRetrieveUpdates + - FluentdNodeDown + ignoredNamespaces: + - openshift-logging + - openshift-redhat-marketplace + - openshift-operators + - openshift-user-workload-monitoring + - openshift-pipelines + - openshift-azure-logging +maintenance: + controlPlaneTime: 90 + ignoredAlerts: + controlPlaneCriticals: + - ClusterOperatorDown + - ClusterOperatorDegraded +nodeDrain: + expectedNodeDrainTime: 8 + timeOut: 45 +scale: + timeOut: 30 +upgradeWindow: + delayTrigger: 30 + timeOut: 120 diff --git a/pkg/util/deployer/deploy_test.go b/pkg/util/deployer/deploy_test.go new file mode 100644 index 00000000000..0b87be5818b --- /dev/null +++ b/pkg/util/deployer/deploy_test.go @@ -0,0 +1,159 @@ +package deployer + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +// files in staticresources are example files that are not used anywhere + +import ( + "context" + "embed" + "errors" + "testing" + + "github.com/go-test/deep" + "github.com/golang/mock/gomock" + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/fake" + + arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1" + "github.com/Azure/ARO-RP/pkg/operator/controllers/muo/config" + mock_dynamichelper "github.com/Azure/ARO-RP/pkg/util/mocks/dynamichelper" +) + +//go:embed staticresources +var staticFiles embed.FS + +func TestDeployCreateOrUpdateSetsOwnerReferences(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + setPullSpec := "MyMUOPullSpec" + cluster := &arov1alpha1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: arov1alpha1.SingletonClusterName, + }, + } + + k8scli := fake.NewSimpleClientset() + dh := mock_dynamichelper.NewMockInterface(controller) + + // the OwnerReference that we expect to be set on each object we Ensure + trueValue := true + truePtr := &trueValue + expectedOwner := metav1.OwnerReference{ + APIVersion: "aro.openshift.io/v1alpha1", + Kind: "Cluster", + Name: arov1alpha1.SingletonClusterName, + UID: cluster.UID, + BlockOwnerDeletion: truePtr, + Controller: truePtr, + } + + // save the list of OwnerReferences on each of the Ensured objects + var ownerReferences [][]metav1.OwnerReference + check := func(ctx context.Context, objs ...kruntime.Object) error { + for _, i := range objs { + obj, err := meta.Accessor(i) + if err != nil { + return err + } + ownerReferences = append(ownerReferences, obj.GetOwnerReferences()) + } + return nil + } + dh.EXPECT().Ensure(gomock.Any(), gomock.Any()).Do(check).Return(nil) + + deployer := NewDeployer(k8scli, dh, staticFiles, "staticresources") + err := deployer.CreateOrUpdate(context.Background(), cluster, &config.MUODeploymentConfig{Pullspec: setPullSpec}) + if err != nil { + t.Error(err) + } + + // Check that each list of OwnerReferences contains our controller + for _, references := range ownerReferences { + errs := deep.Equal([]metav1.OwnerReference{expectedOwner}, references) + for _, e := range errs { + t.Error(e) + } + } +} + +func TestDeployDelete(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + k8scli := fake.NewSimpleClientset() + dh := mock_dynamichelper.NewMockInterface(controller) + dh.EXPECT().EnsureDeleted(gomock.Any(), "Deployment", "openshift-managed-upgrade-operator", "managed-upgrade-operator").Return(nil) + + deployer := NewDeployer(k8scli, dh, staticFiles, "staticresources") + err := deployer.Remove(context.Background(), config.MUODeploymentConfig{}) + if err != nil { + t.Error(err) + } +} + +func TestDeployDeleteFailure(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + k8scli := fake.NewSimpleClientset() + dh := mock_dynamichelper.NewMockInterface(controller) + dh.EXPECT().EnsureDeleted(gomock.Any(), "Deployment", "openshift-managed-upgrade-operator", "managed-upgrade-operator").Return(errors.New("fail")) + + deployer := NewDeployer(k8scli, dh, staticFiles, "staticresources") + err := deployer.Remove(context.Background(), config.MUODeploymentConfig{}) + if err == nil { + t.Error(err) + } + if err.Error() != "error removing deployment:\nfail" { + t.Error(err) + } +} + +func TestDeployIsReady(t *testing.T) { + specReplicas := int32(1) + k8scli := fake.NewSimpleClientset(&appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "managed-upgrade-operator", + Namespace: "openshift-managed-upgrade-operator", + Generation: 1234, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &specReplicas, + }, + Status: appsv1.DeploymentStatus{ + ObservedGeneration: 1234, + Replicas: 1, + ReadyReplicas: 1, + UpdatedReplicas: 1, + AvailableReplicas: 1, + UnavailableReplicas: 0, + }, + }) + + deployer := NewDeployer(k8scli, nil, staticFiles, "staticresources") + ready, err := deployer.IsReady(context.Background(), "openshift-managed-upgrade-operator", "managed-upgrade-operator") + if err != nil { + t.Error(err) + } + if !ready { + t.Error("deployment is not seen as ready") + } +} + +func TestDeployIsReadyMissing(t *testing.T) { + k8scli := fake.NewSimpleClientset() + deployer := NewDeployer(k8scli, nil, staticFiles, "staticresources") + ready, err := deployer.IsReady(context.Background(), "openshift-managed-upgrade-operator", "managed-upgrade-operator") + if err != nil { + t.Error(err) + } + if ready { + t.Error("deployment is wrongly seen as ready") + } +} diff --git a/pkg/util/deployer/deployer.go b/pkg/util/deployer/deployer.go new file mode 100644 index 00000000000..a0228ac3944 --- /dev/null +++ b/pkg/util/deployer/deployer.go @@ -0,0 +1,130 @@ +// deployer is used to template and deploy services in an ARO cluster. +// Some example usage can be found in the muo package. +package deployer + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "bytes" + "context" + "errors" + "io" + "io/fs" + "path/filepath" + "strings" + "text/template" + + appsv1 "k8s.io/api/apps/v1" + kruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + + arov1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1" + "github.com/Azure/ARO-RP/pkg/util/dynamichelper" + "github.com/Azure/ARO-RP/pkg/util/ready" +) + +type Deployer interface { + CreateOrUpdate(context.Context, *arov1alpha1.Cluster, interface{}) error + Remove(context.Context, interface{}) error + IsReady(context.Context, string, string) (bool, error) + Template(interface{}, fs.FS) ([]kruntime.Object, error) +} + +type deployer struct { + kubernetescli kubernetes.Interface + dh dynamichelper.Interface + fs fs.FS + directory string +} + +func NewDeployer(kubernetescli kubernetes.Interface, dh dynamichelper.Interface, fs fs.FS, directory string) Deployer { + return &deployer{ + kubernetescli: kubernetescli, + dh: dh, + fs: fs, + directory: directory, + } +} + +func (depl *deployer) Template(data interface{}, fsys fs.FS) ([]kruntime.Object, error) { + results := make([]kruntime.Object, 0) + template, err := template.ParseFS(fsys, filepath.Join(depl.directory, "*")) + if err != nil { + return nil, err + } + + buffer := new(bytes.Buffer) + for _, templ := range template.Templates() { + err := templ.Execute(buffer, data) + if err != nil { + return nil, err + } + bytes, err := io.ReadAll(buffer) + if err != nil { + return nil, err + } + + obj, _, err := scheme.Codecs.UniversalDeserializer().Decode(bytes, nil, nil) + if err != nil { + return nil, err + } + results = append(results, obj) + buffer.Reset() + } + + return results, nil +} + +func (depl *deployer) CreateOrUpdate(ctx context.Context, cluster *arov1alpha1.Cluster, config interface{}) error { + resources, err := depl.Template(config, depl.fs) + if err != nil { + return err + } + + err = dynamichelper.SetControllerReferences(resources, cluster) + if err != nil { + return err + } + + err = dynamichelper.Prepare(resources) + if err != nil { + return err + } + + return depl.dh.Ensure(ctx, resources...) +} + +func (depl *deployer) Remove(ctx context.Context, data interface{}) error { + resources, err := depl.Template(data, depl.fs) + if err != nil { + return err + } + + var errs []error + for _, obj := range resources { + // delete any deployments we have + if deployment, ok := obj.(*appsv1.Deployment); ok { + err := depl.dh.EnsureDeleted(ctx, "Deployment", deployment.Namespace, deployment.Name) + // Don't error out because then we might delete some resources and not others + if err != nil { + errs = append(errs, err) + } + } + } + + if len(errs) != 0 { + errContent := []string{"error removing deployment:"} + for _, err := range errs { + errContent = append(errContent, err.Error()) + } + return errors.New(strings.Join(errContent, "\n")) + } + + return nil +} + +func (depl *deployer) IsReady(ctx context.Context, namespace, deploymentName string) (bool, error) { + return ready.CheckDeploymentIsReady(ctx, depl.kubernetescli.AppsV1().Deployments(namespace), deploymentName)() +} diff --git a/pkg/util/deployer/generate.go b/pkg/util/deployer/generate.go new file mode 100644 index 00000000000..d83f7b25d15 --- /dev/null +++ b/pkg/util/deployer/generate.go @@ -0,0 +1,7 @@ +package deployer + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +//go:generate go run ../../../vendor/github.com/golang/mock/mockgen -destination=../mocks/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/util/$GOPACKAGE Deployer +//go:generate go run ../../../vendor/golang.org/x/tools/cmd/goimports -local=github.com/Azure/ARO-RP -e -w ../mocks/$GOPACKAGE/$GOPACKAGE.go diff --git a/pkg/util/deployer/staticresources/deployment.yaml b/pkg/util/deployer/staticresources/deployment.yaml new file mode 100644 index 00000000000..dfdbcf574a8 --- /dev/null +++ b/pkg/util/deployer/staticresources/deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: managed-upgrade-operator + namespace: openshift-managed-upgrade-operator +spec: + replicas: 1 + selector: + matchLabels: + name: managed-upgrade-operator + template: + metadata: + labels: + name: managed-upgrade-operator + spec: + serviceAccountName: managed-upgrade-operator + containers: + - name: managed-upgrade-operator + image: "{{ .Pullspec }}" + command: + - managed-upgrade-operator + imagePullPolicy: Always diff --git a/pkg/operator/mocks/muo/muo.go b/pkg/util/mocks/deployer/deployer.go similarity index 63% rename from pkg/operator/mocks/muo/muo.go rename to pkg/util/mocks/deployer/deployer.go index 17d3f141a97..b8a24828b2b 100644 --- a/pkg/operator/mocks/muo/muo.go +++ b/pkg/util/mocks/deployer/deployer.go @@ -1,18 +1,18 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Azure/ARO-RP/pkg/operator/controllers/muo (interfaces: Deployer) +// Source: github.com/Azure/ARO-RP/pkg/util/deployer (interfaces: Deployer) -// Package mock_muo is a generated GoMock package. -package mock_muo +// Package mock_deployer is a generated GoMock package. +package mock_deployer import ( context "context" + fs "io/fs" reflect "reflect" gomock "github.com/golang/mock/gomock" runtime "k8s.io/apimachinery/pkg/runtime" v1alpha1 "github.com/Azure/ARO-RP/pkg/operator/apis/aro.openshift.io/v1alpha1" - config "github.com/Azure/ARO-RP/pkg/operator/controllers/muo/config" ) // MockDeployer is a mock of Deployer interface. @@ -39,7 +39,7 @@ func (m *MockDeployer) EXPECT() *MockDeployerMockRecorder { } // CreateOrUpdate mocks base method. -func (m *MockDeployer) CreateOrUpdate(arg0 context.Context, arg1 *v1alpha1.Cluster, arg2 *config.MUODeploymentConfig) error { +func (m *MockDeployer) CreateOrUpdate(arg0 context.Context, arg1 *v1alpha1.Cluster, arg2 interface{}) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateOrUpdate", arg0, arg1, arg2) ret0, _ := ret[0].(error) @@ -53,45 +53,45 @@ func (mr *MockDeployerMockRecorder) CreateOrUpdate(arg0, arg1, arg2 interface{}) } // IsReady mocks base method. -func (m *MockDeployer) IsReady(arg0 context.Context) (bool, error) { +func (m *MockDeployer) IsReady(arg0 context.Context, arg1, arg2 string) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsReady", arg0) + ret := m.ctrl.Call(m, "IsReady", arg0, arg1, arg2) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } // IsReady indicates an expected call of IsReady. -func (mr *MockDeployerMockRecorder) IsReady(arg0 interface{}) *gomock.Call { +func (mr *MockDeployerMockRecorder) IsReady(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsReady", reflect.TypeOf((*MockDeployer)(nil).IsReady), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsReady", reflect.TypeOf((*MockDeployer)(nil).IsReady), arg0, arg1, arg2) } // Remove mocks base method. -func (m *MockDeployer) Remove(arg0 context.Context) error { +func (m *MockDeployer) Remove(arg0 context.Context, arg1 interface{}) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Remove", arg0) + ret := m.ctrl.Call(m, "Remove", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // Remove indicates an expected call of Remove. -func (mr *MockDeployerMockRecorder) Remove(arg0 interface{}) *gomock.Call { +func (mr *MockDeployerMockRecorder) Remove(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockDeployer)(nil).Remove), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockDeployer)(nil).Remove), arg0, arg1) } -// Resources mocks base method. -func (m *MockDeployer) Resources(arg0 *config.MUODeploymentConfig) ([]runtime.Object, error) { +// Template mocks base method. +func (m *MockDeployer) Template(arg0 interface{}, arg1 fs.FS) ([]runtime.Object, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Resources", arg0) + ret := m.ctrl.Call(m, "Template", arg0, arg1) ret0, _ := ret[0].([]runtime.Object) ret1, _ := ret[1].(error) return ret0, ret1 } -// Resources indicates an expected call of Resources. -func (mr *MockDeployerMockRecorder) Resources(arg0 interface{}) *gomock.Call { +// Template indicates an expected call of Template. +func (mr *MockDeployerMockRecorder) Template(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Resources", reflect.TypeOf((*MockDeployer)(nil).Resources), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Template", reflect.TypeOf((*MockDeployer)(nil).Template), arg0, arg1) }