-
Notifications
You must be signed in to change notification settings - Fork 15
/
table_kubernetes_pod_security_policy.go
272 lines (245 loc) · 9.15 KB
/
table_kubernetes_pod_security_policy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
package kubernetes
import (
"context"
v1beta1 "k8s.io/api/policy/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"
)
func tableKubernetesPodSecurityPolicy(ctx context.Context) *plugin.Table {
return &plugin.Table{
Name: "kubernetes_pod_security_policy",
Description: "A Pod Security Policy is a cluster-level resource that controls security sensitive aspects of the pod specification. The PodSecurityPolicy objects define a set of conditions that a pod must run with in order to be accepted into the system, as well as defaults for the related fields.",
Get: &plugin.GetConfig{
KeyColumns: plugin.SingleColumn("name"),
Hydrate: getPodSecurityPolicy,
},
List: &plugin.ListConfig{
Hydrate: listPodSecurityPolicy,
},
// PodSecurityPolicy, is a non-namespaced resource.
Columns: k8sCommonGlobalColumns([]*plugin.Column{
// PodSecurityPolicySpec
{
Name: "allow_privilege_escalation",
Type: proto.ColumnType_BOOL,
Description: "Determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.",
Transform: transform.FromField("Spec.AllowPrivilegeEscalation"),
},
{
Name: "default_allow_privilege_escalation",
Type: proto.ColumnType_BOOL,
Description: "Controls the default setting for whether a process can gain more privileges than its parent process.",
Transform: transform.FromField("Spec.DefaultAllowPrivilegeEscalation"),
},
{
Name: "host_network",
Type: proto.ColumnType_BOOL,
Description: "Determines if the policy allows the use of HostNetwork in the pod spec.",
Transform: transform.FromField("Spec.HostNetwork"),
},
{
Name: "host_ports",
Type: proto.ColumnType_JSON,
Description: "Determines which host port ranges are allowed to be exposed.",
Transform: transform.FromField("Spec.HostPorts"),
},
{
Name: "host_pid",
Type: proto.ColumnType_BOOL,
Description: "Determines if the policy allows the use of HostPID in the pod spec.",
Transform: transform.FromField("Spec.HostPID"),
},
{
Name: "host_ipc",
Type: proto.ColumnType_BOOL,
Description: "Determines if the policy allows the use of HostIPC in the pod spec.",
Transform: transform.FromField("Spec.HostIPC"),
},
{
Name: "privileged",
Type: proto.ColumnType_BOOL,
Description: "privileged determines if a pod can request to be run as privileged.",
Transform: transform.FromField("Spec.Privileged"),
},
{
Name: "read_only_root_filesystem",
Type: proto.ColumnType_BOOL,
Description: "If set to true will force containers to run with a read only root file system. If set to false the container may run with a read only root file system if it wishes but it will not be forced to.",
Transform: transform.FromField("Spec.ReadOnlyRootFilesystem"),
},
// JSON Fields
{
Name: "allowed_csi_drivers",
Type: proto.ColumnType_JSON,
Description: "An allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.",
Transform: transform.FromField("Spec.allowedCSIDrivers"),
},
{
Name: "allowed_host_paths",
Type: proto.ColumnType_JSON,
Description: "An allowlist of host paths. Empty indicates that all host paths may be used.",
Transform: transform.FromField("Spec.AllowedHostPaths"),
},
{
Name: "allowed_flex_volumes",
Type: proto.ColumnType_JSON,
Description: "An allowlist of Flexvolumes. Empty or nil indicates that all Flexvolumes may be used.",
Transform: transform.FromField("Spec.AllowedFlexVolumes"),
},
{
Name: "allowed_proc_mount_types",
Type: proto.ColumnType_JSON,
Description: "An allowlist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used.",
Transform: transform.FromField("Spec.AllowedProcMountTypes"),
},
{
Name: "allowed_unsafe_sysctls",
Type: proto.ColumnType_JSON,
Description: "List of explicitly allowed unsafe sysctls, defaults to none.",
Transform: transform.FromField("Spec.AllowedUnsafeSysctls"),
},
{
Name: "default_add_capabilities",
Type: proto.ColumnType_JSON,
Description: "List of the default set of capabilities that will be added to the container unless the pod spec specifically drops the capability.",
Transform: transform.FromField("Spec.DefaultAddCapabilities"),
},
{
Name: "forbidden_sysctls",
Type: proto.ColumnType_JSON,
Description: "List of explicitly forbidden sysctls, defaults to none.",
Transform: transform.FromField("Spec.ForbiddenSysctls"),
},
{
Name: "fs_group",
Type: proto.ColumnType_JSON,
Description: "The strategy that will dictate what fs group is used by the SecurityContext.",
Transform: transform.FromField("Spec.FSGroup"),
},
{
Name: "required_drop_capabilities",
Type: proto.ColumnType_JSON,
Description: "List of the capabilities that will be dropped from the container. These are required to be dropped and cannot be added.",
Transform: transform.FromField("Spec.RequiredDropCapabilities"),
},
{
Name: "run_as_group",
Type: proto.ColumnType_JSON,
Description: "The strategy that will dictate the allowable RunAsGroup values that may be set.",
Transform: transform.FromField("Spec.RunAsGroup"),
},
{
Name: "run_as_user",
Type: proto.ColumnType_JSON,
Description: "The strategy that will dictate the allowable RunAsUser values that may be set.",
Transform: transform.FromField("Spec.RunAsUser"),
},
{
Name: "runtime_class",
Type: proto.ColumnType_JSON,
Description: "The strategy that will dictate the allowable RuntimeClasses for a pod.",
Transform: transform.FromField("Spec.RuntimeClass"),
},
{
Name: "se_linux",
Type: proto.ColumnType_JSON,
Description: "The strategy that will dictate the allowable labels that may be set.",
Transform: transform.FromField("Spec.SELinux"),
},
{
Name: "supplemental_groups",
Type: proto.ColumnType_JSON,
Description: "The strategy that will dictate what supplemental groups are used by the SecurityContext.",
Transform: transform.FromField("Spec.SupplementalGroups"),
},
{
Name: "volumes",
Type: proto.ColumnType_JSON,
Description: "An allowlist of volume plugins. Empty indicates that no volumes may be used.",
Transform: transform.FromField("Spec.Volumes"),
},
//// Steampipe Standard Columns
{
Name: "title",
Type: proto.ColumnType_STRING,
Description: ColumnDescriptionTitle,
Transform: transform.FromField("Name"),
},
{
Name: "tags",
Type: proto.ColumnType_JSON,
Description: ColumnDescriptionTags,
Transform: transform.From(transformPodSecurityPolicyTags),
},
}),
}
}
//// HYDRATE FUNCTIONS
func listPodSecurityPolicy(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
logger := plugin.Logger(ctx)
logger.Trace("listPodSecurityPolicy")
clientset, err := GetNewClientset(ctx, d)
if err != nil {
return nil, err
}
input := metav1.ListOptions{
Limit: 500,
}
// Limiting the results
limit := d.QueryContext.Limit
if d.QueryContext.Limit != nil {
if *limit < input.Limit {
if *limit < 1 {
input.Limit = 1
} else {
input.Limit = *limit
}
}
}
var response *v1beta1.PodSecurityPolicyList
pageLeft := true
for pageLeft {
response, err = clientset.PolicyV1beta1().PodSecurityPolicies().List(ctx, input)
if err != nil {
return nil, err
}
if response.GetContinue() != "" {
input.Continue = response.Continue
} else {
pageLeft = false
}
for _, podSecurityPolicy := range response.Items {
d.StreamListItem(ctx, podSecurityPolicy)
// Context can be cancelled due to manual cancellation or the limit has been hit
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}
}
return nil, nil
}
func getPodSecurityPolicy(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
logger := plugin.Logger(ctx)
logger.Trace("getPodSecurityPolicy")
clientset, err := GetNewClientset(ctx, d)
if err != nil {
return nil, err
}
name := d.EqualsQuals["name"].GetStringValue()
// return if name is empty
if name == "" {
return nil, nil
}
podSecurityPolicy, err := clientset.PolicyV1beta1().PodSecurityPolicies().Get(ctx, name, metav1.GetOptions{})
if err != nil && !isNotFoundError(err) {
return nil, err
}
return *podSecurityPolicy, nil
}
//// TRANSFORM FUNCTIONS
func transformPodSecurityPolicyTags(_ context.Context, d *transform.TransformData) (interface{}, error) {
obj := d.HydrateItem.(v1beta1.PodSecurityPolicy)
return mergeTags(obj.Labels, obj.Annotations), nil
}