/
config.go
111 lines (102 loc) · 3.81 KB
/
config.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
/*******************************************************************************
*
* Copyright 2023 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You should have received a copy of the License along with this
* program. If not, 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 core
import (
"fmt"
"os"
"time"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
"github.com/gophercloud/utils/openstack/clientconfig"
"github.com/majewsky/schwift"
"github.com/majewsky/schwift/gopherschwift"
"github.com/sapcc/go-bits/osext"
)
// Configuration contains all the configuration parameters that we read from
// the process environment on startup.
type Configuration struct {
//configuration for upload to/download from Swift
Container *schwift.Container
SegmentContainer *schwift.Container
ObjectNamePrefix string
//backup schedule
Interval time.Duration
//configuration for connection to Postgres
PgHostname string
PgUsername string
PgPassword string
}
// NewConfiguration reads all configuration parameters from the process
// environment.
func NewConfiguration() (*Configuration, error) {
//initialize connection to Swift
ao, err := clientconfig.AuthOptions(nil)
if err != nil {
return nil, fmt.Errorf("cannot find OpenStack credentials: %w", err)
}
ao.AllowReauth = true
provider, err := openstack.AuthenticatedClient(*ao)
if err != nil {
return nil, fmt.Errorf("cannot connect to OpenStack: %w", err)
}
eo := gophercloud.EndpointOpts{
//note that empty values are acceptable in these two fields (but OS_REGION_NAME is strictly required down below)
Region: os.Getenv("OS_REGION_NAME"),
Availability: gophercloud.Availability(os.Getenv("OS_INTERFACE")),
}
client, err := openstack.NewObjectStorageV1(provider, eo)
if err != nil {
return nil, fmt.Errorf("cannot connect to Swift: %w", err)
}
account, err := gopherschwift.Wrap(client, nil)
if err != nil {
return nil, fmt.Errorf("cannot connect to Swift: %w", err)
}
cfg := Configuration{
Container: account.Container("db_backup"),
SegmentContainer: account.Container("db_backup_segments"),
ObjectNamePrefix: fmt.Sprintf("%s/%s/%s/",
osext.MustGetenv("OS_REGION_NAME"),
osext.MustGetenv("MY_POD_NAMESPACE"),
osext.MustGetenv("MY_POD_NAME"),
),
PgHostname: osext.GetenvOrDefault("PGSQL_HOST", "localhost"),
PgUsername: osext.GetenvOrDefault("PGSQL_USER", "postgres"),
PgPassword: osext.MustGetenv("PGPASSWORD"),
}
//read additional environment variables
cfg.Interval, err = time.ParseDuration(osext.MustGetenv("BACKUP_PGSQL_FULL"))
if err != nil {
return nil, fmt.Errorf("malformed value for BACKUP_PGSQL_FULL: %q", os.Getenv("BACKUP_PGSQL_FULL"))
}
return &cfg, nil
}
// ArgsForPsql prepends common options for psql to the given list of arguments.
// The arguments given to this method are specific to a particular psql
// invocation, and this function adds those that are always required.
func (cfg Configuration) ArgsForPsql(args ...string) []string {
common := []string{
"--variable", "ON_ERROR_STOP=1",
"--quiet", "--no-align",
"--host", cfg.PgHostname,
"--username", cfg.PgUsername, //NOTE: PGPASSWORD comes via inherited env variable
"--dbname", "postgres", //ensure that -d does not default to the app username
}
return append(common, args...)
}