func()

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)
	}
}