Skip to content

Commit 2d821a7

Browse files
committed
feat: add Identity client
1 parent c37c875 commit 2d821a7

File tree

9 files changed

+240
-0
lines changed

9 files changed

+240
-0
lines changed

pkg/connect/client/clientset.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
clusterv1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/cluster/v1alpha1"
1111
datastorev1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/datastore/v1alpha1"
1212
federationV1Alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/federation/v1alpha1"
13+
identityv1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/identity/v1alpha1"
1314
trustzonev1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/trustzone/v1alpha1"
1415
workloadv1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/workload/v1alpha1"
1516

@@ -27,6 +28,7 @@ type ClientSet interface {
2728
FederationV1Alpha1() federationV1Alpha1.FederationClient
2829
DataStoreV1Alpha1() datastorev1alpha1.DataStoreClient
2930
WorkloadV1Alpha1() workloadv1alpha1.WorkloadClient
31+
IdentityV1Alpha1() identityv1alpha1.IdentityClient
3032
}
3133

3234
type clientSet struct {
@@ -38,6 +40,7 @@ type clientSet struct {
3840
federationV1Alpha1 federationV1Alpha1.FederationClient
3941
datastoreV1Alpha1 datastorev1alpha1.DataStoreClient
4042
workloadV1Alpha1 workloadv1alpha1.WorkloadClient
43+
identityV1Alpha1 identityv1alpha1.IdentityClient
4144
}
4245

4346
// New instantiates a new ClientSet for communication with a Connect API.
@@ -51,6 +54,7 @@ func New(conn grpc.ClientConnInterface) ClientSet {
5154
federationV1Alpha1: federationV1Alpha1.New(conn),
5255
datastoreV1Alpha1: datastorev1alpha1.New(conn),
5356
workloadV1Alpha1: workloadv1alpha1.New(conn),
57+
identityV1Alpha1: identityv1alpha1.New(conn),
5458
}
5559
}
5660

@@ -85,3 +89,7 @@ func (c *clientSet) DataStoreV1Alpha1() datastorev1alpha1.DataStoreClient {
8589
func (c *clientSet) WorkloadV1Alpha1() workloadv1alpha1.WorkloadClient {
8690
return c.workloadV1Alpha1
8791
}
92+
93+
func (c *clientSet) IdentityV1Alpha1() identityv1alpha1.IdentityClient {
94+
return c.identityV1Alpha1
95+
}

pkg/connect/client/clientset_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ func TestClientSet(t *testing.T) {
1919
require.NotNil(t, client.APBindingV1Alpha1())
2020
require.NotNil(t, client.FederationV1Alpha1())
2121
require.NotNil(t, client.DataStoreV1Alpha1())
22+
require.NotNil(t, client.WorkloadV1Alpha1())
23+
require.NotNil(t, client.IdentityV1Alpha1())
2224
}

pkg/connect/client/fake/client/fakeclient.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
fakeconnect "github.com/cofide/cofide-api-sdk/pkg/connect/client/fake/connect"
1919
federationV1Alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/federation/v1alpha1"
2020
fakefederationV1Alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/federation/v1alpha1/fake"
21+
identityv1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/identity/v1alpha1"
22+
fakeidentityv1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/identity/v1alpha1/fake"
2123
trustzonev1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/trustzone/v1alpha1"
2224
faketrustzonev1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/trustzone/v1alpha1/fake"
2325
workloadv1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/workload/v1alpha1"
@@ -33,6 +35,7 @@ type fakeClientSet struct {
3335
federationV1Alpha1 federationV1Alpha1.FederationClient
3436
datastoreV1Alpha1 datastorev1alpha1.DataStoreClient
3537
workloadV1Alpha1 workloadv1alpha1.WorkloadClient
38+
identityV1Alpha1 identityv1alpha1.IdentityClient
3639
}
3740

3841
// New instantiates a new ClientSet that fakes communication with a Connect API.
@@ -46,6 +49,7 @@ func New(fake *fakeconnect.FakeConnect) client.ClientSet {
4649
federationV1Alpha1: fakefederationV1Alpha1.New(fake),
4750
datastoreV1Alpha1: fakedatastorev1alpha1.New(fake),
4851
workloadV1Alpha1: fakeworkloadv1alpha1.New(fake),
52+
identityV1Alpha1: fakeidentityv1alpha1.New(fake),
4953
}
5054
}
5155

