github.com/rohankumardubey/proxyfs@v0.0.0-20210108201508-653efa9ab00e/pfsagentConfig/validators.go (about)

     1  package pfsagentConfig
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"strings"
     9  )
    10  
    11  // ValidateAuthURL checks that an AUTH URL pointing to a SwiftStack cluster
    12  // func ValidateAuthURL(urlToBeTested string) error {
    13  // 	return nil
    14  // }
    15  
    16  // ValidateAccess runs all
    17  func ValidateAccess() (errorType int, err error) {
    18  	mySwiftParams := new(SwiftParams)
    19  	mySwiftParams.User = confMap["Agent"]["SwiftAuthUser"][0]
    20  	mySwiftParams.Key = confMap["Agent"]["SwiftAuthKey"][0]
    21  	mySwiftParams.Account = confMap["Agent"]["SwiftAccountName"][0]
    22  	mySwiftParams.AuthURL = confMap["Agent"]["SwiftAuthURL"][0]
    23  
    24  	err = validateURL(mySwiftParams)
    25  	if nil != err {
    26  		errorType = typeAuthURL
    27  		return
    28  	}
    29  	_, err = validateCredentails(mySwiftParams)
    30  	if nil != err {
    31  		errorType = typeCredentails
    32  		return
    33  	}
    34  	err = validateAccount(mySwiftParams)
    35  	if nil != err {
    36  		errorType = typeAccount
    37  		return
    38  	}
    39  	return -1, nil
    40  }
    41  
    42  func validateURL(mySwiftParams *SwiftParams) error {
    43  	parts := strings.Split(mySwiftParams.AuthURL, "/")
    44  	if len(parts) < 5 {
    45  		return fmt.Errorf(`
    46  Auth URL should be of the form:
    47  <protocol>://<url>/auth/v<API version>
    48  where
    49          - protocol is either 'http' or 'https'
    50          - url is the public address of the cluster (such as 'swiftcluster.com' or '192.168.2.100')
    51          - API version is usually in the format of 1.0, 2.0 etc.
    52  `)
    53  	}
    54  	protocol := parts[0]
    55  	if strings.Index(protocol, "http") != 0 && strings.Index(protocol, "https") != 0 {
    56  		return fmt.Errorf("Auth URL Should Start With http:// Or https://\n\tYour Protocol is %v", protocol)
    57  	}
    58  	if parts[3] != "auth" {
    59  		return fmt.Errorf("A Valid Auth URL Should Have The Word 'auth' After The Address.\n\tExample: https://swiftcluster.com/auth/v1.0")
    60  	}
    61  	if strings.Index(parts[4], "v") != 0 || len(parts[4]) != 4 {
    62  		return fmt.Errorf("A Valid Auth URL Should Have The Protocol Version After The Term 'auth'.\n\tExample: https://swiftcluster.com/auth/v1.0")
    63  	}
    64  	address := strings.Split(parts[2], "/")[0]
    65  	url := fmt.Sprintf("%v//%v", protocol, address)
    66  	response, generalAccessErr := http.Get(url)
    67  	if nil != generalAccessErr {
    68  		return fmt.Errorf("Error Connecting To The Cluster's URL, Which Probably Means The URL Has Errors.\n\tDetected Cluster URL: %v\n\tError: %v", url, generalAccessErr)
    69  	}
    70  	infoURL := fmt.Sprintf("%v/info", url)
    71  	response, httpErr := http.Get(infoURL)
    72  	if nil != httpErr {
    73  		return fmt.Errorf("Error Connecting To The Cluster's 'info' URL (%v), Though The URL Itself (%v) Is Reponding.\n\tPlease Check Your URL\n\tError: %v", infoURL, url, httpErr)
    74  	}
    75  	defer response.Body.Close()
    76  	infoBody, bodyReadErr := ioutil.ReadAll(response.Body)
    77  	if nil != bodyReadErr {
    78  		return fmt.Errorf("Error Reading Response From %v\n\tError: %v", infoURL, bodyReadErr)
    79  	}
    80  	var infoInterface interface{}
    81  	jsonErr := json.Unmarshal(infoBody, &infoInterface)
    82  	if nil != jsonErr {
    83  		return fmt.Errorf("Error Parsing Info From %v.\nBody Text: %v\n\tError: %v", infoURL, string(infoBody), jsonErr)
    84  	}
    85  	validJSON := infoInterface.(map[string]interface{})
    86  	if nil == validJSON["swift"] {
    87  		return fmt.Errorf("Error Finding The Term 'swift' In Parsed JSON\n\tError: %v", validJSON)
    88  	}
    89  
    90  	authClient := &http.Client{}
    91  	authTokenRequest, authTokenErr := http.NewRequest("GET", mySwiftParams.AuthURL, nil)
    92  	if nil != authTokenErr {
    93  		fmt.Printf("Error Creting Auth Request:\n%v\n", authTokenErr)
    94  	}
    95  	authURLResponse, authURLErr := authClient.Do(authTokenRequest)
    96  	if nil != authURLErr {
    97  		return fmt.Errorf("Error Executing Auth URL Request:\n\tURL: %v\n\tError: %v", mySwiftParams.AuthURL, authURLErr)
    98  	}
    99  	if authURLResponse.StatusCode != 401 {
   100  		return fmt.Errorf("Error Response From Auth URL. Get On Auth URL With No User/Key Should Result In Status '401 Unauthorize'\n\tStatus code: %v", authURLResponse.Status)
   101  	}
   102  
   103  	return nil
   104  }
   105  
   106  func validateCredentails(mySwiftParams *SwiftParams) (authToken string, err error) {
   107  	authToken, err = GetAuthToken(mySwiftParams)
   108  	if nil != err {
   109  		return
   110  	}
   111  	mySwiftParams.AuthToken = authToken
   112  	return
   113  }
   114  
   115  func validateAccount(mySwiftParams *SwiftParams) error {
   116  	headers, headErr := GetAccountHeaders(mySwiftParams)
   117  	fmt.Printf("\n\nvalidation succeeded? %v\n\n", nil == headErr)
   118  	if nil != headErr {
   119  		return headErr
   120  	}
   121  	if len(headers) == 0 {
   122  		return fmt.Errorf("Though The Request Succeeded There Were No Headers Returned")
   123  	}
   124  	return nil
   125  }