github.com/outbrain/consul@v1.4.5/agent/connect_ca_endpoint.go (about)

     1  package agent
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"github.com/hashicorp/consul/agent/structs"
     8  )
     9  
    10  // GET /v1/connect/ca/roots
    11  func (s *HTTPServer) ConnectCARoots(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
    12  	var args structs.DCSpecificRequest
    13  	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
    14  		return nil, nil
    15  	}
    16  
    17  	var reply structs.IndexedCARoots
    18  	defer setMeta(resp, &reply.QueryMeta)
    19  	if err := s.agent.RPC("ConnectCA.Roots", &args, &reply); err != nil {
    20  		return nil, err
    21  	}
    22  
    23  	return reply, nil
    24  }
    25  
    26  // /v1/connect/ca/configuration
    27  func (s *HTTPServer) ConnectCAConfiguration(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
    28  	switch req.Method {
    29  	case "GET":
    30  		return s.ConnectCAConfigurationGet(resp, req)
    31  
    32  	case "PUT":
    33  		return s.ConnectCAConfigurationSet(resp, req)
    34  
    35  	default:
    36  		return nil, MethodNotAllowedError{req.Method, []string{"GET", "POST"}}
    37  	}
    38  }
    39  
    40  // GEt /v1/connect/ca/configuration
    41  func (s *HTTPServer) ConnectCAConfigurationGet(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
    42  	// Method is tested in ConnectCAConfiguration
    43  	var args structs.DCSpecificRequest
    44  	if done := s.parse(resp, req, &args.Datacenter, &args.QueryOptions); done {
    45  		return nil, nil
    46  	}
    47  
    48  	var reply structs.CAConfiguration
    49  	err := s.agent.RPC("ConnectCA.ConfigurationGet", &args, &reply)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	fixupConfig(&reply)
    55  	return reply, nil
    56  }
    57  
    58  // PUT /v1/connect/ca/configuration
    59  func (s *HTTPServer) ConnectCAConfigurationSet(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
    60  	// Method is tested in ConnectCAConfiguration
    61  
    62  	var args structs.CARequest
    63  	s.parseDC(req, &args.Datacenter)
    64  	s.parseToken(req, &args.Token)
    65  	if err := decodeBody(req, &args.Config, nil); err != nil {
    66  		resp.WriteHeader(http.StatusBadRequest)
    67  		fmt.Fprintf(resp, "Request decode failed: %v", err)
    68  		return nil, nil
    69  	}
    70  
    71  	var reply interface{}
    72  	err := s.agent.RPC("ConnectCA.ConfigurationSet", &args, &reply)
    73  	return nil, err
    74  }
    75  
    76  // A hack to fix up the config types inside of the map[string]interface{}
    77  // so that they get formatted correctly during json.Marshal. Without this,
    78  // string values that get converted to []uint8 end up getting output back
    79  // to the user in base64-encoded form.
    80  func fixupConfig(conf *structs.CAConfiguration) {
    81  	for k, v := range conf.Config {
    82  		if raw, ok := v.([]uint8); ok {
    83  			strVal := structs.Uint8ToString(raw)
    84  			conf.Config[k] = strVal
    85  			switch conf.Provider {
    86  			case structs.ConsulCAProvider:
    87  				if k == "PrivateKey" && strVal != "" {
    88  					conf.Config["PrivateKey"] = "hidden"
    89  				}
    90  			case structs.VaultCAProvider:
    91  				if k == "Token" && strVal != "" {
    92  					conf.Config["Token"] = "hidden"
    93  				}
    94  			}
    95  		}
    96  	}
    97  }