Skip to content

Commit 5808a08

Browse files
authored
Display node attributes as flattened JSON paths (#29)
* add function to generate json path * fix S1034 lint error * update templates
1 parent 188b611 commit 5808a08

File tree

9 files changed

+140
-22
lines changed

9 files changed

+140
-22
lines changed

internal/app/ui/templates/environment.html

+48-7
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,59 @@ <h2 class="environment-headline">{{.environment.Name}}</h2>
66
<p class="lead">{{.environment.Description}}</p>
77
</div>
88
<div class="">
9-
<a type="button" href="/ui/nodes?q=environment:{{.environment.Name}}" class="btn btn-outline-primary">View Nodes</a>
9+
<a type="button" href="/ui/nodes?q=environment:{{.environment.Name}}" class="btn btn-outline-primary">View
10+
Nodes</a>
1011
</div>
1112
</div>
1213
</div>
1314
{{ if .environment.CookbookVersions }}
1415
<h3>Cookbook Versions</h3>
15-
<ul class="list-unstyled">
16-
{{ range $cookbook, $constraint := .environment.CookbookVersions}}
17-
<li><strong>{{ $cookbook }}</strong> {{$constraint}}</li>
18-
{{end}}
19-
</ul>
20-
16+
<ul class="list-unstyled">
17+
{{ range $cookbook, $constraint := .environment.CookbookVersions}}
18+
<li><strong>{{ $cookbook }}</strong> {{$constraint}}</li>
19+
{{end}}
20+
</ul>
2121
{{ end }}
2222

23+
{{ if or .environment.DefaultAttributes .environment.OverrideAttributes }}
24+
<h4>Attributes</h4>
25+
<ul class="nav nav-tabs">
26+
<li class="nav-item">
27+
<a class="nav-link active" data-bs-toggle="tab" data-bs-target="#default-tab-pane">Default</a>
28+
</li>
29+
<li class="nav-item">
30+
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#override-tab-pane">Override</a>
31+
</li>
32+
</ul>
33+
<div class="tab-content" id="myTabContent">
34+
<div class="tab-pane active" id="default-tab-pane" role="tabpanel">
35+
<div class="table-responsive">
36+
<table class="table table-striped">
37+
<tbody>
38+
{{ range $index, $value := .environment.DefaultAttributes }}
39+
<tr>
40+
<td><span class="environment-attribute-key">{{$index}}</span></td>
41+
<td><span class="environment-attribute-value"><code>{{$value}}</code></span></td>
42+
</tr>
43+
{{ end }}
44+
</tbody>
45+
</table>
46+
</div>
47+
</div>
48+
<div class="tab-pane" id="override-tab-pane" role="tabpanel">
49+
<div class="table-responsive">
50+
<table class="table table-striped">
51+
<tbody>
52+
{{ range $index, $value := .environment.OverrideAttributes }}
53+
<tr>
54+
<td><span class="environment-attribute-key">{{$index}}</span></td>
55+
<td><span class="environment-attribute-value"><code>{{$value}}</code></span></td>
56+
</tr>
57+
{{ end }}
58+
</tbody>
59+
</table>
60+
</div>
61+
</div>
62+
</div>
63+
{{ end }}
2364
{{end}}

internal/app/ui/templates/partials/node/attributes.html

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<!-- Attributes -->
22
<ul class="nav nav-tabs">
33
<li class="nav-item">
4-
<a class="nav-link active" data-bs-toggle="tab" data-bs-target="#merged-tab-pane">Merged</a>
4+
<a class="nav-link disabled" data-bs-toggle="tab" data-bs-target="#merged-tab-pane">Merged</a>
55
</li>
66
<li class="nav-item">
7-
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#default-tab-pane">Default</a>
7+
<a class="nav-link active" data-bs-toggle="tab" data-bs-target="#default-tab-pane">Default</a>
88
</li>
99
<li class="nav-item">
1010
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#normal-tab-pane">Normal</a>
@@ -17,62 +17,63 @@
1717
</li>
1818
</ul>
1919
<div class="tab-content" id="myTabContent">
20-
<div class="tab-pane fade show active" id="merged-tab-pane" role="tabpanel">
20+
<div class="tab-pane" id="merged-tab-pane" role="tabpanel">
2121
<div class="table-responsive">
22+
Merge functionality does not exist
2223
<table class="table table-striped">
2324
<tbody>
24-
{{ range $index, $value := .node.DefaultAttributes }}
25+
{{ range $index, $value := .node.NormalAttributes }}
2526
<tr>
26-
<td><span class="node-attribute-key">$.{{$index}}</span></td>
27+
<td><span class="node-attribute-key">{{$index}}</span></td>
2728
<td><span class="node-attribute-value"><code>{{$value}}</code></span></td>
2829
</tr>
2930
{{ end }}
3031
</tbody>
3132
</table>
3233
</div>
3334
</div>
34-
<div class="tab-pane fade show" id="default-tab-pane" role="tabpanel">
35+
<div class="tab-pane active" id="default-tab-pane" role="tabpanel">
3536
<table class="table table-striped">
3637
<tbody>
3738
{{ range $index, $value := .node.DefaultAttributes }}
3839
<tr>
39-
<td><span class="node-attribute-key">$.{{$index}}</span></td>
40+
<td><span class="node-attribute-key">{{$index}}</span></td>
4041
<td><span class="node-attribute-value"><code>{{$value}}</code></span></td>
4142
</tr>
4243
{{ end }}
4344
</tbody>
4445
</table>
4546
</div>
46-
<div class="tab-pane fade" id="normal-tab-pane" role="tabpanel">
47+
<div class="tab-pane" id="normal-tab-pane" role="tabpanel">
4748
<table class="table table-striped">
4849
<tbody>
4950
{{ range $index, $value := .node.NormalAttributes }}
5051
<tr>
51-
<td><span class="node-attribute-key">$.{{$index}}</span></td>
52+
<td><span class="node-attribute-key">{{$index}}</span></td>
5253
<td><span class="node-attribute-value"><code>{{$value}}</code></span></td>
5354
</tr>
5455
{{ end }}
5556
</tbody>
5657
</table>
5758
</div>
58-
<div class="tab-pane fade" id="override-tab-pane" role="tabpanel">
59+
<div class="tab-pane" id="override-tab-pane" role="tabpanel">
5960
<table class="table table-striped">
6061
<tbody>
6162
{{ range $index, $value := .node.OverrideAttributes }}
6263
<tr>
63-
<td><span class="node-attribute-key">$.{{$index}}</span></td>
64+
<td><span class="node-attribute-key">{{$index}}</span></td>
6465
<td><span class="node-attribute-value"><code>{{$value}}</code></span></td>
6566
</tr>
6667
{{ end }}
6768
</tbody>
6869
</table>
6970
</div>
70-
<div class="tab-pane fade" id="automatic-tab-pane" role="tabpanel">
71+
<div class="tab-pane" id="automatic-tab-pane" role="tabpanel">
7172
<table class="table table-striped">
7273
<tbody>
7374
{{ range $index, $value := .node.AutomaticAttributes }}
7475
<tr>
75-
<td><span class="node-attribute-key">$.{{$index}}</span></td>
76+
<td><span class="node-attribute-key">{{$index}}</span></td>
7677
<td><span class="node-attribute-value"><code>{{$value}}</code></span></td>
7778
</tr>
7879
{{ end }}

internal/app/ui/templates/role.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ <h4>Attributes</h4>
3434
<tbody>
3535
{{ range $index, $value := .role.DefaultAttributes }}
3636
<tr>
37-
<td><span class="role-attribute-key">$.{{$index}}</span></td>
37+
<td><span class="role-attribute-key">{{$index}}</span></td>
3838
<td><span class="role-attribute-value"><code>{{$value}}</code></span></td>
3939
</tr>
4040
{{ end }}
@@ -48,7 +48,7 @@ <h4>Attributes</h4>
4848
<tbody>
4949
{{ range $index, $value := .role.OverrideAttributes }}
5050
<tr>
51-
<td><span class="role-attribute-key">$.{{$index}}</span></td>
51+
<td><span class="role-attribute-key">{{$index}}</span></td>
5252
<td><span class="role-attribute-value"><code>{{$value}}</code></span></td>
5353
</tr>
5454
{{ end }}

internal/chef/databags.go

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package chef
33
import (
44
"context"
55
"errors"
6+
"github.com/drewhammond/chefbrowser/internal/util"
67

78
"github.com/go-chef/chef"
89
)
@@ -36,5 +37,6 @@ func (s Service) GetDatabagItemContent(ctx context.Context, databag string, item
3637
return contents, ErrDatabagItemNotFound
3738
}
3839

40+
contents = util.MakeJSONPath(contents.(map[string]interface{}), "$")
3941
return contents, nil
4042
}

