mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-09-30 17:50:28 +02:00
Code refactor
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
package constants
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
TPRName = "postgresql"
|
||||
TPRVendor = "acid.zalan.do"
|
||||
TPRDescription = "Managed PostgreSQL clusters"
|
||||
TPRReadyWaitInterval = 3 * time.Second
|
||||
TPRReadyWaitTimeout = 30 * time.Second
|
||||
TPRApiVersion = "v1"
|
||||
|
||||
ResourceName = TPRName + "s"
|
||||
ResyncPeriod = 5 * time.Minute
|
||||
|
||||
EtcdHost = "etcd-client.default.svc.cluster.local:2379" //TODO: move to the operator spec
|
||||
|
||||
PasswordLength = 64
|
||||
)
|
||||
@@ -0,0 +1,66 @@
|
||||
package k8sutil
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/pkg/api"
|
||||
apierrors "k8s.io/client-go/pkg/api/errors"
|
||||
"k8s.io/client-go/pkg/api/unversioned"
|
||||
"k8s.io/client-go/pkg/runtime"
|
||||
"k8s.io/client-go/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
"github.bus.zalan.do/acid/postgres-operator/pkg/spec"
|
||||
"github.bus.zalan.do/acid/postgres-operator/pkg/util/constants"
|
||||
)
|
||||
|
||||
func RestConfig(kubeConfig string, outOfCluster bool) (config *rest.Config, err error) {
|
||||
if outOfCluster {
|
||||
/* out-of-cluster process */
|
||||
rules := clientcmd.NewDefaultClientConfigLoadingRules()
|
||||
overrides := &clientcmd.ConfigOverrides{}
|
||||
rules.ExplicitPath = kubeConfig
|
||||
config, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides).ClientConfig()
|
||||
} else {
|
||||
/* in-cluster pod */
|
||||
config, err = rest.InClusterConfig()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func KubernetesClient(config *rest.Config) (client *kubernetes.Clientset, err error) {
|
||||
return kubernetes.NewForConfig(config)
|
||||
}
|
||||
|
||||
func IsKubernetesResourceAlreadyExistError(err error) bool {
|
||||
return apierrors.IsAlreadyExists(err)
|
||||
}
|
||||
|
||||
func ResourceNotFound(err error) bool {
|
||||
return apierrors.IsNotFound(err)
|
||||
}
|
||||
|
||||
func KubernetesRestClient(c *rest.Config) (*rest.RESTClient, error) {
|
||||
c.APIPath = "/apis"
|
||||
c.GroupVersion = &unversioned.GroupVersion{
|
||||
Group: constants.TPRVendor,
|
||||
Version: constants.TPRApiVersion,
|
||||
}
|
||||
c.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
schemeBuilder := runtime.NewSchemeBuilder(
|
||||
func(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(
|
||||
*c.GroupVersion,
|
||||
&spec.Postgresql{},
|
||||
&spec.PostgresqlList{},
|
||||
&api.ListOptions{},
|
||||
&api.DeleteOptions{},
|
||||
)
|
||||
return nil
|
||||
})
|
||||
schemeBuilder.AddToScheme(api.Scheme)
|
||||
|
||||
return rest.RESTClientFor(c)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package k8sutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"github.bus.zalan.do/acid/postgres-operator/pkg/util/constants"
|
||||
"github.bus.zalan.do/acid/postgres-operator/pkg/util/retryutil"
|
||||
)
|
||||
|
||||
func listClustersURI(ns string) string {
|
||||
return fmt.Sprintf("/apis/%s/%s/namespaces/%s/%s", constants.TPRVendor, constants.TPRApiVersion, ns, constants.ResourceName)
|
||||
}
|
||||
|
||||
func WaitTPRReady(restclient rest.Interface, interval, timeout time.Duration, ns string) error {
|
||||
return retryutil.Retry(interval, int(timeout/interval), func() (bool, error) {
|
||||
_, err := restclient.Get().RequestURI(listClustersURI(ns)).DoRaw()
|
||||
if err != nil {
|
||||
if ResourceNotFound(err) { // not set up yet. wait more.
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package retryutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RetryError struct {
|
||||
n int
|
||||
}
|
||||
|
||||
func (e *RetryError) Error() string {
|
||||
return fmt.Sprintf("still failing after %d retries", e.n)
|
||||
}
|
||||
|
||||
type ConditionFunc func() (bool, error)
|
||||
|
||||
// Retry retries f every interval until after maxRetries.
|
||||
// The interval won't be affected by how long f takes.
|
||||
// For example, if interval is 3s, f takes 1s, another f will be called 2s later.
|
||||
// However, if f takes longer than interval, it will be delayed.
|
||||
func Retry(interval time.Duration, maxRetries int, f ConditionFunc) error {
|
||||
if maxRetries <= 0 {
|
||||
return fmt.Errorf("maxRetries (%d) should be > 0", maxRetries)
|
||||
}
|
||||
tick := time.NewTicker(interval)
|
||||
defer tick.Stop()
|
||||
|
||||
for i := 0; ; i++ {
|
||||
ok, err := f()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
if i+1 == maxRetries {
|
||||
break
|
||||
}
|
||||
<-tick.C
|
||||
}
|
||||
return &RetryError{maxRetries}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
var passwordChars = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*=")
|
||||
|
||||
func init() {
|
||||
rand.Seed(int64(time.Now().Unix()))
|
||||
}
|
||||
|
||||
func RandomPasswordBytes(n int) []byte {
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
b[i] = passwordChars[rand.Intn(len(passwordChars))]
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
Reference in New Issue
Block a user