Skip to content

Commit

Permalink
feat: add multi cis spec support (#113)
Browse files Browse the repository at this point in the history
* feat: add multi cis spec support

Signed-off-by: chenk <[email protected]>

* feat: multi cis spec support

Signed-off-by: chenk <[email protected]>

* feat: multi cis spec support

Signed-off-by: chenk <[email protected]>

* feat: multi cis spec support

Signed-off-by: chenk <[email protected]>

* feat: multi cis spec support

Signed-off-by: chenk <[email protected]>

* feat: multi cis spec support

Signed-off-by: chenk <[email protected]>

* feat: multi cis spec support

Signed-off-by: chenk <[email protected]>

* feat: multi cis spec support

Signed-off-by: chenk <[email protected]>

* feat: multi cis spec support

Signed-off-by: chenk <[email protected]>

---------

Signed-off-by: chenk <[email protected]>
  • Loading branch information
chen-keinan authored May 2, 2024
1 parent a4bf9de commit e67c4e9
Show file tree
Hide file tree
Showing 7 changed files with 420 additions and 80 deletions.
134 changes: 105 additions & 29 deletions pkg/collector/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,35 @@ import (
"context"
"encoding/json"
"errors"
"os"
"strings"
"time"

"fmt"
"log"
"os"
"path/filepath"

"strconv"
"time"

"github.com/spf13/cobra"
)

var configMapper = map[string]string{
"kubeletAnonymousAuthArgumentSet": "authentication.anonymous.enabled",
"kubeletAuthorizationModeArgumentSet": "authorization.mode",
"kubeletClientCaFileArgumentSet": "authentication.x509.clientCAFile",
"kubeletReadOnlyPortArgumentSet": "readOnlyPort",
"kubeletStreamingConnectionIdleTimeoutArgumentSet": "streamingConnectionIdleTimeout",
"kubeletProtectKernelDefaultsArgumentSet": "protectKernelDefaults",
"kubeletMakeIptablesUtilChainsArgumentSet": "makeIPTablesUtilChains",
"kubeletEventQpsArgumentSet": "eventRecordQPS",
"kubeletRotateKubeletServerCertificateArgumentSet": "featureGates.RotateKubeletServerCertificate",
"kubeletRotateCertificatesArgumentSet": "rotateCertificates",
"kubeletTlsCertFileTlsArgumentSet": "tlsCertFile",
"kubeletTlsPrivateKeyFileArgumentSet": "tlsPrivateKeyFile",
"kubeletOnlyUseStrongCryptographic": "tlsCipherSuites",
}

type SpecVersion struct {
Name string
Version string
}

var platfromSpec = map[string]SpecVersion{
"k8s-1.23": {
Name: "cis",
Name: "k8s-cis",
Version: "1.23",
},
}

// CollectData run spec audit command and output it result data
func CollectData(cmd *cobra.Command, target string) error {
log.SetFlags(log.LstdFlags | log.Lmicroseconds)

cluster, err := GetCluster()
if err != nil {
return err
Expand All @@ -65,15 +54,20 @@ func CollectData(cmd *cobra.Command, target string) error {
if err != nil {
return err
}
infoCollectorMap, err := LoadConfig(target)
lp, err := LoadConfigParams()
if err != nil {
return err
}
cm := configParams(lp, shellCmd)
infoCollectorMap, err := LoadConfig(target, cm)
if err != nil {
return err
}
specName := cmd.Flag("spec").Value.String()
specVersion := cmd.Flag("version").Value.String()
sv := SpecVersion{Name: specName, Version: specVersion}
if len(sv.Name) == 0 || len(sv.Version) == 0 {
sv = specByPlatfromVersion(p.Name)
sv = specByPlatfromVersion(p)
}
for _, infoCollector := range infoCollectorMap {
nodeInfo := make(map[string]*Info)
Expand All @@ -86,19 +80,19 @@ func CollectData(cmd *cobra.Command, target string) error {
}
output, err := shellCmd.Execute(ci.Audit)
if err != nil {
fmt.Print(err)
return err
}
values := StringToArray(output, ",")
nodeInfo[ci.Key] = &Info{Values: values}
}
nodeName := cmd.Flag("node").Value.String()
nodeConfig, err := loadNodeConfig(ctx, *cluster, nodeName)
if err == nil {

configVal, err := getValuesFromkubeletConfig(nodeConfig)
mapping, err := LoadKubeletMapping()
if err != nil {
return err
}
configVal := getValuesFromkubeletConfig(nodeConfig, mapping)
mergeConfigValues(nodeInfo, configVal)
}
nodeData := Node{
Expand Down Expand Up @@ -130,17 +124,18 @@ func loadNodeConfig(ctx context.Context, cluster Cluster, nodeName string) (map[
return nodeConfig, nil
}

func specByPlatfromVersion(platfrom string) SpecVersion {
return platfromSpec[fmt.Sprintf("%s-%s", platfrom, platfrom)]
func specByPlatfromVersion(platfrom Platform) SpecVersion {
return platfromSpec[fmt.Sprintf("%s-%s", platfrom.Name, platfrom.Version)]
}

func getValuesFromkubeletConfig(nodeConfig map[string]interface{}) (map[string]*Info, error) {
func getValuesFromkubeletConfig(nodeConfig map[string]interface{}, configMapper map[string]string) map[string]*Info {
overrideConfig := make(map[string]*Info)
values := nodeConfig["kubeletconfig"]
for k, v := range configMapper {
p := values
var found bool
splittedValues := StringToArray(v, ".")
paramValue := strings.TrimPrefix(v, "kubeletconfig.")
splittedValues := StringToArray(paramValue, ".")
for _, sv := range splittedValues {
next := p.(map[string]interface{})
if k, ok := next[sv.(string)]; ok {
Expand All @@ -161,7 +156,7 @@ func getValuesFromkubeletConfig(nodeConfig map[string]interface{}) (map[string]*
}
}
}
return overrideConfig, nil
return overrideConfig
}

func mergeConfigValues(configValues map[string]*Info, overrideConfig map[string]*Info) map[string]*Info {
Expand All @@ -170,3 +165,84 @@ func mergeConfigValues(configValues map[string]*Info, overrideConfig map[string]
}
return configValues
}

func binLookup(binsNames []string, defaultBinName string, sh Shell) string {
if len(binsNames) == 0 {
return ""
}
for _, bin := range binsNames {
cmd := fmt.Sprintf(`pgrep -l "" | grep '%s' | awk '{print $2}' | awk 'NR==1' 2>/dev/null`, bin)
name, err := sh.Execute(cmd)
if err != nil {
return defaultBinName
}
if strings.TrimSpace(name) != "" {
return filepath.Base(name)
}
}
return defaultBinName
}

func configLookup(configNames []string, defaultConfigName string, sh Shell) string {
if len(configNames) == 0 {
return ""
}
for _, config := range configNames {
configCms := fmt.Sprintf(`ls %s 2>/dev/null | awk 'NR==1'`, config)
cmdConfig, err := sh.Execute(configCms)
if err != nil {
return defaultConfigName
}
if strings.TrimSpace(cmdConfig) != "" {
return cmdConfig
}
}
return defaultConfigName
}

func configData(param Params, sh Shell, binName string, paramMaps map[string]string) {
bins := binLookup(param.Binaries, param.DefaultBinaries, sh)
if bins != "" {
paramMaps[fmt.Sprintf("$%s.bins", binName)] = bins
}
confs := configLookup(param.Config, param.DefaultConfig, sh)
if confs != "" {
paramMaps[fmt.Sprintf("$%s.confs", binName)] = confs
}
kubeConfig := configLookup(param.KubeConfig, param.DefaultKubeConfig, sh)
if kubeConfig != "" {
paramMaps[fmt.Sprintf("$%s.kubeconfig", binName)] = kubeConfig
}
dataDir := folderLookup(param.DataDirs, param.DefaultDataDir, sh)
if dataDir != "" {
paramMaps[fmt.Sprintf("$%s.datadirs", binName)] = dataDir
}
services := configLookup(param.Services, param.DefalutServices, sh)
if services != "" {
paramMaps[fmt.Sprintf("$%s.svc", binName)] = services
}
CAFile := folderLookup(param.CAFile, param.DefaultCAFile, sh)
if CAFile != "" {
paramMaps[fmt.Sprintf("$%s.cafile", binName)] = CAFile
}
}

func folderLookup(paths []string, defaultFolder string, sh Shell) string {
path := configLookup(paths, defaultFolder, sh)
if path == "" {
return ""
}
return filepath.Dir(path)
}

func configParams(config *Config, sh Shell) map[string]string {
mapParams := make(map[string]string)
configData(config.Node.APIserver, sh, "apiserver", mapParams)
configData(config.Node.ControllerManager, sh, "controllermanager", mapParams)
configData(config.Node.Scheduler, sh, "scheduler", mapParams)
configData(config.Node.Etcd, sh, "etcd", mapParams)
configData(config.Node.Proxy, sh, "proxy", mapParams)
configData(config.Node.KubeLet, sh, "kubelet", mapParams)
configData(config.Node.Flanneld, sh, "flanneld", mapParams)
return mapParams
}
3 changes: 2 additions & 1 deletion pkg/collector/collect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ func TestParseNodeConfig(t *testing.T) {
nodeConfig := make(map[string]interface{})
err = json.Unmarshal(data, &nodeConfig)
assert.NoError(t, err)
m, err := getValuesFromkubeletConfig(nodeConfig)
mapping, err := LoadKubeletMapping()
assert.NoError(t, err)
m := getValuesFromkubeletConfig(nodeConfig, mapping)
for k, v := range m {
if _, ok := tt.expextedNodeConfigFile[k]; ok {
assert.Equal(t, v, tt.expextedNodeConfigFile[k])
Expand Down
Loading

0 comments on commit e67c4e9

Please sign in to comment.