From e8a5dd53b320322236d6c9fd9287dd0cf2993ef0 Mon Sep 17 00:00:00 2001 From: Jason Costello Date: Sat, 4 Jan 2025 19:52:36 +0000 Subject: [PATCH 1/4] Adds Reason column to federation list, integration test coverage for no bundle case --- cmd/cofidectl/cmd/federation/federation.go | 29 ++++++++++++++-------- tests/integration/federation/test.sh | 12 ++++++++- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/cmd/cofidectl/cmd/federation/federation.go b/cmd/cofidectl/cmd/federation/federation.go index 5848c36..89ee9b6 100644 --- a/cmd/cofidectl/cmd/federation/federation.go +++ b/cmd/cofidectl/cmd/federation/federation.go @@ -18,6 +18,14 @@ import ( "github.com/spf13/cobra" ) +const ( + FederationStatus_HEALTHY string = "Healthy" + FederationStatus_UNHEALTHY string = "Unhealthy" + + FederationStatusReason_NO_BUNDLE_FOUND string = "No bundle found" + FederationStatusReason_BUNDLES_DO_NOT_MATCH string = "Bundles do not match" +) + type FederationCommand struct { cmdCtx *cmdcontext.CommandContext } @@ -84,7 +92,7 @@ func (c *FederationCommand) GetListCommand() *cobra.Command { return err } - status, err := checkFederationStatus(cmd.Context(), kubeConfig, from, to) + status, reason, err := checkFederationStatus(cmd.Context(), kubeConfig, from, to) if err != nil { return err } @@ -93,11 +101,12 @@ func (c *FederationCommand) GetListCommand() *cobra.Command { federation.From, federation.To, status, + reason, } } table := tablewriter.NewWriter(os.Stdout) - table.SetHeader([]string{"From Trust Zone", "To Trust Zone", "Status"}) + table.SetHeader([]string{"From Trust Zone", "To Trust Zone", "Status", "Reason"}) table.SetBorder(false) table.AppendBulk(data) table.Render() @@ -115,24 +124,24 @@ type bundles struct { // checkFederationStatus builds a comparison map between two trust domains, retrieves there server CA bundle and any federated bundles available // locally from the SPIRE server, and then compares the bundles on each to verify SPIRE has the correct bundles on each side of the federation -func checkFederationStatus(ctx context.Context, kubeConfig string, from *trust_zone_proto.TrustZone, to *trust_zone_proto.TrustZone) (string, error) { +func checkFederationStatus(ctx context.Context, kubeConfig string, from *trust_zone_proto.TrustZone, to *trust_zone_proto.TrustZone) (string, string, error) { compare := make(map[*trust_zone_proto.TrustZone]bundles) for _, tz := range []*trust_zone_proto.TrustZone{from, to} { if deployed, err := isTrustZoneDeployed(ctx, tz); err != nil { - return "", err + return "", "", err } else if !deployed { - return "Inactive", nil + return "Inactive", "", nil } client, err := kubeutil.NewKubeClientFromSpecifiedContext(kubeConfig, tz.GetKubernetesContext()) if err != nil { - return "", err + return "", "", err } serverCABundle, federatedBundles, err := spire.GetServerCABundleAndFederatedBundles(ctx, client) if err != nil { - return "", err + return "", "", err } compare[tz] = bundles{ @@ -144,15 +153,15 @@ func checkFederationStatus(ctx context.Context, kubeConfig string, from *trust_z // Bundle does not exist at all on opposite trust domain _, ok := compare[from].federatedBundles[to.TrustDomain] if !ok { - return "Unhealthy", nil + return FederationStatus_UNHEALTHY, FederationStatusReason_NO_BUNDLE_FOUND, nil } // Bundle does not match entry on opposite trust domain if compare[from].federatedBundles[to.TrustDomain] != compare[to].serverCABundle { - return "Unhealthy", nil + return FederationStatus_UNHEALTHY, FederationStatusReason_BUNDLES_DO_NOT_MATCH, nil } - return "Healthy", nil + return FederationStatus_HEALTHY, "", nil } // isTrustZoneDeployed returns whether a trust zone has been deployed, i.e. whether a SPIRE Helm release has been installed. diff --git a/tests/integration/federation/test.sh b/tests/integration/federation/test.sh index c37ae53..e620d94 100755 --- a/tests/integration/federation/test.sh +++ b/tests/integration/federation/test.sh @@ -127,7 +127,16 @@ function show_workload_status() { fi echo "cofidectl workload status successful" - exit 0 +} + +function teardown_federation_and_verify() { + kubectl exec --context $K8S_CLUSTER_2_CONTEXT -n spire spire-server-0 -- /opt/spire/bin/spire-server federation delete -id td1 + kubectl --context $K8S_CLUSTER_2_CONTEXT delete clusterspiffeids.spire.spiffe.io spire-spire-namespace + kubectl exec --context $K8S_CLUSTER_2_CONTEXT -n spire spire-server-0 -- /opt/spire/bin/spire-server bundle delete -id td1 + federations=$(./cofidectl federation list) + if ! echo "$federations" | grep "Unhealthy | No bundle found" >/dev/null; then + return 1 + fi } function down() { @@ -145,6 +154,7 @@ function main() { run_tests post_deploy show_workload_status + teardown_federation_and_verify down echo "Success!" } From 069c8030be7acaadaab2ee5fbd32c4662211fd6c Mon Sep 17 00:00:00 2001 From: Jason Costello Date: Mon, 6 Jan 2025 09:27:15 +0000 Subject: [PATCH 2/4] [From review] Adjust consts --- cmd/cofidectl/cmd/federation/federation.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/cofidectl/cmd/federation/federation.go b/cmd/cofidectl/cmd/federation/federation.go index 89ee9b6..5da0152 100644 --- a/cmd/cofidectl/cmd/federation/federation.go +++ b/cmd/cofidectl/cmd/federation/federation.go @@ -19,11 +19,11 @@ import ( ) const ( - FederationStatus_HEALTHY string = "Healthy" - FederationStatus_UNHEALTHY string = "Unhealthy" + FederationStatusHealthy string = "Healthy" + FederationStatusUnhealthy string = "Unhealthy" - FederationStatusReason_NO_BUNDLE_FOUND string = "No bundle found" - FederationStatusReason_BUNDLES_DO_NOT_MATCH string = "Bundles do not match" + FederationStatusReasonNoBundleFound string = "No bundle found" + FederationStatusReasonBundlesDoNotMatch string = "Bundles do not match" ) type FederationCommand struct { @@ -153,15 +153,15 @@ func checkFederationStatus(ctx context.Context, kubeConfig string, from *trust_z // Bundle does not exist at all on opposite trust domain _, ok := compare[from].federatedBundles[to.TrustDomain] if !ok { - return FederationStatus_UNHEALTHY, FederationStatusReason_NO_BUNDLE_FOUND, nil + return FederationStatusUnhealthy, FederationStatusReasonNoBundleFound, nil } // Bundle does not match entry on opposite trust domain if compare[from].federatedBundles[to.TrustDomain] != compare[to].serverCABundle { - return FederationStatus_UNHEALTHY, FederationStatusReason_BUNDLES_DO_NOT_MATCH, nil + return FederationStatusUnhealthy, FederationStatusReasonBundlesDoNotMatch, nil } - return FederationStatus_HEALTHY, "", nil + return FederationStatusHealthy, "", nil } // isTrustZoneDeployed returns whether a trust zone has been deployed, i.e. whether a SPIRE Helm release has been installed. From f2664f8bd610be16555294a2326f8b855ece1d9b Mon Sep 17 00:00:00 2001 From: Jason Costello Date: Tue, 7 Jan 2025 12:01:19 +0000 Subject: [PATCH 3/4] [From review] Remove early exit 0 from int. test --- tests/integration/single-trust-zone/test.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/single-trust-zone/test.sh b/tests/integration/single-trust-zone/test.sh index 4a501ab..8de910a 100755 --- a/tests/integration/single-trust-zone/test.sh +++ b/tests/integration/single-trust-zone/test.sh @@ -95,7 +95,6 @@ function show_workload_status() { fi echo "cofidectl workload status successful" - exit 0 } function down() { From f1f3cdcc885e523697d252bda89634fe81a8a7d9 Mon Sep 17 00:00:00 2001 From: Jason Costello Date: Tue, 7 Jan 2025 12:18:55 +0000 Subject: [PATCH 4/4] Change ordering of teardown to mitigate race condition --- tests/integration/federation/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/federation/test.sh b/tests/integration/federation/test.sh index e620d94..0158740 100755 --- a/tests/integration/federation/test.sh +++ b/tests/integration/federation/test.sh @@ -130,8 +130,8 @@ function show_workload_status() { } function teardown_federation_and_verify() { - kubectl exec --context $K8S_CLUSTER_2_CONTEXT -n spire spire-server-0 -- /opt/spire/bin/spire-server federation delete -id td1 kubectl --context $K8S_CLUSTER_2_CONTEXT delete clusterspiffeids.spire.spiffe.io spire-spire-namespace + kubectl exec --context $K8S_CLUSTER_2_CONTEXT -n spire spire-server-0 -- /opt/spire/bin/spire-server federation delete -id td1 kubectl exec --context $K8S_CLUSTER_2_CONTEXT -n spire spire-server-0 -- /opt/spire/bin/spire-server bundle delete -id td1 federations=$(./cofidectl federation list) if ! echo "$federations" | grep "Unhealthy | No bundle found" >/dev/null; then