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

[GraphQL] List entity config & state resources #4808

Merged
merged 38 commits into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f772529
more debugging
jamesdphillips Jul 7, 2022
dd46780
more debugging
jamesdphillips Jul 7, 2022
66d49a1
more debugging
jamesdphillips Jul 7, 2022
eef64ab
more debugging
jamesdphillips Jul 7, 2022
34385bd
omit debugging
jamesdphillips Jul 7, 2022
c956621
leverage code generator more
jamesdphillips Jul 8, 2022
6211bd4
rollback metadata change.. for now
jamesdphillips Jul 8, 2022
d31c3f0
abandoned prototype
jamesdphillips Jul 20, 2022
a429b35
query entity config & state
jamesdphillips Jul 20, 2022
3fcc96c
move
jamesdphillips Jul 20, 2022
ca6159f
fix borked rebase
jamesdphillips Jul 20, 2022
e9615cf
register the extensions
jamesdphillips Jul 20, 2022
78736a1
ensure we do not register more than one interface
jamesdphillips Jul 20, 2022
f2bee16
i hate
jamesdphillips Jul 20, 2022
a22c754
add tests
jamesdphillips Jul 21, 2022
2b0238c
make entity config & state available through the same RBAC rule
jamesdphillips Jul 21, 2022
ad59134
fixup fetching
jamesdphillips Jul 21, 2022
071ce7c
okay
jamesdphillips Jul 21, 2022
d8ae7ec
restore gen file
jamesdphillips Jul 21, 2022
29d2b40
test
jamesdphillips Jul 21, 2022
d337552
handle nil err
jamesdphillips Jul 21, 2022
589a314
gimme that store v2
jamesdphillips Jul 21, 2022
a086b2b
proxy
jamesdphillips Jul 21, 2022
593cf7a
fixes nil issue
jamesdphillips Jul 21, 2022
f722983
oof
jamesdphillips Jul 21, 2022
a9a0557
to corev/v2 Entity
jamesdphillips Jul 21, 2022
d5727ef
fields()
jamesdphillips Jul 21, 2022
5e89348
remove unused
jamesdphillips Jul 21, 2022
31e6727
bad rebase
jamesdphillips Jul 21, 2022
ada1de3
Merge remote-tracking branch 'origin/develop/6' into jdp/entity-list-…
jamesdphillips Aug 11, 2022
a38fb9a
add tests for entity config & state fields
jamesdphillips Aug 11, 2022
a7b9041
add test coverage for generic translator
jamesdphillips Aug 11, 2022
beb8e78
add test coverage for corev3 GraphQL types
jamesdphillips Aug 11, 2022
2734c2a
omit uniqueness tests
jamesdphillips Aug 11, 2022
caf4181
extract sort order
jamesdphillips Aug 11, 2022
f1a247f
Merge remote-tracking branch 'origin/develop/6' into jdp/entity-list-…
jamesdphillips Aug 11, 2022
65f4789
bil check
jamesdphillips Aug 11, 2022
bd96fc6
Merge remote-tracking branch 'origin/develop/6' into jdp/entity-list-…
jamesdphillips Aug 18, 2022
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
33 changes: 33 additions & 0 deletions api/core/v3/entity_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package v3

import (
"strconv"
"strings"

corev2 "github.com/sensu/sensu-go/api/core/v2"
)

var entityConfigRBACName = (&corev2.Entity{}).RBACName()

func (e *EntityConfig) rbacName() string {
return entityConfigRBACName
}

func (e *EntityConfig) Fields() map[string]string {
fields := map[string]string{
"entity_config.name": e.Metadata.Name,
"entity_config.namespace": e.Metadata.Namespace,
"entity_config.deregister": strconv.FormatBool(e.Deregister),
"entity_config.entity_class": e.EntityClass,
"entity_config.subscriptions": strings.Join(e.Subscriptions, ","),
}
MergeMapWithPrefix(fields, e.Metadata.Labels, "entity_config.labels.")
return fields
}

// MergeMapWithPrefix merges contents of one map into another using a prefix.
func MergeMapWithPrefix(a map[string]string, b map[string]string, prefix string) {
for k, v := range b {
a[prefix+k] = v
}
}
60 changes: 60 additions & 0 deletions api/core/v3/entity_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package v3

import (
"reflect"
"testing"

v2 "github.com/sensu/sensu-go/api/core/v2"
)

func TestEntityConfigFields(t *testing.T) {
tests := []struct {
name string
args Fielder
wantKey string
want string
}{
{
name: "exposes name",
args: FixtureEntityConfig("my-agent"),
wantKey: "entity_config.name",
want: "my-agent",
},
{
name: "exposes deregister",
args: &EntityConfig{Metadata: &v2.ObjectMeta{}, Deregister: true},
wantKey: "entity_config.deregister",
want: "true",
},
{
name: "exposes class",
args: &EntityConfig{Metadata: &v2.ObjectMeta{}, EntityClass: "agent"},
wantKey: "entity_config.entity_class",
want: "agent",
},
{
name: "exposes subscriptions",
args: &EntityConfig{Metadata: &v2.ObjectMeta{}, Subscriptions: []string{"www", "unix"}},
wantKey: "entity_config.subscriptions",
want: "www,unix",
},
{
name: "exposes labels",
args: &EntityConfig{
Metadata: &v2.ObjectMeta{
Labels: map[string]string{"region": "philadelphia"},
},
},
wantKey: "entity_config.labels.region",
want: "philadelphia",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.args.Fields()
if !reflect.DeepEqual(got[tt.wantKey], tt.want) {
t.Errorf("EntityConfig.Fields() = got[%s] %v, want[%s] %v", tt.wantKey, got[tt.wantKey], tt.wantKey, tt.want)
}
})
}
}
19 changes: 19 additions & 0 deletions api/core/v3/entity_state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package v3

