Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ apis: use logicalcluster.Name in API types #3130

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (p *crdNoOverlappingGVRAdmission) Validate(ctx context.Context, a admission
if err != nil {
return fmt.Errorf("failed to retrieve cluster from context: %w", err)
}
clusterName := logicalcluster.Name(cluster.String()) // TODO(sttts): remove this cast once ClusterNameFrom returns a tenancy.Name
clusterName := cluster
// ignore CRDs targeting system and non-root workspaces
if clusterName == apibinding.SystemBoundCRDsClusterName || clusterName == apiserver.LocalAdminCluster {
return nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/admission/mutatingwebhook/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (p *Plugin) getSourceClusterForGroupResource(clusterName logicalcluster.Nam
for _, br := range apiBinding.Status.BoundResources {
if br.Group == groupResource.Group && br.Resource == groupResource.Resource {
// GroupResource comes from an APIBinding/APIExport
return logicalcluster.Name(apiBinding.Status.APIExportClusterName), nil
return apiBinding.Status.APIExportClusterName, nil
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/admission/validatingwebhook/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func (p *Plugin) getSourceClusterForGroupResource(clusterName logicalcluster.Nam
for _, br := range apiBinding.Status.BoundResources {
if br.Group == groupResource.Group && br.Resource == groupResource.Resource {
// GroupResource comes from an APIBinding/APIExport
return logicalcluster.Name(apiBinding.Status.APIExportClusterName), nil
return apiBinding.Status.APIExportClusterName, nil
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions pkg/index/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@ func (c *State) UpsertWorkspace(shard string, ws *tenancyv1alpha1.Workspace) {
// 1. cluster name is different
// 2. mount object string is different (updated, added, or removed)
// When we promote this to workspace structure, we should make this check smarter and better tested.
if (cluster.String() == ws.Spec.Cluster) && (ws.Annotations[tenancyv1alpha1.ExperimentalWorkspaceMountAnnotationKey] != "" && mountObjString == ws.Annotations[tenancyv1alpha1.ExperimentalWorkspaceMountAnnotationKey]) {
if (cluster == ws.Spec.Cluster) && (ws.Annotations[tenancyv1alpha1.ExperimentalWorkspaceMountAnnotationKey] != "" && mountObjString == ws.Annotations[tenancyv1alpha1.ExperimentalWorkspaceMountAnnotationKey]) {
return
}

c.lock.Lock()
defer c.lock.Unlock()

if cluster := c.shardWorkspaceNameCluster[shard][clusterName][ws.Name]; cluster.String() != ws.Spec.Cluster {
if cluster := c.shardWorkspaceNameCluster[shard][clusterName][ws.Name]; cluster != ws.Spec.Cluster {
if c.shardWorkspaceNameCluster[shard] == nil {
c.shardWorkspaceNameCluster[shard] = map[logicalcluster.Name]map[string]logicalcluster.Name{}
c.shardWorkspaceName[shard] = map[logicalcluster.Name]string{}
Expand All @@ -108,9 +108,9 @@ func (c *State) UpsertWorkspace(shard string, ws *tenancyv1alpha1.Workspace) {
if c.shardWorkspaceNameCluster[shard][clusterName] == nil {
c.shardWorkspaceNameCluster[shard][clusterName] = map[string]logicalcluster.Name{}
}
c.shardWorkspaceNameCluster[shard][clusterName][ws.Name] = logicalcluster.Name(ws.Spec.Cluster)
c.shardWorkspaceName[shard][logicalcluster.Name(ws.Spec.Cluster)] = ws.Name
c.shardClusterParentCluster[shard][logicalcluster.Name(ws.Spec.Cluster)] = clusterName
c.shardWorkspaceNameCluster[shard][clusterName][ws.Name] = ws.Spec.Cluster
c.shardWorkspaceName[shard][ws.Spec.Cluster] = ws.Name
c.shardClusterParentCluster[shard][ws.Spec.Cluster] = clusterName
}

if mountObjString := c.clusterWorkspaceMountAnnotation[clusterName][ws.Name]; mountObjString != ws.Annotations[tenancyv1alpha1.ExperimentalWorkspaceMountAnnotationKey] {
Expand Down Expand Up @@ -145,12 +145,12 @@ func (c *State) DeleteWorkspace(shard string, ws *tenancyv1alpha1.Workspace) {
delete(c.shardWorkspaceNameCluster, shard)
}

delete(c.shardWorkspaceName[shard], logicalcluster.Name(ws.Spec.Cluster))
delete(c.shardWorkspaceName[shard], ws.Spec.Cluster)
if len(c.shardWorkspaceName[shard]) == 0 {
delete(c.shardWorkspaceName, shard)
}

delete(c.shardClusterParentCluster[shard], logicalcluster.Name(ws.Spec.Cluster))
delete(c.shardClusterParentCluster[shard], ws.Spec.Cluster)
if len(c.shardClusterParentCluster[shard]) == 0 {
delete(c.shardClusterParentCluster, shard)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/index/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,15 +487,15 @@ func validateLookupOutput(t *testing.T, path logicalcluster.Path, shard string,
}
}

func newWorkspace(name, cluster, scheduledCluster string) *tenancyv1alpha1.Workspace {
func newWorkspace(name string, cluster, scheduledCluster logicalcluster.Name) *tenancyv1alpha1.Workspace {
return &tenancyv1alpha1.Workspace{
ObjectMeta: metav1.ObjectMeta{Name: name, Annotations: map[string]string{"kcp.io/cluster": cluster}},
ObjectMeta: metav1.ObjectMeta{Name: name, Annotations: map[string]string{"kcp.io/cluster": cluster.String()}},
Spec: tenancyv1alpha1.WorkspaceSpec{Cluster: scheduledCluster},
Status: tenancyv1alpha1.WorkspaceStatus{Phase: corev1alpha1.LogicalClusterPhaseReady},
}
}

func newWorkspaceWithAnnotation(name, cluster, scheduledCluster string, annotations map[string]string) *tenancyv1alpha1.Workspace {
func newWorkspaceWithAnnotation(name string, cluster, scheduledCluster logicalcluster.Name, annotations map[string]string) *tenancyv1alpha1.Workspace {
ws := newWorkspace(name, cluster, scheduledCluster)
for k, v := range annotations {
ws.Annotations[k] = v
Expand Down
2 changes: 1 addition & 1 deletion pkg/reconciler/apis/apibinding/apibinding_reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func (r *bindingReconciler) reconcile(ctx context.Context, apiBinding *apisv1alp
// Record the APIExport's host cluster name for lookup in webhooks.
// The full path is unreliable for this purpose.
clusterName := logicalcluster.From(apiExport)
apiBinding.Status.APIExportClusterName = clusterName.String()
apiBinding.Status.APIExportClusterName = clusterName

var needToWaitForRequeueWhenEstablished []string

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (r *deletionReconciler) reconcile(ctx context.Context, workspace *tenancyv1

// If the logical cluster hasn't been created yet, we have to look at the annotation to
// get the cluster name, instead of looking at status.
clusterName := logicalcluster.Name(workspace.Spec.Cluster)
clusterName := workspace.Spec.Cluster
if workspace.Status.Phase == corev1alpha1.LogicalClusterPhaseScheduling {
a, ok := workspace.Annotations[workspaceClusterAnnotationKey]
if !ok {
Expand Down
4 changes: 2 additions & 2 deletions pkg/reconciler/tenancy/workspace/workspace_reconcile_phase.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (r *phaseReconciler) reconcile(ctx context.Context, workspace *tenancyv1alp
case corev1alpha1.LogicalClusterPhaseInitializing:
logger = logger.WithValues("cluster", workspace.Spec.Cluster)

logicalCluster, err := r.getLogicalCluster(ctx, logicalcluster.NewPath(workspace.Spec.Cluster))
logicalCluster, err := r.getLogicalCluster(ctx, workspace.Spec.Cluster.Path())
if err != nil && !apierrors.IsNotFound(err) {
return reconcileStatusStopAndRequeue, err
} else if apierrors.IsNotFound(err) {
Expand Down Expand Up @@ -78,7 +78,7 @@ func (r *phaseReconciler) reconcile(ctx context.Context, workspace *tenancyv1alp
if !workspace.DeletionTimestamp.IsZero() {
logger = logger.WithValues("cluster", workspace.Spec.Cluster)

logicalCluster, err := r.getLogicalCluster(ctx, logicalcluster.NewPath(workspace.Spec.Cluster))
logicalCluster, err := r.getLogicalCluster(ctx, workspace.Spec.Cluster.Path())
if err != nil && !apierrors.IsNotFound(err) {
return reconcileStatusStopAndRequeue, err
} else if apierrors.IsNotFound(err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func (r *schedulingReconciler) reconcile(ctx context.Context, workspace *tenancy
return reconcileStatusStopAndRequeue, err // requeue
}
u.Path = path.Join(u.Path, canonicalPath.RequestPath())
workspace.Spec.Cluster = clusterName.String()
workspace.Spec.Cluster = clusterName
workspace.Spec.URL = u.String()
logging.WithObject(logger, shard).Info("scheduled workspace to shard")
return reconcileStatusStopAndRequeue, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/home_workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ func (h *homeWorkspaceHandler) ServeHTTP(rw http.ResponseWriter, req *http.Reque
CreationTimestamp: logicalCluster.CreationTimestamp,
},
Spec: tenancyv1alpha1.WorkspaceSpec{
Cluster: logicalcluster.From(logicalCluster).String(),
Cluster: logicalcluster.From(logicalCluster),
URL: logicalCluster.Status.URL,
},
Status: tenancyv1alpha1.WorkspaceStatus{
Expand Down
4 changes: 3 additions & 1 deletion sdk/apis/apis/v1alpha1/types_apibinding.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package v1alpha1

import (
"github.com/kcp-dev/logicalcluster/v3"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

conditionsv1alpha1 "github.com/kcp-dev/kcp/sdk/apis/third_party/conditions/apis/conditions/v1alpha1"
Expand Down Expand Up @@ -142,7 +144,7 @@ type APIBindingStatus struct {
// APIExportClusterName records the name (not path) of the logical cluster that contains the APIExport.
//
// +optional
APIExportClusterName string `json:"apiExportClusterName,omitempty"`
APIExportClusterName logicalcluster.Name `json:"apiExportClusterName,omitempty"`

// boundResources records the state of bound APIs.
//
Expand Down
4 changes: 3 additions & 1 deletion sdk/apis/tenancy/v1alpha1/types_workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package v1alpha1
import (
"fmt"

"github.com/kcp-dev/logicalcluster/v3"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

corev1alpha1 "github.com/kcp-dev/kcp/sdk/apis/core/v1alpha1"
Expand Down Expand Up @@ -168,7 +170,7 @@ type WorkspaceSpec struct {
//
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="cluster is immutable"
Cluster string `json:"cluster,omitempty"`
Cluster logicalcluster.Name `json:"cluster,omitempty"`

// URL is the address under which the Kubernetes-cluster-like endpoint
// can be found. This URL can be used to access the workspace with standard Kubernetes
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions test/e2e/apibinding/apibinding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,13 @@ func TestAPIBinding(t *testing.T) {

orgPath, _ := framework.NewOrganizationFixture(t, server)
provider1Path, provider1 := framework.NewWorkspaceFixture(t, server, orgPath, framework.WithName("service-provider-1"))
provider1ClusterName := logicalcluster.Name(provider1.Spec.Cluster)
provider1ClusterName := provider1.Spec.Cluster
provider2Path, provider2 := framework.NewWorkspaceFixture(t, server, orgPath, framework.WithName("service-provider-2"))
provider2ClusterName := logicalcluster.Name(provider2.Spec.Cluster)
provider2ClusterName := provider2.Spec.Cluster
consumer1Path, _ := framework.NewWorkspaceFixture(t, server, orgPath, framework.WithName("consumer-1-bound-against-1"))
consumer2Path, _ := framework.NewWorkspaceFixture(t, server, orgPath, framework.WithName("consumer-2-bound-against-1"))
consumer3Path, consumer3Workspace := framework.NewWorkspaceFixture(t, server, orgPath, framework.WithName("consumer-3-bound-against-2"))
consumer3ClusterName := logicalcluster.Name(consumer3Workspace.Spec.Cluster)
consumer3ClusterName := consumer3Workspace.Spec.Cluster

cfg := server.BaseConfig(t)

Expand Down
4 changes: 2 additions & 2 deletions test/e2e/audit/audit_log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ func TestAuditLogs(t *testing.T) {
require.NoError(t, err, "Error parsing JSON data")

workspaceNameSent := ws.Spec.Cluster
require.Equal(t, workspaceNameSent, requestAuditEvent.Annotations["tenancy.kcp.io/workspace"])
require.Equal(t, workspaceNameSent, responseAuditEvent.Annotations["tenancy.kcp.io/workspace"])
require.Equal(t, workspaceNameSent.String(), requestAuditEvent.Annotations["tenancy.kcp.io/workspace"])
require.Equal(t, workspaceNameSent.String(), responseAuditEvent.Annotations["tenancy.kcp.io/workspace"])

for _, annotation := range []string{
"request.auth.kcp.io/01-requiredgroups",
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/authorizer/authorizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ func TestAuthorizer(t *testing.T) {
deepSARClient, err := kcpkubernetesclientset.NewForConfig(authorization.WithDeepSARConfig(rest.CopyConfig(server.RootShardSystemMasterBaseConfig(t))))
require.NoError(t, err)
framework.Eventually(t, func() (bool, string) {
resp, err = deepSARClient.Cluster(logicalcluster.NewPath(org2Workspace1.Spec.Cluster)).AuthorizationV1().SubjectAccessReviews().Create(ctx, sar, metav1.CreateOptions{})
resp, err = deepSARClient.Cluster(org2Workspace1.Spec.Cluster.Path()).AuthorizationV1().SubjectAccessReviews().Create(ctx, sar, metav1.CreateOptions{})
if err != nil {
return false, fmt.Sprintf("failed to create SAR: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/conformance/cross_logical_cluster_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ func TestCrossLogicalClusterList(t *testing.T) {
_, ws1 := framework.NewOrganizationFixture(t, server, framework.WithRootShard())
_, ws2 := framework.NewOrganizationFixture(t, server, framework.WithRootShard())
logicalClusters := []logicalcluster.Name{
logicalcluster.Name(ws1.Spec.Cluster),
logicalcluster.Name(ws2.Spec.Cluster),
ws1.Spec.Cluster,
ws2.Spec.Cluster,
}
expectedWorkspaces := sets.New[string]()
for i, clusterName := range logicalClusters {
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/conformance/webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func TestMutatingWebhookInWorkspace(t *testing.T) {
if err := json.Unmarshal(review.Request.Object.Raw, &u.Object); err != nil {
return nil, err
}
clusterInReviewObject.Store(logicalcluster.From(&u).String())
clusterInReviewObject.Store(logicalcluster.From(&u))
return &v1.AdmissionResponse{Allowed: true}, nil
},
ObjectGVK: schema.GroupVersionKind{
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/framework/kcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,7 @@ func NewFakeWorkloadServer(t *testing.T, server RunningServer, org logicalcluste
t.Helper()

path, ws := NewWorkspaceFixture(t, server, org, WithName(syncTargetName+"-sink"), TODO_WithoutMultiShardSupport())
logicalClusterName := logicalcluster.Name(ws.Spec.Cluster)
logicalClusterName := ws.Spec.Cluster
rawConfig, err := server.RawConfig()
require.NoError(t, err, "failed to read config for server")
logicalConfig, kubeconfigPath := WriteLogicalClusterConfig(t, rawConfig, "base", path)
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/framework/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func newWorkspaceFixture[O WorkspaceOption](t *testing.T, createClusterClient, c
}, workspaceInitTimeout, time.Millisecond*100, "failed to wait for %s workspace %s to become ready", ws.Spec.Type, parent.Join(ws.Name))

Eventually(t, func() (bool, string) {
if _, err := clusterClient.Cluster(logicalcluster.NewPath(ws.Spec.Cluster)).CoreV1alpha1().LogicalClusters().Get(ctx, corev1alpha1.LogicalClusterName, metav1.GetOptions{}); err != nil {
if _, err := clusterClient.Cluster(ws.Spec.Cluster.Path()).CoreV1alpha1().LogicalClusters().Get(ctx, corev1alpha1.LogicalClusterName, metav1.GetOptions{}); err != nil {
return false, fmt.Sprintf("failed to get LogicalCluster %s by cluster name %s: %v", parent.Join(ws.Name), ws.Spec.Cluster, err)
}
if _, err := clusterClient.Cluster(parent.Join(ws.Name)).CoreV1alpha1().LogicalClusters().Get(ctx, corev1alpha1.LogicalClusterName, metav1.GetOptions{}); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/reconciler/cache/replication_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func replicateResource(ctx context.Context, t *testing.T,
orgPath, _ := framework.NewOrganizationFixture(t, server)
if clusterName.Empty() {
_, ws := framework.NewWorkspaceFixture(t, server, orgPath, framework.WithRootShard())
clusterName = logicalcluster.Name(ws.Spec.Cluster)
clusterName = ws.Spec.Cluster
}
resMeta, err := meta.Accessor(res)
require.NoError(t, err)
Expand Down Expand Up @@ -390,7 +390,7 @@ func replicateResourceNegative(ctx context.Context, t *testing.T,
orgPath, _ := framework.NewOrganizationFixture(t, server)
if clusterName.Empty() {
_, ws := framework.NewWorkspaceFixture(t, server, orgPath, framework.WithRootShard())
clusterName = logicalcluster.Name(ws.Spec.Cluster)
clusterName = ws.Spec.Cluster
}
resMeta, err := meta.Accessor(res)
require.NoError(t, err)
Expand Down
3 changes: 1 addition & 2 deletions test/e2e/reconciler/workspacedeletion/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"time"

kcpkubernetesclientset "github.com/kcp-dev/client-go/kubernetes"
"github.com/kcp-dev/logicalcluster/v3"
"github.com/stretchr/testify/require"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -201,7 +200,7 @@ func TestWorkspaceDeletion(t *testing.T) {

t.Logf("Create a workspace with in the org workspace")
_, ws := framework.NewWorkspaceFixture(t, server, orgPath, framework.WithName("org-ws-cleanup"), framework.WithRootShard())
wsClusterName := logicalcluster.Name(ws.Spec.Cluster)
wsClusterName := ws.Spec.Cluster

t.Logf("Should have finalizer added in workspace")
require.Eventually(t, func() bool {
Expand Down
Loading
Loading