Skip to content

Commit

Permalink
Fix so that TF resources can be reconciled and suspended (#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
SvenW authored Oct 15, 2024
1 parent 05a6a54 commit 7c561ea
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 41 deletions.
8 changes: 8 additions & 0 deletions pkg/flux/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"time"

"github.com/bombsimon/logrusr/v4"
tf "github.com/flux-iac/tofu-controller/api/v1alpha2"
helmv2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizationv1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta"
Expand Down Expand Up @@ -99,6 +100,12 @@ func NewReconcileCommand(resource string) *reconcileCommand {
groupVersion: sourcev1beta2.GroupVersion,
kind: sourcev1beta2.HelmChartKind,
}
case tf.TerraformKind:
return &reconcileCommand{
object: terraformAdapter{&tf.Terraform{}},
groupVersion: tf.GroupVersion,
kind: tf.TerraformKind,
}
}

return nil
Expand All @@ -110,6 +117,7 @@ func (r *reconcileCommand) Run(config *rest.Config, namespace, name string) {
sourcev1beta2.AddToScheme(scheme)
kustomizationv1.AddToScheme(scheme)
helmv2beta1.AddToScheme(scheme)
tf.AddToScheme(scheme)

log := logrusr.New(logrus.New())
logf.SetLogger(log)
Expand Down
8 changes: 8 additions & 0 deletions pkg/flux/resume.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"time"

tf "github.com/flux-iac/tofu-controller/api/v1alpha2"
helmv2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizationv1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta"
Expand Down Expand Up @@ -106,6 +107,12 @@ func NewResumeCommand(resource string) *resumeCommand {
groupVersion: sourcev1beta2.GroupVersion,
list: bucketListAdapter{&sourcev1beta2.BucketList{}},
}
case tf.TerraformKind:
return &resumeCommand{
kind: tf.TerraformKind,
groupVersion: tf.GroupVersion,
list: &terraformListAdapter{&tf.TerraformList{}},
}
}

