Adds an optional reason cli flag to the suspend command that

accepts a reason for why the resource was suspended.

Defines the resource metadata annotation key that stores the reason for
the resource suspension.

Updates the suspend and resume resource patching to add or remove the
annotation holding the suspend reason.

Signed-off-by: Travis Mattera <travis@mattera.io>
This commit is contained in:
Travis Mattera 2023-09-11 19:53:34 -07:00
parent 0d18dc128a
commit 479fc3cd3b
No known key found for this signature in database
GPG key ID: 6E9A8A6A0A74CA52
23 changed files with 66 additions and 14 deletions

View file

@ -49,6 +49,9 @@ func (obj alertAdapter) getObservedGeneration() int64 {
func (obj alertAdapter) setUnsuspended() {
obj.Alert.Spec.Suspend = false
if _, ok := obj.Alert.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.Alert.Annotations, SuspendReasonAnnotation)
}
}
func (obj alertAdapter) successMessage() string {

View file

@ -52,6 +52,9 @@ func (obj helmReleaseAdapter) getObservedGeneration() int64 {
func (obj helmReleaseAdapter) setUnsuspended() {
obj.HelmRelease.Spec.Suspend = false
if _, ok := obj.HelmRelease.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.HelmRelease.Annotations, SuspendReasonAnnotation)
}
}
func (obj helmReleaseAdapter) successMessage() string {

View file

@ -48,6 +48,9 @@ func (obj imageRepositoryAdapter) getObservedGeneration() int64 {
func (obj imageRepositoryAdapter) setUnsuspended() {
obj.ImageRepository.Spec.Suspend = false
if _, ok := obj.ImageRepository.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.ImageRepository.Annotations, SuspendReasonAnnotation)
}
}
func (a imageRepositoryListAdapter) resumeItem(i int) resumable {

View file

@ -44,6 +44,9 @@ func init() {
func (obj imageUpdateAutomationAdapter) setUnsuspended() {
obj.ImageUpdateAutomation.Spec.Suspend = false
if _, ok := obj.ImageUpdateAutomation.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.ImageUpdateAutomation.Annotations, SuspendReasonAnnotation)
}
}
func (obj imageUpdateAutomationAdapter) getObservedGeneration() int64 {

View file

@ -52,6 +52,9 @@ func (obj kustomizationAdapter) getObservedGeneration() int64 {
func (obj kustomizationAdapter) setUnsuspended() {
obj.Kustomization.Spec.Suspend = false
if _, ok := obj.Kustomization.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.Kustomization.Annotations, SuspendReasonAnnotation)
}
}
func (obj kustomizationAdapter) successMessage() string {

View file

@ -49,6 +49,9 @@ func (obj receiverAdapter) getObservedGeneration() int64 {
func (obj receiverAdapter) setUnsuspended() {
obj.Receiver.Spec.Suspend = false
if _, ok := obj.Receiver.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.Receiver.Annotations, SuspendReasonAnnotation)
}
}
func (obj receiverAdapter) successMessage() string {

View file

@ -48,6 +48,9 @@ func (obj bucketAdapter) getObservedGeneration() int64 {
func (obj bucketAdapter) setUnsuspended() {
obj.Bucket.Spec.Suspend = false
if _, ok := obj.Bucket.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.Bucket.Annotations, SuspendReasonAnnotation)
}
}
func (a bucketListAdapter) resumeItem(i int) resumable {

View file

@ -50,6 +50,9 @@ func (obj helmChartAdapter) getObservedGeneration() int64 {
func (obj helmChartAdapter) setUnsuspended() {
obj.HelmChart.Spec.Suspend = false
if _, ok := obj.HelmChart.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.HelmChart.Annotations, SuspendReasonAnnotation)
}
}
func (obj helmChartAdapter) successMessage() string {

View file

@ -48,6 +48,9 @@ func (obj gitRepositoryAdapter) getObservedGeneration() int64 {
func (obj gitRepositoryAdapter) setUnsuspended() {
obj.GitRepository.Spec.Suspend = false
if _, ok := obj.GitRepository.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.GitRepository.Annotations, SuspendReasonAnnotation)
}
}
func (a gitRepositoryListAdapter) resumeItem(i int) resumable {

View file

@ -48,6 +48,9 @@ func (obj helmRepositoryAdapter) getObservedGeneration() int64 {
func (obj helmRepositoryAdapter) setUnsuspended() {
obj.HelmRepository.Spec.Suspend = false
if _, ok := obj.HelmRepository.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.HelmRepository.Annotations, SuspendReasonAnnotation)
}
}
func (a helmRepositoryListAdapter) resumeItem(i int) resumable {

View file

@ -48,6 +48,9 @@ func (obj ociRepositoryAdapter) getObservedGeneration() int64 {
func (obj ociRepositoryAdapter) setUnsuspended() {
obj.OCIRepository.Spec.Suspend = false
if _, ok := obj.OCIRepository.Annotations[SuspendReasonAnnotation]; ok {
delete(obj.OCIRepository.Annotations, SuspendReasonAnnotation)
}
}
func (a ociRepositoryListAdapter) resumeItem(i int) resumable {

View file

@ -34,7 +34,8 @@ var suspendCmd = &cobra.Command{
}
type SuspendFlags struct {
all bool
all bool
reason string
}
var suspendArgs SuspendFlags
@ -42,6 +43,8 @@ var suspendArgs SuspendFlags
func init() {
suspendCmd.PersistentFlags().BoolVarP(&suspendArgs.all, "all", "", false,
"suspend all resources in that namespace")
suspendCmd.PersistentFlags().StringVarP(&suspendArgs.reason, "reason", "r", "suspended",
"set a reason for why the resource is suspended")
rootCmd.AddCommand(suspendCmd)
}
@ -49,7 +52,7 @@ type suspendable interface {
adapter
copyable
isSuspended() bool
setSuspended()
setSuspended(reason string)
}
type suspendCommand struct {
@ -76,6 +79,7 @@ func (suspend suspendCommand) run(cmd *cobra.Command, args []string) error {
return err
}
// in case of all, get all in namespace and patch 'em
if len(args) < 1 && suspendArgs.all {
listOpts := []client.ListOption{
client.InNamespace(*kubeconfigArgs.Namespace),
@ -88,6 +92,7 @@ func (suspend suspendCommand) run(cmd *cobra.Command, args []string) error {
return nil
}
// when not all, patch list of args
processed := make(map[string]struct{}, len(args))
for _, arg := range args {
if _, has := processed[arg]; has {
@ -130,7 +135,7 @@ func (suspend suspendCommand) patch(ctx context.Context, kubeClient client.WithW
obj := suspend.list.item(i)
patch := client.MergeFrom(obj.deepCopyClientObject())
obj.setSuspended()
obj.setSuspended(suspendArgs.reason)
if err := kubeClient.Patch(ctx, obj.asClientObject(), patch); err != nil {
return err
}
@ -140,3 +145,6 @@ func (suspend suspendCommand) patch(ctx context.Context, kubeClient client.WithW
return nil
}
// SuspendReasonAnnotation is the metadata key used to store the reason for resource suspension
const SuspendReasonAnnotation string = "suspend.fluxcd.io/reason"

View file

@ -47,8 +47,9 @@ func (obj alertAdapter) isSuspended() bool {
return obj.Alert.Spec.Suspend
}
func (obj alertAdapter) setSuspended() {
func (obj alertAdapter) setSuspended(reason string) {
obj.Alert.Spec.Suspend = true
obj.Alert.Annotations[SuspendReasonAnnotation] = reason
}
func (a alertListAdapter) item(i int) suspendable {

View file

@ -48,8 +48,9 @@ func (obj helmReleaseAdapter) isSuspended() bool {
return obj.HelmRelease.Spec.Suspend
}
func (obj helmReleaseAdapter) setSuspended() {
func (obj helmReleaseAdapter) setSuspended(reason string) {
obj.HelmRelease.Spec.Suspend = true
obj.HelmRelease.Annotations[SuspendReasonAnnotation] = reason
}
func (a helmReleaseListAdapter) item(i int) suspendable {

View file

@ -47,8 +47,9 @@ func (obj imageRepositoryAdapter) isSuspended() bool {
return obj.ImageRepository.Spec.Suspend
}
func (obj imageRepositoryAdapter) setSuspended() {
func (obj imageRepositoryAdapter) setSuspended(reason string) {
obj.ImageRepository.Spec.Suspend = true
obj.ImageRepository.Annotations[SuspendReasonAnnotation] = reason
}
func (a imageRepositoryListAdapter) item(i int) suspendable {

View file

@ -47,8 +47,9 @@ func (update imageUpdateAutomationAdapter) isSuspended() bool {
return update.ImageUpdateAutomation.Spec.Suspend
}
func (update imageUpdateAutomationAdapter) setSuspended() {
func (update imageUpdateAutomationAdapter) setSuspended(reason string) {
update.ImageUpdateAutomation.Spec.Suspend = true
update.ImageUpdateAutomation.Annotations[SuspendReasonAnnotation] = reason
}
func (a imageUpdateAutomationListAdapter) item(i int) suspendable {

View file

@ -48,8 +48,9 @@ func (obj kustomizationAdapter) isSuspended() bool {
return obj.Kustomization.Spec.Suspend
}
func (obj kustomizationAdapter) setSuspended() {
func (obj kustomizationAdapter) setSuspended(reason string) {
obj.Kustomization.Spec.Suspend = true
obj.Kustomization.Annotations[SuspendReasonAnnotation] = reason
}
func (a kustomizationListAdapter) item(i int) suspendable {

View file

@ -47,8 +47,9 @@ func (obj receiverAdapter) isSuspended() bool {
return obj.Receiver.Spec.Suspend
}
func (obj receiverAdapter) setSuspended() {
func (obj receiverAdapter) setSuspended(reason string) {
obj.Receiver.Spec.Suspend = true
obj.Receiver.Annotations[SuspendReasonAnnotation] = reason
}
func (a receiverListAdapter) item(i int) suspendable {

View file

@ -47,8 +47,9 @@ func (obj bucketAdapter) isSuspended() bool {
return obj.Bucket.Spec.Suspend
}
func (obj bucketAdapter) setSuspended() {
func (obj bucketAdapter) setSuspended(reason string) {
obj.Bucket.Spec.Suspend = true
obj.Bucket.Annotations[SuspendReasonAnnotation] = reason
}
func (a bucketListAdapter) item(i int) suspendable {

View file

@ -47,8 +47,9 @@ func (obj helmChartAdapter) isSuspended() bool {
return obj.HelmChart.Spec.Suspend
}
func (obj helmChartAdapter) setSuspended() {
func (obj helmChartAdapter) setSuspended(reason string) {
obj.HelmChart.Spec.Suspend = true
obj.HelmChart.Annotations[SuspendReasonAnnotation] = reason
}
func (a helmChartListAdapter) item(i int) suspendable {

View file

@ -47,8 +47,9 @@ func (obj gitRepositoryAdapter) isSuspended() bool {
return obj.GitRepository.Spec.Suspend
}
func (obj gitRepositoryAdapter) setSuspended() {
func (obj gitRepositoryAdapter) setSuspended(reason string) {
obj.GitRepository.Spec.Suspend = true
obj.GitRepository.Annotations[SuspendReasonAnnotation] = reason
}
func (a gitRepositoryListAdapter) item(i int) suspendable {

View file

@ -47,8 +47,9 @@ func (obj helmRepositoryAdapter) isSuspended() bool {
return obj.HelmRepository.Spec.Suspend
}
func (obj helmRepositoryAdapter) setSuspended() {
func (obj helmRepositoryAdapter) setSuspended(reason string) {
obj.HelmRepository.Spec.Suspend = true
obj.HelmRepository.Annotations[SuspendReasonAnnotation] = reason
}
func (a helmRepositoryListAdapter) item(i int) suspendable {

View file

@ -47,8 +47,9 @@ func (obj ociRepositoryAdapter) isSuspended() bool {
return obj.OCIRepository.Spec.Suspend
}
func (obj ociRepositoryAdapter) setSuspended() {
func (obj ociRepositoryAdapter) setSuspended(reason string) {
obj.OCIRepository.Spec.Suspend = true
obj.OCIRepository.Annotations[SuspendReasonAnnotation] = reason
}
func (a ociRepositoryListAdapter) item(i int) suspendable {