INTERNAL: improve symptomdata
[ric-plt/xapp-frame.git] / pkg / xapp / Utils.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 package xapp
21
22 import (
23         "archive/zip"
24         "fmt"
25         "io"
26         "io/ioutil"
27         "os"
28         "path/filepath"
29         "strings"
30 )
31
32 type Utils struct {
33         baseDir string
34         status  string
35 }
36
37 func NewUtils() *Utils {
38         b := Config.GetString("controls.symptomdata.baseDir")
39         if b == "" {
40                 b = "/tmp/symptomdata/"
41         }
42
43         return &Utils{
44                 baseDir: b,
45         }
46 }
47
48 func (u *Utils) FileExists(f string) bool {
49         _, err := os.Stat(f)
50         return err == nil || os.IsExist(err)
51 }
52
53 func (u *Utils) CreateDir(path string) error {
54         if u.FileExists(path) {
55                 os.RemoveAll(path)
56         }
57         err := os.MkdirAll(path, os.ModePerm)
58         if err != nil {
59                 return err
60         }
61         os.Chmod(path, os.ModePerm)
62         return nil
63 }
64
65 func (u *Utils) DeleteFile(fileName string) {
66         os.Remove(fileName)
67 }
68
69 func (u *Utils) AddFileToZip(zipWriter *zip.Writer, filePath string, filename string) error {
70         fileToZip, err := os.Open(filename)
71         if err != nil {
72                 return err
73         }
74         defer fileToZip.Close()
75
76         info, err := fileToZip.Stat()
77         if err != nil {
78                 return err
79         }
80
81         header, err := zip.FileInfoHeader(info)
82         if err != nil {
83                 return err
84         }
85
86         header.Name = strings.TrimPrefix(filename, filePath)
87         header.Method = zip.Deflate
88
89         writer, err := zipWriter.CreateHeader(header)
90         if err != nil {
91                 return err
92         }
93         if info.Size() > 0 {
94                 _, err = io.Copy(writer, fileToZip)
95         }
96         return err
97 }
98
99 func (u *Utils) ZipFiles(newZipFile *os.File, filePath string, files []string) error {
100         defer newZipFile.Close()
101         zipWriter := zip.NewWriter(newZipFile)
102         defer zipWriter.Close()
103         for _, file := range files {
104                 if err := u.AddFileToZip(zipWriter, filePath, file); err != nil {
105                         return err
106                 }
107         }
108
109         return nil
110 }
111
112 func (u *Utils) ZipFilesToTmpFile(baseDir string, tmpfilename string, fileList []string) (string, error) {
113         //Generate zip file
114         tmpFile, err := ioutil.TempFile("", tmpfilename)
115         if err != nil {
116                 return "", fmt.Errorf("Failed to create a tmp file: %w", err)
117         }
118         err = u.ZipFiles(tmpFile, baseDir, fileList)
119         if err != nil {
120                 os.Remove(tmpFile.Name())
121                 return "", fmt.Errorf("Failed to zip the files: %w", err)
122         }
123         return tmpFile.Name(), nil
124 }
125
126 func (u *Utils) GetFileFromZip(file *zip.File, filePath string) (string, error) {
127         filename := filepath.Join(filePath, file.Name)
128
129         if file.FileInfo().IsDir() {
130                 os.MkdirAll(filename, os.ModePerm)
131                 return "", nil
132         }
133
134         if err := os.MkdirAll(filepath.Dir(filename), os.ModePerm); err != nil {
135                 return "", fmt.Errorf("mkdir failed %s", filepath.Dir(filename))
136         }
137
138         dstFile, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
139         if err != nil {
140                 return "", fmt.Errorf("openfile failed %s", filename)
141         }
142         defer dstFile.Close()
143
144         fileInArchive, err := file.Open()
145         if err != nil {
146                 return "", fmt.Errorf("zip file open failed %s", file.Name)
147         }
148         defer fileInArchive.Close()
149
150         if _, err := io.Copy(dstFile, fileInArchive); err != nil {
151                 return "", fmt.Errorf("copy failed %s -> %s", file.Name, filename)
152         }
153         return filename, nil
154
155 }
156
157 func (u *Utils) UnZipFiles(zippedFile string, filePath string) ([]string, error) {
158         retval := []string{}
159         zipReader, err := zip.OpenReader(zippedFile)
160         if err != nil {
161                 return retval, fmt.Errorf("Failed to open zip reader: %w", err)
162         }
163         defer zipReader.Close()
164
165         //fmt.Printf("Reading zipfile: %s\n", zippedFile)
166         for _, file := range zipReader.File {
167                 fname, err := u.GetFileFromZip(file, filePath)
168                 if err != nil {
169                         return retval, fmt.Errorf("Failed to unzip the files: %w", err)
170                 }
171                 if len(fname) > 0 {
172                         retval = append(retval, fname)
173                 }
174         }
175         return retval, nil
176 }
177
178 func (u *Utils) FetchFiles(filePath string, fileList []string) []string {
179         files, err := ioutil.ReadDir(filePath)
180         if err != nil {
181                 fmt.Printf("ioutil.ReadDir failed: %+v\n", err)
182                 return nil
183         }
184         for _, file := range files {
185                 if !file.IsDir() {
186                         fileList = append(fileList, filepath.Join(filePath, file.Name()))
187                 } else {
188                         fileList = u.FetchFiles(filepath.Join(filePath, file.Name()), fileList)
189                 }
190         }
191         return fileList
192 }
193
194 func (u *Utils) WriteToFile(fileName string, data string) error {
195         f, err := os.Create(fileName)
196         defer f.Close()
197
198         if err != nil {
199                 Logger.Error("Unable to create file %s': %+v", fileName, err)
200         } else {
201                 _, err := io.WriteString(f, data)
202                 if err != nil {
203                         Logger.Error("Unable to write to file '%s': %+v", fileName, err)
204                         u.DeleteFile(fileName)
205                 }
206         }
207         return err
208 }