Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FQDN check should pass/fail after retrying mutliple times to reach the node #8244

Merged
merged 11 commits into from
Oct 23, 2023
37 changes: 21 additions & 16 deletions components/automate-cli/pkg/verifyserver/constants/fqdn.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
package constants

const (
FQDN_TITLE = "FQDN is reachable"
FQDN_ERROR_MESSAGE = "FQDN is not reachable"
FQDN_RESOLUTION_MESSAGE = "Ensure FQDN is reachable and mapped to load balancer.Also, ensure your Port 443 is open and load balancer is able to reach to the machine on port 443. Review security group or firewall settings."
NODE_TITLE = "Nodes are reachable"
NODE_SUCCESS_MESSAGE = "All nodes are reachable"
NODE_ERROR_MESSAGE = "%v is not reachable"
NODE_RESOLUTION_MESSAGE = "Ensure your Port 443 is open. Review security group or firewall settings."
CERTIFICATE_TITLE = "Certificate validity for FQDN"
CERTIFICATE_SUCCESS_MESSAGE = "FQDN has with valid certificates"
CERTIFICATE_ERROR_MESSAGE = "FQDN certificate is not valid."
CERTIFICATE_RESOLUTION_MESSAGE = "Generate new valid certificates and provide those."
IP_TO_HASH_FAIL_MESSAGE = "Failed to hash the IP."
DEFAULT_HTTPS_PORT = "443"
SERVER_IP_HEADER_KEY = "x-server-ip"
CHAN_RESULT_ERROR_MESSAGE = "error recieved"
MIN_NUMBER_OF_CALLS = 50
FQDN_TITLE = "FQDN is reachable"
FQDN_ERROR_MESSAGE = "FQDN is not reachable"
FQDN_RESOLUTION_MESSAGE = "Ensure FQDN is reachable and mapped to load balancer. Also, ensure your Port 443 is open and load balancer is able to reach to the machine on port 443. Review security group or firewall settings."
CERT_CN_MISMATCH_RESOLUTION_MESSAGE = "Ensure the certificate provided is Valid. In case of self-signed certificate, make sure the DNS provided in \"subjectAltName\" matches with \"CN\" (Common Name)"
CERT_CN_MISMATCH_ERROR_PATTERN = "x509: certificate is not valid for any names, but wanted to match"
INVALID_FQDN_CERT_RESOLUTION_MESSAGE = "Ensure the certificate provided is Valid. In case of self-signed certificate, make sure the root-ca and the certificate provided in LB belongs to same CA"
INVALID_FQDN_CERT_ERROR_PATTERN = "x509: certificate signed by unknown authority"
GENERIC_FQDN_CERT_RESOLUTION_MESSAGE = "Ensure the certificate provided is Valid. Also check if the FQDN is reachable, and mapped to load balancer. Review security group or firewall settings for the load-balance."
NODE_TITLE = "Nodes are reachable"
NODE_SUCCESS_MESSAGE = "All nodes are reachable"
NODE_ERROR_MESSAGE = "%v is not reachable"
NODE_RESOLUTION_MESSAGE = "Ensure your Port 443 is open. Review security group or firewall settings of the node."
CERTIFICATE_TITLE = "Certificate validity for FQDN"
CERTIFICATE_SUCCESS_MESSAGE = "FQDN has with valid certificates"
CERTIFICATE_ERROR_MESSAGE = "FQDN certificate is not valid."
CERTIFICATE_RESOLUTION_MESSAGE = "Generate new valid certificates and provide those."
IP_TO_HASH_FAIL_MESSAGE = "Failed to hash the IP."
DEFAULT_HTTPS_PORT = "443"
SERVER_IP_HEADER_KEY = "x-server-ip"
CHAN_RESULT_ERROR_MESSAGE = "error recieved"
MIN_NUMBER_OF_CALLS = 50
)
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ func (h *Handler) CheckFqdn(c *fiber.Ctx) error {
return fiber.NewError(http.StatusBadRequest, "node_type should be automate or chef-infra-server, Please provide node_type.")
}

res := h.FqdnService.CheckFqdnReachability(*req, constants.DEFAULT_HTTPS_PORT, time.Minute*1)
res := h.FqdnService.CheckFqdnReachability(*req, constants.DEFAULT_HTTPS_PORT, time.Second*30)
ArvinthC3000 marked this conversation as resolved.
Show resolved Hide resolved
return c.JSON(response.BuildSuccessResponse(res))
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func TriggerCheckAPI(endPoint, host, nodeType, method string, output chan<- mode
}

client := http.Client{
Timeout: 35 * time.Second,
Timeout: 65 * time.Second,
}
resp, err := client.Do(req)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,25 +149,45 @@ func (fq *FqdnService) MakeConcurrentCalls(url string, client *http.Client, setN
return errors.New("nodes are not reachable")
}

