Skip to content

Commit 58e5d9d

Browse files
author
Jeff McCormick
committed
merge in rest branch
2 parents 8353913 + c46e841 commit 58e5d9d

File tree

105 files changed

+4576
-5990
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+4576
-5990
lines changed

Makefile

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ runapiserver: check-go-vars
2525
apiserver --kubeconfig=/etc/kubernetes/admin.conf
2626
apiserver: check-go-vars
2727
go install apiserver.go
28-
rpgo: check-go-vars
29-
cd rpgo && go install rpgo.go
3028
pgo: check-go-vars
3129
cd pgo && go install pgo.go
32-
runpgo: check-go-vars
33-
pgo --kubeconfig=/etc/kubernetes/admin.conf
3430
clean: check-go-vars
3531
rm -rf $(GOPATH)/pkg/* $(GOBIN)/postgres-operator $(GOBIN)/apiserver $(GOBIN)/*pgo
32+
apiserverimage: check-go-vars
33+
go install apiserver.go
34+
cp $(GOBIN)/apiserver bin/
35+
docker build -t apiserver -f $(CO_BASEOS)/Dockerfile.apiserver.$(CO_BASEOS) .
36+
docker tag apiserver crunchydata/apiserver:$(CO_BASEOS)-$(CO_VERSION)
3637
operatorimage: check-go-vars
3738
go install postgres-operator.go
3839
cp $(GOBIN)/postgres-operator bin/postgres-operator/
@@ -46,22 +47,23 @@ csvloadimage:
4647
docker tag csvload crunchydata/csvload:$(CO_BASEOS)-$(CO_VERSION)
4748
all:
4849
make operatorimage
50+
make apiserverimage
4951
make lsimage
5052
make csvloadimage
5153
make pgo
5254
push:
5355
docker push crunchydata/lspvc:$(CO_IMAGE_TAG)
5456
docker push crunchydata/csvload:$(CO_IMAGE_TAG)
5557
docker push crunchydata/postgres-operator:$(CO_IMAGE_TAG)
58+
docker push crunchydata/apiserver:$(CO_IMAGE_TAG)
5659
release: check-go-vars
60+
make macpgo
5761
rm -rf $(RELTMPDIR) $(RELFILE)
5862
mkdir $(RELTMPDIR)
5963
cp $(GOBIN)/pgo $(RELTMPDIR)
6064
cp $(GOBIN)/pgo-mac $(RELTMPDIR)
6165
cp $(COROOT)/examples/pgo-bash-completion $(RELTMPDIR)
62-
cp $(COROOT)/examples/*pgo.yaml* $(RELTMPDIR)
63-
cp $(COROOT)/examples/*pgo.lspvc-template.json $(RELTMPDIR)
64-
cp $(COROOT)/examples/*pgo.csvload-template.json $(RELTMPDIR)
66+
cp -r $(COROOT)/conf/ $(RELTMPDIR)
6567
tar czvf $(RELFILE) -C $(RELTMPDIR) .
6668
default:
6769
all

apiserver.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,37 @@ import (
55
"github.com/crunchydata/postgres-operator/apiserver/backupservice"
66
"github.com/crunchydata/postgres-operator/apiserver/cloneservice"
77
"github.com/crunchydata/postgres-operator/apiserver/clusterservice"
8+
"github.com/crunchydata/postgres-operator/apiserver/labelservice"
9+
"github.com/crunchydata/postgres-operator/apiserver/loadservice"
810
"github.com/crunchydata/postgres-operator/apiserver/policyservice"
11+
"github.com/crunchydata/postgres-operator/apiserver/pvcservice"
912
"github.com/crunchydata/postgres-operator/apiserver/upgradeservice"
13+
"github.com/crunchydata/postgres-operator/apiserver/userservice"
14+
"github.com/crunchydata/postgres-operator/apiserver/versionservice"
1015
"github.com/gorilla/mux"
1116
"net/http"
1217
)
1318

1419
func main() {
1520

16-
log.Infoln("restserver starts")
21+
log.Infoln("postgres-operator apiserver starts")
1722
r := mux.NewRouter()
23+
r.HandleFunc("/version", versionservice.VersionHandler)
1824
r.HandleFunc("/clones", cloneservice.CreateCloneHandler)
1925
r.HandleFunc("/policies", policyservice.CreatePolicyHandler)
20-
//r.HandleFunc("/policies/{name}", policyservice.ShowPolicyHandler).
21-
//Queries("selector", "{selector}").Methods("GET", "DELETE")
2226
r.HandleFunc("/policies/{name}", policyservice.ShowPolicyHandler).Methods("GET", "DELETE")
23-
r.HandleFunc("/policies/apply/{name}", policyservice.ApplyPolicyHandler)
24-
r.HandleFunc("/upgrades", upgradeservice.CreateUpgradeHandler)
27+
r.HandleFunc("/pvc/{pvcname}", pvcservice.ShowPVCHandler).Methods("GET")
28+
r.HandleFunc("/policies/apply", policyservice.ApplyPolicyHandler).Methods("POST")
29+
r.HandleFunc("/label", labelservice.LabelHandler).Methods("POST")
30+
r.HandleFunc("/load", loadservice.LoadHandler).Methods("POST")
31+
r.HandleFunc("/user", userservice.UserHandler).Methods("POST")
32+
r.HandleFunc("/upgrades", upgradeservice.CreateUpgradeHandler).Methods("POST")
2533
r.HandleFunc("/upgrades/{name}", upgradeservice.ShowUpgradeHandler).Methods("GET", "DELETE")
26-
r.HandleFunc("/clusters", clusterservice.CreateClusterHandler)
34+
r.HandleFunc("/clusters", clusterservice.CreateClusterHandler).Methods("POST")
2735
r.HandleFunc("/clusters/{name}", clusterservice.ShowClusterHandler).Methods("GET", "DELETE")
2836
r.HandleFunc("/clusters/test/{name}", clusterservice.TestClusterHandler)
2937
r.HandleFunc("/clusters/scale/{name}", clusterservice.ScaleClusterHandler)
3038
r.HandleFunc("/backups/{name}", backupservice.ShowBackupHandler).Methods("GET", "DELETE")
39+
r.HandleFunc("/backups", backupservice.CreateBackupHandler).Methods("POST")
3140
log.Fatal(http.ListenAndServe(":8080", r))
3241
}
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
package backupservice
2+
3+
/*
4+
Copyright 2017 Crunchy Data Solutions, Inc.
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
import (
19+
log "github.com/Sirupsen/logrus"
20+
crv1 "github.com/crunchydata/postgres-operator/apis/cr/v1"
21+
"github.com/crunchydata/postgres-operator/apiserver"
22+
"github.com/crunchydata/postgres-operator/apiserver/util"
23+
msgs "github.com/crunchydata/postgres-operator/apiservermsgs"
24+
"github.com/spf13/viper"
25+
kerrors "k8s.io/apimachinery/pkg/api/errors"
26+
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+
"k8s.io/apimachinery/pkg/labels"
28+
)
29+
30+
// ShowBackup ...
31+
func ShowBackup(namespace, name string) msgs.ShowBackupResponse {
32+
response := msgs.ShowBackupResponse{}
33+
response.Status = msgs.Status{Code: msgs.Ok, Msg: ""}
34+
35+
if name == "all" {
36+
//get a list of all backups
37+
err := apiserver.RESTClient.Get().
38+
Resource(crv1.PgbackupResourcePlural).
39+
Namespace(namespace).
40+
Do().Into(&response.BackupList)
41+
if err != nil {
42+
log.Error("error getting list of backups" + err.Error())
43+
response.Status.Code = msgs.Error
44+
response.Status.Msg = err.Error()
45+
return response
46+
}
47+
log.Debug("backups found len is %d\n", len(response.BackupList.Items))
48+
} else {
49+
backup := crv1.Pgbackup{}
50+
err := apiserver.RESTClient.Get().
51+
Resource(crv1.PgbackupResourcePlural).
52+
Namespace(namespace).
53+
Name(name).
54+
Do().Into(&backup)
55+
if err != nil {
56+
log.Error("error getting backup" + err.Error())
57+
response.Status.Code = msgs.Error
58+
response.Status.Msg = err.Error()
59+
return response
60+
}
61+
response.BackupList.Items = make([]crv1.Pgbackup, 1)
62+
response.BackupList.Items[0] = backup
63+
}
64+
65+
return response
66+
67+
}
68+
69+
// DeleteBackup ...
70+
func DeleteBackup(namespace, backupName string) msgs.DeleteBackupResponse {
71+
resp := msgs.DeleteBackupResponse{}
72+
resp.Status.Code = msgs.Ok
73+
resp.Status.Msg = ""
74+
resp.Results = make([]string, 0)
75+
76+
var err error
77+
78+
if backupName == "all" {
79+
err = apiserver.RESTClient.Delete().
80+
Resource(crv1.PgbackupResourcePlural).
81+
Namespace(namespace).
82+
Do().
83+
Error()
84+
resp.Results = append(resp.Results, "all")
85+
} else {
86+
err = apiserver.RESTClient.Delete().
87+
Resource(crv1.PgbackupResourcePlural).
88+
Namespace(namespace).
89+
Name(backupName).
90+
Do().
91+
Error()
92+
resp.Results = append(resp.Results, backupName)
93+
}
94+
95+
if err != nil {
96+
log.Error("error deleting pgbackup ")
97+
log.Error(err.Error())
98+
resp.Status.Code = msgs.Error
99+
resp.Status.Msg = err.Error()
100+
}
101+
102+
return resp
103+
104+
}
105+
106+
// CreateBackup ...
107+
// pgo backup mycluster
108+
// pgo backup all
109+
// pgo backup --selector=name=mycluster
110+
func CreateBackup(request *msgs.CreateBackupRequest) msgs.CreateBackupResponse {
111+
var err error
112+
resp := msgs.CreateBackupResponse{}
113+
resp.Status.Code = msgs.Ok
114+
resp.Status.Msg = ""
115+
resp.Results = make([]string, 0)
116+
117+
var newInstance *crv1.Pgbackup
118+
119+
if request.Selector != "" {
120+
//use the selector instead of an argument list to filter on
121+
122+
myselector, err := labels.Parse(request.Selector)
123+
if err != nil {
124+
log.Error(err)
125+
resp.Status.Code = msgs.Error
126+
resp.Status.Msg = err.Error()
127+
return resp
128+
}
129+
130+
//get the clusters list
131+
clusterList := crv1.PgclusterList{}
132+
err = apiserver.RESTClient.Get().
133+
Resource(crv1.PgclusterResourcePlural).
134+
Namespace(request.Namespace).
135+
LabelsSelectorParam(myselector).
136+
Do().
137+
Into(&clusterList)
138+
if err != nil {
139+
log.Error("error getting cluster list" + err.Error())
140+
resp.Status.Code = msgs.Error
141+
resp.Status.Msg = err.Error()
142+
return resp
143+
}
144+
145+
if len(clusterList.Items) == 0 {
146+
log.Debug("no clusters found")
147+
resp.Status.Msg = "no clusters found"
148+
return resp
149+
} else {
150+
newargs := make([]string, 0)
151+
for _, cluster := range clusterList.Items {
152+
newargs = append(newargs, cluster.Spec.Name)
153+
}
154+
request.Args = newargs
155+
}
156+
157+
}
158+
for _, arg := range request.Args {
159+
log.Debug("create backup called for " + arg)
160+
result := crv1.Pgbackup{}
161+
162+
// error if it already exists
163+
err = apiserver.RESTClient.Get().
164+
Resource(crv1.PgbackupResourcePlural).
165+
Namespace(request.Namespace).
166+
Name(arg).
167+
Do().
168+
Into(&result)
169+
if err == nil {
170+
log.Debug("pgbackup " + arg + " was found so we recreate it")
171+
dels := make([]string, 1)
172+
dels[0] = arg
173+
DeleteBackup(arg, request.Namespace)
174+
} else if kerrors.IsNotFound(err) {
175+
msg := "pgbackup " + arg + " not found so we will create it"
176+
resp.Results = append(resp.Results, "pgbackup "+msg)
177+
} else {
178+
log.Error("error getting pgbackup " + arg)
179+
log.Error(err.Error())
180+
resp.Results = append(resp.Results, "error getting pgbackup for "+arg)
181+
break
182+
}
183+
// Create an instance of our CRD
184+
newInstance, err = getBackupParams(arg, request.Namespace)
185+
if err != nil {
186+
msg := "error creating backup for " + arg
187+
log.Error(err)
188+
resp.Results = append(resp.Results, msg)
189+
break
190+
}
191+
err = apiserver.RESTClient.Post().
192+
Resource(crv1.PgbackupResourcePlural).
193+
Namespace(request.Namespace).
194+
Body(newInstance).
195+
Do().Into(&result)
196+
if err != nil {
197+
log.Error("error in creating Pgbackup CRD instance")
198+
log.Error(err.Error())
199+
resp.Status.Code = msgs.Error
200+
resp.Status.Msg = err.Error()
201+
return resp
202+
}
203+
resp.Results = append(resp.Results, "created Pgbackup "+arg)
204+
205+
}
206+
207+
return resp
208+
}
209+
210+
func getBackupParams(name, Namespace string) (*crv1.Pgbackup, error) {
211+
var err error
212+
var newInstance *crv1.Pgbackup
213+
214+
storageSpec := crv1.PgStorageSpec{}
215+
spec := crv1.PgbackupSpec{}
216+
spec.Name = name
217+
spec.StorageSpec = storageSpec
218+
spec.StorageSpec.Name = viper.GetString("BackupStorage.Name")
219+
spec.StorageSpec.AccessMode = viper.GetString("BackupStorage.AccessMode")
220+
spec.StorageSpec.Size = viper.GetString("BackupStorage.Size")
221+
spec.StorageSpec.StorageClass = viper.GetString("BackupStorage.StorageClass")
222+
spec.StorageSpec.StorageType = viper.GetString("BackupStorage.StorageType")
223+
spec.StorageSpec.SupplementalGroups = viper.GetString("BackupStorage.SupplementalGroups")
224+
spec.StorageSpec.Fsgroup = viper.GetString("BackupStorage.Fsgroup")
225+
spec.CCPImageTag = viper.GetString("Cluster.CCPImageTag")
226+
spec.BackupStatus = "initial"
227+
spec.BackupHost = "basic"
228+
spec.BackupUser = "primaryuser"
229+
spec.BackupPass = "password"
230+
spec.BackupPort = "5432"
231+
232+
cluster := crv1.Pgcluster{}
233+
err = apiserver.RESTClient.Get().
234+
Resource(crv1.PgclusterResourcePlural).
235+
Namespace(Namespace).
236+
Name(name).
237+
Do().
238+
Into(&cluster)
239+
if err == nil {
240+
spec.BackupHost = cluster.Spec.Name
241+
spec.BackupPass, err = util.GetSecretPassword(cluster.Spec.Name, crv1.PrimarySecretSuffix, Namespace)
242+
if err != nil {
243+
return newInstance, err
244+
}
245+
spec.BackupPort = cluster.Spec.Port
246+
} else if kerrors.IsNotFound(err) {
247+
log.Debug(name + " is not a cluster")
248+
return newInstance, err
249+
} else {
250+
log.Error("error getting pgcluster " + name)
251+
log.Error(err.Error())
252+
return newInstance, err
253+
}
254+
255+
newInstance = &crv1.Pgbackup{
256+
ObjectMeta: meta_v1.ObjectMeta{
257+
Name: name,
258+
},
259+
Spec: spec,
260+
}
261+
return newInstance, nil
262+
}

0 commit comments

Comments
 (0)