Skip to content

Commit 2056e06

Browse files
authored
Merge pull request #77 from prachidamle/fix_race
Set security-runner job properties and ensure pod cleanup, also use current scan name to avoid multiple scan jobs
2 parents 71ef64c + 05e3b42 commit 2056e06

File tree

12 files changed

+1423
-35
lines changed

12 files changed

+1423
-35
lines changed

pkg/securityscan/controller.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@ import (
1414
detector "github.com/rancher/kubernetes-provider-detector"
1515
"github.com/rancher/wrangler/pkg/apply"
1616
"github.com/rancher/wrangler/pkg/crd"
17+
appsctl "github.com/rancher/wrangler/pkg/generated/controllers/apps"
18+
appsctlv1 "github.com/rancher/wrangler/pkg/generated/controllers/apps/v1"
1719
batchctl "github.com/rancher/wrangler/pkg/generated/controllers/batch"
20+
batchctlv1 "github.com/rancher/wrangler/pkg/generated/controllers/batch/v1"
1821
corectl "github.com/rancher/wrangler/pkg/generated/controllers/core"
22+
corectlv1 "github.com/rancher/wrangler/pkg/generated/controllers/core/v1"
1923
"github.com/rancher/wrangler/pkg/start"
2024

2125
"sync"
@@ -24,6 +28,7 @@ import (
2428

2529
cisoperatorapiv1 "github.com/rancher/cis-operator/pkg/apis/cis.cattle.io/v1"
2630
cisoperatorctl "github.com/rancher/cis-operator/pkg/generated/controllers/cis.cattle.io"
31+
cisoperatorctlv1 "github.com/rancher/cis-operator/pkg/generated/controllers/cis.cattle.io/v1"
2732
"github.com/rancher/cis-operator/pkg/securityscan/scan"
2833
)
2934

@@ -38,11 +43,13 @@ type Controller struct {
3843
xcs *kubeapiext.Clientset
3944
coreFactory *corectl.Factory
4045
batchFactory *batchctl.Factory
46+
appsFactory *appsctl.Factory
4147
cisFactory *cisoperatorctl.Factory
4248
apply apply.Apply
4349
monitoringClient v1monitoringclient.MonitoringV1Interface
4450

45-
mu *sync.Mutex
51+
mu *sync.Mutex
52+
currentScanName string
4653

4754
numTestsFailed *prometheus.GaugeVec
4855
numScansComplete *prometheus.CounterVec
@@ -51,6 +58,16 @@ type Controller struct {
5158
numTestsNA *prometheus.GaugeVec
5259
numTestsPassed *prometheus.GaugeVec
5360
numTestsWarn *prometheus.GaugeVec
61+
62+
scans cisoperatorctlv1.ClusterScanController
63+
jobs batchctlv1.JobController
64+
configmaps corectlv1.ConfigMapController
65+
configMapCache corectlv1.ConfigMapCache
66+
services corectlv1.ServiceController
67+
pods corectlv1.PodController
68+
podCache corectlv1.PodCache
69+
daemonsets appsctlv1.DaemonSetController
70+
daemonsetCache appsctlv1.DaemonSetCache
5471
}
5572

5673
func NewController(ctx context.Context, cfg *rest.Config, namespace, name string, imgConfig *cisoperatorapiv1.ScanImageConfig) (ctl *Controller, err error) {
@@ -112,6 +129,11 @@ func NewController(ctx context.Context, cfg *rest.Config, namespace, name string
112129
return nil, fmt.Errorf("Error building core NewFactoryFromConfig: %s", err.Error())
113130
}
114131

132+
ctl.appsFactory, err = appsctl.NewFactoryFromConfig(cfg)
133+
if err != nil {
134+
return nil, fmt.Errorf("Error building apps NewFactoryFromConfig: %s", err.Error())
135+
}
136+
115137
ctl.monitoringClient, err = v1monitoringclient.NewForConfig(cfg)
116138
if err != nil {
117139
return nil, fmt.Errorf("Error building v1 monitoring client from config: %s", err.Error())
@@ -121,6 +143,17 @@ func NewController(ctx context.Context, cfg *rest.Config, namespace, name string
121143
if err != nil {
122144
return nil, fmt.Errorf("Error registering CIS Metrics: %s", err.Error())
123145
}
146+
147+
ctl.scans = ctl.cisFactory.Cis().V1().ClusterScan()
148+
ctl.jobs = ctl.batchFactory.Batch().V1().Job()
149+
ctl.configmaps = ctl.coreFactory.Core().V1().ConfigMap()
150+
ctl.configMapCache = ctl.coreFactory.Core().V1().ConfigMap().Cache()
151+
ctl.services = ctl.coreFactory.Core().V1().Service()
152+
ctl.pods = ctl.coreFactory.Core().V1().Pod()
153+
ctl.podCache = ctl.coreFactory.Core().V1().Pod().Cache()
154+
ctl.daemonsets = ctl.appsFactory.Apps().V1().DaemonSet()
155+
ctl.daemonsetCache = ctl.appsFactory.Apps().V1().DaemonSet().Cache()
156+
124157
return ctl, nil
125158
}
126159

pkg/securityscan/job/job.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,34 @@ import (
2121
const (
2222
defaultTerminationGracePeriodSeconds = int64(0)
2323
defaultBackoffLimit = int32(0)
24+
defaultTTLSecondsAfterFinished = int32(0)
2425
)
2526

2627
var (
2728
ConditionComplete = condition.Cond(batchv1.JobComplete)
2829
ConditionFailed = condition.Cond(batchv1.JobFailed)
2930

30-
BackoffLimit = func(defaultValue int32) int32 {
31-
if str, ok := os.LookupEnv("SYSTEM_UPGRADE_JOB_BACKOFF_LIMIT"); ok {
32-
if i, err := strconv.ParseInt(str, 10, 32); err != nil {
33-
logrus.Errorf("failed to parse $%s: %v", "SYSTEM_UPGRADE_JOB_BACKOFF_LIMIT", err)
34-
} else {
35-
return int32(i)
36-
}
37-
}
38-
return defaultValue
39-
}(defaultBackoffLimit)
31+
backoffLimit = readFromEnv("CIS_JOB_BACKOFF_LIMIT", defaultBackoffLimit)
4032

4133
TerminationGracePeriodSeconds = func(defaultValue int64) int64 {
4234
return defaultValue
4335
}(defaultTerminationGracePeriodSeconds)
36+
37+
ttlSecondsAfterFinished = readFromEnv("CIS_JOB_TTL_SECONDS_AFTER_FINISH", defaultTTLSecondsAfterFinished)
4438
)
4539

40+
func readFromEnv(key string, defaultValue int32) int32 {
41+
if str, ok := os.LookupEnv(key); ok {
42+
i, err := strconv.ParseInt(str, 10, 32)
43+
if err != nil {
44+
logrus.Errorf("failed to parse $%s: %v", key, err)
45+
return defaultValue
46+
}
47+
return int32(i)
48+
}
49+
return defaultValue
50+
}
51+
4652
func New(clusterscan *cisoperatorapiv1.ClusterScan, clusterscanprofile *cisoperatorapiv1.ClusterScanProfile, controllerName string, imageConfig *cisoperatorapiv1.ScanImageConfig) *batchv1.Job {
4753
privileged := true
4854
job := &batchv1.Job{
@@ -63,7 +69,8 @@ func New(clusterscan *cisoperatorapiv1.ClusterScan, clusterscanprofile *cisopera
6369
}},
6470
},
6571
Spec: batchv1.JobSpec{
66-
BackoffLimit: &BackoffLimit,
72+
BackoffLimit: &backoffLimit,
73+
TTLSecondsAfterFinished: &ttlSecondsAfterFinished,
6774
Template: corev1.PodTemplateSpec{
6875
ObjectMeta: metav1.ObjectMeta{
6976
Labels: labels.Set{

pkg/securityscan/jobHandler.go

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"github.com/rancher/wrangler/pkg/name"
2323
)
2424

25+
var sonobuoyWorkerLabel = map[string]string{"sonobuoy-plugin": "rancher-kube-bench"}
26+
2527
// job events (successful completions) should remove the job after validatinf Done annotation and Output CM
2628
func (c *Controller) handleJobs(ctx context.Context) error {
2729
scans := c.cisFactory.Cis().V1().ClusterScan()
@@ -59,7 +61,6 @@ func (c *Controller) handleJobs(ctx context.Context) error {
5961

6062
// if the scan has completed then delete the job
6163
if v1.ClusterScanConditionComplete.IsTrue(scan) {
62-
c.ensureCleanup(scan)
6364
if !v1.ClusterScanConditionFailed.IsTrue(scan) {
6465
logrus.Infof("Marking ClusterScanConditionAlerted for scan: %v", scanName)
6566
v1.ClusterScanConditionAlerted.Unknown(scan)
@@ -71,12 +72,21 @@ func (c *Controller) handleJobs(ctx context.Context) error {
7172
c.rescheduleScan(scan)
7273
c.purgeOldClusterScanReports(scan)
7374
}
75+
err := c.deleteJob(jobs, obj, metav1.DeletePropagationBackground)
76+
if err != nil {
77+
return obj, fmt.Errorf("error deleting job: %v", err)
78+
}
79+
err = c.ensureCleanup(scan)
80+
if err != nil {
81+
return obj, err
82+
}
7483
//update scan
7584
_, err = scans.UpdateStatus(scan)
7685
if err != nil {
7786
return nil, fmt.Errorf("error updating condition of cluster scan object: %v", scanName)
7887
}
79-
return obj, c.deleteJob(jobs, obj, metav1.DeletePropagationBackground)
88+
c.currentScanName = ""
89+
return obj, nil
8090
}
8191

8292
if v1.ClusterScanConditionRunCompleted.IsTrue(scan) {
@@ -187,9 +197,38 @@ func (c *Controller) createClusterScanReport(outputBytes []byte, scan *v1.Cluste
187197

188198
func (c *Controller) ensureCleanup(scan *v1.ClusterScan) error {
189199
var err error
190-
configmaps := c.coreFactory.Core().V1().ConfigMap()
200+
// Delete the dameonset
201+
dsPrefix := "sonobuoy-rancher-kube-bench-daemon-set"
202+
dsList, err := c.daemonsetCache.List(v1.ClusterScanNS, labels.Set(sonobuoyWorkerLabel).AsSelector())
203+
if err != nil {
204+
return fmt.Errorf("cis: ensureCleanup: error listing daemonsets: %v", err)
205+
}
206+
for _, ds := range dsList {
207+
if !strings.HasPrefix(ds.Name, dsPrefix) {
208+
continue
209+
}
210+
if e := c.daemonsets.Delete(v1.ClusterScanNS, ds.Name, &metav1.DeleteOptions{}); e != nil && !errors.IsNotFound(e) {
211+
return fmt.Errorf("cis: ensureCleanup: error deleting daemonset %v: %v", ds.Name, e)
212+
}
213+
}
214+
215+
// Delete the pod
216+
podPrefix := name.SafeConcatName("security-scan-runner", scan.Name)
217+
podList, err := c.podCache.List(v1.ClusterScanNS, labels.Set(SonobuoyMasterLabel).AsSelector())
218+
if err != nil {
219+
return fmt.Errorf("cis: ensureCleanup: error listing pods: %v", err)
220+
}
221+
for _, pod := range podList {
222+
if !strings.HasPrefix(pod.Name, podPrefix) {
223+
continue
224+
}
225+
if e := c.pods.Delete(v1.ClusterScanNS, pod.Name, &metav1.DeleteOptions{}); e != nil && !errors.IsNotFound(e) {
226+
return fmt.Errorf("cis: ensureCleanup: error deleting pod %v: %v", pod.Name, e)
227+
}
228+
}
229+
191230
// Delete cms
192-
cms, err := configmaps.Cache().List(v1.ClusterScanNS, labels.NewSelector())
231+
cms, err := c.configMapCache.List(v1.ClusterScanNS, labels.NewSelector())
193232
if err != nil {
194233
return fmt.Errorf("cis: ensureCleanup: error listing cm: %v", err)
195234
}
@@ -198,7 +237,7 @@ func (c *Controller) ensureCleanup(scan *v1.ClusterScan) error {
198237
continue
199238
}
200239

201-
if e := configmaps.Delete(v1.ClusterScanNS, cm.Name, &metav1.DeleteOptions{}); e != nil && !errors.IsNotFound(e) {
240+
if e := c.configmaps.Delete(v1.ClusterScanNS, cm.Name, &metav1.DeleteOptions{}); e != nil && !errors.IsNotFound(e) {
202241
return fmt.Errorf("cis: ensureCleanup: error deleting cm %v: %v", cm.Name, e)
203242
}
204243
}

0 commit comments

Comments
 (0)