Skip to content

Commit

Permalink
code consolidation 1
Browse files Browse the repository at this point in the history
Signed-off-by: kaizhe <derek0405@gmail.com>
  • Loading branch information
Kaizhe committed Feb 6, 2020
1 parent eefcfba commit 0150396
Show file tree
Hide file tree
Showing 9 changed files with 384 additions and 603 deletions.
742 changes: 324 additions & 418 deletions advisor/types/escalation.go

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions advisor/types/escalation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func TestEscalationReportEscalated(t *testing.T) {

r := NewEscalationReport()

r.GenerateEscalationReport(pspRestricted, pspPrivileged)
r.GenerateEscalationReportFromPSPs(pspRestricted, pspPrivileged)

if !r.PrivilegeEscalated() {
t.Fatal("privilege should be escalated")
Expand All @@ -99,11 +99,11 @@ func TestEscalationReportEscalated(t *testing.T) {
t.Fatal("hostPID should be escalated")
}

if !r.RunAsUserStrategyEscalated() {
if !r.RunUserAsRootEscalated() {
t.Fatal("runAsUser should be escalated")
}

if !r.RunAsGroupStrategyEscalated() {
if !r.RunGroupAsRootEscalated() {
t.Fatal("runAsGroup should be escalated")
}

Expand Down Expand Up @@ -135,7 +135,7 @@ func TestEscalationReportReduced(t *testing.T) {

r := NewEscalationReport()

err = r.GenerateEscalationReport(pspPrivileged, pspRestricted)
err = r.GenerateEscalationReportFromPSPs(pspPrivileged, pspRestricted)

if err != nil {
t.Fatal(err)
Expand All @@ -157,11 +157,11 @@ func TestEscalationReportReduced(t *testing.T) {
t.Fatal("hostPID should be reduced")
}

if !r.RunAsUserStrategyReduced() {
if !r.RunUserAsRootReduced() {
t.Fatal("runAsUser should be reduced")
}

if !r.RunAsGroupStrategyReduced() {
if !r.RunGroupAsRootReduced() {
t.Fatal("runAsGroup should be reduced")
}

Expand Down
10 changes: 10 additions & 0 deletions advisor/types/securityspec.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package types

import "github.com/sysdiglabs/kube-psp-advisor/utils"

var (
DefaultCaps = []string{
"SETPCAP",
Expand Down Expand Up @@ -77,3 +79,11 @@ type Metadata struct {
Namespace string `json:"namespace"`
YamlFile string `json:"file"`
}

func (css ContainerSecuritySpec) ContainCapability(cap string) bool {
m := utils.ArrayToMap(css.Capabilities)

_, exsits := m[cap]

return exsits
}
178 changes: 11 additions & 167 deletions comparator/comparator.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,18 @@ import (
"encoding/json"
"fmt"
"log"
"os"
"strings"

"github.com/sysdiglabs/kube-psp-advisor/generator"

"github.com/olekukonko/tablewriter"
"github.com/sysdiglabs/kube-psp-advisor/advisor/types"
"k8s.io/api/policy/v1beta1"
)

const (
NotAvailable = "N/A"
Source = "Source"
Target = "Target"
Source = "Source"
Target = "Target"
)

type Comparator struct {
srcPSP *v1beta1.PodSecurityPolicy
targetPSP *v1beta1.PodSecurityPolicy
escalationReport *types.EscalationReport
gen *generator.Generator
srcCssList []types.ContainerSecuritySpec
Expand Down Expand Up @@ -78,174 +71,25 @@ func (c *Comparator) LoadYamls(yamls []string, dir string) error {
}

func (c *Comparator) Compare() bool {
c.srcPSP = c.gen.GeneratePSP(c.srcCssList, c.srcPssList, "", types.Version1_11)
c.targetPSP = c.gen.GeneratePSP(c.targetCssList, c.targetPssList, "", types.Version1_11)

err := c.escalationReport.GenerateEscalationReport(c.srcPSP, c.targetPSP)

if err != nil {
log.Printf("failed to generate escalation report: %s", err)
}

c.escalationReport.EnrichEscalationReport(c.srcCssList, c.targetCssList, c.srcPssList, c.targetPssList)
c.escalationReport.GenerateEscalationReportFromSecurityContext(c.srcCssList, c.targetCssList, c.srcPssList, c.targetPssList)
log.Printf("%+v\n", c.srcCssList)
log.Printf("%+v\n", c.targetCssList)

return c.escalationReport.NoChanges()
}

func (c *Comparator) ComparePSP(psp1, psp2 *v1beta1.PodSecurityPolicy) bool {
c.clear()

c.srcPSP = psp1
c.targetPSP = psp2
err := c.escalationReport.GenerateEscalationReport(psp1, psp2)

if err != nil {
fmt.Println(err)
}
func (c *Comparator) Clear() {
c.srcCssList = []types.ContainerSecuritySpec{}
c.targetCssList = []types.ContainerSecuritySpec{}
c.srcPssList = []types.PodSecuritySpec{}
c.targetPssList = []types.PodSecuritySpec{}

return c.escalationReport.NoChanges()
}

func (c *Comparator) clear() {
c.srcPSP = nil
c.targetPSP = nil
c.escalationReport = types.NewEscalationReport()
}

func metaListToString(metaList []types.Metadata) string {
ret := []string{}
for _, meta := range metaList {
ret = append(ret, fmt.Sprintf("%s/%s/%s in %s", meta.Kind, meta.Namespace, meta.Name, meta.YamlFile))
}

return strings.Join(ret, "\n")
}

func (c *Comparator) FindPrivilegedChangedWorkload(status int) string {
srcCssMap := map[types.Metadata]types.ContainerSecuritySpec{}
targetCssMap := map[types.Metadata]types.ContainerSecuritySpec{}

metaList := []types.Metadata{}

for _, css := range c.srcCssList {
srcCssMap[css.Metadata] = css
}

for _, css := range c.targetCssList {
targetCssMap[css.Metadata] = css
}

if status == types.Escalated {
for meta, targetCss := range targetCssMap {
srcCss, exits := srcCssMap[meta]
if targetCss.Privileged && (!exits || !srcCss.Privileged) {
metaList = append(metaList, meta)
}
}
} else if status == types.Reduced {
for meta, srcCss := range srcCssMap {
targetCss, exists := targetCssMap[meta]

if !targetCss.Privileged && (!exists || srcCss.Privileged) {
metaList = append(metaList, meta)
}
}
}

return metaListToString(metaList)
}

func (c *Comparator) PrintEscalationReport(jsonFormat bool) {
if c.targetPSP == nil || c.srcPSP == nil {
return
}

if !jsonFormat {
table1 := tablewriter.NewWriter(os.Stdout)
table1.SetHeader([]string{"Security Attributes", "Previous", "Current", "Changed", "Detail"})

data := [][]string{
{"Privileged", getBool(c.srcPSP.Spec.Privileged), getBool(c.targetPSP.Spec.Privileged), types.GetEscalatedStatus(c.escalationReport.Privileged.Status), c.FindPrivilegedChangedWorkload(c.escalationReport.Privileged.Status)},
{"hostIPC", getBool(c.srcPSP.Spec.HostPID), getBool(c.targetPSP.Spec.HostPID), types.GetEscalatedStatus(c.escalationReport.HostPID.Status), ""},
{"hostNetwork", getBool(c.srcPSP.Spec.HostNetwork), getBool(c.targetPSP.Spec.HostNetwork), types.GetEscalatedStatus(c.escalationReport.HostNetwork.Status), ""},
{"HostPID", getBool(c.srcPSP.Spec.HostPID), getBool(c.targetPSP.Spec.HostPID), types.GetEscalatedStatus(c.escalationReport.HostPID.Status), ""},
{"ReadOnlyRootFileSystem", getBool(c.srcPSP.Spec.ReadOnlyRootFilesystem), getBool(c.targetPSP.Spec.ReadOnlyRootFilesystem), types.GetEscalatedStatus(c.escalationReport.ReadOnlyRootFS.Status), ""},
{"RunAsUserStrategy", string(c.srcPSP.Spec.RunAsUser.Rule), string(c.targetPSP.Spec.RunAsUser.Rule), types.GetEscalatedStatus(c.escalationReport.RunAsUserStrategy.Status), ""},
}

srcRunAsGroup := ""
targetRunAsGroup := ""

if c.srcPSP.Spec.RunAsGroup == nil {
srcRunAsGroup = string(v1beta1.RunAsGroupStrategyRunAsAny)
} else {
srcRunAsGroup = string(c.srcPSP.Spec.RunAsGroup.Rule)
}

if c.targetPSP.Spec.RunAsGroup == nil {
targetRunAsGroup = string(v1beta1.RunAsGroupStrategyRunAsAny)
} else {
targetRunAsGroup = string(c.targetPSP.Spec.RunAsGroup.Rule)
}

data = append(data,
[]string{"RunAsGroupStrategy", srcRunAsGroup, targetRunAsGroup, types.GetEscalatedStatus(c.escalationReport.RunAsGroupStrategy.Status)})

table1.AppendBulk(data)

table1.Render()

table2 := tablewriter.NewWriter(os.Stdout)
// print capabilities, volumes
table2.SetHeader([]string{"Security Attributes", "Changed"})

addedCaps := ""
removedCaps := ""
addedVols := ""
removedVols := ""
func (c *Comparator) PrintEscalationReport() {
data, _ := json.Marshal(c.escalationReport)

if c.escalationReport.AddedCapabilities() {
addedCaps = strings.Join(c.escalationReport.NewCapabilities, ",")
} else {
addedCaps = NotAvailable
}

if c.escalationReport.DroppedCapabilities() {
removedCaps = strings.Join(c.escalationReport.RemovedCapabilities, ",")
} else {
removedCaps = NotAvailable
}

if c.escalationReport.AddedVolumes() {
addedVols = strings.Join(c.escalationReport.NewVolumeTypes, ",")
} else {
addedVols = NotAvailable
}

if c.escalationReport.RemovedVolumes() {
removedVols = strings.Join(c.escalationReport.RemovedVolumeTypes, ",")
} else {
removedVols = NotAvailable
}
data2 := [][]string{
{"Added Linux Capabilities", addedCaps},
{"Removed Linux Capabilities", removedCaps},
{"Added Volumes", addedVols},
{"Removed Volumes", removedVols},
}

table2.AppendBulk(data2)

table2.Render()
} else {
data, _ := json.Marshal(c.escalationReport)

fmt.Println(string(data))
}
}
fmt.Println(string(data))

func getBool(value bool) string {
return fmt.Sprintf("%t", value)
}
29 changes: 24 additions & 5 deletions generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,23 @@ func getHostPorts(containerPorts []corev1.ContainerPort) (hostPorts []int32) {

func getEffectiveCapablities(add, drop []string) (effectiveCaps []string) {
dropCapMap := utils.ArrayToMap(drop)
addCapMap := utils.ArrayToMap(add)
defaultCaps := types.DefaultCaps
effectiveCapMap := map[string]bool{}

for _, cap := range defaultCaps {
if _, exists := dropCapMap[cap]; !exists {
effectiveCaps = append(effectiveCaps, cap)
effectiveCapMap[cap] = true
}
}

effectiveCaps = append(effectiveCaps, add...)
for cap := range addCapMap {
if _, exists := dropCapMap[cap]; !exists {
effectiveCapMap[cap] = true
}
}

effectiveCaps = utils.MapToArray(effectiveCapMap)

return
}
Expand Down Expand Up @@ -229,14 +237,25 @@ func getCapabilities(sc *corev1.SecurityContext) (addList []string, dropList []s
addCaps := sc.Capabilities.Add
dropCaps := sc.Capabilities.Drop

addCapMap := map[string]bool{}
dropCapMap := map[string]bool{}

for _, cap := range addCaps {
addList = append(addList, string(cap))
addCapMap[string(cap)] = true
}

for _, cap := range dropCaps {
dropList = append(dropList, string(cap))
dropCapMap[string(cap)] = true
}
return

// delete cap if exists both in the drop list and add list
for cap := range addCapMap {
if _, exists := dropCapMap[cap]; exists {
delete(addCapMap, cap)
delete(dropCapMap, cap)
}
}
return utils.MapToArray(addCapMap), utils.MapToArray(dropCapMap)
}

func mountServiceAccountToken(spec corev1.PodSpec, sa corev1.ServiceAccount) bool {
Expand Down
2 changes: 1 addition & 1 deletion generator/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func TestCSS(t *testing.T) {
t.Fatal("psp should have SYS_ADMIN in capabilities")
}

if !psp.Spec.ReadOnlyRootFilesystem {
if psp.Spec.ReadOnlyRootFilesystem {
t.Fatal("psp should have readonlyrootsystem to false")
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f // indirect
golang.org/x/text v0.3.2 // indirect
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
golang.org/x/tools v0.0.0-20200204192400-7124308813f3 // indirect
golang.org/x/tools v0.0.0-20200205195138-aa017ee80473 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/inf.v0 v0.9.0 // indirect
gopkg.in/yaml.v2 v2.2.4 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 h1:KW20qMcLRWuIgjdCpHFJbVZ
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204192400-7124308813f3 h1:Ms82wn6YK4ZycO6Bxyh0kxX3gFFVGo79CCuc52xgcys=
golang.org/x/tools v0.0.0-20200204192400-7124308813f3/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204230316-67a4523381ef h1:mdhEDFpO1Tfj7PXIflIuP1tbXt4rJgHIvbzdh62SARw=
golang.org/x/tools v0.0.0-20200204230316-67a4523381ef/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200205195138-aa017ee80473 h1:gaOXSkl+mOwq/9Li61bnQwshSq2Te4ekRliwH3SpWSc=
golang.org/x/tools v0.0.0-20200205195138-aa017ee80473/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
Expand Down
Loading

0 comments on commit 0150396

Please sign in to comment.