Repository: skupperproject/skupper
Pull request #1571 (2024-08-06 19:56:33)

fix validator unit test
Fix parameters allowed in CLI connector workload flag option.


Patch:
diff --git a/api/types/crds/skupper_link_crd.yaml b/api/types/crds/skupper_link_crd.yaml
index 5a6f30c2..952c07d2 100644
--- a/api/types/crds/skupper_link_crd.yaml
+++ b/api/types/crds/skupper_link_crd.yaml
@@ -41,6 +41,10 @@ spec:
               properties:
                 status:
                   type: string
+                remoteSiteId:
+                  type: string
+                remoteSiteName:
+                  type: string
                 conditions:
                   type: array
                   items:
@@ -84,6 +88,10 @@ spec:
         type: string
         description: The status of the link
         jsonPath: .status.status
+      - name: Remote Site
+        type: string
+        description: The name of the site linked to
+        jsonPath: .status.remoteSiteName
   scope: Namespaced
   names:
     plural: links
diff --git a/api/types/crds/skupper_site_crd.yaml b/api/types/crds/skupper_site_crd.yaml
index e5c38d04..326e11ff 100644
--- a/api/types/crds/skupper_site_crd.yaml
+++ b/api/types/crds/skupper_site_crd.yaml
@@ -113,6 +113,10 @@ spec:
                               type: string
                             remoteSiteId:
                               type: string
+                            remoteSiteName:
+                              type: string
+                            operational:
+                              type: boolean
                       services:
                         type: array
                         items:
diff --git a/cmd/controller/controller.go b/cmd/controller/controller.go
index e5ec8be6..59c66c11 100644
--- a/cmd/controller/controller.go
+++ b/cmd/controller/controller.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"io"
 	"log"
+	"strings"
 
 	corev1 "k8s.io/api/core/v1"
 	networkingv1 "k8s.io/api/networking/v1beta1"
