-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Blaize Kaye
committed
Jul 29, 2024
1 parent
c1e734f
commit 30df9af
Showing
1 changed file
with
24 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,28 +42,21 @@ type BuildReconciler struct { | |
} | ||
|
||
const insightsScannedLabel = "insights.lagoon.sh/scanned" | ||
const scanImageName = "imagecache.amazeeio.cloud/bomoko/insights-scan:latest" | ||
const dockerhost = "docker-host.lagoon.svc" //TODO in future versions this will be read from the build CRD | ||
|
||
//+kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch;create;update;patch;delete | ||
//+kubebuilder:rbac:groups=core,resources=namespaces/status,verbs=get;update;patch | ||
//+kubebuilder:rbac:groups=core,resources=namespaces/finalizers,verbs=update | ||
|
||
// Reconcile is part of the main kubernetes reconciliation loop which aims to | ||
// move the current state of the cluster closer to the desired state. | ||
// TODO(user): Modify the Reconcile function to compare the state specified by | ||
// the Namespace object against the actual cluster state, and then | ||
// perform operations to make the cluster state reflect the state specified by | ||
// the user. | ||
// | ||
// For more details, check Reconcile and its Result here: | ||
// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/reconcile | ||
// Reconcile is part of the Kubebuilder machinery - it kicks off when we find a build pod in the correct | ||
// state for scanning - i.e. whenever there's a successful build. | ||
func (r *BuildReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { | ||
log := log.FromContext(ctx) | ||
logger := log.FromContext(ctx).WithValues("NamespacedName", req.NamespacedName) | ||
|
||
var buildPod corev1.Pod | ||
|
||
if err := r.Get(ctx, req.NamespacedName, &buildPod); err != nil { | ||
log.Error(err, "Unable to load Pod") | ||
logger.Error(err, fmt.Sprintf("Unable to load Pod- %v", req.Namespace)) | ||
return ctrl.Result{}, client.IgnoreNotFound(err) | ||
} | ||
|
||
|
@@ -74,7 +67,7 @@ func (r *BuildReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl | |
namespace := &corev1.Namespace{} | ||
err := r.Get(ctx, client.ObjectKey{Name: buildPod.Namespace}, namespace) | ||
if err != nil { | ||
log.Error(err, "Failed to get Namespace") | ||
logger.Error(err, fmt.Sprintf("Unable to load namespace - %v", buildPod.Namespace)) | ||
return reconcile.Result{}, client.IgnoreNotFound(err) | ||
} | ||
|
||
|
@@ -89,38 +82,40 @@ func (r *BuildReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl | |
|
||
imageList, err := r.scanDeployments(ctx, req, buildPod.Namespace) | ||
if err != nil { | ||
log.Error(err, "Unable to scan deployments") | ||
logger.Error(err, "Unable to scan deployments") | ||
return ctrl.Result{}, client.IgnoreNotFound(err) | ||
} | ||
|
||
// now we generate the pod spec we'd like to deploy | ||
podspec, err := generateScanPodSpec(imageList, r.ScanImageName, buildPod.Name, buildPod.Namespace, projectName, envName) | ||
podspec, err := generateScanPodSpec(imageList, r.ScanImageName, buildPod.Name, buildPod.Namespace, projectName, envName, dockerhost) | ||
if err != nil { | ||
log.Error(err, "Unable to generate podspec") | ||
logger.Error(err, "Unable to generate the podspec for the image scanner.") | ||
return ctrl.Result{}, client.IgnoreNotFound(err) | ||
} | ||
|
||
// Remove any existing pods | ||
err = r.killExistingScans(ctx, scannerNameFromBuildname(buildPod.Name), buildPod.Namespace) | ||
if err != nil { | ||
log.Error(err, "Unable to remove existing scan pods") | ||
logger.Error(err, "Unable to remove existing scan pods") | ||
return ctrl.Result{}, client.IgnoreNotFound(err) | ||
} | ||
|
||
// Deploy scan pod | ||
err = r.Client.Create(ctx, podspec) | ||
if err != nil { | ||
log.Error(err, "Couldn't create pod") | ||
logger.Error(err, "Couldn't create pod") | ||
return ctrl.Result{}, client.IgnoreNotFound(err) | ||
} | ||
|
||
labels := buildPod.GetLabels() | ||
// Let's label the pod as having been seen | ||
labels[insightsScannedLabel] = "true" | ||
labels[insightsScannedLabel] = "true" // Right now this assumes a fire and forget style setup | ||
// TODO: in the future we may want to have a slightly more complex approach to monitoring insights scans | ||
|
||
buildPod.SetLabels(labels) | ||
err = r.Update(ctx, &buildPod) | ||
if err != nil { | ||
log.Error(err, fmt.Sprintf("Unable to update pod labels: %v", req.NamespacedName.String())) | ||
logger.Error(err, fmt.Sprintf("Unable to update pod labels: %v", req.NamespacedName.String())) | ||
return ctrl.Result{}, client.IgnoreNotFound(err) | ||
} | ||
} | ||
|
@@ -162,7 +157,8 @@ func (r *BuildReconciler) scanDeployments(ctx context.Context, req ctrl.Request, | |
return imageList, nil | ||
} | ||
|
||
func generateScanPodSpec(images []string, scanImageName, buildName, namespace, projectName, environmentName string) (*corev1.Pod, error) { | ||
// generateScanPodSpec generates the pod spec for the scanner that will be injected into the namespace | ||
func generateScanPodSpec(images []string, scanImageName, buildName, namespace, projectName, environmentName, dockerhost string) (*corev1.Pod, error) { | ||
|
||
if len(images) == 0 { | ||
return nil, errors.New("No images to scan") | ||
|
@@ -201,6 +197,10 @@ func generateScanPodSpec(images []string, scanImageName, buildName, namespace, p | |
Name: "ENVIRONMENT", | ||
Value: environmentName, | ||
}, | ||
{ | ||
Name: "DOCKER_HOST", | ||
Value: dockerhost, | ||
}, | ||
}, | ||
ImagePullPolicy: "Always", | ||
VolumeMounts: []corev1.VolumeMount{ | ||
|
@@ -233,9 +233,7 @@ func generateScanPodSpec(images []string, scanImageName, buildName, namespace, p | |
|
||
func (r *BuildReconciler) killExistingScans(ctx context.Context, newScannerName string, namespace string) error { | ||
// Find pods in namespace with the image scan pod labels | ||
|
||
podlist := &corev1.PodList{} | ||
//ls := client.MatchingLabels{"insights.lagoon.sh/imagescanner": "scanning"} | ||
ls := client.MatchingLabels(imageScanPodLabels()) | ||
ns := client.InNamespace(namespace) | ||
err := r.Client.List(ctx, podlist, ns, ls) | ||
|
@@ -248,13 +246,11 @@ func (r *BuildReconciler) killExistingScans(ctx context.Context, newScannerName | |
|
||
log.Log.Info("Looking at following image by name: " + i.Name) | ||
//if i.Name != newScannerName { // Then we have a rogue pod | ||
log.Log.Info("Deleting image") | ||
err = r.Client.Delete(ctx, &i) | ||
if err != nil { | ||
|
||
return err | ||
} | ||
log.Log.Info(fmt.Sprintf("Going to delete pod: %v", i.Name)) | ||
log.Log.Info(fmt.Sprintf("Successfully deleted old insights-scanner pod: %v", i.Name)) | ||
//} | ||
} | ||
return nil | ||
|
@@ -263,14 +259,15 @@ func (r *BuildReconciler) killExistingScans(ctx context.Context, newScannerName | |
func imageScanPodLabels() map[string]string { | ||
return map[string]string{ | ||
"insights.lagoon.sh/imagescanner": "scanning", | ||
"lagoon.sh/buildName": "notabuild", //TODO: this only exists to give me appropriate permissions - change roles etc. | ||
} | ||
} | ||
|
||
func scannerNameFromBuildname(buildName string) string { | ||
return fmt.Sprintf("insights-scanner-%v", buildName) | ||
} | ||
|
||
// successfulBuildPodsPredicate returns a list of predicate functions to determine | ||
// if the build we're looking at has been successfully completed | ||
func successfulBuildPodsPredicate() predicate.Predicate { | ||
return predicate.Funcs{ | ||
CreateFunc: func(event event.CreateEvent) bool { return false }, | ||
|
@@ -288,13 +285,11 @@ func successfulBuildPodsPredicate() predicate.Predicate { | |
labels := event.ObjectNew.GetLabels() | ||
_, err := getValueFromMap(labels, "lagoon.sh/buildName") | ||
if err != nil { | ||
log.Log.Info(fmt.Sprintf("Not a build pod, skipping : %v", event.ObjectNew.GetName())) | ||
return false //this isn't a build pod | ||
} | ||
|
||
_, err = getValueFromMap(labels, "insights.lagoon.sh/imagescanner") | ||
if err == nil { | ||
log.Log.Info(fmt.Sprintf("Found a scanner pod, skipping : %v", event.ObjectNew.GetName())) | ||
return false //this isn't a build pod | ||
} | ||
|
||
|
@@ -304,7 +299,6 @@ func successfulBuildPodsPredicate() predicate.Predicate { | |
return false | ||
} | ||
return true | ||
|
||
}, | ||
GenericFunc: func(genericEvent event.GenericEvent) bool { | ||
return false | ||
|