che-operator/pkg/common/utils/utils.go

243 lines
5.2 KiB
Go

//
// Copyright (c) 2019-2023 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//
package utils
import (
"crypto/sha256"
"encoding/base64"
"io/ioutil"
"math/rand"
"strings"
"time"
"k8s.io/apimachinery/pkg/labels"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/discovery"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/yaml"
)
func Contains(list []string, s string) bool {
for _, v := range list {
if v == s {
return true
}
}
return false
}
func Remove(list []string, s string) []string {
for i, v := range list {
if v == s {
list = append(list[:i], list[i+1:]...)
}
}
return list
}
func GeneratePassword(stringLength int) (passwd string) {
rand.Seed(time.Now().UnixNano())
chars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz" +
"0123456789")
length := stringLength
buf := make([]rune, length)
for i := range buf {
buf[i] = chars[rand.Intn(len(chars))]
}
passwd = string(buf)
return passwd
}
func IsK8SResourceServed(discoveryClient discovery.DiscoveryInterface, resourceName string) bool {
_, resourceList, err := discoveryClient.ServerGroupsAndResources()
if err != nil {
return false
}
return hasAPIResourceNameInList(resourceName, resourceList)
}
func hasAPIResourceNameInList(name string, resources []*metav1.APIResourceList) bool {
for _, l := range resources {
for _, r := range l.APIResources {
if r.Name == name {
return true
}
}
}
return false
}
func GetValue(value string, defaultValue string) string {
if value == "" {
value = defaultValue
}
return value
}
// GetImageNameAndTag returns the image repository and tag name from the provided image
// Referenced from https://github.com/che-incubator/chectl/blob/main/src/util.ts
func GetImageNameAndTag(image string) (string, string) {
var imageName, imageTag string
if strings.Contains(image, "@") {
// Image is referenced via a digest
index := strings.Index(image, "@")
imageName = image[:index]
imageTag = image[index+1:]
} else {
// Image is referenced via a tag
lastColonIndex := strings.LastIndex(image, ":")
if lastColonIndex == -1 {
imageName = image
imageTag = "latest"
} else {
beforeLastColon := image[:lastColonIndex]
afterLastColon := image[lastColonIndex+1:]
if strings.Contains(afterLastColon, "/") {
// The colon is for registry port and not for a tag
imageName = image
imageTag = "latest"
} else {
// The colon separates image name from the tag
imageName = beforeLastColon
imageTag = afterLastColon
}
}
}
return imageName, imageTag
}
func ReadObjectInto(yamlFile string, obj interface{}) error {
data, err := ioutil.ReadFile(yamlFile)
if err != nil {
return err
}
err = yaml.Unmarshal(data, obj)
if err != nil {
return err
}
return nil
}
func ComputeHash256(data []byte) string {
hasher := sha256.New()
hasher.Write(data)
return base64.URLEncoding.EncodeToString(hasher.Sum(nil))
}
func GetPullPolicyFromDockerImage(dockerImage string) string {
tag := ""
parts := strings.Split(dockerImage, ":")
if len(parts) > 1 {
tag = parts[1]
}
if tag == "latest" || tag == "nightly" || tag == "next" {
return "Always"
}
return "IfNotPresent"
}
func GetMap(value map[string]string, defaultValue map[string]string) map[string]string {
ret := value
if len(value) < 1 {
ret = defaultValue
}
return ret
}
func InNamespaceEventFilter(namespace string) predicate.Predicate {
return predicate.Funcs{
CreateFunc: func(ce event.CreateEvent) bool {
return namespace == ce.Object.GetNamespace()
},
DeleteFunc: func(de event.DeleteEvent) bool {
return namespace == de.Object.GetNamespace()
},
UpdateFunc: func(ue event.UpdateEvent) bool {
return namespace == ue.ObjectOld.GetNamespace()
},
GenericFunc: func(ge event.GenericEvent) bool {
return namespace == ge.Object.GetNamespace()
},
}
}
func ParseMap(src string) map[string]string {
if src == "" {
return nil
}
m := map[string]string{}
for _, item := range strings.Split(src, ",") {
keyValuePair := strings.Split(item, "=")
if len(keyValuePair) == 1 {
continue
}
key := strings.TrimSpace(keyValuePair[0])
value := strings.TrimSpace(keyValuePair[1])
if key != "" && value != "" {
m[keyValuePair[0]] = keyValuePair[1]
}
}
return m
}
func CloneMap(m map[string]string) map[string]string {
if m == nil {
return nil
}
result := make(map[string]string)
for k, v := range m {
result[k] = v
}
return result
}
func AddMap(a map[string]string, b map[string]string) {
for k, v := range b {
a[k] = v
}
}
// Converts label map into plain string
func FormatLabels(m map[string]string) string {
if len(m) == 0 {
return ""
}
return labels.FormatLabels(m)
}
// Whitelists the host.
// Sample: Whitelist("che.yourcompany.com") -> ".yourcompany.com"
func Whitelist(hostname string) (value string) {
i := strings.Index(hostname, ".")
if i > -1 {
j := strings.LastIndex(hostname, ".")
if j > i {
return hostname[i:]
}
}
return hostname
}