mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 20:57:24 +00:00
feat(system api): list instances by domains (#6806)
Allow to list instances by their domains on the system API. closes #6785
This commit is contained in:
parent
b9061ffadc
commit
ad26ca88d7
@ -63,6 +63,8 @@ func InstanceQueryToModel(searchQuery *instance_pb.Query) (query.SearchQuery, er
|
||||
switch q := searchQuery.Query.(type) {
|
||||
case *instance_pb.Query_IdQuery:
|
||||
return query.NewInstanceIDsListSearchQuery(q.IdQuery.Ids...)
|
||||
case *instance_pb.Query_DomainQuery:
|
||||
return query.NewInstanceDomainsListSearchQuery(q.DomainQuery.Domains...)
|
||||
default:
|
||||
return nil, errors.ThrowInvalidArgument(nil, "INST-3m0se", "List.Query.Invalid")
|
||||
}
|
||||
|
109
internal/api/grpc/system/instance_integration_test.go
Normal file
109
internal/api/grpc/system/instance_integration_test.go
Normal file
@ -0,0 +1,109 @@
|
||||
//go:build integration
|
||||
|
||||
package system_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/instance"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/object"
|
||||
system_pb "github.com/zitadel/zitadel/pkg/grpc/system"
|
||||
)
|
||||
|
||||
func TestServer_ListInstances(t *testing.T) {
|
||||
domain, instanceID, _ := Tester.UseIsolatedInstance(CTX, SystemCTX)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
req *system_pb.ListInstancesRequest
|
||||
want []*instance.Instance
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "empty query error",
|
||||
req: &system_pb.ListInstancesRequest{
|
||||
Queries: []*instance.Query{{}},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "non-existing id",
|
||||
req: &system_pb.ListInstancesRequest{
|
||||
Queries: []*instance.Query{{
|
||||
Query: &instance.Query_IdQuery{
|
||||
IdQuery: &instance.IdsQuery{
|
||||
Ids: []string{"foo"},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
want: []*instance.Instance{},
|
||||
},
|
||||
{
|
||||
name: "get 1 by id",
|
||||
req: &system_pb.ListInstancesRequest{
|
||||
Query: &object.ListQuery{
|
||||
Limit: 1,
|
||||
},
|
||||
Queries: []*instance.Query{{
|
||||
Query: &instance.Query_IdQuery{
|
||||
IdQuery: &instance.IdsQuery{
|
||||
Ids: []string{instanceID},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
want: []*instance.Instance{{
|
||||
Id: instanceID,
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "non-existing domain",
|
||||
req: &system_pb.ListInstancesRequest{
|
||||
Queries: []*instance.Query{{
|
||||
Query: &instance.Query_DomainQuery{
|
||||
DomainQuery: &instance.DomainsQuery{
|
||||
Domains: []string{"foo"},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
want: []*instance.Instance{},
|
||||
},
|
||||
{
|
||||
name: "get 1 by domain",
|
||||
req: &system_pb.ListInstancesRequest{
|
||||
Query: &object.ListQuery{
|
||||
Limit: 1,
|
||||
},
|
||||
Queries: []*instance.Query{{
|
||||
Query: &instance.Query_DomainQuery{
|
||||
DomainQuery: &instance.DomainsQuery{
|
||||
Domains: []string{domain},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
want: []*instance.Instance{{
|
||||
Id: instanceID,
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
resp, err := Tester.Client.System.ListInstances(SystemCTX, tt.req)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
got := resp.GetResult()
|
||||
assert.Len(t, got, len(tt.want))
|
||||
for i := 0; i < len(tt.want); i++ {
|
||||
assert.Equalf(t, tt.want[i].GetId(), got[i].GetId(), "instance[%d] id", i)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -150,6 +150,15 @@ func NewInstanceIDsListSearchQuery(ids ...string) (SearchQuery, error) {
|
||||
return NewListQuery(InstanceColumnID, list, ListIn)
|
||||
}
|
||||
|
||||
func NewInstanceDomainsListSearchQuery(domains ...string) (SearchQuery, error) {
|
||||
list := make([]interface{}, len(domains))
|
||||
for i, value := range domains {
|
||||
list[i] = value
|
||||
}
|
||||
|
||||
return NewListQuery(InstanceDomainDomainCol, list, ListIn)
|
||||
}
|
||||
|
||||
func (q *InstanceSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
||||
query = q.SearchRequest.toQuery(query)
|
||||
for _, q := range q.Queries {
|
||||
@ -280,7 +289,8 @@ func prepareInstancesQuery(ctx context.Context, db prepareDatabase) (sq.SelectBu
|
||||
return sq.Select(
|
||||
InstanceColumnID.identifier(),
|
||||
countColumn.identifier(),
|
||||
).From(instanceTable.identifier()),
|
||||
).From(instanceTable.identifier()).
|
||||
LeftJoin(join(InstanceDomainInstanceIDCol, InstanceColumnID)),
|
||||
func(builder sq.SelectBuilder) sq.SelectBuilder {
|
||||
return sq.Select(
|
||||
instanceFilterCountColumn,
|
||||
|
@ -55,7 +55,8 @@ var (
|
||||
` projections.instance_domains.creation_date,` +
|
||||
` projections.instance_domains.change_date, ` +
|
||||
` projections.instance_domains.sequence` +
|
||||
` FROM (SELECT projections.instances.id, COUNT(*) OVER () FROM projections.instances) AS f` +
|
||||
` FROM (SELECT projections.instances.id, COUNT(*) OVER () FROM projections.instances` +
|
||||
` LEFT JOIN projections.instance_domains ON projections.instances.id = projections.instance_domains.instance_id) AS f` +
|
||||
` LEFT JOIN projections.instances ON f.id = projections.instances.id` +
|
||||
` LEFT JOIN projections.instance_domains ON f.id = projections.instance_domains.instance_id` +
|
||||
` AS OF SYSTEM TIME '-1 ms'`
|
||||
|
@ -71,6 +71,7 @@ message Query {
|
||||
option (validate.required) = true;
|
||||
|
||||
IdsQuery id_query = 1;
|
||||
DomainsQuery domain_query = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,6 +84,17 @@ message IdsQuery {
|
||||
];
|
||||
}
|
||||
|
||||
message DomainsQuery {
|
||||
repeated string domains = 1 [
|
||||
(validate.rules).repeated = {max_items: 20, items: {string: {min_len: 1, max_len: 100}}},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
max_items: 20,
|
||||
example: "[\"my-instace.zitadel.cloud\", \"auth.custom.com\"]";
|
||||
description: "Return the instances that have the requested domains";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
enum FieldName {
|
||||
FIELD_NAME_UNSPECIFIED = 0;
|
||||
FIELD_NAME_ID = 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user