-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy paths3.go
231 lines (192 loc) · 6.66 KB
/
s3.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
Copyright © 2021, 2022, 2023 Red Hat, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
// Generated documentation is available at:
// https://pkg.go.dev/github.com/RedHatInsights/insights-results-aggregator-exporter
//
// Documentation in literate-programming-style is available at:
// https://redhatinsights.github.io/insights-results-aggregator-exporter/packages/s3.html
import (
"bytes"
"context"
"encoding/csv"
"errors"
"fmt"
"io"
"github.com/rs/zerolog/log"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
// error messages
const (
unableToInitializeConnection = "Unable to initialize connection to S3"
minioClientIsNil = "Minio Client is nil"
wrongMinioClientReference = "Wrong Minio client reference"
wrongBucketName = "Wrong bucket name"
objectNameIsNotSet = "Object name is not set"
wrongObjectName = "Wrong object name"
bucketNameIsNotSet = "Bucket name is not set"
configurationIsNil = "Configuration is nil"
configurationError = "Configuration error"
)
// NewS3Connection function initializes connection to S3/Minio storage.
func NewS3Connection(configuration *ConfigStruct) (*minio.Client, context.Context, error) {
// check if configuration structure has been provided
if configuration == nil {
err := errors.New(configurationIsNil)
log.Error().Err(err).Msg(configurationError)
return nil, nil, err
}
// retrieve S3/Minio configuration
s3Configuration := GetS3Configuration(configuration)
var endpoint string
if s3Configuration.EndpointPort == 0 {
endpoint = s3Configuration.EndpointURL
} else {
endpoint = fmt.Sprintf("%s:%d",
s3Configuration.EndpointURL, s3Configuration.EndpointPort)
}
log.Info().Str("S3 endpoint", endpoint).Msg("Preparing connection")
ctx := context.Background()
// initialize Minio client object
minioClient, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(
s3Configuration.AccessKeyID,
s3Configuration.SecretAccessKey, ""),
Secure: s3Configuration.UseSSL,
})
// check if client has been constructed properly
if err != nil {
log.Error().Err(err).Msg(unableToInitializeConnection)
return nil, nil, err
}
log.Info().Msg("Connection established")
return minioClient, ctx, nil
}
// s3BucketExists function checks if bucket with given name exists and can be
// accessed by current client
func s3BucketExists(ctx context.Context, minioClient *minio.Client,
bucketName string) (bool, error) {
// check if Minio client has been passed to this function
if minioClient == nil {
err := errors.New(minioClientIsNil)
log.Error().Err(err).Msg(wrongMinioClientReference)
return false, err
}
// check if proper bucket name has been passed to this function
if bucketName == "" {
err := errors.New(bucketNameIsNotSet)
log.Error().Err(err).Msg(wrongBucketName)
return false, err
}
// check bucket existence
found, err := minioClient.BucketExists(ctx, bucketName)
if err != nil {
log.Error().Err(err).Str("bucket", bucketName).Msg("Bucket can not be found")
return false, err
}
// everything seems to be ok
return found, nil
}
// storeTableNames function stores all table names passed via tableNames
// parameter into given bucket under selected object name
func storeTableNames(ctx context.Context, minioClient *minio.Client,
bucketName string, objectName string, tableNames []TableName) error {
// check if Minio client has been passed to this function
if minioClient == nil {
err := errors.New(minioClientIsNil)
log.Error().Err(err).Msg(wrongMinioClientReference)
return err
}
// check if proper bucket name has been passed to this function
if bucketName == "" {
err := errors.New(bucketNameIsNotSet)
log.Error().Err(err).Msg(wrongBucketName)
return err
}
// check if proper object name has been passed to this function
if objectName == "" {
err := errors.New(objectNameIsNotSet)
log.Error().Err(err).Msg(wrongObjectName)
return err
}
// conversion to CSV
buffer := new(bytes.Buffer)
writer := csv.NewWriter(buffer)
var data = [][]string{{"Table name"}}
err := writer.WriteAll(data)
if err != nil {
return err
}
for _, tableName := range tableNames {
err := writer.Write([]string{string(tableName)})
if err != nil {
log.Error().Err(err).Msg("Write to CSV")
}
}
writer.Flush()
reader := io.Reader(buffer)
// store CSV data into S3/Minio
options := minio.PutObjectOptions{ContentType: "text/csv"}
_, err = minioClient.PutObject(ctx, bucketName, objectName, reader, -1, options)
if err != nil {
return err
}
// everything seems to be ok
return nil
}
// storeDisabledRulesIntoS3 function stores info about disabled rules into S3
// into given bucket under selected object name
func storeDisabledRulesIntoS3(ctx context.Context, minioClient *minio.Client,
bucketName string, objectName string, disabledRulesInfo []DisabledRuleInfo) error {
// check if Minio client has been passed to this function
if minioClient == nil {
err := errors.New(minioClientIsNil)
log.Error().Err(err).Msg(wrongMinioClientReference)
return err
}
// check if proper bucket name has been passed to this function
if bucketName == "" {
err := errors.New(bucketNameIsNotSet)
log.Error().Err(err).Msg(wrongBucketName)
return err
}
// check if proper object name has been passed to this function
if objectName == "" {
err := errors.New(objectNameIsNotSet)
log.Error().Err(err).Msg(wrongObjectName)
return err
}
// conversion to CSV
buffer := new(bytes.Buffer)
err := DisabledRulesToCSV(buffer, disabledRulesInfo)
if err != nil {
log.Error().Err(err).Msg("Write table name to CSV")
return err
}
reader := io.Reader(buffer)
// store CSV data into S3/Minio
options := minio.PutObjectOptions{ContentType: "text/csv"}
_, err = minioClient.PutObject(ctx, bucketName, objectName, reader, -1, options)
if err != nil {
return err
}
// everything seems to be ok
return nil
}
func storeBufferToS3(ctx context.Context, minioClient *minio.Client,
bucketName string, objectName string, buffer bytes.Buffer) error {
options := minio.PutObjectOptions{ContentType: "text/plain"}
_, err := minioClient.PutObject(ctx, bucketName, objectName, &buffer, -1, options)
return err
}