github.com/tigera/api@v0.0.0-20240320170621-278e89a8c5fb/pkg/apis/projectcalico/v3/reportdata.go (about) 1 // Copyright (c) 2019 Tigera, Inc. All rights reserved. 2 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package v3 16 17 import ( 18 "fmt" 19 20 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 "k8s.io/apiserver/pkg/apis/audit" 22 ) 23 24 // ReportData contains the aggregated data available for rendering in report templates. The data available is dependent 25 // on the selector/report configuration. 26 // 27 // The data is stored directly in elastic search. To reduce nesting and simplify indexing, all summary values are 28 // contained at the top level. 29 type ReportData struct { 30 ReportName string `json:"reportName"` 31 ReportTypeName string `json:"reportTypeName"` 32 ReportSpec ReportSpec `json:"reportSpec"` 33 ReportTypeSpec ReportTypeSpec `json:"reportTypeSpec"` 34 StartTime metav1.Time `json:"startTime"` 35 EndTime metav1.Time `json:"endTime"` 36 GenerationTime metav1.Time `json:"generationTime"` 37 38 // The set of in-scope endpoints. 39 Endpoints []EndpointsReportEndpoint `json:"endpoints,omitempty"` 40 41 // Endpoint stats in a reporting period. 42 EndpointsSummary EndpointsSummary `json:"endpointsSummary,omitempty"` 43 44 // The set of namespaces containing in-scope endpoints. 45 Namespaces []EndpointsReportNamespace `json:"namespaces,omitempty"` 46 47 // Endpoint stats for given namespaces in a reporting period. 48 NamespacesSummary EndpointsSummary `json:"namespacesSummary,omitempty"` 49 50 // The set of services containing in-scope endpoints. 51 Services []EndpointsReportService `json:"services,omitempty"` 52 53 // Endpoint stats for services in a reporting period. 54 ServicesSummary EndpointsSummary `json:"servicesSummary,omitempty"` 55 56 // The time-ordered set of in-scope audit events that occurred within the reporting interval. 57 AuditEvents []audit.Event `json:"auditEvents,omitempty"` 58 59 // Audit log stats in a reporting period. 60 AuditSummary AuditSummary `json:"auditSummary,omitempty"` 61 62 // Flows for in-scope endpoints that have been recorded within the reporting period. 63 Flows []EndpointsReportFlow `json:"flows,omitempty"` 64 65 // CISBenchmark contains the per-node results of a cis benchmark scan. 66 CISBenchmark []CISBenchmarkNode `json:"cisBenchmark,omitempty"` 67 68 // CISBenchmarkSummary high level test results. 69 CISBenchmarkSummary CISBenchmarkSummary `json:"cisBenchmarkSummary,omitempty"` 70 } 71 72 // This tracks different statistics for Endpoints, Summary and Services. 73 type EndpointsSummary struct { 74 // For endpoints: the total number of in-scope endpoints. 75 // Namespaces: the total number of namespaces containing in-scope endpoints. 76 // Services: the total number of services containing in-scope endpoints. 77 // 78 // Source: Calculated from pod/wep, hep, namespace and service account labels. 79 NumTotal int `json:"numTotal,omitempty"` 80 81 // For endpoints: the total number of service accounts for in-scope endpoints. 82 // Namespaces: n/a. 83 // Services: n/a. 84 NumServiceAccounts int `json:"numServiceAccounts,omitempty"` 85 86 // For endpoints: the number of in-scope endpoints that were ingress protected during the reporting interval. 87 // Namespaces: the number of namespaces whose in-scope endpoints were ingress protected during 88 // the reporting interval. 89 // Services: the number of services whose in-scope endpoints were ingress protected during the reporting 90 // interval. 91 // 92 // See below for defn of ingress-protected. 93 NumIngressProtected int `json:"numIngressProtected,omitempty"` 94 95 // For endpoints: the number of in-scope endpoints that were egress protected during the reporting interval. 96 // Namespaces: the number of namespaces whose in-scope endpoints were egress protected during the reporting 97 // interval. 98 // 99 // See below for defn of egress-protected. 100 NumEgressProtected int `json:"numEgressProtected,omitempty"` 101 102 // For endpoints: the number of in-scope endpoints whose policy would allow ingress traffic from the Internet 103 // for *any* period within the reporting interval. 104 // (See below for how this is calculated for an endpoint.) 105 // Namespaces: the number of namespaces that contained in-scope endpoints that would allow ingress traffic 106 // from the Internet for *any* period within the reporting interval. 107 // Services: the number of services that contained in-scope endpoints that would allow ingress traffic 108 // from the Internet for *any* period within the reporting interval. 109 NumIngressFromInternet int `json:"numIngressFromInternet,omitempty"` 110 111 // For endpoints: the number of in-scope endpoints whose policy would allow egress traffic to the Internet 112 // for *any* period within the reporting interval. 113 // (See below for how this is calculated for an endpoint.) 114 // Namespaces: the number of namespaces that contained in-scope endpoints that would allow egress traffic 115 // to the Internet for *any* period within the reporting interval. 116 NumEgressToInternet int `json:"numEgressToInternet,omitempty"` 117 118 // For endpoints: the number of in-scope endpoints whose policy would allow ingress traffic from a 119 // different namespace for *any* period within the reporting interval. 120 // (See below for how this is calculated for an endpoint.) 121 // Namespaces: the number of namespaces that contained in-scope endpoints that would allow ingress 122 // traffic from another namespace for *any* period within the reporting interval. 123 // Services: the number of services that contained in-scope endpoints that would allow ingress 124 // traffic from another namespace for *any* period within the reporting interval. 125 NumIngressFromOtherNamespace int `json:"numIngressFromOtherNamespace,omitempty"` 126 127 // For endpoints: the number of in-scope endpoints whose policy would allow ingress traffic from 128 // a different namespace for *any* period within the reporting interval. 129 // (See below for how this is calculated for an endpoint.) 130 // Namespaces: the number of namespaces that contained in-scope endpoints that would allow egress 131 // traffic to another namespace for *any* period within the reporting interval. 132 NumEgressToOtherNamespace int `json:"numEgressToOtherNamespace,omitempty"` 133 134 // For endpoints: the number of in-scope endpoints that were envoy-enabled within the reporting interval. 135 // Namespaces: the number of namespaces whose in-scope endpoints were always Envoy-enabled 136 // Services: the number of services whose in-scope endpoints were always Envoy-enabled 137 // 138 // See below for defn of envoy-enabled 139 NumEnvoyEnabled int `json:"numEnvoyEnabled,omitempty"` 140 } 141 142 type AuditSummary struct { 143 // The total number of in-scope audit logs. 144 NumTotal int `json:"numTotal,omitempty"` 145 146 // The number of in-scope audit log create events. 147 NumCreate int `json:"numCreate,omitempty"` 148 149 // The number of in-scope audit log patch or replace events. 150 NumModify int `json:"numModify,omitempty"` 151 152 // The number of in-scope audit log delete events. 153 NumDelete int `json:"numDelete,omitempty"` 154 } 155 156 type EndpointsReportEndpoint struct { 157 Endpoint ResourceID `json:"endpoint,omitempty"` 158 159 // Whether ingress traffic to this endpoint was always protected during the reporting interval. 160 // 161 // Ingress protection is defined as denying ingress traffic unless explicitly whitelisted. This is translated as 162 // the endpoint having some explicit ingress policy applied to it. 163 // 164 // Source: Calculated from the set of ingress policies that apply to each endpoint. 165 // 166 // Set to: 167 // - false if there are no ingress policies applied to the endpoint at any point during the reporting interval. 168 // - true otherwise. 169 // 170 // Note: Policy is not inspected for protection bypass: for example match-all-and-allow rules which would effectively 171 // short-circuit the default tier-drop behavior, in this case the match-all-and-allow would be considered to be 172 // an explicit whitelist of all traffic. We could include simplistic all-match rules and check that they 173 // don't result in an allow. To check for more circuitous match-all allows is much trickier (e.g. you have one 174 // rule that allows for src!=1.2.3.0/24 and another rule that allows for src==1.2.3.0/24, which combined 175 // is essentially an allow-all). 176 IngressProtected bool `json:"ingressProtected,omitempty"` 177 178 // Whether egress traffic to this endpoint was always protected during the reporting interval. 179 // 180 // Egress protection is defined as denying egress traffic unless explicitly whitelisted. This is translated as 181 // the endpoint having some explicit egress policy applied to it. 182 // 183 // Source: Calculated from the set of egress policies that apply to each endpoint. 184 // 185 // Set to: 186 // - false if there are no egress policies applied to the endpoint at any point during the reporting interval. 187 // - true otherwise. 188 // 189 // Note: Policy is not inspected for protection bypass: for example match-all-and-allow rules which would effectively 190 // short-circuit the default tier-drop behavior, in this case the match-all-and-allow would be considered to be 191 // an explicit whitelist of all traffic. We could include simplistic all-match rules and check that they 192 // don't result in an allow. To check for more circuitous match-all allows is much trickier (e.g. you have one 193 // rule that allows for src!=1.2.3.0/24 and another rule that allows for src==1.2.3.0/24, which combined 194 // is essentially an allow-all). Similarly, policy that only contains pass rules would still count as being 195 // protected. 196 EgressProtected bool `json:"egressProtected,omitempty"` 197 198 // Whether the matching policy has any ingress allow rules from a public IP address (as defined by the complement of 199 // the private addresses; private addresses default to those defined in RFC 1918, but may also be configured separately). 200 // 201 // Source: Calculated from the policies applied to the endpoint. The ingress allow rules in each policy are checked 202 // to determine if any CIDR specified in the rule, either directly or through a matching network set, is an 203 // internet address. Endpoint addresses are not included - therefore ingress from a pod that has a public 204 // IP address will not be considered as “from internet”. 205 // 206 // Note: This is a simplification since it does not examine the policies to determine if it's actually possible to 207 // hit one of these allow rules (e.g. a previous rule may be a match-all-deny). 208 IngressFromInternet bool `json:"ingressFromInternet,omitempty"` 209 210 // Whether the matching policy has any egress allow rules to a public IP address (as defined by the complement of 211 // the private addresses; private addresses default to those defined in RFC 1918, but may also be configured separately). 212 // 213 // Source: Calculated from the policies applied to the endpoint. The egress allow rules in each policy are checked 214 // to determine if any CIDR specified in the rule, either directly or through a matching network set, is an 215 // internet address. Endpoint addresses are not included - therefore egress to a pod that has a public 216 // IP address will not be considered as “to internet”. 217 // 218 // Note 1: This is a simplification since it does not examine the policies to determine if it's actually possible to 219 // hit one of these allow rules (e.g. a previous rule may be a match-all-deny). 220 EgressToInternet bool `json:"egressToInternet,omitempty"` 221 222 // Whether the matching policy has any ingress allow rules from another namespace. 223 // 224 // Source: Calculated from the policies applied to the endpoint. 225 // 226 // Set to true if: 227 // - this is a pod (i.e. namespaced) with an applied GlobalNetworkPolicy with an ingress allow rule with no CIDR match. 228 // - this is a pod with an applied NetworkPolicy with an ingress allow rule with a non-empty NamespaceSelector. 229 // 230 // Note: This is a simplification since it does not examine the policies to determine if it's actually possible to 231 // hit one of these allow rules (e.g. a previous rule may be a match-all-deny, or endpoint selector may not 232 // match any endpoints within the namespace). 233 IngressFromOtherNamespace bool `json:"ingressFromOtherNamespace,omitempty"` 234 235 // Whether the matching policy has any egress allow rules to another namespace. 236 // 237 // Source: Calculated from the policies applied to the endpoint. 238 // 239 // Set to true if: 240 // - this is a pod endpoint (i.e. namespaced) matches a GlobalNetworkPolicy with an egress allow rule with no CIDR match. 241 // - this is a pod endpoint which matches a NetworkPolicy with an egress allow rule with a non-empty NamespaceSelector. 242 // 243 // Note: This is a simplification since it does not examine the policies to determine if it's actually possible to 244 // hit one of these allow rules (e.g. a previous rule may be a match-all-deny, or endpoint selector may not 245 // match any endpoints within the namespace). 246 EgressToOtherNamespace bool `json:"egressToOtherNamespace,omitempty"` 247 248 // Whether this pod is envoy-enabled. This is simply an indicator of whether an Envoy container is running within the pod. 249 // Provided Istio is configured appropriately, this can provide a simplistic determination of whether the pod is mTLS 250 // enabled. 251 // 252 // Source: Pod spec. 253 // 254 // Set to: 255 // - true if envoy is running within the pod 256 // - false if envoy is not running within the pod 257 EnvoyEnabled bool `json:"envoyEnabled,omitempty"` 258 259 // The set of policies that apply to an endpoint may change within the reporting interval, this is the superset of all 260 // policies that applied to the endpoint during that interval. 261 AppliedPolicies []ResourceID `json:"appliedPolicies,omitempty"` 262 263 // The list of services that exposed this endpoint at any moment during the reporting interval. 264 // 265 // Source: Determined from the Kubernetes endpoints resource associated with the service. 266 Services []ResourceID `json:"services,omitempty"` 267 268 // The ServiceAccount configured on this endpoint. 269 ServiceAccount string `json:"serviceAccount,omitempty"` 270 271 // The flow log aggregation name. This is used to locate flow logs associated with this endpoint when flow log 272 // aggregation is turned on. 273 FlowLogAggregationName string `json:"flowLogAggregationName,omitempty"` 274 } 275 276 type EndpointsReportFlow struct { 277 // The source of the flow log. 278 Source FlowEndpoint `json:"source"` 279 280 // The destination of the flow log. 281 Destination FlowEndpoint `json:"destination"` 282 } 283 284 type FlowEndpoint struct { 285 // The endpoint type, indicating whether this is a Pod, HostEndpoint, NetworkSet, or internet. 286 Kind string `json:"kind"` 287 288 // The name of the endpoint. Note that this name may actually be a name prefix if flow logs have 289 // been aggregated. 290 Name string `json:"name"` 291 292 // Whether the name is an aggregation prefix rather than the actual name. 293 NameIsAggregationPrefix bool `json:"nameIsAggregationPrefix,omitempty"` 294 295 // The namespace of the endpoint. 296 Namespace string `json:"namespace,omitempty"` 297 } 298 299 type EndpointsReportNamespace struct { 300 Namespace ResourceID `json:"namespace,omitempty"` 301 302 // Whether ingress traffic was protected for all endpoints within this namespace within the reporting interval. 303 // This is a summary of information contained in the endpoints data. 304 IngressProtected bool `json:"ingressProtected,omitempty"` 305 306 // Whether egress traffic was protected for all endpoints within this namespace within the reporting interval. 307 // This is a summary of information contained in the endpoints data. 308 EgressProtected bool `json:"egressProtected,omitempty"` 309 310 // Whether ingress traffic was allowed from the internet for any endpoint within this namespace within the reporting 311 // interval. 312 IngressFromInternet bool `json:"ingressFromInternet,omitempty"` 313 314 // Whether ingress traffic was allowed from the internet for any endpoint within this namespace within the reporting 315 // interval. 316 EgressToInternet bool `json:"egressToInternet,omitempty"` 317 318 // Whether ingress traffic was allowed from another namespace for any endpoint within this namespace within the 319 // reporting interval. 320 IngressFromOtherNamespace bool `json:"ingressFromOtherNamespace,omitempty"` 321 322 // Whether ingress traffic was allowed from another namespace for any endpoint within this namespace within the 323 // reporting interval. 324 EgressToOtherNamespace bool `json:"egressToOtherNamespace,omitempty"` 325 326 // Whether envoy was enabled for all endpoints within this namespace within the reporting interval. 327 // This is a summary of information contained in the endpoints data. 328 EnvoyEnabled bool `json:"envoyEnabled,omitempty"` 329 } 330 331 type EndpointsReportService struct { 332 Service ResourceID `json:"service,omitempty"` 333 334 // Whether ingress traffic was protected for all endpoints within this namespace within the reporting interval. 335 // This is a summary of information contained in the endpoints data. 336 IngressProtected bool `json:"ingressProtected,omitempty"` 337 338 // Whether ingress traffic was allowed from the internet for any endpoint exposed by this service within the reporting 339 // interval. 340 IngressFromInternet bool `json:"ingressFromInternet,omitempty"` 341 342 // Whether ingress traffic was allowed from another namespace for any endpoint exposed by this service within the 343 // reporting interval. 344 IngressFromOtherNamespace bool `json:"ingressFromOtherNamespace,omitempty"` 345 346 // Whether envoy was enabled for all endpoints that were exposed by this service within the reporting interval. 347 // This is a summary of information contained in the endpoints data. 348 EnvoyEnabled bool `json:"envoyEnabled,omitempty"` 349 } 350 351 // Prints FlowEndpoint contents. This is a slightly less verbose version of the resource names but should have 352 // sufficient context to be useful. 353 func (f FlowEndpoint) String() string { 354 switch f.Kind { 355 case KindK8sPod: 356 // We add in the v1 version to be inline with the ResourceID printed format. 357 return fmt.Sprintf("%s.v1(%s/%s)", f.Kind, f.Namespace, f.Name) 358 case KindHostEndpoint, KindGlobalNetworkSet: 359 return fmt.Sprintf("%s(%s)", f.Kind, f.Name) 360 case KindFlowPublic, KindFlowPrivate: 361 return f.Kind 362 } 363 return fmt.Sprintf("%s(%s/%s)", f.Kind, f.Namespace, f.Name) 364 } 365 366 // CISBenchmarkSummary describes a CIS benchmarking result across an entire cluster. 367 type CISBenchmarkSummary struct { 368 Type string `json:"type"` 369 HighCount int `json:"highCount"` 370 MedCount int `json:"medCount"` 371 LowCount int `json:"lowCount"` 372 } 373 374 // CISBenchmarkNode describes a CIS benchmarking result on a single node. 375 type CISBenchmarkNode struct { 376 // NodeName is the name of the node the this set of benchmark results is from. 377 NodeName string `json:"nodeName"` 378 379 // KubernetesVersion is the version of the kubelet running on this node. 380 KubernetesVersion string `json:"kubernetesVersion"` 381 382 // BenchmarksVersion is the version of the benchmarks that ran on this node. 383 BenchmarksVersion string `json:"benchmarksVersion"` 384 385 // Summary is a set of summary stats for this set of node-specific benchmarks. 386 Summary CISBenchmarkNodeSummary `json:"summary"` 387 388 // Results is the detailed set of results for this set of node-specific benchmarks. 389 Results []CISBenchmarkSectionResult `json:"results"` 390 } 391 392 // CISBenchmarkNodeSummary keeps count of tests passed, failed, and marked as info on a single node. 393 // Also has a status field to describe whether it is in HIGH, MED, or LOW status (based on [high|med]Threshold). 394 type CISBenchmarkNodeSummary struct { 395 Status string `json:"status"` 396 TotalPass int `json:"totalPass"` 397 TotalFail int `json:"totalFail"` 398 TotalInfo int `json:"totalInfo"` 399 Total int `json:"total"` 400 } 401 402 // CISBenchmarkSectionResult describes the result of running the CIS benchmark on a single component. 403 type CISBenchmarkSectionResult struct { 404 Status string `json:"status"` 405 Section string `json:"section"` 406 Desc string `json:"desc"` 407 Pass int `json:"pass"` 408 Fail int `json:"fail"` 409 Info int `json:"info"` 410 Results []CISBenchmarkResult `json:"results"` 411 } 412 413 // CISBenchmarkResult describes the result of a single CIS benchmark check. 414 type CISBenchmarkResult struct { 415 TestNumber string `json:"testNumber"` 416 TestDesc string `json:"testDesc"` 417 TestInfo string `json:"testInfo"` 418 Status string `json:"status"` 419 Scored bool `json:"scored"` 420 } 421 422 // CISBenchmarkResultCount keeps track of how many nodes had a certain test result. 423 type CISBenchmarkResultCount struct { 424 CISBenchmarkResult 425 Count int `json:"count"` 426 }