package main import ( "fmt" "log" "net/url" ) // config accepts a slice of type Redirect and returns an error // it organizes the data from the input redirects in a way that makes sense for FortiOS objects // then outputs the configuration to stdout func config(redirects []Redirect) error { // A map which contains the name of a redirect policy as the key, and a slice of strings as a value. // The value of the string is the name of the url-rewrite-rule which needs to be referenced by the redirect policy object in FortiOS redirectPolicies := make(map[string][]string) // Iterate over all redirects and output url-rewrite-rules fmt.Printf("\n\n------------------------\n\n\n") fmt.Println("config waf url-rewrite url-rewrite-rule") for _, redirect := range redirects { sourceURL, err := url.Parse(redirect.sourceURL) if err != nil { log.Printf("skipping redirect: unable to parse source URL '%s': %v", redirect.sourceURL, err) continue } fmt.Printf("edit \"%s\"\n", redirect.sourceURL) fmt.Println("set action redirect") fmt.Printf("set location %s\n", redirect.destinationURL) fmt.Println("set action redirect") fmt.Println("config match-condition") fmt.Println("edit 0") fmt.Println("set object http-url") fmt.Printf("set reg-exp %s\n", sourceURL.Path) fmt.Println("set protocol-filter enable") fmt.Printf("set HTTP-protocol %s\n", sourceURL.Scheme) fmt.Println("next") fmt.Println("end") fmt.Println("next") // Add this rule to the policy map redirectPolicies[sourceURL.Host] = append(redirectPolicies[sourceURL.Host], redirect.sourceURL) } fmt.Println("end") // Iterate over values in the policy map and output the policy configuration fmt.Println("config waf url-rewrite url-rewrite-policy") for policyName, policyRules := range redirectPolicies { fmt.Printf("edit \"%s\"\n", policyName) for _, ruleName := range policyRules { fmt.Println("edit 0") fmt.Printf("set url-rewrite-rule-name %s-redirects\n", ruleName) fmt.Println("next") fmt.Println("end") } fmt.Println("next") } fmt.Println("end") return nil }