-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.go
181 lines (144 loc) · 4.68 KB
/
util.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
package main
import (
"context"
"errors"
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
"strings"
"github.com/joho/godotenv"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
// Used for internal error handling, as the code for error handling can become
// quite repetitive.
func handleError(err error, failed bool, exit bool) {
if err != nil {
if failed {
fmt.Println(Fata("FAILED!"))
}
log.Fatal(err)
if exit {
os.Exit(1)
}
}
}
// Given a host, key, and it's secret, return a new minioClient.
func createClient(host string, key string, secret string) (*minio.Client, error) {
useSSL := true
var endpoint string
if strings.Contains(host, "http://") {
useSSL = false
endpoint = strings.Replace(host, "http://", "", 1)
} else {
endpoint = strings.Replace(host, "https://", "", 1)
}
// Initialize minio client object.
minioClient, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(key, secret, ""),
Secure: useSSL,
})
if err != nil {
return nil, err
}
return minioClient, nil
}
// Checks whether configuration for a given profile exists. If so, it returns
// the full path to the config file.
func configExists(profile string) (string, bool) {
// Get user's home directory
home, err := os.UserHomeDir()
if err != nil {
log.Fatal(Fata("A fatal error occurred: %w"), err)
}
config := home + "/.config/copycat/" + profile
if _, err := os.Stat(config); err == nil {
return config, true
} else {
log.Fatal(err)
}
return "", false
}
// Gets the "active" client, and returns a minioClient, the active bucket name
// and, if successful, nil. Otherwise, the err will be set.
func getClient() (*minio.Client, string, error) {
config, configExists := configExists(os.Getenv("COPYCAT_PROFILE"))
if !configExists {
fmt.Println("Configuration does not exist. Run " + Info("copycat configure") + " to create configuration file.")
os.Exit(1)
}
godotenv.Load(config)
client, err := createClient(os.Getenv("HOSTNAME"), os.Getenv("KEY"), os.Getenv("SECRET"))
if err != nil {
return nil, "", fmt.Errorf("error creating new client: %w", err)
}
return client, os.Getenv("BUCKET"), nil
}
// Given a bucket name, ensure that the bucket exists. Can be modified to
// create the bucket if it isn't found - however, default behavior is to just
// return false if the bucket does not exist.
func ensureBucket(minioClient *minio.Client, bucket string) error {
found, err := minioClient.BucketExists(context.Background(), bucket)
if err != nil {
log.Fatal(err)
return err
}
if found {
return nil
}
// Uncomment for bucket creation if bucket does not exist
/*
err = minioClient.MakeBucket(context.Background(), bucket, minio.MakeBucketOptions{Region: "eu-west"})
if err != nil {
log.Fatal(err)
return err
}
*/
return nil
}
// Given a host, it's access information, the bucket to be used, and a path
// create a new configuration file in the given path. Returns nil if successful,
// otherwise an error.
func createConfig(host string, key string, secret string, bucket string, path string) error {
config := []byte("HOSTNAME=" + host + "\nKEY=" + key + "\nSECRET=" + secret + "\nBUCKET=" + bucket)
err := os.WriteFile(path, config, 0644)
if err != nil {
return fmt.Errorf("error writing config file: %w", err)
}
return nil
}
// Wrapper function used for uploading files given it's storage name and the
// path to store it in.
func uploadFile(minioClient *minio.Client, objectName string, filePath string, contentType string, bucket string) error {
_, err := minioClient.FPutObject(context.Background(), bucket, objectName, filePath, minio.PutObjectOptions{ContentType: contentType})
return err
}
// Helper function used to ensure that expected arguments are set, otherwise
// terminates the program.
func requireArgs(args []string, count int, strict bool, files bool) {
if (strict && len(args) != count) || len(args) < count {
fmt.Println(Warn("Expected " + strconv.Itoa(count) + " argument(s), got " + strconv.Itoa(len(args))))
help(files)
os.Exit(1)
}
}
// Get's the version of the uploaded binary, and returns that. If successful,
// the version will be returned alongside a nil error value. Otherwise, err
// will be set.
func getVersion() (string, error) {
resp, err := http.Get(os.Getenv(("VERSION_LOG")))
if err != nil {
return "", fmt.Errorf("HTTP error: %w", err)
}
response, err := io.ReadAll(resp.Body)
// Ensure that file fetched actually has a version tag in it.
if err != nil || response[0] != 118 {
return "", errors.New("file not fetched properly")
}
// See if string starts with a "v" for legacy reasons.
hostVersion := string(response[:len(response)-1])
return hostVersion, nil
}