mirror of
				https://github.com/traefik/traefik.git
				synced 2025-11-04 10:21:15 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			97 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package api
 | 
						|
 | 
						|
import (
 | 
						|
	"archive/tar"
 | 
						|
	"compress/gzip"
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"net/http"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/rs/zerolog/log"
 | 
						|
	"github.com/traefik/traefik/v3/pkg/redactor"
 | 
						|
	"github.com/traefik/traefik/v3/pkg/version"
 | 
						|
)
 | 
						|
 | 
						|
func (h Handler) getSupportDump(rw http.ResponseWriter, req *http.Request) {
 | 
						|
	logger := log.Ctx(req.Context())
 | 
						|
 | 
						|
	staticConfig, err := redactor.Anonymize(h.staticConfig)
 | 
						|
	if err != nil {
 | 
						|
		logger.Error().Err(err).Msg("Unable to anonymize and marshal static configuration")
 | 
						|
		writeError(rw, err.Error(), http.StatusInternalServerError)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	runtimeConfig, err := json.Marshal(h.runtimeConfiguration)
 | 
						|
	if err != nil {
 | 
						|
		logger.Error().Err(err).Msg("Unable to marshal runtime configuration")
 | 
						|
		writeError(rw, err.Error(), http.StatusInternalServerError)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	tVersion, err := json.Marshal(struct {
 | 
						|
		Version   string    `json:"version"`
 | 
						|
		Codename  string    `json:"codename"`
 | 
						|
		StartDate time.Time `json:"startDate"`
 | 
						|
	}{
 | 
						|
		Version:   version.Version,
 | 
						|
		Codename:  version.Codename,
 | 
						|
		StartDate: version.StartDate,
 | 
						|
	})
 | 
						|
	if err != nil {
 | 
						|
		logger.Error().Err(err).Msg("Unable to marshal version")
 | 
						|
		writeError(rw, err.Error(), http.StatusInternalServerError)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	rw.Header().Set("Content-Type", "application/gzip")
 | 
						|
	rw.Header().Set("Content-Disposition", "attachment; filename=support-dump.tar.gz")
 | 
						|
 | 
						|
	// Create gzip writer.
 | 
						|
	gw := gzip.NewWriter(rw)
 | 
						|
	defer gw.Close()
 | 
						|
 | 
						|
	// Create tar writer.
 | 
						|
	tw := tar.NewWriter(gw)
 | 
						|
	defer tw.Close()
 | 
						|
 | 
						|
	// Add configuration files to the archive.
 | 
						|
	if err := addFile(tw, "version.json", tVersion); err != nil {
 | 
						|
		logger.Error().Err(err).Msg("Unable to archive version file")
 | 
						|
		writeError(rw, err.Error(), http.StatusInternalServerError)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	if err := addFile(tw, "static-config.json", []byte(staticConfig)); err != nil {
 | 
						|
		logger.Error().Err(err).Msg("Unable to archive static configuration")
 | 
						|
		writeError(rw, err.Error(), http.StatusInternalServerError)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	if err := addFile(tw, "runtime-config.json", runtimeConfig); err != nil {
 | 
						|
		logger.Error().Err(err).Msg("Unable to archive runtime configuration")
 | 
						|
		writeError(rw, err.Error(), http.StatusInternalServerError)
 | 
						|
		return
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func addFile(tw *tar.Writer, name string, content []byte) error {
 | 
						|
	header := &tar.Header{
 | 
						|
		Name:    name,
 | 
						|
		Mode:    0o600,
 | 
						|
		Size:    int64(len(content)),
 | 
						|
		ModTime: time.Now(),
 | 
						|
	}
 | 
						|
 | 
						|
	if err := tw.WriteHeader(header); err != nil {
 | 
						|
		return fmt.Errorf("writing tar header: %w", err)
 | 
						|
	}
 | 
						|
 | 
						|
	if _, err := tw.Write(content); err != nil {
 | 
						|
		return fmt.Errorf("writing tar content: %w", err)
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 |