github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/plugin/builtin/manifest/manifest_plugin.go (about)

     1  package manifest
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	"github.com/evergreen-ci/evergreen/model/manifest"
     9  	"github.com/evergreen-ci/evergreen/model/version"
    10  	"github.com/evergreen-ci/evergreen/plugin"
    11  	"github.com/gorilla/mux"
    12  	"github.com/mitchellh/mapstructure"
    13  	"github.com/mongodb/grip"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  const (
    18  	ManifestLoadCmd    = "load"
    19  	ManifestAttachCmd  = "attach"
    20  	ManifestPluginName = "manifest"
    21  
    22  	ManifestLoadAPIEndpoint = "load"
    23  )
    24  
    25  type manifestParams struct {
    26  	GithubToken string `mapstructure:"github_token"`
    27  }
    28  
    29  // ManifestPlugin handles the creation of a Build Manifest associated with a version.
    30  type ManifestPlugin struct {
    31  	OAuthCredentials string
    32  }
    33  
    34  func init() {
    35  	plugin.Publish(&ManifestPlugin{})
    36  }
    37  
    38  // Name returns the name of this plugin - satisfies 'Plugin' interface
    39  func (m *ManifestPlugin) Name() string {
    40  	return ManifestPluginName
    41  }
    42  
    43  func (m *ManifestPlugin) Configure(conf map[string]interface{}) error {
    44  	mp := &manifestParams{}
    45  	err := mapstructure.Decode(conf, mp)
    46  	if err != nil {
    47  		return err
    48  	}
    49  	if mp.GithubToken == "" {
    50  		// this should return an error, but never has before
    51  		// (caught an lint error.) Tests break if this returns early.
    52  		grip.Warning(errors.New("GitHub token is empty"))
    53  	}
    54  	m.OAuthCredentials = mp.GithubToken
    55  	return nil
    56  }
    57  
    58  // GetPanelConfig returns a pointer to a plugin's UI configuration.
    59  // or an error, if an error occur while trying to generate the config
    60  // A nil pointer represents a plugin without a UI presence, and is
    61  // not an error.
    62  // GetPanelConfig returns a plugin.PanelConfig struct representing panels
    63  // that will be added to the Version page.
    64  func (m *ManifestPlugin) GetPanelConfig() (*plugin.PanelConfig, error) {
    65  	return &plugin.PanelConfig{
    66  		Panels: []plugin.UIPanel{
    67  			{
    68  				Page:      plugin.VersionPage,
    69  				Position:  plugin.PageRight,
    70  				PanelHTML: "<div ng-include=\"'/plugin/manifest/static/partials/version_manifest_panel.html'\"></div>",
    71  				DataFunc: func(context plugin.UIContext) (interface{}, error) {
    72  					if context.Version == nil {
    73  						return nil, nil
    74  					}
    75  					currentManifest, err := manifest.FindOne(manifest.ById(context.Version.Id))
    76  					if err != nil {
    77  						return nil, err
    78  					}
    79  					if currentManifest == nil {
    80  						return nil, nil
    81  					}
    82  					prettyManifest, err := json.MarshalIndent(currentManifest, "", "  ")
    83  					if err != nil {
    84  						return nil, err
    85  					}
    86  					return string(prettyManifest), nil
    87  				},
    88  			},
    89  		},
    90  	}, nil
    91  }
    92  func (m *ManifestPlugin) GetUIHandler() http.Handler {
    93  	r := mux.NewRouter()
    94  	r.Path("/get/{project_id}/{revision}").HandlerFunc(m.GetManifest)
    95  	return r
    96  }
    97  func (m *ManifestPlugin) GetAPIHandler() http.Handler {
    98  	r := http.NewServeMux()
    99  	r.HandleFunc(fmt.Sprintf("/%v", ManifestLoadAPIEndpoint), m.ManifestLoadHandler)
   100  	r.HandleFunc("/", http.NotFound) // 404 any request not routable to these endpoints
   101  	return r
   102  }
   103  
   104  // NewCommand returns requested commands by name. Fulfills the Plugin interface.
   105  func (m *ManifestPlugin) NewCommand(cmdName string) (plugin.Command, error) {
   106  	switch cmdName {
   107  	case ManifestLoadCmd:
   108  		return &ManifestLoadCommand{}, nil
   109  	default:
   110  		return nil, errors.Errorf("No such %v command: %v", m.Name(), cmdName)
   111  	}
   112  }
   113  
   114  func (m *ManifestPlugin) GetManifest(w http.ResponseWriter, r *http.Request) {
   115  	project := mux.Vars(r)["project_id"]
   116  	revision := mux.Vars(r)["revision"]
   117  
   118  	version, err := version.FindOne(version.ByProjectIdAndRevision(project, revision))
   119  	if err != nil {
   120  		http.Error(w, fmt.Sprintf("error getting version for project %v with revision %v: %v",
   121  			project, revision, err), http.StatusBadRequest)
   122  		return
   123  	}
   124  	if version == nil {
   125  		http.Error(w, fmt.Sprintf("version not found for project %v, with revision %v", project, revision),
   126  			http.StatusNotFound)
   127  		return
   128  	}
   129  
   130  	foundManifest, err := manifest.FindOne(manifest.ById(version.Id))
   131  	if err != nil {
   132  		http.Error(w, fmt.Sprintf("error getting manifest with version id %v: %v",
   133  			version.Id, err), http.StatusBadRequest)
   134  		return
   135  	}
   136  	if foundManifest == nil {
   137  		http.Error(w, fmt.Sprintf("manifest not found for version %v", version.Id), http.StatusNotFound)
   138  		return
   139  	}
   140  	plugin.WriteJSON(w, http.StatusOK, foundManifest)
   141  	return
   142  
   143  }