import (
corev2 "github.com/sensu/sensu-go/api/core/v2"
)

var entityStateRBACName = (&corev2.Entity{}).RBACName()

func (*EntityState) rbacName() string {
return entityStateRBACName
}

func (e *EntityState) Fields() map[string]string {
fields := map[string]string{
"entity_state.name": e.Metadata.Name,
"entity_state.namespace": e.Metadata.Namespace,
}
return fields
}
36 changes: 36 additions & 0 deletions api/core/v3/entity_state_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package v3

import (
"reflect"
"testing"
)

func TestEntityStateFields(t *testing.T) {
tests := []struct {
name string
args Fielder
wantKey string
want string
}{
{
name: "exposes name",
args: FixtureEntityState("my-agent"),
wantKey: "entity_state.name",
want: "my-agent",
},
{
name: "exposes deregister",
args: FixtureEntityState("my-agent"),
wantKey: "entity_state.namespace",
want: "default",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.args.Fields()
if !reflect.DeepEqual(got[tt.wantKey], tt.want) {
t.Errorf("EntityState.Fields() = got[%s] %v, want[%s] %v", tt.wantKey, got[tt.wantKey], tt.wantKey, tt.want)
}
})
}
}
7 changes: 7 additions & 0 deletions api/core/v3/fielder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package v3

// Fielder includes a set of fields that represent a resource.
type Fielder interface {
// Fields returns a set of fields that represent the resource.
Fields() map[string]string
}
16 changes: 0 additions & 16 deletions api/core/v3/resource_generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,20 +484,4 @@ func TestResourceUniqueness(t *testing.T) {
if got, want := len(types), len(typeMap)/2; got != want {
t.Fatalf("bad number of types: got %d, want %d", got, want)
}
rbacNames := make(map[string]bool)
for _, v := range types {
if name := v.RBACName(); rbacNames[name] {
t.Errorf("duplicate rbac name: %s", name)
} else {
rbacNames[name] = true
}
}
storeNames := make(map[string]bool)
for _, v := range types {
if name := v.StoreName(); storeNames[name] {
t.Errorf("duplicate store suffix: %s", name)
} else {
storeNames[name] = true
}
}
}
16 changes: 0 additions & 16 deletions api/core/v3/resource_generated_test.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -176,20 +176,4 @@ func TestResourceUniqueness(t *testing.T) {
if got, want := len(types), len(typeMap)/2; got != want {
t.Fatalf("bad number of types: got %d, want %d", got, want)
}
rbacNames := make(map[string]bool)
for _, v := range types {
if name := v.RBACName(); rbacNames[name] {
t.Errorf("duplicate rbac name: %s", name)
} else {
rbacNames[name] = true
}
}
storeNames := make(map[string]bool)
for _, v := range types {
if name := v.StoreName(); storeNames[name] {
t.Errorf("duplicate store suffix: %s", name)
} else {
storeNames[name] = true
}
}
}
14 changes: 9 additions & 5 deletions api/core/v3/typemap.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ func init() {
for _, v := range typeMap {
if r, ok := v.(Resource); ok {
rbacMap[r.RBACName()] = r
storeMap[r.StoreName()] = r
}
}
for _, v := range rbacMap {
storeMap[v.StoreName()] = v
}
types.RegisterResolver("core/v3", ResolveRawResource)
}

Expand Down Expand Up @@ -101,8 +99,14 @@ func ResolveResourceByStoreName(name string) (Resource, error) {

// ListResources lists all of the resources in the package.
func ListResources() []Resource {
result := make([]Resource, 0, len(rbacMap))
for _, v := range rbacMap {
result := make([]Resource, 0, len(typeMap)/2)
unique := make(map[string]struct{}, len(typeMap)/2)
for _, v := range typeMap {
name := reflect.ValueOf(v).Elem().Type().Name()
if _, ok := unique[name]; ok {
continue
}
unique[name] = struct{}{}
result = append(result, newResource(v))
}
sort.Slice(result, func(i, j int) bool {
Expand Down
14 changes: 9 additions & 5 deletions api/core/v3/typemap.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ func init() {
for _, v := range typeMap {
if r, ok := v.(Resource); ok {
rbacMap[r.RBACName()] = r
storeMap[r.StoreName()] = r
}
}
for _, v := range rbacMap {
storeMap[v.StoreName()] = v
}
types.RegisterResolver("core/v3", ResolveRawResource)
}

Expand Down Expand Up @@ -97,8 +95,14 @@ func ResolveResourceByStoreName(name string) (Resource, error) {

// ListResources lists all of the resources in the package.
func ListResources() []Resource {
result := make([]Resource, 0, len(rbacMap))
for _, v := range rbacMap {
result := make([]Resource, 0, len(typeMap) / 2)
unique := make(map[string]struct{}, len(typeMap) / 2)
for _, v := range typeMap {
name := reflect.ValueOf(v).Elem().Type().Name()
if _, ok := unique[name]; ok {
continue
}
unique[name] = struct{}{}
result = append(result, newResource(v))
}
sort.Slice(result, func(i, j int) bool {
Expand Down
6 changes: 6 additions & 0 deletions backend/api/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ func (g *GenericClient) list(ctx context.Context, resources interface{}, pred *s
StoreName: g.Kind.StorePrefix(),
Context: ctx,
}
if pred != nil && pred.Ordering == "NAME" {
req.SortOrder = storev2.SortAscend
if pred.Descending {
req.SortOrder = storev2.SortDescend
}
}
list, err := g.StoreV2.List(req, pred)
if err != nil {
return err
Expand Down
Loading