-
Notifications
You must be signed in to change notification settings - Fork 644
/
config_functions.go
145 lines (125 loc) · 4.02 KB
/
config_functions.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright IBM Corp. 2017, 2021 All Rights Reserved.
// Licensed under the Mozilla Public License v2.0
package conns
import (
"fmt"
"net/http"
"net/url"
"os"
"strings"
bluemix "github.com/IBM-Cloud/bluemix-go"
"github.com/IBM-Cloud/bluemix-go/api/functions"
bxsession "github.com/IBM-Cloud/bluemix-go/session"
"github.com/apache/openwhisk-client-go/whisk"
)
// DefaultServiceURL is the default URL to make service requests to.
const DefaultServiceURL = "https://us-south.functions.cloud.ibm.com"
// FunctionClient ...
func FunctionClient(c *bluemix.Config) (*whisk.Client, error) {
baseEndpoint := getBaseURL(c.Region)
u, err := url.Parse(fmt.Sprintf("%s/api", baseEndpoint))
if err != nil {
return nil, err
}
functionsClient, err := whisk.NewClient(http.DefaultClient, &whisk.Config{
Host: u.Host,
Version: "v1",
})
return functionsClient, err
}
// getBaseURL ..
func getBaseURL(region string) string {
baseEndpoint := fmt.Sprintf(DefaultServiceURL)
if region != "us-south" {
baseEndpoint = fmt.Sprintf("https://%s.functions.cloud.ibm.com", region)
}
return baseEndpoint
}
/*
*
* Configure a HTTP client using the OpenWhisk properties (i.e. host, auth, iamtoken)
* Only cf-based namespaces needs auth key value.
* iam-based namespace don't have an auth key and needs only iam token for authorization.
*
*/
func SetupOpenWhiskClientConfig(namespace string, sess *bxsession.Session, functionNamespace functions.FunctionServiceAPI) (*whisk.Client, error) {
u, _ := url.Parse(fmt.Sprintf("https://%s.functions.cloud.ibm.com/api", sess.Config.Region))
wskClient, _ := whisk.NewClient(http.DefaultClient, &whisk.Config{
Host: u.Host,
Version: "v1",
})
nsList, err := functionNamespace.Namespaces().GetNamespaces()
if err != nil {
return nil, err
}
var validNamespace bool
var isCFNamespace bool
allNamespaces := []string{}
for _, n := range nsList.Namespaces {
allNamespaces = append(allNamespaces, n.GetName())
if n.GetName() == namespace || n.GetID() == namespace {
if os.Getenv("TF_LOG") != "" {
whisk.SetDebug(true)
}
if n.IsCf() {
isCFNamespace = true
break
}
validNamespace = true
// Configure whisk properties to handle iam-based/iam-migrated namespaces.
if n.IsIamEnabled() {
additionalHeaders := make(http.Header)
err := RefreshToken(sess)
if err != nil {
for count := sess.Config.MaxRetries; *count >= 0; *count-- {
if err == nil || !isRetryable(err) {
break
}
err = RefreshToken(sess)
}
if err != nil {
return nil, err
}
}
additionalHeaders.Add("Authorization", sess.Config.IAMAccessToken)
additionalHeaders.Add("X-Namespace-Id", n.GetID())
wskClient.Config.Namespace = n.GetID()
wskClient.Config.AdditionalHeaders = additionalHeaders
return wskClient, nil
}
}
}
// Configure whisk properties to handle cf-based namespaces.
if isCFNamespace {
if sess.Config.UAAAccessToken == "" && sess.Config.UAARefreshToken == "" {
return nil, fmt.Errorf("Couldn't retrieve auth key for IBM Cloud Function")
}
err := validateNamespace(namespace)
if err != nil {
return nil, err
}
nsList, err := functionNamespace.Namespaces().GetCloudFoundaryNamespaces()
if err != nil {
return nil, err
}
for _, n := range nsList.Namespaces {
if n.GetName() == namespace {
wskClient.Config.Namespace = n.GetName()
wskClient.Config.AuthToken = fmt.Sprintf("%s:%s", n.GetUUID(), n.GetKey())
return wskClient, nil
}
}
}
if !validNamespace {
return nil, fmt.Errorf("Namespace '%s' is not in the list of entitled namespaces. Available namespaces are %s", namespace, allNamespaces)
}
return nil, fmt.Errorf("Failed to create whisk config object for namespace '%s'", namespace)
}
func validateNamespace(ns string) error {
os := strings.Split(ns, "_")
if len(os) < 2 || (len(os) == 2 && (len(os[0]) == 0 || len(os[1]) == 0)) {
return fmt.Errorf(
"Namespace is (%s), it must be of the form <org>_<space>, provider can't find the auth key if you use _ as well", ns)
}
return nil
}