Skip to content

Commit 31303db

Browse files
authored
Merge pull request #52 from yashviagrawal/develop
Appknox-Go: Region and Host functionality
2 parents 245b530 + 3e27f05 commit 31303db

File tree

4 files changed

+144
-22
lines changed

4 files changed

+144
-22
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Flags:
3333
-k, --insecure Disable Security Checks
3434
--pac string pac file path or url
3535
--proxy string proxy url
36+
--region string Region names, e.g., global, saudi, uae. By default, global is used
3637
--version version for appknox
3738
3839
Use "appknox [command] --help" for more information about a command.

cmd/root.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"os"
66
"path/filepath"
77

8-
"github.com/appknox/appknox-go/appknox"
8+
// "github.com/appknox/appknox-go/appknox"
99
"github.com/spf13/cobra"
1010
"github.com/spf13/viper"
1111
)
@@ -35,10 +35,15 @@ func init() {
3535
viper.BindEnv("access-token", "APPKNOX_ACCESS_TOKEN")
3636
viper.SetDefault("access-token", "")
3737

38-
RootCmd.PersistentFlags().String("host", appknox.DefaultAPIHost, "Appknox Server")
39-
viper.BindPFlag("host", RootCmd.PersistentFlags().Lookup("host"))
40-
viper.BindEnv("host", "APPKNOX_API_HOST")
41-
viper.SetDefault("host", appknox.DefaultAPIHost)
38+
RootCmd.PersistentFlags().String("host", "", "Appknox Server") // No default value here
39+
viper.BindPFlag("host", RootCmd.PersistentFlags().Lookup("host"))
40+
viper.BindEnv("host", "APPKNOX_API_HOST")
41+
42+
43+
RootCmd.PersistentFlags().String("region", "", "Region names, e.g., global, saudi, uae. By default, global is used")
44+
viper.BindPFlag("region", RootCmd.PersistentFlags().Lookup("region"))
45+
viper.BindEnv("region", "APPKNOX_API_REGION")
46+
viper.SetDefault("region", "global")
4247

4348
RootCmd.PersistentFlags().String("proxy", "", "proxy url")
4449
viper.BindPFlag("proxy", RootCmd.PersistentFlags().Lookup("proxy"))

helper/clientInitialize.go

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,89 @@ func getAppknoxAccessToken() string {
2424
return accessToken
2525
}
2626

27+
// GetHostMappings returns a map of host names to URLs.
28+
func GetHostMappings() map[string]string {
29+
return map[string]string{
30+
"global": "https://api.appknox.com/",
31+
"saudi": "https://sa.secure.appknox.com/",
32+
// Add more mappings as needed
33+
}
34+
}
35+
36+
// ResolveHostAndRegion checks the host and region and returns the resolved base URL
37+
func ResolveHostAndRegion(host, region string, hostMappings map[string]string) (string, error) {
38+
// If both region and host are provided, prioritize host and ignore region
39+
if host != "" {
40+
fmt.Printf("Both region and host provided. Using host URL: %s, ignoring region\n", host)
41+
// Validate the host is a proper URL
42+
_, err := url.ParseRequestURI(host)
43+
if err != nil {
44+
return "", fmt.Errorf("invalid host URL: %s", host)
45+
}
46+
return host, nil
47+
}
48+
49+
// If region is provided, map it to the host URL
50+
if region != "" {
51+
if mappedHost, exists := hostMappings[region]; exists {
52+
return mappedHost, nil
53+
}
54+
// Invalid region, return error and show available regions
55+
availableRegions := make([]string, 0, len(hostMappings))
56+
for key := range hostMappings {
57+
availableRegions = append(availableRegions, key)
58+
}
59+
return "", fmt.Errorf("Invalid region name: %s. Available regions: %s", region, strings.Join(availableRegions, ", "))
60+
}
61+
62+
// If neither host nor region are provided, default to the global host
63+
return hostMappings["global"], nil
64+
}
65+
66+
2767
func getClient() *appknox.Client {
28-
token := getAppknoxAccessToken()
29-
host := viper.GetString("host")
30-
client, err := appknox.NewClient(token)
31-
if err != nil {
32-
fmt.Println(err)
33-
os.Exit(1)
34-
}
35-
proxyURL, err := GetProxy()
36-
if err != nil {
37-
fmt.Println(err)
38-
os.Exit(1)
39-
}
40-
insecure := viper.GetBool("insecure")
41-
client = client.SetHTTPTransportParams(proxyURL, insecure)
42-
baseHost, err := url.Parse(host)
68+
token := getAppknoxAccessToken()
69+
70+
// Check for region and host first
71+
region := viper.GetString("region")
72+
host := viper.GetString("host")
73+
74+
// Get the host mappings
75+
hostMappings := GetHostMappings()
76+
77+
// Use the new function to resolve the host and region
78+
resolvedHost, err := ResolveHostAndRegion(host, region, hostMappings)
4379
if err != nil {
4480
fmt.Println(err)
4581
os.Exit(1)
4682
}
47-
client.BaseURL = baseHost
48-
return client
83+
84+
client, err := appknox.NewClient(token)
85+
if err != nil {
86+
fmt.Println(err)
87+
os.Exit(1)
88+
}
89+
90+
proxyURL, err := GetProxy()
91+
if err != nil {
92+
fmt.Println(err)
93+
os.Exit(1)
94+
}
95+
96+
insecure := viper.GetBool("insecure")
97+
client = client.SetHTTPTransportParams(proxyURL, insecure)
98+
99+
baseHost, err := url.Parse(resolvedHost)
100+
if err != nil {
101+
fmt.Println(err)
102+
os.Exit(1)
103+
}
104+
client.BaseURL = baseHost
105+
return client
49106
}
50107

108+
109+
51110
// CheckToken checks if access token is valid.
52111
func CheckToken() (*appknox.Me, error) {
53112
return GetMe()

helper/resolve_host_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package helper
2+
3+
import (
4+
"strings"
5+
"testing"
6+
)
7+
8+
func TestResolveHostAndRegion(t *testing.T) {
9+
hostMappings := GetHostMappings()
10+
11+
tests := []struct {
12+
name string
13+
host string
14+
region string
15+
expectedHost string
16+
expectError bool
17+
errorMessage string
18+
}{
19+
// Case: Both host and region are empty, should default to global
20+
{"Empty host and region", "", "", hostMappings["global"], false, ""},
21+
22+
// Case: Empty host, valid region
23+
{"Empty host, valid region", "", "global", hostMappings["global"], false, ""},
24+
25+
// Case: Empty host, invalid region
26+
{"Empty host, invalid region", "", "invalid-region", "", true, "Invalid region name: invalid-region. Available regions: global, saudi"},
27+
28+
// Case: Valid host, ignore region
29+
{"Valid host, ignore region", "http://custom-host.com", "global", "http://custom-host.com", false, ""},
30+
31+
// Case: Empty host, valid region 'saudi'
32+
{"Empty host, valid saudi region", "", "saudi", hostMappings["saudi"], false, ""},
33+
34+
// Case: Invalid host URL format
35+
{"Invalid host URL format", "invalid_url", "", "", true, "invalid host URL: invalid_url"},
36+
}
37+
38+
for _, test := range tests {
39+
t.Run(test.name, func(t *testing.T) {
40+
result, err := ResolveHostAndRegion(test.host, test.region, hostMappings)
41+
42+
if (err != nil) != test.expectError {
43+
t.Errorf("Expected error: %v, got: %v", test.expectError, err)
44+
}
45+
46+
if test.expectError && err != nil {
47+
if !strings.Contains(err.Error(), test.errorMessage) {
48+
t.Errorf("Expected error message: %v, got: %v", test.errorMessage, err.Error())
49+
}
50+
}
51+
52+
if result != test.expectedHost && !test.expectError {
53+
t.Errorf("Expected host: %s, got: %s", test.expectedHost, result)
54+
}
55+
})
56+
}
57+
}

0 commit comments

Comments
 (0)