func (p *pluginControl) SwapPlugins(in *core.RequestedPlugin, out core.CatalogedPlugin) serror.SnapError { details, serr := p.returnPluginDetails(in) if serr != nil { return serr } if details.IsPackage { defer os.RemoveAll(filepath.Dir(details.ExecPath)) } lp, err := p.pluginManager.LoadPlugin(details, p.eventManager) if err != nil { return err } // Make sure plugin types and names are the same if lp.TypeName() != out.TypeName() || lp.Name() != out.Name() { serr := serror.New(errors.New("Plugin types and names must match.")) serr.SetFields(map[string]interface{}{ "in-type": lp.TypeName(), "out-type": out.TypeName(), "in-name": lp.Name(), "out-name": out.Name(), }) _, err := p.pluginManager.UnloadPlugin(lp) if err != nil { se := serror.New(errors.New("Failed to rollback after error")) se.SetFields(map[string]interface{}{ "original-unload-error": serr.Error(), "rollback-unload-error": err.Error(), }) return se } return serr } up, err := p.pluginManager.UnloadPlugin(out) if err != nil { _, err2 := p.pluginManager.UnloadPlugin(lp) if err2 != nil { se := serror.New(errors.New("Failed to rollback after error")) se.SetFields(map[string]interface{}{ "original-unload-error": err.Error(), "rollback-unload-error": err2.Error(), }) return se } return err } event := &control_event.SwapPluginsEvent{ LoadedPluginName: lp.Meta.Name, LoadedPluginVersion: lp.Meta.Version, UnloadedPluginName: up.Meta.Name, UnloadedPluginVersion: up.Meta.Version, PluginType: int(lp.Meta.Type), } defer p.eventManager.Emit(event) return nil }
func catalogedPluginToLoaded(host string, c core.CatalogedPlugin) *rbody.LoadedPlugin { return &rbody.LoadedPlugin{ Name: c.Name(), Version: c.Version(), Type: c.TypeName(), Signed: c.IsSigned(), Status: c.Status(), LoadedTimestamp: c.LoadedTimestamp().Unix(), Href: catalogedPluginURI(host, c), } }
func catalogedPluginURI(host string, c core.CatalogedPlugin) string { return fmt.Sprintf("%s://%s/v1/plugins/%s/%s/%d", protocolPrefix, host, c.TypeName(), c.Name(), c.Version()) }
func (s *Server) getPlugin(w http.ResponseWriter, r *http.Request, p httprouter.Params) { plName := p.ByName("name") plType := p.ByName("type") plVersion, iErr := strconv.ParseInt(p.ByName("version"), 10, 0) f := map[string]interface{}{ "plugin-name": plName, "plugin-version": plVersion, "plugin-type": plType, } if iErr != nil { se := serror.New(errors.New("invalid version")) se.SetFields(f) respond(400, rbody.FromSnapError(se), w) return } if plName == "" { se := serror.New(errors.New("missing plugin name")) se.SetFields(f) respond(400, rbody.FromSnapError(se), w) return } if plType == "" { se := serror.New(errors.New("missing plugin type")) se.SetFields(f) respond(400, rbody.FromSnapError(se), w) return } pluginCatalog := s.mm.PluginCatalog() var plugin core.CatalogedPlugin for _, item := range pluginCatalog { if item.Name() == plName && item.Version() == int(plVersion) && item.TypeName() == plType { plugin = item break } } if plugin == nil { se := serror.New(ErrPluginNotFound, f) respond(404, rbody.FromSnapError(se), w) return } rd := r.FormValue("download") d, _ := strconv.ParseBool(rd) if d { b, err := ioutil.ReadFile(plugin.PluginPath()) if err != nil { f["plugin-path"] = plugin.PluginPath() se := serror.New(err, f) respond(500, rbody.FromSnapError(se), w) return } w.Header().Set("Content-Encoding", "gzip") gz := gzip.NewWriter(w) defer gz.Close() _, err = gz.Write(b) if err != nil { f["plugin-path"] = plugin.PluginPath() se := serror.New(err, f) respond(500, rbody.FromSnapError(se), w) return } return } else { pluginRet := &rbody.PluginReturned{ Name: plugin.Name(), Version: plugin.Version(), Type: plugin.TypeName(), Signed: plugin.IsSigned(), Status: plugin.Status(), LoadedTimestamp: plugin.LoadedTimestamp().Unix(), Href: catalogedPluginURI(r.Host, plugin), } respond(200, pluginRet, w) } }
func (s *Server) getPlugin(w http.ResponseWriter, r *http.Request, p httprouter.Params) { plName := p.ByName("name") plType := p.ByName("type") plVersion, iErr := strconv.ParseInt(p.ByName("version"), 10, 0) f := map[string]interface{}{ "plugin-name": plName, "plugin-version": plVersion, "plugin-type": plType, } if iErr != nil { se := serror.New(errors.New("invalid version")) se.SetFields(f) respond(400, rbody.FromSnapError(se), w) return } if plName == "" { se := serror.New(errors.New("missing plugin name")) se.SetFields(f) respond(400, rbody.FromSnapError(se), w) return } if plType == "" { se := serror.New(errors.New("missing plugin type")) se.SetFields(f) respond(400, rbody.FromSnapError(se), w) return } pluginCatalog := s.mm.PluginCatalog() var plugin core.CatalogedPlugin for _, item := range pluginCatalog { if item.Name() == plName && item.Version() == int(plVersion) && item.TypeName() == plType { plugin = item break } } if plugin == nil { se := serror.New(ErrPluginNotFound, f) respond(404, rbody.FromSnapError(se), w) return } rd := r.FormValue("download") d, _ := strconv.ParseBool(rd) var configPolicy []rbody.PolicyTable if plugin.TypeName() == "processor" || plugin.TypeName() == "publisher" { rules := plugin.Policy().Get([]string{""}).RulesAsTable() configPolicy = make([]rbody.PolicyTable, 0, len(rules)) for _, r := range rules { configPolicy = append(configPolicy, rbody.PolicyTable{ Name: r.Name, Type: r.Type, Default: r.Default, Required: r.Required, Minimum: r.Minimum, Maximum: r.Maximum, }) } } else { configPolicy = nil } if d { b, err := ioutil.ReadFile(plugin.PluginPath()) if err != nil { f["plugin-path"] = plugin.PluginPath() se := serror.New(err, f) respond(500, rbody.FromSnapError(se), w) return } w.Header().Set("Content-Encoding", "gzip") gz := gzip.NewWriter(w) defer gz.Close() _, err = gz.Write(b) if err != nil { f["plugin-path"] = plugin.PluginPath() se := serror.New(err, f) respond(500, rbody.FromSnapError(se), w) return } return } else { pluginRet := &rbody.PluginReturned{ Name: plugin.Name(), Version: plugin.Version(), Type: plugin.TypeName(), Signed: plugin.IsSigned(), Status: plugin.Status(), LoadedTimestamp: plugin.LoadedTimestamp().Unix(), Href: pluginURI(r.Host, plugin), ConfigPolicy: configPolicy, } respond(200, pluginRet, w) } }