get rid of arrays in the kuberesources;
use shorter form of checking for errors
This commit is contained in:
		
							parent
							
								
									abd313f2d9
								
							
						
					
					
						commit
						416dace289
					
				|  | @ -40,11 +40,12 @@ type Config struct { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type KubeResources struct { | type KubeResources struct { | ||||||
| 	Services     map[types.UID]*v1.Service | 	Service     *v1.Service | ||||||
| 	Endpoints    map[types.UID]*v1.Endpoints | 	Endpoint    *v1.Endpoints | ||||||
| 	Secrets     map[types.UID]*v1.Secret | 	Secrets     map[types.UID]*v1.Secret | ||||||
| 	Statefulsets map[types.UID]*v1beta1.StatefulSet | 	Statefulset *v1beta1.StatefulSet | ||||||
| 	//Pods are treated separately
 | 	//Pods are treated separately
 | ||||||
|  | 	//PVCs are treated separately
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type Cluster struct { | type Cluster struct { | ||||||
|  | @ -63,12 +64,7 @@ type Cluster struct { | ||||||
| 
 | 
 | ||||||
| func New(cfg Config, pgSpec spec.Postgresql) *Cluster { | func New(cfg Config, pgSpec spec.Postgresql) *Cluster { | ||||||
| 	lg := logrus.WithField("pkg", "cluster").WithField("cluster-name", pgSpec.Metadata.Name) | 	lg := logrus.WithField("pkg", "cluster").WithField("cluster-name", pgSpec.Metadata.Name) | ||||||
| 	kubeResources := KubeResources{ | 	kubeResources := KubeResources{Secrets: make(map[types.UID]*v1.Secret)} | ||||||
| 		Services:     make(map[types.UID]*v1.Service), |  | ||||||
| 		Endpoints:    make(map[types.UID]*v1.Endpoints), |  | ||||||
| 		Secrets:      make(map[types.UID]*v1.Secret), |  | ||||||
| 		Statefulsets: make(map[types.UID]*v1beta1.StatefulSet), |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	cluster := &Cluster{ | 	cluster := &Cluster{ | ||||||
| 		config:         cfg, | 		config:         cfg, | ||||||
|  | @ -149,18 +145,15 @@ func (c *Cluster) Create() error { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	c.initSystemUsers() | 	c.initSystemUsers() | ||||||
| 	err = c.initRobotUsers() | 	if err := c.initRobotUsers(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Can't init robot users: %s", err) | 		return fmt.Errorf("Can't init robot users: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = c.initHumanUsers() | 	if err := c.initHumanUsers(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Can't init human users: %s", err) | 		return fmt.Errorf("Can't init human users: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = c.applySecrets() | 	if err := c.applySecrets(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Can't create secrets: %s", err) | 		return fmt.Errorf("Can't create secrets: %s", err) | ||||||
| 	} else { | 	} else { | ||||||
| 		c.logger.Infof("Secrets have been successfully created") | 		c.logger.Infof("Secrets have been successfully created") | ||||||
|  | @ -174,19 +167,17 @@ func (c *Cluster) Create() error { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	c.logger.Info("Waiting for cluster being ready") | 	c.logger.Info("Waiting for cluster being ready") | ||||||
| 	err = c.waitClusterReady() | 	err = c.waitStatefulsetPodsReady() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.logger.Errorf("Failed to create cluster: %s", err) | 		c.logger.Errorf("Failed to create cluster: %s", err) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = c.initDbConn() | 	if err := c.initDbConn(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Can't init db connection: %s", err) | 		return fmt.Errorf("Can't init db connection: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = c.createUsers() | 	if err := c.createUsers(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Can't create users: %s", err) | 		return fmt.Errorf("Can't create users: %s", err) | ||||||
| 	} else { | 	} else { | ||||||
| 		c.logger.Infof("Users have been successfully created") | 		c.logger.Infof("Users have been successfully created") | ||||||
|  | @ -198,18 +189,20 @@ func (c *Cluster) Create() error { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) Update(newSpec *spec.Postgresql, rollingUpdate bool) error { | func (c *Cluster) Update(newSpec *spec.Postgresql, rollingUpdate bool) error { | ||||||
| 	statefulSet := getStatefulSet(c.ClusterName(), newSpec.Spec, c.etcdHost, c.dockerImage) | 	newStatefulSet := getStatefulSet(c.ClusterName(), newSpec.Spec, c.etcdHost, c.dockerImage) | ||||||
|  | 
 | ||||||
|  | 	if !reflect.DeepEqual(newSpec.Spec.Volume, c.Spec.Volume) { | ||||||
|  | 		//TODO: update PVC
 | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	//TODO: mind the case of updating allowedSourceRanges
 | 	//TODO: mind the case of updating allowedSourceRanges
 | ||||||
| 	err := c.updateStatefulSet(statefulSet) | 	if err := c.updateStatefulSet(newStatefulSet); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Can't upate cluster: %s", err) | 		return fmt.Errorf("Can't upate cluster: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if rollingUpdate { | 	if rollingUpdate { | ||||||
| 		err = c.recreatePods() |  | ||||||
| 		// TODO: wait for actual streaming to the replica
 | 		// TODO: wait for actual streaming to the replica
 | ||||||
| 		if err != nil { | 		if err := c.recreatePods(); err != nil { | ||||||
| 			return fmt.Errorf("Can't recreate pods: %s", err) | 			return fmt.Errorf("Can't recreate pods: %s", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -218,45 +211,36 @@ func (c *Cluster) Update(newSpec *spec.Postgresql, rollingUpdate bool) error { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) Delete() error { | func (c *Cluster) Delete() error { | ||||||
| 	for _, obj := range c.Statefulsets { | 	if err := c.deleteEndpoint(); err != nil { | ||||||
| 		err := c.deleteStatefulSet(obj) | 		c.logger.Errorf("Can't delete endpoint: %s", err) | ||||||
| 		if err != nil { | 	} else { | ||||||
|  | 		c.logger.Infof("Endpoint '%s' has been deleted", util.NameFromMeta(c.Endpoint.ObjectMeta)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := c.deleteService(); err != nil { | ||||||
|  | 		c.logger.Errorf("Can't delete service: %s", err) | ||||||
|  | 	} else { | ||||||
|  | 		c.logger.Infof("Service '%s' has been deleted", util.NameFromMeta(c.Service.ObjectMeta)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := c.deleteStatefulSet(); err != nil { | ||||||
| 		c.logger.Errorf("Can't delete StatefulSet: %s", err) | 		c.logger.Errorf("Can't delete StatefulSet: %s", err) | ||||||
| 	} else { | 	} else { | ||||||
| 			c.logger.Infof("StatefulSet '%s' has been deleted", util.NameFromMeta(obj.ObjectMeta)) | 		c.logger.Infof("StatefulSet '%s' has been deleted", util.NameFromMeta(c.Statefulset.ObjectMeta)) | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, obj := range c.Secrets { | 	for _, obj := range c.Secrets { | ||||||
| 		err := c.deleteSecret(obj) | 		if err := c.deleteSecret(obj); err != nil { | ||||||
| 		if err != nil { |  | ||||||
| 			c.logger.Errorf("Can't delete secret: %s", err) | 			c.logger.Errorf("Can't delete secret: %s", err) | ||||||
| 		} else { | 		} else { | ||||||
| 			c.logger.Infof("Secret '%s' has been deleted", util.NameFromMeta(obj.ObjectMeta)) | 			c.logger.Infof("Secret '%s' has been deleted", util.NameFromMeta(obj.ObjectMeta)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, obj := range c.Endpoints { | 	if err := c.deletePods(); err != nil { | ||||||
| 		err := c.deleteEndpoint(obj) | 		c.logger.Errorf("Can't delete pods: %s", err) | ||||||
| 		if err != nil { |  | ||||||
| 			c.logger.Errorf("Can't delete endpoint: %s", err) |  | ||||||
| 	} else { | 	} else { | ||||||
| 			c.logger.Infof("Endpoint '%s' has been deleted", util.NameFromMeta(obj.ObjectMeta)) | 		c.logger.Infof("Pods have been deleted") | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for _, obj := range c.Services { |  | ||||||
| 		err := c.deleteService(obj) |  | ||||||
| 		if err != nil { |  | ||||||
| 			c.logger.Errorf("Can't delete service: %s", err) |  | ||||||
| 		} else { |  | ||||||
| 			c.logger.Infof("Service '%s' has been deleted", util.NameFromMeta(obj.ObjectMeta)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	err := c.deletePods() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Can't delete pods: %s", err) |  | ||||||
| 	} | 	} | ||||||
| 	err = c.deletePersistenVolumeClaims() | 	err = c.deletePersistenVolumeClaims() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  |  | ||||||
|  | @ -30,8 +30,7 @@ func (c *Cluster) deletePods() error { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, obj := range pods { | 	for _, obj := range pods { | ||||||
| 		err := c.deletePod(&obj) | 		if err := c.deletePod(&obj); err != nil { | ||||||
| 		if err != nil { |  | ||||||
| 			c.logger.Errorf("Can't delete pod: %s", err) | 			c.logger.Errorf("Can't delete pod: %s", err) | ||||||
| 		} else { | 		} else { | ||||||
| 			c.logger.Infof("Pod '%s' has been deleted", util.NameFromMeta(obj.ObjectMeta)) | 			c.logger.Infof("Pod '%s' has been deleted", util.NameFromMeta(obj.ObjectMeta)) | ||||||
|  | @ -84,13 +83,11 @@ func (c *Cluster) deletePod(pod *v1.Pod) error { | ||||||
| 		delete(c.podSubscribers, podName) | 		delete(c.podSubscribers, podName) | ||||||
| 	}() | 	}() | ||||||
| 
 | 
 | ||||||
| 	err := c.config.KubeClient.Pods(pod.Namespace).Delete(pod.Name, deleteOptions) | 	if err := c.config.KubeClient.Pods(pod.Namespace).Delete(pod.Name, deleteOptions); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = c.waitForPodDeletion(ch) | 	if err := c.waitForPodDeletion(ch); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -118,16 +115,14 @@ func (c *Cluster) recreatePod(pod v1.Pod, spiloRole string) error { | ||||||
| 		delete(c.podSubscribers, podName) | 		delete(c.podSubscribers, podName) | ||||||
| 	}() | 	}() | ||||||
| 
 | 
 | ||||||
| 	err := c.config.KubeClient.Pods(pod.Namespace).Delete(pod.Name, deleteOptions) | 	if err := c.config.KubeClient.Pods(pod.Namespace).Delete(pod.Name, deleteOptions); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Can't delete pod: %s", err) | 		return fmt.Errorf("Can't delete pod: %s", err) | ||||||
| 	} | 	} | ||||||
| 	err = c.waitForPodDeletion(ch) | 
 | ||||||
| 	if err != nil { | 	if err := c.waitForPodDeletion(ch); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	err = c.waitForPodLabel(ch, spiloRole) | 	if err := c.waitForPodLabel(ch, spiloRole); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	c.logger.Infof("Pod '%s' is ready", podName) | 	c.logger.Infof("Pod '%s' is ready", podName) | ||||||
|  | @ -161,7 +156,7 @@ func (c *Cluster) recreatePods() error { | ||||||
| 	} | 	} | ||||||
| 	pods, err := c.config.KubeClient.Pods(namespace).List(listOptions) | 	pods, err := c.config.KubeClient.Pods(namespace).List(listOptions) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("Can't get list of pods: %s", err) | 		return fmt.Errorf("Can't get the list of the pods: %s", err) | ||||||
| 	} else { | 	} else { | ||||||
| 		c.logger.Infof("There are %d pods in the cluster to recreate", len(pods.Items)) | 		c.logger.Infof("There are %d pods in the cluster to recreate", len(pods.Items)) | ||||||
| 	} | 	} | ||||||
|  | @ -187,8 +182,8 @@ func (c *Cluster) recreatePods() error { | ||||||
| 	//TODO: do manual failover
 | 	//TODO: do manual failover
 | ||||||
| 	//TODO: specify master, leave new master empty
 | 	//TODO: specify master, leave new master empty
 | ||||||
| 	c.logger.Infof("Recreating master pod '%s'", util.NameFromMeta(masterPod.ObjectMeta)) | 	c.logger.Infof("Recreating master pod '%s'", util.NameFromMeta(masterPod.ObjectMeta)) | ||||||
| 	err = c.recreatePod(masterPod, "replica") | 
 | ||||||
| 	if err != nil { | 	if err := c.recreatePod(masterPod, "replica"); err != nil { | ||||||
| 		return fmt.Errorf("Can't recreate master pod '%s': %s", util.NameFromMeta(masterPod.ObjectMeta), err) | 		return fmt.Errorf("Can't recreate master pod '%s': %s", util.NameFromMeta(masterPod.ObjectMeta), err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,24 +38,19 @@ func (c *Cluster) LoadResources() error { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("Can't get list of services: %s", err) | 		return fmt.Errorf("Can't get list of services: %s", err) | ||||||
| 	} | 	} | ||||||
| 	for i, service := range services.Items { | 	if len(services.Items) > 1 { | ||||||
| 		if _, ok := c.Services[service.UID]; ok { | 		return fmt.Errorf("Too many(%d) Services for a cluster", len(services.Items)) | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		c.Services[service.UID] = &services.Items[i] |  | ||||||
| 	} | 	} | ||||||
|  | 	c.Service = &services.Items[0] | ||||||
| 
 | 
 | ||||||
| 	endpoints, err := c.config.KubeClient.Endpoints(ns).List(listOptions) | 	endpoints, err := c.config.KubeClient.Endpoints(ns).List(listOptions) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("Can't get list of endpoints: %s", err) | 		return fmt.Errorf("Can't get list of endpoints: %s", err) | ||||||
| 	} | 	} | ||||||
| 	for i, endpoint := range endpoints.Items { | 	if len(endpoints.Items) > 1 { | ||||||
| 		if _, ok := c.Endpoints[endpoint.UID]; ok { | 		return fmt.Errorf("Too many(%d) Endpoints for a cluster", len(endpoints.Items)) | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		c.Endpoints[endpoint.UID] = &endpoints.Items[i] |  | ||||||
| 		c.logger.Debugf("Endpoint loaded, uid: %s", endpoint.UID) |  | ||||||
| 	} | 	} | ||||||
|  | 	c.Endpoint = &endpoints.Items[0] | ||||||
| 
 | 
 | ||||||
| 	secrets, err := c.config.KubeClient.Secrets(ns).List(listOptions) | 	secrets, err := c.config.KubeClient.Secrets(ns).List(listOptions) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | @ -73,33 +68,23 @@ func (c *Cluster) LoadResources() error { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("Can't get list of stateful sets: %s", err) | 		return fmt.Errorf("Can't get list of stateful sets: %s", err) | ||||||
| 	} | 	} | ||||||
| 	for i, statefulSet := range statefulSets.Items { | 	if len(statefulSets.Items) > 1 { | ||||||
| 		if _, ok := c.Statefulsets[statefulSet.UID]; ok { | 		return fmt.Errorf("Too many(%d) StatefulSets for a cluster", len(statefulSets.Items)) | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		c.Statefulsets[statefulSet.UID] = &statefulSets.Items[i] |  | ||||||
| 		c.logger.Debugf("StatefulSet loaded, uid: %s", statefulSet.UID) |  | ||||||
| 	} | 	} | ||||||
|  | 	c.Statefulset = &statefulSets.Items[0] | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) ListResources() error { | func (c *Cluster) ListResources() error { | ||||||
| 	for _, obj := range c.Statefulsets { | 	c.logger.Infof("StatefulSet: %s (uid: %s)", util.NameFromMeta(c.Statefulset.ObjectMeta), c.Statefulset.UID) | ||||||
| 		c.logger.Infof("StatefulSet: %s", util.NameFromMeta(obj.ObjectMeta)) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	for _, obj := range c.Secrets { | 	for _, obj := range c.Secrets { | ||||||
| 		c.logger.Infof("Secret: %s", util.NameFromMeta(obj.ObjectMeta)) | 		c.logger.Infof("Secret: %s (uid: %s)", util.NameFromMeta(obj.ObjectMeta), obj.UID) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, obj := range c.Endpoints { | 	c.logger.Infof("Endpoint: %s (uid: %s)", util.NameFromMeta(c.Endpoint.ObjectMeta), c.Endpoint.UID) | ||||||
| 		c.logger.Infof("Endpoint: %s", util.NameFromMeta(obj.ObjectMeta)) | 	c.logger.Infof("Service: %s (uid: %s)", util.NameFromMeta(c.Service.ObjectMeta), c.Service.UID) | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for _, obj := range c.Services { |  | ||||||
| 		c.logger.Infof("Service: %s", util.NameFromMeta(obj.ObjectMeta)) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	pods, err := c.clusterPods() | 	pods, err := c.clusterPods() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | @ -107,13 +92,16 @@ func (c *Cluster) ListResources() error { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, obj := range pods { | 	for _, obj := range pods { | ||||||
| 		c.logger.Infof("Pod: %s", util.NameFromMeta(obj.ObjectMeta)) | 		c.logger.Infof("Pod: %s (uid: %s)", util.NameFromMeta(obj.ObjectMeta), obj.UID) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) createStatefulSet() (*v1beta1.StatefulSet, error) { | func (c *Cluster) createStatefulSet() (*v1beta1.StatefulSet, error) { | ||||||
|  | 	if c.Statefulset != nil { | ||||||
|  | 		return nil, fmt.Errorf("StatefulSet already exists in the cluster") | ||||||
|  | 	} | ||||||
| 	statefulSetSpec := getStatefulSet(c.ClusterName(), c.Spec, c.etcdHost, c.dockerImage) | 	statefulSetSpec := getStatefulSet(c.ClusterName(), c.Spec, c.etcdHost, c.dockerImage) | ||||||
| 	statefulSet, err := c.config.KubeClient.StatefulSets(statefulSetSpec.Namespace).Create(statefulSetSpec) | 	statefulSet, err := c.config.KubeClient.StatefulSets(statefulSetSpec.Namespace).Create(statefulSetSpec) | ||||||
| 	if k8sutil.ResourceAlreadyExists(err) { | 	if k8sutil.ResourceAlreadyExists(err) { | ||||||
|  | @ -122,61 +110,44 @@ func (c *Cluster) createStatefulSet() (*v1beta1.StatefulSet, error) { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	c.Statefulsets[statefulSet.UID] = statefulSet | 	c.Statefulset = statefulSet | ||||||
| 	c.logger.Debugf("Created new StatefulSet, uid: %s", statefulSet.UID) | 	c.logger.Debugf("Created new StatefulSet, uid: %s", statefulSet.UID) | ||||||
| 
 | 
 | ||||||
| 	return statefulSet, nil | 	return statefulSet, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) updateStatefulSet(statefulSet *v1beta1.StatefulSet) error { | func (c *Cluster) updateStatefulSet(newStatefulSet *v1beta1.StatefulSet) error { | ||||||
| 	statefulSet, err := c.config.KubeClient.StatefulSets(statefulSet.Namespace).Update(statefulSet) | 	if c.Statefulset == nil { | ||||||
| 	if err != nil { | 		return fmt.Errorf("There is no StatefulSet in the cluster") | ||||||
| 		c.Statefulsets[statefulSet.UID] = statefulSet |  | ||||||
| 	} | 	} | ||||||
| 
 | 	statefulSet, err := c.config.KubeClient.StatefulSets(newStatefulSet.Namespace).Update(newStatefulSet) | ||||||
| 	return err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Cluster) deleteStatefulSet(statefulSet *v1beta1.StatefulSet) error { |  | ||||||
| 	err := c.config.KubeClient. |  | ||||||
| 		StatefulSets(statefulSet.Namespace). |  | ||||||
| 		Delete(statefulSet.Name, deleteOptions) |  | ||||||
| 
 |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	delete(c.Statefulsets, statefulSet.UID) | 
 | ||||||
|  | 	c.Statefulset = statefulSet | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) createEndpoint() (*v1.Endpoints, error) { | func (c *Cluster) deleteStatefulSet() error { | ||||||
| 	endpointSpec := resources.Endpoint(c.ClusterName()) | 	if c.Statefulset == nil { | ||||||
| 
 | 		return fmt.Errorf("There is no StatefulSet in the cluster") | ||||||
| 	endpoint, err := c.config.KubeClient.Endpoints(endpointSpec.Namespace).Create(endpointSpec) |  | ||||||
| 	if k8sutil.ResourceAlreadyExists(err) { |  | ||||||
| 		return nil, fmt.Errorf("Endpoint '%s' already exists", util.NameFromMeta(endpointSpec.ObjectMeta)) |  | ||||||
| 	} |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	c.Endpoints[endpoint.UID] = endpoint |  | ||||||
| 	c.logger.Debugf("Created new endpoint, uid: %s", endpoint.UID) |  | ||||||
| 
 |  | ||||||
| 	return endpoint, nil |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) deleteEndpoint(endpoint *v1.Endpoints) error { | 	err := c.config.KubeClient.StatefulSets(c.Statefulset.Namespace).Delete(c.Statefulset.Name, deleteOptions) | ||||||
| 	err := c.config.KubeClient.Endpoints(endpoint.Namespace).Delete(endpoint.Name, deleteOptions) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	delete(c.Endpoints, endpoint.UID) | 	c.Statefulset = nil | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) createService() (*v1.Service, error) { | func (c *Cluster) createService() (*v1.Service, error) { | ||||||
|  | 	if c.Service != nil { | ||||||
|  | 		return nil, fmt.Errorf("Service already exists in the cluster") | ||||||
|  | 	} | ||||||
| 	serviceSpec := resources.Service(c.ClusterName(), c.Spec.AllowedSourceRanges) | 	serviceSpec := resources.Service(c.ClusterName(), c.Spec.AllowedSourceRanges) | ||||||
| 
 | 
 | ||||||
| 	service, err := c.config.KubeClient.Services(serviceSpec.Namespace).Create(serviceSpec) | 	service, err := c.config.KubeClient.Services(serviceSpec.Namespace).Create(serviceSpec) | ||||||
|  | @ -186,40 +157,74 @@ func (c *Cluster) createService() (*v1.Service, error) { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	c.Services[service.UID] = service | 	c.Service = service | ||||||
| 	c.logger.Debugf("Created new service, uid: %s", service.UID) |  | ||||||
| 
 | 
 | ||||||
| 	return service, nil | 	return service, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) deleteService(service *v1.Service) error { | func (c *Cluster) updateService(newService *v1.Service) error { | ||||||
| 	err := c.config.KubeClient.Services(service.Namespace).Delete(service.Name, deleteOptions) | 	if c.Service == nil { | ||||||
|  | 		return fmt.Errorf("There is no Service in the cluster") | ||||||
|  | 	} | ||||||
|  | 	newService.ObjectMeta = c.Service.ObjectMeta | ||||||
|  | 	newService.Spec.ClusterIP = c.Service.Spec.ClusterIP | ||||||
|  | 
 | ||||||
|  | 	svc, err := c.config.KubeClient.Services(newService.Namespace).Update(newService) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	delete(c.Services, service.UID) | 	c.Service = svc | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) createUsers() error { | func (c *Cluster) deleteService() error { | ||||||
| 	for username, user := range c.pgUsers { | 	if c.Service == nil { | ||||||
| 		if username == constants.SuperuserName || username == constants.ReplicationUsername { | 		return fmt.Errorf("There is no Service in the cluster") | ||||||
| 			continue | 	} | ||||||
|  | 	err := c.config.KubeClient.Services(c.Service.Namespace).Delete(c.Service.Name, deleteOptions) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	c.Service = nil | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 		isHuman, err := c.createPgUser(user) | func (c *Cluster) createEndpoint() (*v1.Endpoints, error) { | ||||||
| 		var userType string | 	if c.Endpoint != nil { | ||||||
| 		if isHuman { | 		return nil, fmt.Errorf("Endpoint already exists in the cluster") | ||||||
| 			userType = "human" | 	} | ||||||
| 		} else { | 	endpointSpec := resources.Endpoint(c.ClusterName()) | ||||||
| 			userType = "robot" | 
 | ||||||
|  | 	endpoint, err := c.config.KubeClient.Endpoints(endpointSpec.Namespace).Create(endpointSpec) | ||||||
|  | 	if k8sutil.ResourceAlreadyExists(err) { | ||||||
|  | 		return nil, fmt.Errorf("Endpoint '%s' already exists", util.NameFromMeta(endpointSpec.ObjectMeta)) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 			return fmt.Errorf("Can't create %s user '%s': %s", userType, username, err) | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	c.Endpoint = endpoint | ||||||
|  | 
 | ||||||
|  | 	return endpoint, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (c *Cluster) updateEndpoint(newEndpoint *v1.Endpoints) error { | ||||||
|  | 	//TODO: to be implemented
 | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *Cluster) deleteEndpoint() error { | ||||||
|  | 	if c.Endpoint == nil { | ||||||
|  | 		return fmt.Errorf("There is no Endpoint in the cluster") | ||||||
|  | 	} | ||||||
|  | 	err := c.config.KubeClient.Endpoints(c.Endpoint.Namespace).Delete(c.Endpoint.Name, deleteOptions) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	c.Endpoint = nil | ||||||
|  | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -263,3 +268,24 @@ func (c *Cluster) deleteSecret(secret *v1.Secret) error { | ||||||
| 
 | 
 | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (c *Cluster) createUsers() error { | ||||||
|  | 	for username, user := range c.pgUsers { | ||||||
|  | 		if username == constants.SuperuserName || username == constants.ReplicationUsername { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		isHuman, err := c.createPgUser(user) | ||||||
|  | 		var userType string | ||||||
|  | 		if isHuman { | ||||||
|  | 			userType = "human" | ||||||
|  | 		} else { | ||||||
|  | 			userType = "robot" | ||||||
|  | 		} | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("Can't create %s user '%s': %s", userType, username, err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -137,16 +137,14 @@ func (c *Cluster) waitPodLabelsReady() error { | ||||||
| 		}) | 		}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Cluster) waitClusterReady() error { | func (c *Cluster) waitStatefulsetPodsReady() error { | ||||||
| 	// TODO: wait for the first Pod only
 | 	// TODO: wait for the first Pod only
 | ||||||
| 	err := c.waitStatefulsetReady() | 	if err := c.waitStatefulsetReady(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Statuful set error: %s", err) | 		return fmt.Errorf("Statuful set error: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// TODO: wait only for master
 | 	// TODO: wait only for master
 | ||||||
| 	err = c.waitPodLabelsReady() | 	if err := c.waitPodLabelsReady(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("Pod labels error: %s", err) | 		return fmt.Errorf("Pod labels error: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -52,8 +52,7 @@ func (c *Controller) Run(stopCh <-chan struct{}, wg *sync.WaitGroup) { | ||||||
| 	wg.Add(1) | 	wg.Add(1) | ||||||
| 
 | 
 | ||||||
| 	c.initController() | 	c.initController() | ||||||
| 	err := c.initEtcdClient() | 	if err := c.initEtcdClient(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		c.logger.Errorf("Can't get etcd client: %s", err) | 		c.logger.Errorf("Can't get etcd client: %s", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  | @ -65,8 +64,7 @@ func (c *Controller) Run(stopCh <-chan struct{}, wg *sync.WaitGroup) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (c *Controller) initController() { | func (c *Controller) initController() { | ||||||
| 	err := c.createTPR() | 	if err := c.createTPR(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		c.logger.Fatalf("Can't register ThirdPartyResource: %s", err) | 		c.logger.Fatalf("Can't register ThirdPartyResource: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -52,9 +52,8 @@ func (c *Controller) clusterListFunc(options api.ListOptions) (runtime.Object, e | ||||||
| 		c.stopChMap[clusterName] = stopCh | 		c.stopChMap[clusterName] = stopCh | ||||||
| 		c.clusters[clusterName] = cl | 		c.clusters[clusterName] = cl | ||||||
| 		cl.LoadResources() | 		cl.LoadResources() | ||||||
| 		cl.ListResources() |  | ||||||
| 
 |  | ||||||
| 		go cl.Run(stopCh) | 		go cl.Run(stopCh) | ||||||
|  | 		cl.ListResources() | ||||||
| 	} | 	} | ||||||
| 	if len(c.clusters) > 0 { | 	if len(c.clusters) > 0 { | ||||||
| 		c.logger.Infof("There are %d clusters currently running", len(c.clusters)) | 		c.logger.Infof("There are %d clusters currently running", len(c.clusters)) | ||||||
|  | @ -96,8 +95,7 @@ func (c *Controller) postgresqlAdd(obj interface{}) { | ||||||
| 	c.logger.Infof("Creation of a new Postgresql cluster '%s' started", clusterName) | 	c.logger.Infof("Creation of a new Postgresql cluster '%s' started", clusterName) | ||||||
| 	cl := cluster.New(c.makeClusterConfig(), *pg) | 	cl := cluster.New(c.makeClusterConfig(), *pg) | ||||||
| 	cl.MustSetStatus(spec.ClusterStatusCreating) | 	cl.MustSetStatus(spec.ClusterStatusCreating) | ||||||
| 	err := cl.Create() | 	if err := cl.Create(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		c.logger.Errorf("Can't create cluster: %s", err) | 		c.logger.Errorf("Can't create cluster: %s", err) | ||||||
| 		cl.MustSetStatus(spec.ClusterStatusAddFailed) | 		cl.MustSetStatus(spec.ClusterStatusAddFailed) | ||||||
| 		return | 		return | ||||||
|  | @ -150,8 +148,7 @@ func (c *Controller) postgresqlUpdate(prev, cur interface{}) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	pgCluster.MustSetStatus(spec.ClusterStatusUpdating) | 	pgCluster.MustSetStatus(spec.ClusterStatusUpdating) | ||||||
| 	err := pgCluster.Update(pgNew, rollingUpdate) | 	if err := pgCluster.Update(pgNew, rollingUpdate); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		pgCluster.MustSetStatus(spec.ClusterStatusUpdateFailed) | 		pgCluster.MustSetStatus(spec.ClusterStatusUpdateFailed) | ||||||
| 		c.logger.Errorf("Can't update cluster: %s", err) | 		c.logger.Errorf("Can't update cluster: %s", err) | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -176,8 +173,7 @@ func (c *Controller) postgresqlDelete(obj interface{}) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	c.logger.Infof("Cluster delete: %s", util.NameFromMeta(pgCur.Metadata)) | 	c.logger.Infof("Cluster delete: %s", util.NameFromMeta(pgCur.Metadata)) | ||||||
| 	err := pgCluster.Delete() | 	if err := pgCluster.Delete(); err != nil { | ||||||
| 	if err != nil { |  | ||||||
| 		c.logger.Errorf("Can't delete cluster '%s': %s", clusterName, err) | 		c.logger.Errorf("Can't delete cluster '%s': %s", clusterName, err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue