internal/checkpoint/checkpoint.go (126 lines of code) (raw):

package checkpoint import ( "context" "fmt" . "git.jetbrains.team/tch/teamcity-operator/api/v1beta1" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" ) type Checkpoint struct { Client client.Client CurrentStage Stage Instance TeamCity } func NewCheckpoint(client client.Client, instance TeamCity) *Checkpoint { return &Checkpoint{ Client: client, Instance: instance, CurrentStage: getInitialStageFromInstance(instance), } } func (c *Checkpoint) DoCheckpointWithDesiredStage(ctx context.Context, desiredStage Stage) error { currentStage, err := c.FetchCurrentStageFromCluster(ctx) if err != nil { if errors.IsNotFound(err) { c.CurrentStage = desiredStage err = c.Create(ctx) if err != nil { return err } return nil } return err } c.CurrentStage = currentStage canChangeStage, err := c.CurrentStage.canChangeStageValue(desiredStage) if err != nil { return err } if canChangeStage { c.CurrentStage = desiredStage err = c.Update(ctx) } return nil } func (c *Checkpoint) Create(ctx context.Context) error { configMap := c.toConfigMapObject() if err := c.Client.Create(ctx, &configMap); err != nil { return err } return nil } func (c *Checkpoint) UpdateStageFromConfigMap(ctx context.Context) error { stage, err := c.FetchCurrentStageFromCluster(ctx) if err != nil { if errors.IsNotFound(err) { initialStage := getInitialStageFromInstance(c.Instance) c.CurrentStage = initialStage return nil } return err } c.CurrentStage = stage return nil } func (c *Checkpoint) FetchCurrentStageFromCluster(ctx context.Context) (Stage, error) { stage := NewStage("") configMap, err := c.GetConfigMap(ctx) if err != nil { return stage, err } stage, err = GetStageStringValueFromConfigMap(&configMap) if err != nil { return stage, err } return stage, nil } func (c *Checkpoint) GetConfigMap(ctx context.Context) (v1.ConfigMap, error) { var configMap v1.ConfigMap namespacedName := c.getNamespacedName() if err := c.Client.Get(ctx, namespacedName, &configMap); err != nil { return configMap, err } return configMap, nil } func (c *Checkpoint) Update(ctx context.Context) error { checkpointCM := c.toConfigMapObject() if err := c.Client.Update(ctx, &checkpointCM); err != nil { return nil } return nil } func (c *Checkpoint) Delete(ctx context.Context) error { configMap, err := c.GetConfigMap(ctx) if err != nil { if !errors.IsNotFound(err) { return err } } if err := c.Client.Delete(ctx, &configMap); err != nil { return err } return nil } func (c *Checkpoint) getCheckpointConfigMapName() string { return fmt.Sprintf("%s-%s", StageConfigMapNamePrefix, c.Instance.Name) } func (c *Checkpoint) getNamespacedName() types.NamespacedName { return types.NamespacedName{ Name: c.getCheckpointConfigMapName(), Namespace: c.Instance.Namespace, } } func (c *Checkpoint) toConfigMapObject() v1.ConfigMap { return v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: ConstructCheckpointName(c.Instance.Name), Namespace: c.Instance.Namespace, }, Data: map[string]string{ StageConfigMapKey: c.CurrentStage.String(), }, } }