Skip to content

Commit

Permalink
Dynamically retrieve parents
Browse files Browse the repository at this point in the history
  • Loading branch information
baderbuddy committed Mar 16, 2020
1 parent fe55216 commit bb34be7
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 57 deletions.
7 changes: 0 additions & 7 deletions pkg/config/supportedcontrollers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import (
appsv1beta1 "k8s.io/api/apps/v1beta1"
appsv1beta2 "k8s.io/api/apps/v1beta2"
batchv1 "k8s.io/api/batch/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
)
Expand Down Expand Up @@ -124,11 +122,6 @@ func (s SupportedController) ListSupportedAPIVersions() []runtime.Object {
supportedVersions = []runtime.Object{
&batchv1.Job{},
}
case CronJobs:
supportedVersions = []runtime.Object{
&batchv1beta1.CronJob{},
&batchv2alpha1.CronJob{},
}
case ReplicationControllers:
supportedVersions = []runtime.Object{
&corev1.ReplicationController{},
Expand Down
60 changes: 21 additions & 39 deletions pkg/kube/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ import (
batchv1 "k8s.io/api/batch/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sYaml "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth" // Required for other auth providers like GKE.
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
"sigs.k8s.io/controller-runtime/pkg/client/config"
)

Expand All @@ -37,6 +41,8 @@ type ResourceProvider struct {
ReplicationControllers []corev1.ReplicationController
Namespaces []corev1.Namespace
Pods []corev1.Pod
DynamicClient *dynamic.Interface
RestMapper *meta.RESTMapper
}

type k8sResource struct {
Expand Down Expand Up @@ -114,11 +120,11 @@ func CreateResourceProviderFromCluster() (*ResourceProvider, error) {
logrus.Errorf("Error creating Kubernetes client: %v", err)
return nil, err
}
return CreateResourceProviderFromAPI(api, kubeConf.Host)
return CreateResourceProviderFromAPI(api, kubeConf.Host, kubeConf)
}

// CreateResourceProviderFromAPI creates a new ResourceProvider from an existing k8s interface
func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string) (*ResourceProvider, error) {
func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string, kubeConf *rest.Config) (*ResourceProvider, error) {
listOpts := metav1.ListOptions{}
serverVersion, err := kube.Discovery().ServerVersion()
if err != nil {
Expand All @@ -133,10 +139,6 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string
if err != nil {
return nil, err
}
cronJobs, err := getCronJobs(kube)
if err != nil {
return nil, err
}
daemonSets, err := getDaemonSets(kube)
if err != nil {
return nil, err
Expand Down Expand Up @@ -167,6 +169,17 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string
logrus.Errorf("Error fetching Pods: %v", err)
return nil, err
}
dynamicInterface, err := dynamic.NewForConfig(kubeConf)
if err != nil {
logrus.Errorf("Error connecting to dynamic interface: %v", err)
return nil, err
}
resources, err := restmapper.GetAPIGroupResources(kube.Discovery())
if err != nil {
logrus.Errorf("Error getting API Group resources: %v", err)
return nil, err
}
restMapper := restmapper.NewDiscoveryRESTMapper(resources)

api := ResourceProvider{
ServerVersion: serverVersion.Major + "." + serverVersion.Minor,
Expand All @@ -176,12 +189,13 @@ func CreateResourceProviderFromAPI(kube kubernetes.Interface, clusterName string
Deployments: deploys,
StatefulSets: statefulSets,
DaemonSets: daemonSets,
CronJobs: cronJobs,
Jobs: jobs.Items,
ReplicationControllers: replicationControllers.Items,
Nodes: nodes.Items,
Namespaces: namespaces.Items,
Pods: pods.Items,
DynamicClient: &dynamicInterface,
RestMapper: &restMapper,
}
return &api, nil
}
Expand Down Expand Up @@ -355,35 +369,3 @@ func getDaemonSets(kube kubernetes.Interface) ([]appsv1.DaemonSet, error) {
}
return controllers, nil
}

func getCronJobs(kube kubernetes.Interface) ([]batchv1beta1.CronJob, error) {
listOpts := metav1.ListOptions{}
controllerList, err := kube.BatchV1beta1().CronJobs("").List(listOpts)
if err != nil {
logrus.Errorf("Error fetching CronJobs: %v", err)
return nil, err
}
controllers := controllerList.Items

controllersV2A1, err := kube.BatchV2alpha1().CronJobs("").List(listOpts)
if err != nil {
logrus.Errorf("Error fetching CronJobs v2alpha1: %v", err)
return nil, err
}

for _, oldController := range controllersV2A1.Items {
str, err := json.Marshal(oldController)
if err != nil {
logrus.Errorf("Error marshaling old CronJob version: %v", err)
return nil, err
}
controller := batchv1beta1.CronJob{}
err = json.Unmarshal(str, &controller)
if err != nil {
logrus.Errorf("Error unmarshaling old CronJob version: %v", err)
return nil, err
}
controllers = append(controllers, controller)
}
return controllers, nil
}
41 changes: 31 additions & 10 deletions pkg/validator/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@ package validator
import (
"strings"

"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"

conf "github.com/fairwindsops/polaris/pkg/config"
"github.com/fairwindsops/polaris/pkg/kube"
"github.com/fairwindsops/polaris/pkg/validator/controllers"
controller "github.com/fairwindsops/polaris/pkg/validator/controllers"
"github.com/sirupsen/logrus"
)

const exemptionAnnotationKey = "polaris.fairwinds.com/exempt"

// ValidateController validates a single controller, returns a ControllerResult.
func ValidateController(conf *conf.Configuration, controller controller.Interface) (ControllerResult, error) {
func ValidateController(conf *conf.Configuration, controller controller.Interface, kubeResources *kube.ResourceProvider) (ControllerResult, error) {
podResult, err := ValidatePod(conf, controller)
if err != nil {
return ControllerResult{}, err
Expand All @@ -43,11 +46,31 @@ func ValidateController(conf *conf.Configuration, controller controller.Interfac
owners := controller.GetObjectMeta().OwnerReferences
// If an owner exists then set the name to the controller.
// This allows us to handle CRDs creating Controllers or DeploymentConfigs in OpenShift.
if len(owners) > 0 {
for len(owners) > 0 {
firstOwner := owners[0]
result.Kind = firstOwner.Kind
result.Name = firstOwner.Name
if kubeResources.DynamicClient != nil {

dynamicClient := *kubeResources.DynamicClient
restMapper := *kubeResources.RestMapper
fqKind := schema.FromAPIVersionAndKind(firstOwner.APIVersion, firstOwner.Kind)
mapping, err := restMapper.RESTMapping(fqKind.GroupKind(), fqKind.Version)
if err != nil {
logrus.Warnf("Error retrieving mapping %s of API %s and Kind %s because of error: %v ", firstOwner.Name, firstOwner.APIVersion, firstOwner.Kind, err)
return result, nil
}
getParents, err := dynamicClient.Resource(mapping.Resource).Namespace(controller.GetObjectMeta().Namespace).Get(firstOwner.Name, metav1.GetOptions{})
if err != nil {
logrus.Warnf("Error retrieving parent object %s of API %s and Kind %s because of error: %v ", firstOwner.Name, firstOwner.APIVersion, firstOwner.Kind, err)
return result, nil
}
owners = getParents.GetOwnerReferences()
} else {
break
}
}

return result, nil
}

Expand Down Expand Up @@ -80,19 +103,17 @@ func deduplicateControllers(controllerResults []ControllerResult) []ControllerRe
// builds a list of ResourceResults organized by namespace.
func ValidateControllers(config *conf.Configuration, kubeResources *kube.ResourceProvider) ([]ControllerResult, error) {
var controllersToAudit []controller.Interface
for _, supportedControllers := range config.ControllersToScan {
loadedControllers, err := controllers.LoadControllersByKind(supportedControllers, kubeResources)
if err != nil {
logrus.Warn(err)
}
controllersToAudit = append(controllersToAudit, loadedControllers...)
loadedControllers, err := controllers.LoadControllersByKind(conf.NakedPods, kubeResources)
if err != nil {
logrus.Warn(err)
}
controllersToAudit = append(controllersToAudit, loadedControllers...)
results := []ControllerResult{}
for _, controller := range controllersToAudit {
if !config.DisallowExemptions && hasExemptionAnnotation(controller) {
continue
}
result, err := ValidateController(config, controller)
result, err := ValidateController(config, controller, kubeResources)
if err != nil {
return nil, err
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/validator/controllers/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ func (g GenericController) GetNamespace() string {
func LoadControllersByKind(controllerKind config.SupportedController, kubeResources *kube.ResourceProvider) ([]Interface, error) {
interfaces := []Interface{}
switch controllerKind {
case config.NakedPods:
for _, pod := range kubeResources.Pods {
interfaces = append(interfaces, NewNakedPodController(pod))
}
case config.Deployments:
for _, deploy := range kubeResources.Deployments {
interfaces = append(interfaces, NewDeploymentController(deploy))
Expand Down
3 changes: 2 additions & 1 deletion pkg/webhook/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"net/http"

"github.com/fairwindsops/polaris/pkg/config"
"github.com/fairwindsops/polaris/pkg/kube"
validator "github.com/fairwindsops/polaris/pkg/validator"
"github.com/fairwindsops/polaris/pkg/validator/controllers"

Expand Down Expand Up @@ -142,7 +143,7 @@ func (v *Validator) Handle(ctx context.Context, req types.Request) types.Respons
}
if err == nil {
var controllerResult validator.ControllerResult
controllerResult, err = validator.ValidateController(&v.Config, controller)
controllerResult, err = validator.ValidateController(&v.Config, controller, &kube.ResourceProvider{})
podResult = controllerResult.PodResult
}
}
Expand Down

0 comments on commit bb34be7

Please sign in to comment.