@@ -80,3 +84,7 @@ func (c *fakeClientSet) DataStoreV1Alpha1() datastorev1alpha1.DataStoreClient {
8084
func (c *fakeClientSet) WorkloadV1Alpha1() workloadv1alpha1.WorkloadClient {
8185
return c.workloadV1Alpha1
8286
}
87+
88+
func (c *fakeClientSet) IdentityV1Alpha1() identityv1alpha1.IdentityClient {
89+
return c.identityV1Alpha1
90+
}

pkg/connect/client/fake/client/fakeclient_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,10 @@ func TestFakeClientSet(t *testing.T) {
1515
require.NotNil(t, client.TrustZoneV1Alpha1())
1616
require.NotNil(t, client.ClusterV1Alpha1())
1717
require.NotNil(t, client.AgentV1Alpha1())
18+
require.NotNil(t, client.AttestationPolicyV1Alpha1())
19+
require.NotNil(t, client.APBindingV1Alpha1())
20+
require.NotNil(t, client.FederationV1Alpha1())
21+
require.NotNil(t, client.DataStoreV1Alpha1())
22+
require.NotNil(t, client.WorkloadV1Alpha1())
23+
require.NotNil(t, client.IdentityV1Alpha1())
1824
}

pkg/connect/client/fake/connect/fakeconnect.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
datastoresvcpb "github.com/cofide/cofide-api-sdk/gen/go/proto/connect/datastore_service/v1alpha1"
1111
federatedservicepb "github.com/cofide/cofide-api-sdk/gen/go/proto/federated_service/v1alpha1"
1212
federationpb "github.com/cofide/cofide-api-sdk/gen/go/proto/federation/v1alpha1"
13+
identitypb "github.com/cofide/cofide-api-sdk/gen/go/proto/identity/v1alpha1"
1314
trustzonepb "github.com/cofide/cofide-api-sdk/gen/go/proto/trust_zone/v1alpha1"
1415
workloadpb "github.com/cofide/cofide-api-sdk/gen/go/proto/workload/v1alpha1"
1516
"github.com/spiffe/spire-api-sdk/proto/spire/api/types"
@@ -32,6 +33,7 @@ type FakeConnect struct {
3233
Federations map[string]*federationpb.Federation
3334
AttestedNodes map[string]*datastoresvcpb.AttestedNode
3435
Workloads map[string]*workloadpb.Workload
36+
Identities map[string]*identitypb.Identity
3537
}
3638

3739
func New() *FakeConnect {
@@ -48,6 +50,7 @@ func New() *FakeConnect {
4850
Federations: make(map[string]*federationpb.Federation),
4951
AttestedNodes: make(map[string]*datastoresvcpb.AttestedNode),
5052
Workloads: make(map[string]*workloadpb.Workload),
53+
Identities: make(map[string]*identitypb.Identity),
5154
}
5255
}
5356

@@ -106,3 +109,10 @@ func (f *FakeConnect) ValidateWorkload(workloadID string) error {
106109
}
107110
return nil
108111
}
112+
113+
func (f *FakeConnect) ValidateIdentity(identityID string) error {
114+
if _, ok := f.Identities[identityID]; !ok {
115+
return status.Error(codes.InvalidArgument, "invalid identity")
116+
}
117+
return nil
118+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2025 Cofide Limited.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package fake
5+
6+
import (
7+
"context"
8+
9+
identitysvcpb "github.com/cofide/cofide-api-sdk/gen/go/proto/connect/identity_service/v1alpha1"
10+
identitypb "github.com/cofide/cofide-api-sdk/gen/go/proto/identity/v1alpha1"
11+
fakeconnect "github.com/cofide/cofide-api-sdk/pkg/connect/client/fake/connect"
12+
identityv1alpha1 "github.com/cofide/cofide-api-sdk/pkg/connect/client/identity/v1alpha1"
13+
"google.golang.org/grpc/codes"
14+
"google.golang.org/grpc/status"
15+
"google.golang.org/protobuf/proto"
16+
)
17+
18+
type fakeIdentityClient struct {
19+
fake *fakeconnect.FakeConnect
20+
}
21+
22+
// New instantiates a new IdentityClient for communication with a fake Connect API.
23+
func New(fake *fakeconnect.FakeConnect) identityv1alpha1.IdentityClient {
24+
return &fakeIdentityClient{
25+
fake: fake,
26+
}
27+
}
28+
29+
func (c *fakeIdentityClient) GetIdentity(ctx context.Context, identityID string) (*identitypb.Identity, error) {
30+
c.fake.Mu.Lock()
31+
defer c.fake.Mu.Unlock()
32+
33+
identity, ok := c.fake.Identities[identityID]
34+
if !ok {
35+
return nil, status.Error(codes.NotFound, "identity not found")
36+
}
37+
return clone(identity), nil
38+
}
39+
40+
func (c *fakeIdentityClient) ListIdentities(ctx context.Context, filter *identitysvcpb.ListIdentitiesRequest_Filter) ([]*identitypb.Identity, error) {
41+
c.fake.Mu.Lock()
42+
defer c.fake.Mu.Unlock()
43+
44+
identities := []*identitypb.Identity{}
45+
for _, identity := range c.fake.Identities {
46+
if identityMatches(identity, filter) {
47+
identities = append(identities, clone(identity))
48+
}
49+
}
50+
return identities, nil
51+
}
52+
53+
func identityMatches(identity *identitypb.Identity, filter *identitysvcpb.ListIdentitiesRequest_Filter) bool {
54+
if filter == nil {
55+
return true
56+
}
57+
if filter.OrgId != nil && identity.GetOrgId() != *filter.OrgId {
58+
return false
59+
}
60+
if filter.TrustZoneId != nil && identity.GetTrustZoneId() != *filter.TrustZoneId {
61+
return false
62+
}
63+
if filter.ClusterId != nil && identity.GetClusterId() != *filter.ClusterId {
64+
return false
65+
}
66+
if filter.AttestationPolicyId != nil && identity.GetAttestationPolicyId() != *filter.AttestationPolicyId {
67+
return false
68+
}
69+
if filter.ApBindingId != nil && identity.GetApBindingId() != *filter.ApBindingId {
70+
return false
71+
}
72+
if filter.WorkloadId != nil && identity.GetWorkloadId() != *filter.WorkloadId {
73+
return false
74+
}
75+
if filter.SpiffeId != nil && identity.GetSpiffeId() != *filter.SpiffeId {
76+
return false
77+
}
78+
return true
79+
}
80+
81+
func clone(identity *identitypb.Identity) *identitypb.Identity {
82+
return proto.Clone(identity).(*identitypb.Identity)
83+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2025 Cofide Limited.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package fake
5+
6+
import (
7+
"context"
8+
"testing"
9+
10+
identitypb "github.com/cofide/cofide-api-sdk/gen/go/proto/identity/v1alpha1"
11+
fakeconnect "github.com/cofide/cofide-api-sdk/pkg/connect/client/fake/connect"
12+
"github.com/cofide/cofide-api-sdk/pkg/connect/client/test"
13+
"github.com/stretchr/testify/assert"
14+
"github.com/stretchr/testify/require"
15+
)
16+
17+
func Test_fakeIdentityClient_GetIdentity(t *testing.T) {
18+
fake := fakeconnect.New()
19+
client := New(fake)
20+
ctx := context.Background()
21+
22+
_, err := client.GetIdentity(ctx, test.FakeIdentityID)
23+
require.Error(t, err)
24+
25+
identity := test.FakeIdentity()
26+
fake.Identities[test.FakeIdentityID] = identity
27+
28+
gotIdentity, err := client.GetIdentity(ctx, test.FakeIdentityID)
29+
require.NoError(t, err)
30+
assert.EqualExportedValues(t, identity, gotIdentity)
31+
}
32+
33+
func Test_fakeIdentityClient_ListIdentities(t *testing.T) {
34+
fake := fakeconnect.New()
35+
client := New(fake)
36+
ctx := context.Background()
37+
38+
identity := test.FakeIdentity()
39+
40+
identities, err := client.ListIdentities(ctx, nil)
41+
require.NoError(t, err)
42+
assert.EqualExportedValues(t, []*identitypb.Identity{}, identities)
43+
44+
fake.Identities[test.FakeIdentityID] = test.FakeIdentity()
45+
46+
identities, err = client.ListIdentities(ctx, nil)
47+
require.NoError(t, err)
48+
assert.EqualExportedValues(t, []*identitypb.Identity{identity}, identities)
49+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2025 Cofide Limited.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package v1alpha1
5+
6+
import (
7+
"context"
8+
9+
identitysvcpb "github.com/cofide/cofide-api-sdk/gen/go/proto/connect/identity_service/v1alpha1"
10+
identitypb "github.com/cofide/cofide-api-sdk/gen/go/proto/identity/v1alpha1"
11+
"google.golang.org/grpc"
12+
)
13+
14+
// IdentityClient is an interface for a client for the v1alpha1 version of the Connect IdentityService.
15+
type IdentityClient interface {
16+
GetIdentity(ctx context.Context, identityID string) (*identitypb.Identity, error)
17+
ListIdentities(ctx context.Context, filter *identitysvcpb.ListIdentitiesRequest_Filter) ([]*identitypb.Identity, error)
18+
}
19+
20+
type identityClient struct {
21+
identityClient identitysvcpb.IdentityServiceClient
22+
}
23+
24+
// New instantiates a new TrustZoneClient for communication with a Connect API.
25+
func New(conn grpc.ClientConnInterface) IdentityClient {
26+
return &identityClient{
27+
identityClient: identitysvcpb.NewIdentityServiceClient(conn),
28+
}
29+
}
30+
31+
func (c *identityClient) GetIdentity(ctx context.Context, identityID string) (*identitypb.Identity, error) {
32+
resp, err := c.identityClient.GetIdentity(ctx, &identitysvcpb.GetIdentityRequest{IdentityId: identityID})
33+
if err != nil {
34+
return nil, err
35+
}
36+
return resp.Identity, nil
37+
}
38+
39+
func (c *identityClient) ListIdentities(ctx context.Context, filter *identitysvcpb.ListIdentitiesRequest_Filter) ([]*identitypb.Identity, error) {
40+
resp, err := c.identityClient.ListIdentities(ctx, &identitysvcpb.ListIdentitiesRequest{Filter: filter})
41+
if err != nil {
42+
return nil, err
43+
}
44+
return resp.Identities, nil
45+
}

pkg/connect/client/test/fakes.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
attestationpolicypb "github.com/cofide/cofide-api-sdk/gen/go/proto/attestation_policy/v1alpha1"
1010
clusterpb "github.com/cofide/cofide-api-sdk/gen/go/proto/cluster/v1alpha1"
1111
federatedservicepb "github.com/cofide/cofide-api-sdk/gen/go/proto/federated_service/v1alpha1"
12+
identitypb "github.com/cofide/cofide-api-sdk/gen/go/proto/identity/v1alpha1"
1213
trustzonepb "github.com/cofide/cofide-api-sdk/gen/go/proto/trust_zone/v1alpha1"
1314
workloadpb "github.com/cofide/cofide-api-sdk/gen/go/proto/workload/v1alpha1"
1415
"github.com/spiffe/spire-api-sdk/proto/spire/api/types"
@@ -37,6 +38,12 @@ const (
3738
FakeK8sPodUID = "fake-k8s-pod-uid"
3839
FakeK8sPodName = "fake-k8s-pod-name"
3940
FakeK8sPodNamespace = "fake-k8s-pod-namespace"
41+
42+
FakeIdentityID = "fake-identity-id"
43+
FakeSPIFFEID = "spiffe://fake.trust.domain/ns/fake-k8s-pod-namespace/sa/fake-k8s-pod-service-account"
44+
FakeParentID = "spiffe://fake.trust.domain/spire/agent/k8s_psat/fake-cluster-name/fake-spire-agent"
45+
FakeSelectorType = "fake-selector-type"
46+
FakeSelectorValue = "fake-selector-value"
4047
)
4148

4249
func FakeTrustZone() *trustzonepb.TrustZone {
@@ -106,3 +113,25 @@ func FakeK8sPodWorkload() *workloadpb.Workload {
106113
},
107114
}
108115
}
116+
117+
func FakeIdentity() *identitypb.Identity {
118+
return &identitypb.Identity{
119+
Id: FakeIdentityID,
120+
TrustZoneId: FakeTrustZoneID,
121+
ClusterId: FakeClusterID,
122+
WorkloadId: FakeWorkloadID,
123+
SpiffeId: FakeSPIFFEID,
124+
ParentId: FakeParentID,
125+
Selectors: []*identitypb.Selector{
126+
{
127+
Type: FakeSelectorType,
128+
Value: FakeSelectorValue,
129+
},
130+
},
131+
Federations: []*identitypb.IdentityFederation{
132+
{
133+
TrustZoneId: PtrOf(FakeTrustZoneID),
134+
},
135+
},
136+
}
137+
}

0 commit comments

Comments
 (0)