func (fq *FqdnService) triggerRequest(client *http.Client, url string) error {
res, err := client.Get(url)
if err != nil {
fq.log.Error(err.Error())
return err
}
func (fq *FqdnService) triggerRequest(client *http.Client, url string, duration time.Duration) error {
timeout := time.After(duration)

var fqdnError error
loop:
for {
select {
case <-timeout:
fq.log.Debugf("Stopped making API calls after %v seconds.", duration)
if fqdnError == nil {
return errors.New(constants.FQDN_ERROR_MESSAGE)
}
return fqdnError
default:
res, err := client.Get(url)
if err != nil {
fq.log.Error("Iteration logs: ", err.Error())
fqdnError = err
time.Sleep(3 * time.Second)
continue
}
fq.log.Debug("Status Code: ", res.StatusCode)
if res.StatusCode != 200 {
fq.log.Errorf("%v is not reachable.", url)
}
if res.StatusCode == 200 {
fq.log.Debug("FQDN is reachable")
// return nil
break loop
}
}
time.Sleep(3 * time.Second)

fq.log.Debug("Status Code: ", res.StatusCode)
if res.StatusCode != 200 {
fq.log.Debugf("%v is not reachable.", url)
return errors.New("fqdn is not reachable")
}

fq.log.Debug("Fqdn is Reachable.")
return nil
}

// fqdnReachable function will check that are we able to hit the load balancer fqdn or not.
func (fq *FqdnService) fqdnReachable(fqdn, rootCert, nodeType string, isAfterDeployment bool, port string) models.Checks {
func (fq *FqdnService) fqdnReachable(fqdn, rootCert, nodeType string, isAfterDeployment bool, port string, duration time.Duration) models.Checks {
fq.log.Debug("Checking Fqdn Reachability...")
client := fq.createClient(rootCert)
var url string
Expand All @@ -179,9 +199,17 @@ func (fq *FqdnService) fqdnReachable(fqdn, rootCert, nodeType string, isAfterDep
}
fq.log.Debug("URL: ", url)

err := fq.triggerRequest(client, url)
err := fq.triggerRequest(client, url, duration)
if err != nil {
return createCheck(constants.FQDN_TITLE, false, "", constants.FQDN_ERROR_MESSAGE, constants.FQDN_RESOLUTION_MESSAGE)
resoultion_message := ""
if strings.Contains(err.Error(), constants.CERT_CN_MISMATCH_ERROR_PATTERN) {
resoultion_message = constants.CERT_CN_MISMATCH_RESOLUTION_MESSAGE
} else if strings.Contains(err.Error(), constants.INVALID_FQDN_CERT_ERROR_PATTERN) {
resoultion_message = constants.INVALID_FQDN_CERT_RESOLUTION_MESSAGE
} else {
resoultion_message = constants.GENERIC_FQDN_CERT_RESOLUTION_MESSAGE
}
return createCheck(constants.FQDN_TITLE, false, "", err.Error(), resoultion_message)
}
return createCheck(constants.FQDN_TITLE, true, constants.FQDN_TITLE, "", "")
}
Expand Down Expand Up @@ -266,7 +294,7 @@ func (fq *FqdnService) CheckFqdnReachability(req models.FqdnRequest, port string
}

if certificateValidityCheck {
check = fq.fqdnReachable(req.Fqdn, req.RootCert, req.NodeType, req.IsAfterDeployment, port)
check = fq.fqdnReachable(req.Fqdn, req.RootCert, req.NodeType, req.IsAfterDeployment, port, duration)
} else {
check = createCheck(constants.FQDN_TITLE, false, "", constants.FQDN_ERROR_MESSAGE, constants.FQDN_RESOLUTION_MESSAGE)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,8 @@ func TestCheckFqdnReachability(t *testing.T) {
Title: constants.FQDN_TITLE,
Passed: false,
SuccessMsg: "",
ErrorMsg: constants.FQDN_ERROR_MESSAGE,
ResolutionMsg: constants.FQDN_RESOLUTION_MESSAGE,
ErrorMsg: "Get \"https://localhost2:5345\": dial tcp: lookup localhost2: no such host",
ResolutionMsg: constants.GENERIC_FQDN_CERT_RESOLUTION_MESSAGE,
},
{
Title: constants.NODE_TITLE,
Expand Down Expand Up @@ -545,8 +545,8 @@ func TestCheckFqdnReachability(t *testing.T) {
Title: constants.FQDN_TITLE,
Passed: false,
SuccessMsg: "",
ErrorMsg: constants.FQDN_ERROR_MESSAGE,
ResolutionMsg: constants.FQDN_RESOLUTION_MESSAGE,
ErrorMsg: "Get \"https://localhost2:5345/_status\": dial tcp: lookup localhost2: no such host",
ResolutionMsg: constants.GENERIC_FQDN_CERT_RESOLUTION_MESSAGE,
},
{
Title: constants.NODE_TITLE,
Expand Down Expand Up @@ -609,8 +609,8 @@ func TestCheckFqdnReachability(t *testing.T) {
Title: constants.FQDN_TITLE,
Passed: false,
SuccessMsg: "",
ErrorMsg: constants.FQDN_ERROR_MESSAGE,
ResolutionMsg: constants.FQDN_RESOLUTION_MESSAGE,
ErrorMsg: "Get \"https://localhost2:5345\": dial tcp: lookup localhost2: no such host",
ResolutionMsg: constants.GENERIC_FQDN_CERT_RESOLUTION_MESSAGE,
},
{
Title: constants.NODE_TITLE,
Expand Down Expand Up @@ -713,7 +713,7 @@ func TestCheckFqdnReachability(t *testing.T) {
Passed: false,
SuccessMsg: "",
ErrorMsg: constants.FQDN_ERROR_MESSAGE,
ResolutionMsg: constants.FQDN_RESOLUTION_MESSAGE,
ResolutionMsg: constants.GENERIC_FQDN_CERT_RESOLUTION_MESSAGE,
},
{
Title: constants.NODE_TITLE,
Expand Down