Skip to content
This repository has been archived by the owner on Mar 5, 2024. It is now read-only.

Commit

Permalink
Use selector expressions rather than simple label matching (#26)
Browse files Browse the repository at this point in the history
* use selector expressions rather than simple label matching
  • Loading branch information
pnovotnak authored Jul 31, 2020
1 parent 730766c commit 300282a
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 14 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Example:
YAML:
```yaml
nodeSelector:
node-role.kubernetes.io/node: ""
node-role.kubernetes.io/node
daemonsets:
- name: kiam
namespace: kube-system
Expand All @@ -27,9 +27,11 @@ JSON:
```json
{
"nodeSelector": {
"node-role.kubernetes.io/node": ""
},
"nodeSelector": [
"node-role.kubernetes.io/node",
"!node-role.kubernetes.io/master",
"aws.amazon.com/ec2.asg.name in (standard, special)"
],
"daemonsets": [
{
"name": "kiam",
Expand All @@ -38,8 +40,10 @@ JSON:
]
}
```
This example will taint any nodes that have the label `node-role.kubernetes.io/node=""` if they do not have a running and ready pod from the `kiam` daemonset in the `kube-system` namespace.
It will add a taint of `nidhogg.uswitch.com/kube-system.kiam:NoSchedule` until there is a ready kiam pod on the node.
This example will select any nodes in AWS ASGs named "standard" or "special" that have the label
`node-role.kubernetes.io/node` present, and no nodes with label `node-role.kubernetes.io/master`. If the matching nodes
do not have a running and ready pod from the `kiam` daemonset in the `kube-system` namespace. It will add a taint of
`nidhogg.uswitch.com/kube-system.kiam:NoSchedule` until there is a ready kiam pod on the node.

If you want pods to be able to run on the nidhogg tainted nodes you can add a toleration:

Expand Down
2 changes: 2 additions & 0 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ func main() {
os.Exit(1)
}

log.Info("looking for nodes that match selector", handlerConf.Selector.String())

// Get a config to talk to the apiserver
log.Info("setting up client for manager")
cfg, err := config.GetConfig()
Expand Down
6 changes: 3 additions & 3 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ metadata:
data:
config.json: |
{
"nodeSelector": {
"node-role.kubernetes.io/node": ""
},
"nodeSelector": [
"node-role.kubernetes.io/node"
],
"daemonsets": [
{
"name": "kiam",
Expand Down
5 changes: 4 additions & 1 deletion pkg/controller/node/node_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ func TestReconcile(t *testing.T) {
g.Expect(err).NotTo(gomega.HaveOccurred())
c = mgr.GetClient()

recFn, requests := SetupTestReconcile(newReconciler(mgr, nidhogg.HandlerConfig{}))
handler := nidhogg.HandlerConfig{}
handler.BuildSelectors()

recFn, requests := SetupTestReconcile(newReconciler(mgr, handler))
g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred())

stopMgr, mgrStopped := StartTestManager(mgr, g)
Expand Down
4 changes: 4 additions & 0 deletions pkg/nidhogg/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ func GetConfig(config string) (HandlerConfig, error) {
return HandlerConfig{}, fmt.Errorf("error parsing file: %v", err)
}

if err := handlerConf.BuildSelectors(); err != nil {
return HandlerConfig{}, err
}

return handlerConf, nil

}
21 changes: 17 additions & 4 deletions pkg/nidhogg/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,22 @@ type Handler struct {

// HandlerConfig contains the options for Nidhogg
type HandlerConfig struct {
Daemonsets []Daemonset `json:"daemonsets" yaml:"daemonsets"`
NodeSelector map[string]string `json:"nodeSelector" yaml:"nodeSelector"`
Daemonsets []Daemonset `json:"daemonsets" yaml:"daemonsets"`
NodeSelector []string `json:"nodeSelector" yaml:"nodeSelector"`
Selector labels.Selector
}

func (hc *HandlerConfig) BuildSelectors() error {
hc.Selector = labels.Everything()
for _, rawSelector := range hc.NodeSelector {
if selector, err := labels.Parse(rawSelector); err != nil {
return fmt.Errorf("error parsing selector: %v", err)
} else {
requirements, _ := selector.Requirements()
hc.Selector = hc.Selector.Add(requirements...)
}
}
return nil
}

// Daemonset contains the name and namespace of a Daemonset
Expand All @@ -87,8 +101,7 @@ func (h *Handler) HandleNode(instance *corev1.Node) (reconcile.Result, error) {
log := logf.Log.WithName("nidhogg")

//check whether node matches the nodeSelector
selector := labels.SelectorFromSet(h.config.NodeSelector)
if !selector.Matches(labels.Set(instance.Labels)) {
if !h.config.Selector.Matches(labels.Set(instance.Labels)) {
return reconcile.Result{}, nil
}

Expand Down

0 comments on commit 300282a

Please sign in to comment.