return nil
Expand All @@ -117,6 +124,7 @@ func (r *resumeCommand) Run(config *rest.Config, namespace, name string) {
sourcev1beta2.AddToScheme(scheme)
kustomizationv1.AddToScheme(scheme)
helmv2beta1.AddToScheme(scheme)
tf.AddToScheme(scheme)

kubeClient, err := client.NewWithWatch(config, client.Options{
Scheme: scheme,
Expand Down
9 changes: 9 additions & 0 deletions pkg/flux/suspend.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"context"
"errors"

tf "github.com/flux-iac/tofu-controller/api/v1alpha2"
helmv2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizationv1 "github.com/fluxcd/kustomize-controller/api/v1"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
Expand Down Expand Up @@ -89,6 +90,13 @@ func NewSuspendCommand(resource string) *suspendCommand {
object: bucketAdapter{&sourcev1beta2.Bucket{}},
list: bucketListAdapter{&sourcev1beta2.BucketList{}},
}
case tf.TerraformKind:
return &suspendCommand{
kind: tf.TerraformKind,
groupVersion: tf.GroupVersion,
object: &terraformAdapter{&tf.Terraform{}},
list: &terraformListAdapter{&tf.TerraformList{}},
}
}

return nil
Expand All @@ -100,6 +108,7 @@ func (s *suspendCommand) Run(config *rest.Config, namespace, name string) {
sourcev1beta2.AddToScheme(scheme)
kustomizationv1.AddToScheme(scheme)
helmv2beta1.AddToScheme(scheme)
tf.AddToScheme(scheme)

kubeClient, err := client.NewWithWatch(config, client.Options{
Scheme: scheme,
Expand Down
68 changes: 68 additions & 0 deletions pkg/flux/terraform.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package flux

import (
"fmt"

tf "github.com/flux-iac/tofu-controller/api/v1alpha2"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type terraformAdapter struct {
*tf.Terraform
}

func (h terraformAdapter) asClientObject() client.Object {
return h.Terraform
}

func (h terraformAdapter) deepCopyClientObject() client.Object {
return h.Terraform.DeepCopy()
}

func (obj terraformAdapter) isSuspended() bool {
return obj.Terraform.Spec.Suspend
}

func (obj terraformAdapter) setSuspended() {
obj.Terraform.Spec.Suspend = true
}

func (obj terraformAdapter) setUnsuspended() {
obj.Terraform.Spec.Suspend = false
}

func (obj terraformAdapter) getObservedGeneration() int64 {
return obj.Terraform.Status.ObservedGeneration
}

func (obj terraformAdapter) isStatic() bool {
return false
}

func (obj terraformAdapter) lastHandledReconcileRequest() string {
return obj.Status.LastAttemptedRevision
}

func (obj terraformAdapter) successMessage() string {
return fmt.Sprintf("fetched revision %s", obj.Status.LastAppliedRevision)
}

type terraformListAdapter struct {
*tf.TerraformList
}

func (h terraformListAdapter) asClientList() client.ObjectList {
return h.TerraformList
}

func (h terraformListAdapter) len() int {
return len(h.TerraformList.Items)
}

func (a terraformListAdapter) item(i int) suspendable {
return &terraformAdapter{&a.TerraformList.Items[i]}
}

func (a terraformListAdapter) resumeItem(i int) resumable {
return &terraformAdapter{&a.TerraformList.Items[i]}
}
109 changes: 72 additions & 37 deletions web/src/Footer.jsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,92 @@
import { ArrowDownIcon, ArrowUpIcon } from '@heroicons/react/24/outline';
import React, { memo, useMemo, useState } from 'react';
import { Summary } from './Summary';
import { ExpandedFooter } from "./ExpandedFooter"
import { ArrowDownIcon, ArrowUpIcon } from "@heroicons/react/24/outline";
import React, { memo, useMemo, useState } from "react";
import { Summary } from "./Summary";
import { ExpandedFooter } from "./ExpandedFooter";

const Footer = memo(function Footer(props) {
const { store, capacitorClient, expanded, selected, targetReference, handleToggle, handleNavigationSelect } = props;
const {
store,
capacitorClient,
expanded,
selected,
targetReference,
handleToggle,
handleNavigationSelect,
} = props;

const [fluxState, setFluxState] = useState(store.getState().fluxState);
store.subscribe(() => setFluxState(store.getState().fluxState))
store.subscribe(() => setFluxState(store.getState().fluxState));

const sources = useMemo(() => {
const sources = [];

if (fluxState.ociRepositories) {
sources.push(...fluxState.ociRepositories)
sources.push(...fluxState.gitRepositories)
sources.push(...fluxState.buckets)
sources.push(...fluxState.helmRepositories)
sources.push(...fluxState.helmCharts)
sources.push(...fluxState.ociRepositories);
sources.push(...fluxState.gitRepositories);
sources.push(...fluxState.buckets);
sources.push(...fluxState.helmRepositories);
sources.push(...fluxState.helmCharts);
}
return [...sources].sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));
return [...sources].sort((a, b) =>
a.metadata.name.localeCompare(b.metadata.name),
);
}, [fluxState]);

return (
<div aria-labelledby="slide-over-title" role="dialog" aria-modal="true" className={`fixed inset-x-0 bottom-0 bg-neutral-200 border-t border-neutral-300 ${expanded ? 'h-4/5' : 'h-16'}`}>
<div className={`flex justify-between w-full ${expanded ? '' : 'h-full'}`}>
<div
aria-labelledby="slide-over-title"
role="dialog"
aria-modal="true"
className={`fixed inset-x-0 bottom-0 bg-neutral-200 border-t border-neutral-300 ${expanded ? "h-4/5" : "h-16"}`}
>
<div
className={`flex justify-between w-full ${expanded ? "" : "h-full"}`}
>
<div
className='h-auto w-full cursor-pointer px-16 py-4 flex gap-x-12'
onClick={handleToggle} >
{ !expanded &&
<>
<div>
<Summary resources={sources} label="SOURCES" />
</div>
<div>
<Summary resources={fluxState.kustomizations} label="KUSTOMIZATIONS" />
</div>
<div className="col-span-4">
<Summary resources={fluxState.helmReleases} label="HELM-RELEASES" />
</div>
</>
}
className="h-auto w-full cursor-pointer px-16 py-4 flex gap-x-12"
onClick={handleToggle}
>
{!expanded && (
<>
<div>
<Summary resources={sources} label="SOURCES" />
</div>
<div>
<Summary
resources={fluxState.kustomizations}
label="KUSTOMIZATIONS"
/>
</div>
<div className="col-span-4">
<Summary
resources={fluxState.helmReleases}
label="HELM-RELEASES"
/>
</div>
<div className="col-span-4">
<Summary resources={fluxState.tfResources} label="TERRAFORM" />
</div>
</>
)}
</div>
<div className='px-4 py-2'>
<div className="px-4 py-2">
<button
onClick={handleToggle}
type="button" className="ml-1 rounded-md hover:bg-white hover:text-black text-neutral-700 p-1">
<span className="sr-only">{expanded ? 'Close panel' : 'Open panel'}</span>
{expanded ? <ArrowDownIcon className="h-5 w-5" aria-hidden="true" /> : <ArrowUpIcon className="h-5 w-5" aria-hidden="true" />}
type="button"
className="ml-1 rounded-md hover:bg-white hover:text-black text-neutral-700 p-1"
>
<span className="sr-only">
{expanded ? "Close panel" : "Open panel"}
</span>
{expanded ? (
<ArrowDownIcon className="h-5 w-5" aria-hidden="true" />
) : (
<ArrowUpIcon className="h-5 w-5" aria-hidden="true" />
)}
</button>
</div>
</div>
{expanded &&
{expanded && (
<ExpandedFooter
client={capacitorClient}
handleNavigationSelect={handleNavigationSelect}
Expand All @@ -61,9 +96,9 @@ const Footer = memo(function Footer(props) {
selected={selected}
store={store}
/>
}
)}
</div>
)
})
);
});

export default Footer;
8 changes: 4 additions & 4 deletions web/src/TerraformResource.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState, useRef, useEffect } from "react";
import { ReadyWidget } from "./ReadyWidget";
import { TerraformResourceWidget } from "./TerraformResourceWidget";
import { ErrorBoundary } from "react-error-boundary";
import { fallbackRender } from "./FallbackRender"
import { fallbackRender } from "./FallbackRender";

export function TerraformResource(props) {
const { capacitorClient, item, targetReference, handleNavigationSelect } =
Expand Down Expand Up @@ -66,7 +66,7 @@ export function TerraformResource(props) {
`Are you sure you want to resume ${item.metadata.name}?`,
) &&
capacitorClient.resume(
"helmrelease",
"Terraform",
item.metadata.namespace,
item.metadata.name,
);
Expand All @@ -76,7 +76,7 @@ export function TerraformResource(props) {
`Are you sure you want to suspend ${item.metadata.name}?`,
) &&
capacitorClient.suspend(
"helmrelease",
"Terraform",
item.metadata.namespace,
item.metadata.name,
);
Expand All @@ -89,7 +89,7 @@ export function TerraformResource(props) {
className="bg-transparent hover:bg-neutral-100 font-medium text-sm text-neutral-700 py-1 px-2 border border-neutral-300 rounded"
onClick={() =>
capacitorClient.reconcile(
"helmrelease",
"Terraform",
item.metadata.namespace,
item.metadata.name,
)
Expand Down

0 comments on commit 7c561ea

Please sign in to comment.