github.com/abayer/test-infra@v0.0.5/mungegithub/features/features.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package features
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"k8s.io/apimachinery/pkg/util/sets"
    23  	"k8s.io/test-infra/mungegithub/github"
    24  	"k8s.io/test-infra/mungegithub/options"
    25  
    26  	"github.com/golang/glog"
    27  )
    28  
    29  // Features are all features the code know about. Care should be taken
    30  // not to try to use a feature which isn't 'active'
    31  type Features struct {
    32  	Repos  *RepoInfo
    33  	Server *ServerFeature
    34  	active []feature
    35  }
    36  
    37  type feature interface {
    38  	Name() string
    39  	RegisterOptions(opts *options.Options) sets.String
    40  	Initialize(config *github.Config) error
    41  	EachLoop() error
    42  }
    43  
    44  var featureMap = map[string]feature{}
    45  
    46  // GetActive returns all features requested by a munger
    47  func (f *Features) GetActive() []feature {
    48  	return f.active
    49  }
    50  
    51  // Initialize should be called with the set of all features needed by all (active) mungers
    52  func (f *Features) Initialize(config *github.Config, requestedFeatures []string) error {
    53  	for _, name := range requestedFeatures {
    54  		glog.Infof("Initializing feature: %v", name)
    55  		feat, found := featureMap[name]
    56  		if !found {
    57  			return fmt.Errorf("Could not find a feature named: %s", name)
    58  		}
    59  		f.active = append(f.active, featureMap[name])
    60  		if err := feat.Initialize(config); err != nil {
    61  			return err
    62  		}
    63  		switch name {
    64  		case RepoFeatureName:
    65  			f.Repos = feat.(*RepoInfo)
    66  		case ServerFeatureName:
    67  			f.Server = feat.(*ServerFeature)
    68  		}
    69  	}
    70  	return nil
    71  }
    72  
    73  // EachLoop allows active features to update every loop
    74  func (f *Features) EachLoop() error {
    75  	for _, feat := range f.GetActive() {
    76  		if err := feat.EachLoop(); err != nil {
    77  			return err
    78  		}
    79  	}
    80  	return nil
    81  }
    82  
    83  // RegisterOptions registers the options used by features and returns any options that should
    84  // trigger a restart when they are changed.
    85  func (f *Features) RegisterOptions(opts *options.Options) sets.String {
    86  	immutables := sets.NewString()
    87  	for _, feat := range featureMap {
    88  		immutables = immutables.Union(feat.RegisterOptions(opts))
    89  	}
    90  	return immutables
    91  }
    92  
    93  // RegisterFeature should be called in `init()` by each feature to make itself
    94  // available by name
    95  func RegisterFeature(feat feature) error {
    96  	if _, found := featureMap[feat.Name()]; found {
    97  		glog.Fatalf("a feature with the name (%s) already exists", feat.Name())
    98  	}
    99  	featureMap[feat.Name()] = feat
   100  	glog.Infof("Registered %#v at %s", feat, feat.Name())
   101  	return nil
   102  }