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  }