internal/chef/environments.go

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package chef
33
import (
44
"context"
55
"errors"
6+
"github.com/drewhammond/chefbrowser/internal/util"
67

78
"github.com/go-chef/chef"
89
)
@@ -25,5 +26,8 @@ func (s Service) GetEnvironment(ctx context.Context, name string) (*chef.Environ
2526
return &chef.Environment{}, ErrEnvironmentNotFound
2627
}
2728

29+
environment.DefaultAttributes = util.MakeJSONPath(environment.DefaultAttributes.(map[string]interface{}), "$")
30+
environment.OverrideAttributes = util.MakeJSONPath(environment.OverrideAttributes.(map[string]interface{}), "$")
31+
2832
return environment, nil
2933
}

internal/chef/nodes.go

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package chef
33
import (
44
"context"
55
"fmt"
6+
"github.com/drewhammond/chefbrowser/internal/util"
67
"sort"
78

89
"github.com/go-chef/chef"
@@ -49,5 +50,10 @@ func (s Service) GetNode(ctx context.Context, name string) (*Node, error) {
4950
return nil, err
5051
}
5152

53+
node.AutomaticAttributes = util.MakeJSONPath(node.AutomaticAttributes, "$")
54+
node.NormalAttributes = util.MakeJSONPath(node.NormalAttributes, "$")
55+
node.DefaultAttributes = util.MakeJSONPath(node.DefaultAttributes, "$")
56+
node.OverrideAttributes = util.MakeJSONPath(node.OverrideAttributes, "$")
57+
5258
return &Node{node}, nil
5359
}

