~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
79 lines · 2.0 KB Raw History
package revocation

import (
	"errors"
	"fmt"

	"github.com/johnandersen777/socialweb-computer-kcp/api/v1alpha1"
)

type ClusterView struct {
	Name string

	ServiceAccountPresent bool

	Cold bool
}

type Effect struct {
	Cluster  string
	State    v1alpha1.IdentityState
	DeleteSA bool
}

func Plan(clusters []ClusterView) []Effect {
	out := make([]Effect, 0, len(clusters))
	for _, c := range clusters {
		switch {
		case c.Cold:
			out = append(out, Effect{Cluster: c.Name, State: v1alpha1.IdentityColdDeferred})
		case c.ServiceAccountPresent:
			out = append(out, Effect{Cluster: c.Name, State: v1alpha1.IdentityRevocationPending, DeleteSA: true})
		default:
			out = append(out, Effect{Cluster: c.Name, State: v1alpha1.IdentityRevoked})
		}
	}
	return out
}

type ReplyEntry struct {
	Name  string `json:"name"`
	State string `json:"state"`
}

func Reply(effects []Effect) []ReplyEntry {
	account := string(v1alpha1.IdentityRevoked)
	out := make([]ReplyEntry, 0, len(effects)+1)
	for _, e := range effects {
		if e.State != v1alpha1.IdentityRevoked {
			account = string(v1alpha1.IdentityRevocationPending)
		}
		out = append(out, ReplyEntry{Name: e.Cluster, State: string(e.State)})
	}
	return append([]ReplyEntry{{Name: "", State: account}}, out...)
}

type Settled interface{ settled() }

type settled struct{}

func (settled) settled() {}

func WakeSettled(e Effect) (Settled, error) {
	if e.State != v1alpha1.IdentityRevoked {
		return nil, fmt.Errorf(
			"revocation: refusing Ready for cluster %s: its revocation is %s and its ServiceAccount may still exist. "+
				"A COLD cluster is only safe to defer BECAUSE this gate runs before phase=Ready",
			e.Cluster, e.State)
	}
	return settled{}, nil
}

func Ready(s Settled) (v1alpha1.ClusterPhase, error) {
	if s == nil {
		return v1alpha1.ClusterInitializing, errors.New(
			"revocation: refusing Ready: the revocation reconcile did not run for this wake. " +
				"Set status.URL, run the reconcile, then call Ready with the Settled it returns")
	}
	return v1alpha1.ClusterReady, nil
}