in agent/listenerdraining/listener_draining.go [38:107]
func (envoyListenerDrainHandler *EnvoyListenerDrainHandler) HandleDraining(responseWriter http.ResponseWriter, request *http.Request) {
log.Info("Received request to drain listener connections.")
if !envoyListenerDrainHandler.Limiter.Allow() {
http.Error(responseWriter, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)
return
}
// Validate the request and query parameters before calling Envoy drain endpoint.
if queryParams, err := validateDrainingRequest(request); err != nil {
http.Error(responseWriter, err.Error(), http.StatusBadRequest)
return
} else {
envoyListenerDrainHandler.queryParameters = *queryParams
}
envoyListenerDrainUrl := envoyListenerDrainHandler.getEnvoyListenerDrainUrl()
log.Debugf("Url to Envoy Listener Drain Endpoint: %s", envoyListenerDrainUrl)
// Send request to Envoy Drain endpoint
httpClient, err := client.CreateRetryableHttpClientForEnvoyServer(envoyListenerDrainHandler.AgentConfig)
if err != nil {
log.Errorf("Failed to create Retryable Http Client: %v", err)
http.Error(responseWriter, "Unable to drain Envoy listeners", http.StatusInternalServerError)
return
}
drainRequest, err := client.CreateRetryableAgentRequest(http.MethodPost, envoyListenerDrainUrl, nil)
if err != nil {
log.Errorf("Unable to create drain request to Envoy: %v", err)
http.Error(responseWriter, "Unable to drain Envoy listeners", http.StatusInternalServerError)
return
}
drainResponse, err := httpClient.Do(drainRequest)
if err != nil {
log.Errorf("Unable to reach Envoy Admin port: %v", err)
http.Error(responseWriter, "Unable to drain Envoy listeners", http.StatusInternalServerError)
return
}
if drainResponse == nil {
responseWriter.WriteHeader(http.StatusNoContent)
log.Debug("Empty response from Envoy drain endpoint.")
return
}
defer drainResponse.Body.Close()
if drainResponse.StatusCode != http.StatusOK {
log.Errorf("Draining Envoy listeners failed [response %d - %s]",
drainResponse.StatusCode, drainResponse.Status)
http.Error(responseWriter, "Unable to drain Envoy listeners", http.StatusInternalServerError)
return
}
log.Infof("Initiated Envoy inbound listener draining [response %d - %s]", drainResponse.StatusCode, drainResponse.Status)
responseBody, err := ioutil.ReadAll(drainResponse.Body)
if err != nil {
log.Warnf("Unable to read drain response from Envoy: %v", err)
// We did get a 200 back though
responseWriter.WriteHeader(http.StatusOK)
return
}
responseWriter.WriteHeader(http.StatusOK)
_, err = responseWriter.Write(responseBody)
if err != nil {
log.Errorf("Error while writing response: %s", err)
}
}