cbf345fa292678732f5d7fa2abc59b9e515c9730
[aaf/sms.git] / sms-service / src / preload / preload.go
1 /*
2  * Copyright 2018 Intel Corporation, Inc
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package main
18
19 import (
20         "bytes"
21         "crypto/tls"
22         "crypto/x509"
23         "encoding/json"
24         "flag"
25         "fmt"
26         "io/ioutil"
27         "log"
28         "net/http"
29         "net/url"
30         "path/filepath"
31         "strconv"
32         "strings"
33         "time"
34
35         pkgerrors "github.com/pkg/errors"
36 )
37
38 //DataJSON stores a list of domains from JSON file
39 type DataJSON struct {
40         //Support single domain: {} structure in JSON
41         Domain SecretDomainJSON `json:"domain,omitempty"`
42         //Support plural domains: [{}] structure in JSON
43         Domains []SecretDomainJSON `json:"domains,omitempty"`
44 }
45
46 //SecretDomainJSON stores a name for the Domain and a list of Secrets
47 type SecretDomainJSON struct {
48         Name    string       `json:"name"`
49         Secrets []SecretJSON `json:"secrets"`
50 }
51
52 //SecretJSON stores a name for the Secret and a list of Values
53 type SecretJSON struct {
54         Name   string                 `json:"name"`
55         Values map[string]interface{} `json:"values"`
56 }
57
58 //Processes the JSON file and returns a DataJSON struct
59 func processJSONFile(name string) (DataJSON, error) {
60
61         data, err := ioutil.ReadFile(name)
62         if err != nil {
63                 return DataJSON{}, pkgerrors.Cause(err)
64         }
65
66         d := DataJSON{}
67         err = json.Unmarshal(data, &d)
68         if err != nil {
69                 return DataJSON{}, pkgerrors.Cause(err)
70         }
71
72         return d, nil
73 }
74
75 type smsClient struct {
76         BaseURL *url.URL
77         //In seconds
78         Timeout    int
79         CaCertPath string
80
81         httpClient *http.Client
82 }
83
84 func (c *smsClient) init() error {
85
86         skipVerify := false
87         caCert, err := ioutil.ReadFile(c.CaCertPath)
88         if err != nil {
89                 fmt.Println(pkgerrors.Cause(err))
90                 fmt.Println("Using Insecure Server Verification")
91                 skipVerify = true
92         }
93
94         tlsConfig := &tls.Config{
95                 MinVersion: tls.VersionTLS12,
96         }
97
98         tlsConfig.InsecureSkipVerify = skipVerify
99
100         // Add cert information when skipVerify is false
101         if skipVerify == false {
102                 caCertPool := x509.NewCertPool()
103                 caCertPool.AppendCertsFromPEM(caCert)
104                 tlsConfig.RootCAs = caCertPool
105         }
106
107         tr := &http.Transport{
108                 TLSClientConfig: tlsConfig,
109         }
110
111         c.httpClient = &http.Client{
112                 Transport: tr,
113                 Timeout:   time.Duration(c.Timeout) * time.Second,
114         }
115
116         return nil
117 }
118
119 func (c *smsClient) sendPostRequest(relURL string, message map[string]interface{}) error {
120
121         rel, err := url.Parse(relURL)
122         if err != nil {
123                 return pkgerrors.Cause(err)
124         }
125         u := c.BaseURL.ResolveReference(rel)
126
127         body, err := json.Marshal(message)
128         if err != nil {
129                 return pkgerrors.Cause(err)
130         }
131
132         resp, err := c.httpClient.Post(u.String(), "application/json", bytes.NewBuffer(body))
133         if err != nil {
134                 return pkgerrors.Cause(err)
135         }
136
137         if resp.StatusCode >= 400 && resp.StatusCode < 600 {
138                 // Request Failed
139                 errText, _ := ioutil.ReadAll(resp.Body)
140                 return pkgerrors.Errorf("Request Failed with: %s and Error: %s",
141                         resp.Status, string(errText))
142         }
143
144         return nil
145 }
146
147 func (c *smsClient) createDomain(domain string) error {
148
149         message := map[string]interface{}{
150                 "name": domain,
151         }
152         url := "/v1/sms/domain"
153         err := c.sendPostRequest(url, message)
154         if err != nil {
155                 return pkgerrors.Cause(err)
156         }
157         return nil
158 }
159
160 func (c *smsClient) createSecret(domain string, secret string,
161
162         values map[string]interface{}) error {
163         message := map[string]interface{}{
164                 "name":   secret,
165                 "values": values,
166         }
167
168         url := "/v1/sms/domain/" + strings.TrimSpace(domain) + "/secret"
169         err := c.sendPostRequest(url, message)
170         if err != nil {
171                 return pkgerrors.Cause(err)
172         }
173
174         return nil
175 }
176
177 //uploadToSMS reads through the domain or domains and uploads
178 //their corresponding secrets to SMS service
179 func (c *smsClient) uploadToSMS(data DataJSON) error {
180
181         var ldata []SecretDomainJSON
182
183         //Check if Domain is empty
184         if strings.TrimSpace(data.Domain.Name) != "" {
185                 ldata = append(ldata, data.Domain)
186         } else if len(data.Domains) != 0 {
187                 //Check if plural Domains are empty
188                 ldata = append(ldata, data.Domains...)
189         } else {
190                 return pkgerrors.New("Invalid JSON Data. No domain or domains found")
191         }
192
193         for _, d := range ldata {
194                 err := c.createDomain(d.Name)
195                 if err != nil {
196                         return pkgerrors.Cause(err)
197                 }
198
199                 for _, s := range d.Secrets {
200                         err = c.createSecret(d.Name, s.Name, s.Values)
201                         if err != nil {
202                                 return pkgerrors.Cause(err)
203                         }
204                 }
205         }
206
207         return nil
208 }
209
210 func main() {
211
212         cacert := flag.String("cacert", "/sms/certs/aaf_root_ca.cer",
213                 "Path to the CA Certificate file")
214         serviceurl := flag.String("serviceurl", "https://aaf-sms.onap",
215                 "Url for the SMS Service")
216         serviceport := flag.Int("serviceport", 10443,
217                 "Service port if its different than the default")
218         jsondir := flag.String("jsondir", ".",
219                 "Folder containing json files to upload")
220
221         flag.Parse()
222
223         files, err := ioutil.ReadDir(*jsondir)
224         if err != nil {
225                 log.Fatal(pkgerrors.Cause(err))
226         }
227
228         serviceURL, err := url.Parse(*serviceurl + ":" + strconv.Itoa(*serviceport))
229         if err != nil {
230                 log.Fatal(pkgerrors.Cause(err))
231         }
232
233         client := &smsClient{
234                 Timeout:    30,
235                 BaseURL:    serviceURL,
236                 CaCertPath: *cacert,
237         }
238         client.init()
239
240         for _, file := range files {
241                 if filepath.Ext(file.Name()) == ".json" {
242                         fmt.Println("Processing   ", file.Name())
243                         d, err := processJSONFile(file.Name())
244                         if err != nil {
245                                 log.Printf("Error Reading %s : %s", file.Name(), pkgerrors.Cause(err))
246                                 continue
247                         }
248
249                         err = client.uploadToSMS(d)
250                         if err != nil {
251                                 log.Printf("Error Uploading %s : %s", file.Name(), pkgerrors.Cause(err))
252                                 continue
253                         }
254                 }
255         }
256 }