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.
pull/4231/head
Travis Mattera 2 years ago
parent 9b1e160798
commit cf63aafb16
No known key found for this signature in database
GPG Key ID: 6E9A8A6A0A74CA52

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save