1
1
// This file is part of MinIO Console Server
2
- // Copyright (c) 2021 MinIO, Inc.
2
+ // Copyright (c) 2022 MinIO, Inc.
3
3
//
4
4
// This program is free software: you can redistribute it and/or modify
5
5
// it under the terms of the GNU Affero General Public License as published by
@@ -19,22 +19,33 @@ package operatorapi
19
19
import (
20
20
"context"
21
21
"fmt"
22
+ "io"
23
+ "net/http"
22
24
"os"
25
+ "strings"
26
+ "time"
23
27
24
28
"github.com/go-openapi/runtime/middleware"
29
+ "github.com/golang-jwt/jwt/v4"
25
30
"github.com/minio/console/cluster"
26
31
"github.com/minio/console/models"
27
32
"github.com/minio/console/operatorapi/operations"
28
33
"github.com/minio/console/operatorapi/operations/operator_api"
34
+ "github.com/minio/console/pkg"
29
35
errors "github.com/minio/console/restapi"
36
+ "github.com/minio/pkg/env"
30
37
corev1 "k8s.io/api/core/v1"
31
38
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32
39
)
33
40
34
41
var (
35
42
mpConfigMapDefault = "mp-config"
36
43
mpConfigMapKey = "MP_CONFIG_KEY"
37
- mpEmail = "email"
44
+ mpHostEnvVar = "MP_HOST"
45
+ defaultMPHost = "https://marketplace.apps.min.dev"
46
+ mpEUHostEnvVar = "MP_EU_HOST"
47
+ defaultEUMPHost = "https://marketplace-eu.apps.min.dev"
48
+ isMPEmailSet = "isEmailSet"
38
49
emailNotSetMsg = "Email was not sent in request"
39
50
)
40
51
@@ -56,62 +67,112 @@ func registerMarketplaceHandlers(api *operations.OperatorAPI) {
56
67
})
57
68
}
58
69
59
- func getMPIntegrationResponse (session * models.Principal , params operator_api.GetMPIntegrationParams ) (* models.MpIntegration , * models.Error ) {
60
- if true { // This block will be removed once service to register emails is deployed
61
- return nil , & models.Error {Code : 501 }
62
- }
70
+ func getMPIntegrationResponse (session * models.Principal , params operator_api.GetMPIntegrationParams ) (* operator_api.GetMPIntegrationOKBody , * models.Error ) {
63
71
clientSet , err := cluster .K8sClient (session .STSSessionToken )
64
72
ctx , cancel := context .WithCancel (params .HTTPRequest .Context ())
65
73
defer cancel ()
66
74
if err != nil {
67
75
return nil , errors .ErrorWithContext (ctx , err )
68
76
}
69
- mpEmail , err := getMPEmail (ctx , & k8sClient {client : clientSet })
77
+ isMPEmailSet , err := getMPEmail (ctx , & k8sClient {client : clientSet })
70
78
if err != nil {
71
79
return nil , errors .ErrorWithContext (ctx , errors .ErrNotFound )
72
80
}
73
- return & models. MpIntegration {
74
- Email : mpEmail ,
81
+ return & operator_api. GetMPIntegrationOKBody {
82
+ IsEmailSet : isMPEmailSet ,
75
83
}, nil
76
84
}
77
85
78
- func getMPEmail (ctx context.Context , clientSet K8sClientI ) (string , error ) {
86
+ func getMPEmail (ctx context.Context , clientSet K8sClientI ) (bool , error ) {
79
87
cm , err := clientSet .getConfigMap (ctx , "default" , getMPConfigMapKey (mpConfigMapKey ), metav1.GetOptions {})
80
88
if err != nil {
81
- return "" , err
89
+ return false , err
82
90
}
83
- return cm .Data [mpEmail ] , nil
91
+ return cm .Data [isMPEmailSet ] == "true" , nil
84
92
}
85
93
86
94
func postMPIntegrationResponse (session * models.Principal , params operator_api.PostMPIntegrationParams ) * models.Error {
87
- if true { // This block will be removed once service to register emails is deployed
88
- return & models.Error {Code : 501 }
89
- }
90
95
clientSet , err := cluster .K8sClient (session .STSSessionToken )
91
96
ctx , cancel := context .WithCancel (params .HTTPRequest .Context ())
92
97
defer cancel ()
93
98
if err != nil {
94
99
return errors .ErrorWithContext (ctx , err )
95
100
}
96
- return setMPIntegration (ctx , params .Body .Email , & k8sClient {client : clientSet })
101
+ return setMPIntegration (ctx , params .Body .Email , params . Body . IsInEU , & k8sClient {client : clientSet })
97
102
}
98
103
99
- func setMPIntegration (ctx context.Context , email string , clientSet K8sClientI ) * models.Error {
104
+ func setMPIntegration (ctx context.Context , email string , isInEU bool , clientSet K8sClientI ) * models.Error {
100
105
if email == "" {
101
106
return errors .ErrorWithContext (ctx , errors .ErrBadRequest , fmt .Errorf (emailNotSetMsg ))
102
107
}
103
- if _ , err := setMPEmail (ctx , email , clientSet ); err != nil {
108
+ if _ , err := setMPEmail (ctx , email , isInEU , clientSet ); err != nil {
104
109
return errors .ErrorWithContext (ctx , err )
105
110
}
106
111
return nil
107
112
}
108
113
109
- func setMPEmail (ctx context.Context , email string , clientSet K8sClientI ) (* corev1.ConfigMap , error ) {
110
- cm := createCM (email )
114
+ func setMPEmail (ctx context.Context , email string , isInEU bool , clientSet K8sClientI ) (* corev1.ConfigMap , error ) {
115
+ if err := postEmailToMP (email , isInEU ); err != nil {
116
+ return nil , err
117
+ }
118
+ cm := createCM ()
111
119
return clientSet .createConfigMap (ctx , "default" , cm , metav1.CreateOptions {})
112
120
}
113
121
114
- func createCM (email string ) * corev1.ConfigMap {
122
+ func postEmailToMP (email string , isInEU bool ) error {
123
+ mpURL , err := getMPURL (isInEU )
124
+ if err != nil {
125
+ return err
126
+ }
127
+ return makePostRequestToMP (mpURL , email )
128
+ }
129
+
130
+ func getMPURL (isInEU bool ) (string , error ) {
131
+ mpHost := getMPHost (isInEU )
132
+ if mpHost == "" {
133
+ return "" , fmt .Errorf ("mp host not set" )
134
+ }
135
+ return fmt .Sprintf ("%s/mp-email" , mpHost ), nil
136
+ }
137
+
138
+ func getMPHost (isInEU bool ) string {
139
+ if isInEU {
140
+ return env .Get (mpEUHostEnvVar , defaultEUMPHost )
141
+ }
142
+ return env .Get (mpHostEnvVar , defaultMPHost )
143
+ }
144
+
145
+ func makePostRequestToMP (url , email string ) error {
146
+ request , err := createMPRequest (url , email )
147
+ if err != nil {
148
+ return err
149
+ }
150
+ client := & http.Client {Timeout : 3 * time .Second }
151
+ if res , err := client .Do (request ); err != nil {
152
+ return err
153
+ } else if res .StatusCode >= http .StatusBadRequest {
154
+ b , _ := io .ReadAll (res .Body )
155
+ return fmt .Errorf ("request to %s failed with status code %d and error %s" , url , res .StatusCode , string (b ))
156
+ }
157
+ return nil
158
+ }
159
+
160
+ func createMPRequest (url , email string ) (* http.Request , error ) {
161
+ request , err := http .NewRequest ("POST" , url , strings .NewReader (fmt .Sprintf ("{\" email\" :\" %s\" }" , email )))
162
+ if err != nil {
163
+ return nil , err
164
+ }
165
+ jwtToken := jwt .NewWithClaims (jwt .SigningMethodHS256 , jwt.MapClaims {})
166
+ jwtTokenString , err := jwtToken .SignedString ([]byte (pkg .MPSecret ))
167
+ if err != nil {
168
+ return nil , err
169
+ }
170
+ request .Header .Add ("Cookie" , fmt .Sprintf ("jwtToken=%s" , jwtTokenString ))
171
+ request .Header .Add ("Content-Type" , "application/json" )
172
+ return request , nil
173
+ }
174
+
175
+ func createCM () * corev1.ConfigMap {
115
176
return & corev1.ConfigMap {
116
177
TypeMeta : metav1.TypeMeta {
117
178
Kind : "ConfigMap" ,
@@ -121,7 +182,7 @@ func createCM(email string) *corev1.ConfigMap {
121
182
Name : getMPConfigMapKey (mpConfigMapKey ),
122
183
Namespace : "default" ,
123
184
},
124
- Data : map [string ]string {mpEmail : email },
185
+ Data : map [string ]string {isMPEmailSet : "true" },
125
186
}
126
187
}
127
188
0 commit comments