internal/chef/roles.go

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package chef
33
import (
44
"context"
55
"errors"
6+
"github.com/drewhammond/chefbrowser/internal/util"
67
"sort"
78

89
"github.com/go-chef/chef"
@@ -25,6 +26,9 @@ func (s Service) GetRole(ctx context.Context, name string) (*Role, error) {
2526
return nil, ErrRoleNotFound
2627
}
2728

29+
role.DefaultAttributes = util.MakeJSONPath(role.DefaultAttributes.(map[string]interface{}), "$")
30+
role.OverrideAttributes = util.MakeJSONPath(role.OverrideAttributes.(map[string]interface{}), "$")
31+
2832
return &Role{role}, nil
2933
}
3034

internal/util/helpers.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package util
2+
3+
// MakeJSONPath will take a JSON object and return flattened JSON paths
4+
func MakeJSONPath(obj map[string]interface{}, prefix string) map[string]interface{} {
5+
attrs := make(map[string]interface{})
6+
var nested map[string]interface{}
7+
8+
for k, v := range obj {
9+
switch V := v.(type) {
10+
default:
11+
attrs[prefix+"."+k] = V
12+
case map[string]interface{}:
13+
nested = MakeJSONPath(V, prefix+"."+k)
14+
for k2, v2 := range nested {
15+
attrs[k2] = v2
16+
}
17+
}
18+
}
19+
20+
return attrs
21+
}

internal/util/helpers_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package util
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestMakeJSONPath(t *testing.T) {
9+
10+
input := map[string]interface{}{
11+
"stringkey": "stringval",
12+
"somearr": []string{"one", "two", "three"},
13+
"nested": map[string]interface{}{
14+
"foo": "bar",
15+
"hello": "world",
16+
"bool": false,
17+
"int": 123,
18+
"deep": map[string]interface{}{
19+
"nest": "value",
20+
},
21+
},
22+
}
23+
24+
expected := map[string]interface{}{
25+
"$.stringkey": "stringval",
26+
"$.somearr": []string{"one", "two", "three"},
27+
"$.nested.foo": "bar",
28+
"$.nested.bool": false,
29+
"$.nested.int": 123,
30+
"$.nested.hello": "world",
31+
"$.nested.deep.nest": "value",
32+
}
33+
34+
actual := MakeJSONPath(input, "$")
35+
36+
if !reflect.DeepEqual(expected, actual) {
37+
t.Errorf("failed, in: %v, expected: %v, actual: %v", input, expected, actual)
38+
}
39+
}

0 commit comments

Comments
 (0)