@@ -19,11 +19,17 @@ package updater
1919
2020import (
2121 "errors"
22+ "fmt"
2223 "net"
2324 "strconv"
2425 "strings"
2526
2627 "github.com/go-chef/chef"
28+ "github.com/sirupsen/logrus"
29+ )
30+
31+ var (
32+ log = logrus .New ()
2733)
2834
2935///////////////
@@ -131,12 +137,17 @@ func (cu *ChefUpdater) FetchNodes() error {
131137 return errors .New ("Error getting node info: " + err .Error ())
132138 }
133139
134- attributes , err := getParent (node .NormalAttributes , cu .SerialNumberPath )
140+ // Ensure redborder.blocked exists
141+ cu .ensureBlockedField (n , & node )
142+
143+ // Get parent of sensor UUID path
144+ parentAttrs , err := getParent (node .NormalAttributes , cu .SensorUUIDPath )
135145 if err != nil {
136- return errors . New ( "Error getting node info: " + err . Error () )
146+ return fmt . Errorf ( "Failed to get parent attributes for node %s: %v" , n , err )
137147 }
138148
139- sensorUUID , ok := attributes [getKeyFromPath (cu .SensorUUIDPath )].(string )
149+ sensorKey := getKeyFromPath (cu .SensorUUIDPath )
150+ sensorUUID , ok := parentAttrs [sensorKey ].(string )
140151 if ! ok {
141152 continue
142153 }
@@ -223,6 +234,8 @@ func (cu *ChefUpdater) BlockOrganization(organization string, productType uint32
223234 pType := getKeyFromPath (cu .ProductTypePath )
224235
225236 for _ , node := range cu .nodes {
237+ log .Infof ("Blocking node: %s" , node .Name )
238+
226239 attributes , err := getParent (node .NormalAttributes , cu .BlockedStatusPath )
227240 if err != nil {
228241 errs = append (errs , err )
@@ -238,20 +251,22 @@ func (cu *ChefUpdater) BlockOrganization(organization string, productType uint32
238251 nodeProductType , err := strconv .ParseUint (nodeProductTypeStr , 10 , 32 )
239252 if err != nil || uint32 (nodeProductType ) == productType {
240253 if err != nil {
241- errs = append (errs , errors .New (
242- "Blocking sensor with unknown product type" ),
243- )
254+ errs = append (errs , errors .New ("Blocking sensor with unknown product type" ))
244255 }
245256
246257 attributes [blocked ] = true
247258
248259 if cu .client != nil {
249- cu .client .Nodes .Put (* node )
260+ _ , err := cu .client .Nodes .Put (* node )
261+ if err != nil {
262+ errs = append (errs , err )
263+ } else {
264+ log .Infof ("Successfully blocked and updated node %s" , node .Name )
265+ }
250266 }
251267 }
252268 }
253269 }
254-
255270 return errs
256271}
257272
@@ -260,7 +275,6 @@ func (cu *ChefUpdater) BlockOrganization(organization string, productType uint32
260275func (cu * ChefUpdater ) AllowLicense (license string ) []error {
261276 var errs []error
262277 blocked := getKeyFromPath (cu .BlockedStatusPath )
263- lic := getKeyFromPath (cu .LicenseUUIDPath )
264278
265279 for _ , node := range cu .nodes {
266280 attributes , err := getParent (node .NormalAttributes , cu .BlockedStatusPath )
@@ -269,12 +283,10 @@ func (cu *ChefUpdater) AllowLicense(license string) []error {
269283 continue
270284 }
271285
272- if attributes [lic ] == license {
273- attributes [blocked ] = false
286+ attributes [blocked ] = false
274287
275- if cu .client != nil {
276- cu .client .Nodes .Put (* node )
277- }
288+ if cu .client != nil {
289+ cu .client .Nodes .Put (* node )
278290 }
279291 }
280292
@@ -306,18 +318,27 @@ func (cu *ChefUpdater) ResetAllSensors() error {
306318// node and returns the inner object given a path
307319func getParent (root map [string ]interface {}, path string ) (map [string ]interface {}, error ) {
308320 keys := strings .Split (path , "/" )
309- var ok bool
321+ if len (keys ) == 0 {
322+ return nil , fmt .Errorf ("invalid path: %q" , path )
323+ }
310324
311- attrs := root
312- for i , key := range keys {
313- if i < len (keys )- 1 {
314- if attrs , ok = attrs [key ].(map [string ]interface {}); ! ok || attrs == nil {
315- return nil , errors .New ("Cannot find key: " + path )
316- }
325+ current := root
326+
327+ for _ , key := range keys [:len (keys )- 1 ] {
328+ next , ok := current [key ]
329+ if ! ok {
330+ return nil , fmt .Errorf ("key %q not found in path %q" , key , path )
331+ }
332+
333+ nextMap , ok := next .(map [string ]interface {})
334+ if ! ok {
335+ return nil , fmt .Errorf ("expected map[string]interface{} at key %q but got %T" , key , next )
317336 }
337+
338+ current = nextMap
318339 }
319340
320- return attrs , nil
341+ return current , nil
321342}
322343
323344func findNode (keyPath string , value string , nodes map [string ]* chef.Node ,
@@ -342,3 +363,21 @@ func getKeyFromPath(path string) string {
342363 keys := strings .Split (path , "/" )
343364 return keys [len (keys )- 1 ]
344365}
366+
367+ // Create blocked (redborder -> blocked) field if it doesn't exist in the passed node as parameter
368+ func (cu * ChefUpdater ) ensureBlockedField (n string , node * chef.Node ) {
369+ redborderAttrs , ok := node .NormalAttributes ["redborder" ].(map [string ]interface {})
370+ if ! ok || redborderAttrs == nil {
371+ redborderAttrs = make (map [string ]interface {})
372+ node .NormalAttributes ["redborder" ] = redborderAttrs
373+ }
374+
375+ if _ , exists := redborderAttrs ["blocked" ]; ! exists {
376+ log .Infof ("Adding missing 'blocked: false' field to node %s" , n )
377+ redborderAttrs ["blocked" ] = false
378+
379+ if _ , err := cu .client .Nodes .Put (* node ); err != nil {
380+ log .Errorf ("Failed to update node %s: %v" , n , err )
381+ }
382+ }
383+ }
0 commit comments