github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/caasfirewaller/application_worker.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package caasfirewaller 5 6 import ( 7 "strings" 8 9 "github.com/juju/errors" 10 "gopkg.in/juju/names.v2" 11 "gopkg.in/juju/worker.v1" 12 "gopkg.in/juju/worker.v1/catacomb" 13 14 "github.com/juju/juju/environs/tags" 15 ) 16 17 type applicationWorker struct { 18 catacomb catacomb.Catacomb 19 controllerUUID string 20 modelUUID string 21 application string 22 applicationGetter ApplicationGetter 23 serviceExposer ServiceExposer 24 25 lifeGetter LifeGetter 26 27 initial bool 28 previouslyExposed bool 29 } 30 31 func newApplicationWorker( 32 controllerUUID string, 33 modelUUID string, 34 application string, 35 applicationGetter ApplicationGetter, 36 applicationExposer ServiceExposer, 37 lifeGetter LifeGetter, 38 ) (worker.Worker, error) { 39 w := &applicationWorker{ 40 controllerUUID: controllerUUID, 41 modelUUID: modelUUID, 42 application: application, 43 applicationGetter: applicationGetter, 44 serviceExposer: applicationExposer, 45 lifeGetter: lifeGetter, 46 initial: true, 47 } 48 if err := catacomb.Invoke(catacomb.Plan{ 49 Site: &w.catacomb, 50 Work: w.loop, 51 }); err != nil { 52 return nil, errors.Trace(err) 53 } 54 return w, nil 55 } 56 57 // Kill is part of the worker.Worker interface. 58 func (w *applicationWorker) Kill() { 59 w.catacomb.Kill(nil) 60 } 61 62 // Wait is part of the worker.Worker interface. 63 func (w *applicationWorker) Wait() error { 64 return w.catacomb.Wait() 65 } 66 67 func (w *applicationWorker) loop() (err error) { 68 defer func() { 69 // If the application has been deleted, we can return nil. 70 if errors.IsNotFound(err) { 71 logger.Debugf("caas firewaller application %v has been removed", w.application) 72 err = nil 73 } 74 }() 75 appWatcher, err := w.applicationGetter.WatchApplication(w.application) 76 if err := w.catacomb.Add(appWatcher); err != nil { 77 return errors.Trace(err) 78 } 79 80 for { 81 select { 82 case <-w.catacomb.Dying(): 83 return w.catacomb.ErrDying() 84 case _, ok := <-appWatcher.Changes(): 85 if !ok { 86 return errors.New("application watcher closed") 87 } 88 if err := w.processApplicationChange(); err != nil { 89 if strings.Contains(err.Error(), "unexpected EOF") { 90 return nil 91 } 92 return errors.Trace(err) 93 } 94 } 95 } 96 } 97 98 func (w *applicationWorker) processApplicationChange() (err error) { 99 exposed, err := w.applicationGetter.IsExposed(w.application) 100 if err != nil { 101 return errors.Trace(err) 102 } 103 if !w.initial && exposed == w.previouslyExposed { 104 return nil 105 } 106 107 w.initial = false 108 w.previouslyExposed = exposed 109 if exposed { 110 appConfig, err := w.applicationGetter.ApplicationConfig(w.application) 111 if err != nil { 112 return errors.Trace(err) 113 } 114 resourceTags := tags.ResourceTags( 115 names.NewModelTag(w.modelUUID), 116 names.NewControllerTag(w.controllerUUID), 117 ) 118 if err := w.serviceExposer.ExposeService(w.application, resourceTags, appConfig); err != nil { 119 return errors.Trace(err) 120 } 121 return nil 122 } 123 if err := w.serviceExposer.UnexposeService(w.application); err != nil { 124 return errors.Trace(err) 125 } 126 return nil 127 }