func (s *server) makeHTTPHandler( ctx types.Context, route types.Route) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { w.Header().Set(types.ServerNameHeader, s.name) ctx := context.WithRequestRoute(ctx, req, route) if req.TLS != nil { if len(req.TLS.PeerCertificates) > 0 { userName := req.TLS.PeerCertificates[0].Subject.CommonName ctx = ctx.WithValue(context.UserKey, userName) } } ctx.Info("http request") vars := mux.Vars(req) if vars == nil { vars = map[string]string{} } store := utils.NewStoreWithVars(vars) handlerFunc := s.handleWithMiddleware(ctx, route) if err := handlerFunc(ctx, w, req, store); err != nil { ctx.Error(err) http.Error(w, err.Error(), http.StatusInternalServerError) } } }
func (m *mod) buildMux() *http.ServeMux { mux := http.NewServeMux() // m.ctx.WithServiceName(m.ctx.ServiceName()) mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.2+json") fmt.Fprintln(w, `{"Implements": ["VolumeDriver"]}`) m.ctx.Debug("/Plugin.Activate") }) mux.HandleFunc("/VolumeDriver.Create", func(w http.ResponseWriter, r *http.Request) { var pr pluginRequest if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Create: error decoding json") return } m.ctx.WithField("pluginResponse", pr).Debug("/VolumeDriver.Create") store := apiutils.NewStoreWithVars(pr.Opts) vtype := store.GetStringPtr("type") if vtype == nil { vtype = store.GetStringPtr("volumetype") } _, err := m.lsc.Integration().Create( m.ctx, pr.Name, &apitypes.VolumeCreateOpts{ AvailabilityZone: store.GetStringPtr("availabilityZone"), IOPS: store.GetInt64Ptr("iops"), Size: store.GetInt64Ptr("size"), Type: vtype, Opts: store, }) if err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Create: error creating volume") return } w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.2+json") fmt.Fprintln(w, `{}`) }) mux.HandleFunc("/VolumeDriver.Remove", func(w http.ResponseWriter, r *http.Request) { var pr pluginRequest if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Remove: error decoding json") return } m.ctx.WithField("pluginResponse", pr).Debug("/VolumeDriver.Remove") // TODO We need the service name err := m.lsc.Integration().Remove(m.ctx, pr.Name, apiutils.NewStore()) if err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Remove: error removing volume") return } w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.2+json") fmt.Fprintln(w, `{}`) }) mux.HandleFunc("/VolumeDriver.Path", func(w http.ResponseWriter, r *http.Request) { var pr pluginRequest if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Path: error decoding json") return } m.ctx.WithField("pluginResponse", pr).Debug("/VolumeDriver.Path") mountPath, err := m.lsc.Integration().Path( m.ctx, "", pr.Name, apiutils.NewStore()) if err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Path: error returning path") return } w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.2+json") fmt.Fprintln(w, fmt.Sprintf("{\"Mountpoint\": \"%s\"}", mountPath)) }) mux.HandleFunc("/VolumeDriver.Mount", func(w http.ResponseWriter, r *http.Request) { var pr pluginRequest if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Mount: error decoding json") return } m.ctx.WithField("pluginResponse", pr).Debug("/VolumeDriver.Mount") mountPath, _, err := m.lsc.Integration().Mount( m.ctx, "", pr.Name, &apitypes.VolumeMountOpts{}) if err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Mount: error mounting volume") return } w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.2+json") fmt.Fprintln(w, fmt.Sprintf("{\"Mountpoint\": \"%s\"}", mountPath)) }) mux.HandleFunc("/VolumeDriver.Unmount", func(w http.ResponseWriter, r *http.Request) { var pr pluginRequest if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Unmount: error decoding json") return } m.ctx.WithField("pluginResponse", pr).Debug("/VolumeDriver.Unmount") _, err := m.lsc.Integration().Unmount( m.ctx, "", pr.Name, apiutils.NewStore()) if err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Unmount: error unmounting volume") return } w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.2+json") fmt.Fprintln(w, `{}`) }) mux.HandleFunc("/VolumeDriver.Get", func(w http.ResponseWriter, r *http.Request) { var pr pluginRequest if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Get: error decoding json") return } m.ctx.WithField("pluginResponse", pr).Debug("/VolumeDriver.Get") volMapping, err := m.lsc.Integration().Inspect( m.ctx, pr.Name, apiutils.NewStore()) if err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Get: error getting volume") return } w.Header().Set( "Content-Type", "application/vnd.docker.plugins.v1.2+json") json.NewEncoder(w).Encode(map[string]apitypes.VolumeMapping{ "Volume": volMapping, }) }) mux.HandleFunc("/VolumeDriver.List", func(w http.ResponseWriter, r *http.Request) { var pr pluginRequest if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.List: error decoding json") return } m.ctx.WithField("pluginResponse", pr).Debug("/VolumeDriver.List") volMappings, err := m.lsc.Integration().List(m.ctx, apiutils.NewStore()) if err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.List: error listing volumes") return } w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.2+json") json.NewEncoder(w).Encode( map[string][]apitypes.VolumeMapping{"Volumes": volMappings}) }) mux.HandleFunc("/VolumeDriver.Capabilities", func(w http.ResponseWriter, r *http.Request) { var pr pluginRequest if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { http.Error(w, fmt.Sprintf("{\"Error\":\"%s\"}", err.Error()), 500) m.ctx.WithError(err).Error("/VolumeDriver.Capabilities: error decoding json") return } m.ctx.WithField("pluginResponse", pr).Debug("/VolumeDriver.Capabilities") w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.2+json") fmt.Fprintln(w, `{"Capabilities": { "Scope": "global" }}`) }) return mux }