@@ -350,7 +351,9 @@ func (c *Controller) networkStatusUpdate(key string, cm *corev1.ConfigMap) error
 func extractSiteRecords(status network.NetworkStatusInfo) []skupperv1alpha1.SiteRecord {
 	var records []skupperv1alpha1.SiteRecord
 	routerAPs := map[string]string{} // router access point ID -> site ID
+	siteNames := map[string]string{} // site ID -> site name
 	for _, site := range status.SiteStatus {
+		siteNames[site.Site.Identity] = site.Site.Name
 		for _, router := range site.RouterStatus {
 			for _, ap := range router.AccessPoints {
 				routerAPs[ap.Identity] = site.Site.Identity
@@ -368,14 +371,16 @@ func extractSiteRecords(status network.NetworkStatusInfo) []skupperv1alpha1.Site
 		services := map[string]*skupperv1alpha1.ServiceRecord{}
 		for _, router := range site.RouterStatus {
 			for _, link := range router.Links {
-				if link.Name == "" || link.Peer == "" || link.Status != "up" {
+				if link.Name == "" || link.Peer == "" {
 					continue
 				}
 
 				if site, ok := routerAPs[link.Peer]; ok {
 					record.Links = append(record.Links, skupperv1alpha1.LinkRecord{
-						Name:         link.Name,
-						RemoteSiteId: site,
+						Name:           link.Name,
+						RemoteSiteId:   site,
+						RemoteSiteName: siteNames[site],
+						Operational:    strings.EqualFold(link.Status, "up"),
 					})
 				}
 			}
diff --git a/cmd/controller/deploy_cluster_scope.yaml b/cmd/controller/deploy_cluster_scope.yaml
index 85f849c6..3e9551da 100644
--- a/cmd/controller/deploy_cluster_scope.yaml
+++ b/cmd/controller/deploy_cluster_scope.yaml
@@ -182,7 +182,7 @@ spec:
           type: RuntimeDefault
       containers:
       - name: controller
-        image: quay.io/gordons/controller:v2-attached-connector
+        image: quay.io/gordons/controller:v2-link-status
         imagePullPolicy: Always
         env:
         - name: SKUPPER_ENABLE_GRANTS
diff --git a/internal/cmd/skupper/site/kube/site_create.go b/internal/cmd/skupper/site/kube/site_create.go
index 3cfa6e2d..24fa721b 100644
--- a/internal/cmd/skupper/site/kube/site_create.go
+++ b/internal/cmd/skupper/site/kube/site_create.go
@@ -210,7 +210,7 @@ func (cmd *CmdSiteCreate) WaitUntil() error {
 			return err
 		}
 
-		if resource != nil && resource.Status.StatusMessage == "OK" {
+		if resource != nil && resource.IsConfigured() {
 			return nil
 		}
 
@@ -218,10 +218,10 @@ func (cmd *CmdSiteCreate) WaitUntil() error {
 	})
 
 	if err != nil {
-		return fmt.Errorf("Site %q not ready yet, check the logs for more information\n", cmd.siteName)
+		return fmt.Errorf("Site %q not configured yet, check the logs for more information\n", cmd.siteName)
 	}
 
-	fmt.Printf("Site %q is ready\n", cmd.siteName)
+	fmt.Printf("Site %q is configured. Check the status to see when it is ready\n", cmd.siteName)
 
 	return nil
 }
diff --git a/internal/cmd/skupper/site/kube/site_update.go b/internal/cmd/skupper/site/kube/site_update.go
index 58a6a956..1bf99fe0 100644
--- a/internal/cmd/skupper/site/kube/site_update.go
+++ b/internal/cmd/skupper/site/kube/site_update.go
@@ -236,7 +236,7 @@ func (cmd *CmdSiteUpdate) WaitUntil() error {
 			return err
 		}
 
-		if resource != nil && resource.Status.StatusMessage == "OK" {
+		if resource != nil && resource.IsConfigured() {
 			return nil
 		}
 
diff --git a/internal/cmd/skupper/utils/status.go b/internal/cmd/skupper/utils/status.go
index bf57cbef..1029bd50 100644
--- a/internal/cmd/skupper/utils/status.go
+++ b/internal/cmd/skupper/utils/status.go
@@ -6,7 +6,7 @@ import (
 
 func SiteConfigured(siteList *v1alpha1.SiteList) bool {
 	for _, s := range siteList.Items {
-		if s.IsActive() {
+		if s.IsConfigured() {
 			return true
 		}
 	}
diff --git a/pkg/apis/skupper/v1alpha1/types.go b/pkg/apis/skupper/v1alpha1/types.go
index 5f235fa2..55cf964c 100644
--- a/pkg/apis/skupper/v1alpha1/types.go
+++ b/pkg/apis/skupper/v1alpha1/types.go
@@ -203,7 +203,7 @@ func (s *Site) isReady() bool {
 		meta.IsStatusConditionTrue(s.Status.Conditions, CONDITION_TYPE_RUNNING)
 }
 
-func (s *Site) IsActive() bool {
+func (s *Site) IsConfigured() bool {
 	return meta.IsStatusConditionTrue(s.Status.Conditions, CONDITION_TYPE_CONFIGURED)
 }
 
@@ -219,6 +219,7 @@ const CONDITION_TYPE_RUNNING = "Running"
 const CONDITION_TYPE_MATCHED = "Matched"
 const CONDITION_TYPE_PROCESSED = "Processed"
 const CONDITION_TYPE_REDEEMED = "Redeemed"
+const CONDITION_TYPE_OPERATIONAL = "Operational"
 const CONDITION_TYPE_READY = "Ready"
 
 type SiteStatus struct {
@@ -261,8 +262,10 @@ type ServiceRecord struct {
 }
 
 type LinkRecord struct {
-	Name         string `json:"name"`
-	RemoteSiteId string `json:"remoteSiteId"`
+	Name           string `json:"name"`
+	RemoteSiteId   string `json:"remoteSiteId"`
+	RemoteSiteName string `json:"remoteSiteName"`
+	Operational    bool   `json:"operational"`
 }
 
 // +genclient
@@ -462,8 +465,8 @@ type ConnectorStatus struct {
 type Link struct {
 	v1.TypeMeta   `json:",inline"`
 	v1.ObjectMeta `json:"metadata,omitempty"`
-	Spec          LinkSpec `json:"spec,omitempty"`
-	Status        Status   `json:"status,omitempty"`
+	Spec          LinkSpec   `json:"spec,omitempty"`
+	Status        LinkStatus `json:"status,omitempty"`
 }
 
 func (l *Link) SetConfigured(err error) bool {
@@ -474,6 +477,27 @@ func (l *Link) SetConfigured(err error) bool {
 	return false
 }
 
+func (l *Link) SetOperational(operational bool, remoteSiteId string, remoteSiteName string) bool {
+	var err error
+	if !operational {
+		err = fmt.Errorf("Not operational")
+	}
+	changed := false
+	if l.Status.RemoteSiteId != remoteSiteId {
+		l.Status.RemoteSiteId = remoteSiteId
+		changed = true
+	}
+	if l.Status.RemoteSiteName != remoteSiteName {
+		l.Status.RemoteSiteName = remoteSiteName
+		changed = true
+	}
+	if l.Status.SetCondition(CONDITION_TYPE_OPERATIONAL, err, l.ObjectMeta.Generation) {
+		l.setReady(err)
+		return true
+	}
+	return changed
+}
+
 func (l *Link) setReady(err error) bool {
 	if err != nil {
 		l.Status.StatusMessage = err.Error()
@@ -486,7 +510,8 @@ func (l *Link) setReady(err error) bool {
 }
 
 func (l *Link) isReady() bool {
-	return meta.IsStatusConditionTrue(l.Status.Conditions, CONDITION_TYPE_CONFIGURED)
+	return meta.IsStatusConditionTrue(l.Status.Conditions, CONDITION_TYPE_CONFIGURED) &&
+		meta.IsStatusConditionTrue(l.Status.Conditions, CONDITION_TYPE_OPERATIONAL)
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -514,6 +539,12 @@ func (s *LinkSpec) GetEndpointForRole(name string) (Endpoint, bool) {
 	return Endpoint{}, false
 }
 
+type LinkStatus struct {
+	Status         `json:",inline"`
+	RemoteSiteId   string `json:"remoteSiteId,omitempty"`
+	RemoteSiteName string `json:"remoteSiteName,omitempty"`
+}
+
 // +genclient
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 
diff --git a/pkg/apis/skupper/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/skupper/v1alpha1/zz_generated.deepcopy.go
index 35b520a1..30f0b1d5 100644
--- a/pkg/apis/skupper/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/skupper/v1alpha1/zz_generated.deepcopy.go
@@ -197,6 +197,23 @@ func (in *AccessTokenSpec) DeepCopy() *AccessTokenSpec {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AccessTokenStatus) DeepCopyInto(out *AccessTokenStatus) {
+	*out = *in
+	in.Status.DeepCopyInto(&out.Status)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessTokenStatus.
+func (in *AccessTokenStatus) DeepCopy() *AccessTokenStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(AccessTokenStatus)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *AttachedConnector) DeepCopyInto(out *AttachedConnector) {
 	*out = *in
@@ -702,6 +719,23 @@ func (in *LinkSpec) DeepCopy() *LinkSpec {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *LinkStatus) DeepCopyInto(out *LinkStatus) {
+	*out = *in
+	in.Status.DeepCopyInto(&out.Status)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LinkStatus.
+func (in *LinkStatus) DeepCopy() *LinkStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(LinkStatus)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Listener) DeepCopyInto(out *Listener) {
 	*out = *in
diff --git a/pkg/kube/site/attached_connector.go b/pkg/kube/site/attached_connector.go
index c7b37620..b8185f0c 100644
--- a/pkg/kube/site/attached_connector.go
+++ b/pkg/kube/site/attached_connector.go
@@ -179,7 +179,7 @@ func (a *AttachedConnector) Id() string {
 
 func error_(errors []string) error {
 	if len(errors) > 0 {
-		return fmt.Errorf("Error(s) encountered: %", strings.Join(errors, ", "))
+		return fmt.Errorf("Error(s) encountered: %s", strings.Join(errors, ", "))
 	}
 	return nil
 }
diff --git a/pkg/kube/site/site.go b/pkg/kube/site/site.go
index 93f8ca50..43f3daa6 100644
--- a/pkg/kube/site/site.go
+++ b/pkg/kube/site/site.go
@@ -683,8 +683,7 @@ func (s *Site) link(linkconfig *skupperv1alpha1.Link) error {
 		if config != nil {
 			log.Printf("Connecting site in %s using token %s", s.namespace, linkconfig.ObjectMeta.Name)
 			err := s.updateRouterConfigForGroups(config)
-			config.UpdateStatus(linkconfig)
-			return s.updateLinkStatus(linkconfig, err)
+			return s.updateLinkConfiguredCondition(linkconfig, err)
 		} else {
 			log.Printf("No update to router config required for link %s in %s", linkconfig.ObjectMeta.Name, linkconfig.ObjectMeta.Namespace)
 		}
@@ -705,17 +704,22 @@ func (s *Site) unlink(name string) error {
 	return nil
 }
 
-func (s *Site) updateLinkStatus(link *skupperv1alpha1.Link, err error) error {
+func (s *Site) updateLinkConfiguredCondition(link *skupperv1alpha1.Link, err error) error {
 	if link == nil {
 		return nil
 	}
 	if link.SetConfigured(err) {
-		updated, updateErr := s.controller.GetSkupperClient().SkupperV1alpha1().Links(link.ObjectMeta.Namespace).UpdateStatus(context.TODO(), link, metav1.UpdateOptions{})
-		if updateErr != nil {
-			return updateErr
-		}
-		s.links[link.ObjectMeta.Name].Update(updated)
+		return s.updateLinkStatus(link)
+	}
+	return nil
+}
+
+func (s *Site) updateLinkStatus(link *skupperv1alpha1.Link) error {
+	updated, err := s.controller.GetSkupperClient().SkupperV1alpha1().Links(link.ObjectMeta.Namespace).UpdateStatus(context.TODO(), link, metav1.UpdateOptions{})
+	if err != nil {
+		return err
 	}
+	s.links[link.ObjectMeta.Name].Update(updated)
 	return nil
 }
 
@@ -770,6 +774,22 @@ func (s *Site) updateSiteStatus() error {
 	return nil
 }
 
+func (s *Site) updateLinkOperationalCondition(link *skupperv1alpha1.Link, operational bool, remoteSiteId string, remoteSiteName string) error {
+	if link.SetOperational(operational, remoteSiteId, remoteSiteName) {
+		return s.updateLinkStatus(link)
+	}
+	return nil
+}
+
+func getLinkRecordsForSite(siteId string, network []skupperv1alpha1.SiteRecord) []skupperv1alpha1.LinkRecord {
+	for _, siteRecord := range network {
+		if siteRecord.Id == siteId {
+			return siteRecord.Links
+		}
+	}
+	return nil
+}
+
 func (s *Site) NetworkStatusUpdated(network []skupperv1alpha1.SiteRecord) error {
 	if s.site == nil || reflect.DeepEqual(s.site.Status.Network, network) {
 		return nil
@@ -782,6 +802,16 @@ func (s *Site) NetworkStatusUpdated(network []skupperv1alpha1.SiteRecord) error
 	}
 	s.site = updated
 
+	// find the site record for this site, then process the link records it contains
+	linkRecords := getLinkRecordsForSite(s.site.GetSiteId(), network)
+	for _, linkRecord := range linkRecords {
+		if link, ok := s.links[linkRecord.Name]; ok {
+			if err := s.updateLinkOperationalCondition(link.Definition(), linkRecord.Operational, linkRecord.RemoteSiteId, linkRecord.RemoteSiteName); err != nil {
+				log.Printf("Error updating operational status of link %s/%s: %s", s.site.Namespace, linkRecord.Name, err)
+			}
+		}
+	}
+
 	bindingStatus := newBindingStatus(s.controller, network)
 	s.bindings.Map(bindingStatus.updateMatchingListenerCount, bindingStatus.updateMatchingConnectorCount)
 	log.Printf("Updating matching listeners for attached connectors")
diff --git a/pkg/kube/tokens/tokens.go b/pkg/kube/tokens/tokens.go
index 095b8135..6a2cdffc 100644
--- a/pkg/kube/tokens/tokens.go
+++ b/pkg/kube/tokens/tokens.go
@@ -75,7 +75,7 @@ func getActiveSite(namespace string, clients internalclient.Clients) (*skupperv1
 		return nil, err
 	}
 	for _, site := range sites.Items {
-		if site.IsActive() {
+		if site.IsConfigured() {
 			return &site, nil
 		}
 	}
diff --git a/pkg/site/link.go b/pkg/site/link.go
index 9fd0efaf..f6b5e8f0 100644
--- a/pkg/site/link.go
+++ b/pkg/site/link.go
@@ -69,14 +69,13 @@ func (m LinkMap) Apply(current *qdr.RouterConfig) bool {
 }
 
 func (link *Link) Update(definition *skupperv1alpha1.Link) bool {
-	if reflect.DeepEqual(link.definition, definition) {
-		return false
-	}
+	changed := !reflect.DeepEqual(link.definition, definition)
 	link.definition = definition
-	return true
+	return changed
 }
 
-func (config *Link) UpdateStatus(lc *skupperv1alpha1.Link) {
+func (link *Link) Definition() *skupperv1alpha1.Link {
+	return link.definition
 }
 
 type RemoveConnector struct {


Test patch:
diff --git a/internal/cmd/skupper/connector/kube/connector_create_test.go b/internal/cmd/skupper/connector/kube/connector_create_test.go
index 279573a7..47004b74 100644
--- a/internal/cmd/skupper/connector/kube/connector_create_test.go
+++ b/internal/cmd/skupper/connector/kube/connector_create_test.go
@@ -834,7 +834,7 @@ func TestCmdConnectorCreate_Run(t *testing.T) {
 	}
 }
 
-func TestCmdConnectorCreate_WaitUntilReady(t *testing.T) {
+func TestCmdConnectorCreate_WaitUntily(t *testing.T) {
 	type test struct {
 		name                string
 		output              string
diff --git a/internal/cmd/skupper/connector/kube/connector_delete_test.go b/internal/cmd/skupper/connector/kube/connector_delete_test.go
index 412347f0..5711d823 100644
--- a/internal/cmd/skupper/connector/kube/connector_delete_test.go
+++ b/internal/cmd/skupper/connector/kube/connector_delete_test.go
@@ -184,7 +184,7 @@ func TestCmdConnectorDelete_Run(t *testing.T) {
 	}
 }
 
-func TestCmdConnectorDelete_WaitUntilReady(t *testing.T) {
+func TestCmdConnectorDelete_WaitUntil(t *testing.T) {
 	type test struct {
 		name                string
 		k8sObjects          []runtime.Object
diff --git a/internal/cmd/skupper/connector/kube/connector_update_test.go b/internal/cmd/skupper/connector/kube/connector_update_test.go
index 93e76d7c..2e930d2f 100644
--- a/internal/cmd/skupper/connector/kube/connector_update_test.go
+++ b/internal/cmd/skupper/connector/kube/connector_update_test.go
@@ -498,7 +498,7 @@ func TestCmdConnectorUpdate_Run(t *testing.T) {
 	}
 }
 
-func TestCmdConnectorUpdate_WaitUntilReady(t *testing.T) {
+func TestCmdConnectorUpdate_WaitUntil(t *testing.T) {
 	type test struct {
 		name                string
 		output              string
diff --git a/internal/cmd/skupper/listener/kube/listener_create_test.go b/internal/cmd/skupper/listener/kube/listener_create_test.go
index fbe5deb0..6e611a82 100644
--- a/internal/cmd/skupper/listener/kube/listener_create_test.go
+++ b/internal/cmd/skupper/listener/kube/listener_create_test.go
@@ -702,7 +702,7 @@ func TestCmdListenerCreate_Run(t *testing.T) {
 	}
 }
 
-func TestCmdListenerCreate_WaitUntilReady(t *testing.T) {
+func TestCmdListenerCreate_WaitUntil(t *testing.T) {
 	type test struct {
 		name                string
 		output              string
diff --git a/internal/cmd/skupper/listener/kube/listener_delete_test.go b/internal/cmd/skupper/listener/kube/listener_delete_test.go
index d0602155..8450b731 100644
--- a/internal/cmd/skupper/listener/kube/listener_delete_test.go
+++ b/internal/cmd/skupper/listener/kube/listener_delete_test.go
@@ -207,7 +207,7 @@ func TestCmdListenerDelete_Run(t *testing.T) {
 	}
 }
 
-func TestCmdListenerDelete_WaitUntilReady(t *testing.T) {
+func TestCmdListenerDelete_WaitUntil(t *testing.T) {
 	type test struct {
 		name                string
 		k8sObjects          []runtime.Object
diff --git a/internal/cmd/skupper/listener/kube/listener_update_test.go b/internal/cmd/skupper/listener/kube/listener_update_test.go
index ee38937a..7f0509fc 100644
--- a/internal/cmd/skupper/listener/kube/listener_update_test.go
+++ b/internal/cmd/skupper/listener/kube/listener_update_test.go
@@ -429,7 +429,7 @@ func TestCmdListenerUpdate_Run(t *testing.T) {
 	}
 }
 
-func TestCmdListenerUpdate_WaitUntilReady(t *testing.T) {
+func TestCmdListenerUpdate_WaitUntil(t *testing.T) {
 	type test struct {
 		name                string
 		output              string
diff --git a/internal/cmd/skupper/site/kube/site_create_test.go b/internal/cmd/skupper/site/kube/site_create_test.go
index 8fa10f5f..9064b591 100644
--- a/internal/cmd/skupper/site/kube/site_create_test.go
+++ b/internal/cmd/skupper/site/kube/site_create_test.go
@@ -2,7 +2,6 @@ package kube
 
 import (
 	"fmt"
-
 	"github.com/skupperproject/skupper/internal/cmd/skupper/utils"
 
 	"testing"
@@ -336,14 +335,14 @@ func TestCmdSiteCreate_Run(t *testing.T) {
 		})
 	}
 }
-func TestCmdSiteCreate_WaitUntilReady(t *testing.T) {
+func TestCmdSiteCreate_WaitUntil(t *testing.T) {
 	type test struct {
 		name           string
 		k8sObjects     []runtime.Object
 		skupperObjects []runtime.Object
 		skupperError   string
-		setUpMock      func(command *CmdSiteCreate)
 		expectError    bool
+		output         string
 	}
 
 	testTable := []test{
@@ -387,6 +386,7 @@ func TestCmdSiteCreate_WaitUntilReady(t *testing.T) {
 					},
 				},
 			},
+			output:       "yaml",
 			skupperError: "",
 			expectError:  false,
 		},
@@ -401,7 +401,15 @@ func TestCmdSiteCreate_WaitUntilReady(t *testing.T) {
 					},
 					Status: v1alpha1.SiteStatus{
 						Status: v1alpha1.Status{
-							StatusMessage: "OK",
+							Conditions: []v1.Condition{
+								{
+									Message:            "OK",
+									ObservedGeneration: 1,
+									Reason:             "OK",
+									Status:             "True",
+									Type:               "Configured",
+								},
+							},
 						},
 					},
 				},
@@ -420,6 +428,7 @@ func TestCmdSiteCreate_WaitUntilReady(t *testing.T) {
 		assert.Assert(t, err)
 		command.Client = fakeSkupperClient.GetSkupperClient().SkupperV1alpha1()
 		command.siteName = "my-site"
+		command.output = test.output
 
 		t.Run(test.name, func(t *testing.T) {
 
@@ -428,7 +437,7 @@ func TestCmdSiteCreate_WaitUntilReady(t *testing.T) {
 			if test.expectError {
 				assert.Check(t, err != nil)
 			} else {
-				assert.Check(t, err == nil)
+				assert.Check(t, err == nil, err)
 			}
 
 		})
diff --git a/internal/cmd/skupper/site/kube/site_delete_test.go b/internal/cmd/skupper/site/kube/site_delete_test.go
index 6a9d0576..909e7038 100644
--- a/internal/cmd/skupper/site/kube/site_delete_test.go
+++ b/internal/cmd/skupper/site/kube/site_delete_test.go
@@ -258,6 +258,15 @@ func TestCmdSiteDelete_Run(t *testing.T) {
 					Status: v1alpha1.SiteStatus{
 						Status: v1alpha1.Status{
 							StatusMessage: "OK",
+							Conditions: []v1.Condition{
+								{
+									Message:            "OK",
+									ObservedGeneration: 1,
+									Reason:             "OK",
+									Status:             "True",
+									Type:               "Configured",
+								},
+							},
 						},
 					},
 				},
@@ -298,7 +307,7 @@ func TestCmdSiteDelete_Run(t *testing.T) {
 	}
 }
 
-func TestCmdSiteDelete_WaitUntilReady(t *testing.T) {
+func TestCmdSiteDelete_WaitUntil(t *testing.T) {
 	type test struct {
 		name           string
 		k8sObjects     []runtime.Object
@@ -320,6 +329,15 @@ func TestCmdSiteDelete_WaitUntilReady(t *testing.T) {
 					Status: v1alpha1.SiteStatus{
 						Status: v1alpha1.Status{
 							StatusMessage: "OK",
+							Conditions: []v1.Condition{
+								{
+									Message:            "OK",
+									ObservedGeneration: 1,
+									Reason:             "OK",
+									Status:             "True",
+									Type:               "Configured",
+								},
+							},
 						},
 					},
 				},
diff --git a/internal/cmd/skupper/site/kube/site_status_test.go b/internal/cmd/skupper/site/kube/site_status_test.go
index e1b6eeaf..86470eaf 100644
--- a/internal/cmd/skupper/site/kube/site_status_test.go
+++ b/internal/cmd/skupper/site/kube/site_status_test.go
@@ -135,7 +135,7 @@ func TestCmdSiteStatus_Run(t *testing.T) {
 	}
 }
 
-func TestCmdSiteStatus_WaitUntilReady(t *testing.T) {
+func TestCmdSiteStatus_WaitUntil(t *testing.T) {
 
 	t.Run("", func(t *testing.T) {
 
diff --git a/internal/cmd/skupper/site/kube/site_update_test.go b/internal/cmd/skupper/site/kube/site_update_test.go
index 339b72ef..68ba1dd3 100644
--- a/internal/cmd/skupper/site/kube/site_update_test.go
+++ b/internal/cmd/skupper/site/kube/site_update_test.go
@@ -560,7 +560,7 @@ func TestCmdSiteUpdate_Run(t *testing.T) {
 	}
 }
 
-func TestCmdSiteUpdate_WaitUntilReady(t *testing.T) {
+func TestCmdSiteUpdate_WaitUntil(t *testing.T) {
 	type test struct {
 		name           string
 		k8sObjects     []runtime.Object
diff --git a/internal/cmd/skupper/token/kube/token_issue_test.go b/internal/cmd/skupper/token/kube/token_issue_test.go
index 2d094d9b..f69b69b0 100644
--- a/internal/cmd/skupper/token/kube/token_issue_test.go
+++ b/internal/cmd/skupper/token/kube/token_issue_test.go
@@ -652,7 +652,7 @@ func TestCmdTokenIssue_Run(t *testing.T) {
 	}
 }
 
-func TestCmdTokenIssue_WaitUntilReady(t *testing.T) {
+func TestCmdTokenIssue_WaitUntil(t *testing.T) {
 	type test struct {
 		name                string
 		k8sObjects          []runtime.Object
diff --git a/internal/cmd/skupper/token/kube/token_redeem_test.go b/internal/cmd/skupper/token/kube/token_redeem_test.go
index d6d9fc49..1f1d9e31 100644
--- a/internal/cmd/skupper/token/kube/token_redeem_test.go
+++ b/internal/cmd/skupper/token/kube/token_redeem_test.go
@@ -366,7 +366,7 @@ func TestCmdTokenRedeem_Run(t *testing.T) {
 	}
 }
 
-func TestCmdTokenRedeem_WaitUntilReady(t *testing.T) {
+func TestCmdTokenRedeem_WaitUntil(t *testing.T) {
 	type test struct {
 		name                string
 		k8sObjects          []runtime.Object
diff --git a/internal/cmd/skupper/utils/encode_test.go b/internal/cmd/skupper/utils/encode_test.go
index 49a6415d..0d6291a3 100644
--- a/internal/cmd/skupper/utils/encode_test.go
+++ b/internal/cmd/skupper/utils/encode_test.go
@@ -37,9 +37,7 @@ func Test_Marshal(t *testing.T) {
   "spec": {
     "linkAccess": "default"
   },
-  "status": {
-    "active": false
-  }
+  "status": {}
 }`, false},
 		{"yaml", v1alpha1.Site{
 			TypeMeta: v1.TypeMeta{
@@ -62,8 +60,7 @@ metadata:
   namespace: test
 spec:
   linkAccess: default
-status:
-  active: false
+status: {}
 `,
 			false},
 		{"unsupported", v1alpha1.Site{
diff --git a/pkg/utils/validator/simple_validator_test.go b/pkg/utils/validator/simple_validator_test.go
index c88177ba..683fd0b6 100644
--- a/pkg/utils/validator/simple_validator_test.go
+++ b/pkg/utils/validator/simple_validator_test.go
@@ -180,7 +180,7 @@ func TestNewWorkloadStringValidator_Evaluate(t *testing.T) {
 		{name: "empty string", value: "", result: false},
 		{name: "string with spaces", value: "provided value", result: false},
 		{name: "string with numbers", value: "site123", result: true},
-		{name: "number", value: 123, result: true},
+		{name: "number", value: 123, result: false},
 		{name: "nil value", value: nil, result: false},
 		{name: "string with underscore", value: "abc_def", result: false},
 		{name: "string with equal", value: "abc=def", result: true},