@@ -20,6 +20,7 @@ import (
2020 "fmt"
2121 log "github.com/Sirupsen/logrus"
2222 _ "github.com/lib/pq"
23+ "os"
2324 "strconv"
2425 "time"
2526 //"k8s.io/apimachinery/pkg/labels"
@@ -37,7 +38,7 @@ import (
3738type ConnInfo struct {
3839 Username string
3940 Hostip string
40- StrPort string
41+ Port string
4142 Database string
4243 Password string
4344}
@@ -52,35 +53,38 @@ const DEFAULT_PSW_LEN = 8
5253
5354var PasswordAgeDays , PasswordLength int
5455
56+ var AddUser string
5557var Expired string
5658var UpdatePasswords bool
5759
58- var pswCmd = & cobra.Command {
59- Use : "psw " ,
60- Short : "manage passwords " ,
61- Long : `PSW allows you to manage passwords across a set of clusters
60+ var userCmd = & cobra.Command {
61+ Use : "user " ,
62+ Short : "manage users " ,
63+ Long : `USER allows you to manage users and passwords across a set of clusters
6264For example:
6365
64- pgo psw --selector=name=mycluster --update
65- pgo psw --expired=7 --selector=someotherpolicy
66+ pgo user --selector=name=mycluster --update
67+ pgo user --expired=7 --selector=name=mycluster
68+ pgo user --add-user=bob --selector=sname=mycluster
6669.` ,
6770 Run : func (cmd * cobra.Command , args []string ) {
68- log .Debug ("psw called" )
69- passwordManager ()
71+ log .Debug ("user called" )
72+ userManager ()
7073 },
7174}
7275
7376func init () {
74- RootCmd .AddCommand (pswCmd )
77+ RootCmd .AddCommand (userCmd )
7578
76- pswCmd .Flags ().StringVarP (& Selector , "selector" , "s" , "" , "The selector to use for cluster filtering " )
77- pswCmd .Flags ().StringVarP (& Expired , "expired" , "e" , "" , "--expired=7 shows passwords that will expired in 7 days" )
78- pswCmd .Flags ().BoolVarP (& UpdatePasswords , "update-passwords" , "u" , false , "--update-passwords performs password updating on expired passwords" )
79+ userCmd .Flags ().StringVarP (& Selector , "selector" , "s" , "" , "The selector to use for cluster filtering " )
80+ userCmd .Flags ().StringVarP (& Expired , "expired" , "e" , "" , "--expired=7 shows passwords that will expired in 7 days" )
81+ userCmd .Flags ().StringVarP (& AddUser , "add-user" , "a" , "" , "--add-user=bob adds a new user to selective clusters" )
82+ userCmd .Flags ().BoolVarP (& UpdatePasswords , "update-passwords" , "u" , false , "--update-passwords performs password updating on expired passwords" )
7983 getDefaults ()
8084
8185}
8286
83- func passwordManager () {
87+ func userManager () {
8488 //build the selector based on the selector parameter
8589 //get the clusters list
8690
@@ -101,17 +105,31 @@ func passwordManager() {
101105 }
102106
103107 for _ , d := range deployments .Items {
108+ fmt .Println ("deployment : " + d .ObjectMeta .Name )
109+ info := getPostgresUserInfo (d .ObjectMeta .Name )
110+
111+ if AddUser != "" {
112+ fmt .Println ("adding new user " + AddUser )
113+ addUser (info , AddUser )
114+ newPassword := util .GeneratePassword (PasswordLength )
115+ newExpireDate := GeneratePasswordExpireDate (PasswordAgeDays )
116+ err = updatePassword (info , AddUser , newPassword , newExpireDate )
117+ if err != nil {
118+ log .Error (err .Error ())
119+ os .Exit (2 )
120+ }
121+ }
122+
104123 if Expired != "" {
105- results := callDB (d .ObjectMeta .Name , Expired )
124+ results := callDB (info , d .ObjectMeta .Name , Expired )
106125 if len (results ) > 0 {
107- fmt .Println ("deployment : " + d .ObjectMeta .Name )
108126 fmt .Println ("expired passwords...." )
109127 for _ , v := range results {
110128 fmt .Printf ("RoleName %s Role Valid Until %s\n " , v .Rolname , v .Rolvaliduntil )
111129 if UpdatePasswords {
112130 newPassword := util .GeneratePassword (PasswordLength )
113131 newExpireDate := GeneratePasswordExpireDate (PasswordAgeDays )
114- err = updatePassword (v , newPassword , newExpireDate )
132+ err = updatePassword (v . ConnDetails , v . Rolname , newPassword , newExpireDate )
115133 if err != nil {
116134 fmt .Println ("error in updating password" )
117135 }
@@ -125,42 +143,13 @@ func passwordManager() {
125143
126144}
127145
128- func callDB (clusterName , maxdays string ) []PswResult {
146+ func callDB (info ConnInfo , clusterName , maxdays string ) []PswResult {
129147 var conn * sql.DB
148+ var err error
130149
131150 results := []PswResult {}
132151
133- //get the service for the cluster
134- service , err := Clientset .CoreV1 ().Services (Namespace ).Get (clusterName , meta_v1.GetOptions {})
135- if err != nil {
136- log .Error ("error getting list of services" + err .Error ())
137- return results
138- }
139-
140- //get the secrets for this cluster
141- lo := meta_v1.ListOptions {LabelSelector : "pg-database=" + clusterName }
142- secrets , err := Clientset .Secrets (Namespace ).List (lo )
143- if err != nil {
144- log .Error ("error getting list of secrets" + err .Error ())
145- return results
146- }
147-
148- //get the postgres user secret info
149- var username , password , database , hostip string
150- for _ , s := range secrets .Items {
151- username = string (s .Data ["username" ][:])
152- password = string (s .Data ["password" ][:])
153- database = "postgres"
154- hostip = service .Spec .ClusterIP
155- if username == "postgres" {
156- log .Debug ("got postgres user secrets" )
157- break
158- }
159- }
160-
161- //query the database for users that have expired
162- strPort := fmt .Sprint (service .Spec .Ports [0 ].Port )
163- conn , err = sql .Open ("postgres" , "sslmode=disable user=" + username + " host=" + hostip + " port=" + strPort + " dbname=" + database + " password=" + password )
152+ conn , err = sql .Open ("postgres" , "sslmode=disable user=" + info .Username + " host=" + info .Hostip + " port=" + info .Port + " dbname=" + info .Database + " password=" + info .Password )
164153 if err != nil {
165154 log .Debug (err .Error ())
166155 return results
@@ -188,7 +177,7 @@ func callDB(clusterName, maxdays string) []PswResult {
188177
189178 for rows .Next () {
190179 p := PswResult {}
191- c := ConnInfo {Username : username , Hostip : hostip , StrPort : strPort , Database : database , Password : password }
180+ c := ConnInfo {Username : info . Username , Hostip : info . Hostip , Port : info . Port , Database : info . Database , Password : info . Password }
192181 p .ConnDetails = c
193182
194183 if err = rows .Scan (& p .Rolname , & p .Rolvaliduntil ); err != nil {
@@ -203,11 +192,11 @@ func callDB(clusterName, maxdays string) []PswResult {
203192
204193}
205194
206- func updatePassword (p PswResult , newPassword , passwordExpireDate string ) error {
195+ func updatePassword (p ConnInfo , username , newPassword , passwordExpireDate string ) error {
207196 var err error
208197 var conn * sql.DB
209198
210- conn , err = sql .Open ("postgres" , "sslmode=disable user=" + p .ConnDetails . Username + " host=" + p .ConnDetails . Hostip + " port=" + p .ConnDetails . StrPort + " dbname=" + p .ConnDetails . Database + " password=" + p . ConnDetails .Password )
199+ conn , err = sql .Open ("postgres" , "sslmode=disable user=" + p .Username + " host=" + p .Hostip + " port=" + p .Port + " dbname=" + p .Database + " password=" + p .Password )
211200 if err != nil {
212201 log .Debug (err .Error ())
213202 return err
@@ -216,14 +205,14 @@ func updatePassword(p PswResult, newPassword, passwordExpireDate string) error {
216205 //var ts string
217206 var rows * sql.Rows
218207
219- querystr := "ALTER user " + p . Rolname + " PASSWORD '" + newPassword + "'"
208+ querystr := "ALTER user " + username + " PASSWORD '" + newPassword + "'"
220209 log .Debug (querystr )
221210 rows , err = conn .Query (querystr )
222211 if err != nil {
223212 log .Debug (err .Error ())
224213 return err
225214 }
226- querystr = "ALTER user " + p . Rolname + " VALID UNTIL '" + passwordExpireDate + "'"
215+ querystr = "ALTER user " + username + " VALID UNTIL '" + passwordExpireDate + "'"
227216 log .Debug (querystr )
228217 rows , err = conn .Query (querystr )
229218 if err != nil {
@@ -269,3 +258,86 @@ func getDefaults() {
269258 }
270259
271260}
261+
262+ func getPostgresUserInfo (clusterName string ) ConnInfo {
263+ info := ConnInfo {}
264+
265+ //get the service for the cluster
266+ service , err := Clientset .CoreV1 ().Services (Namespace ).Get (clusterName , meta_v1.GetOptions {})
267+ if err != nil {
268+ log .Error ("error getting list of services" + err .Error ())
269+ os .Exit (2 )
270+ return info
271+ }
272+
273+ //get the secrets for this cluster
274+ lo := meta_v1.ListOptions {LabelSelector : "pg-database=" + clusterName }
275+ secrets , err := Clientset .Secrets (Namespace ).List (lo )
276+ if err != nil {
277+ log .Error ("error getting list of secrets" + err .Error ())
278+ os .Exit (2 )
279+ return info
280+ }
281+
282+ //get the postgres user secret info
283+ var username , password , database , hostip string
284+ for _ , s := range secrets .Items {
285+ username = string (s .Data ["username" ][:])
286+ password = string (s .Data ["password" ][:])
287+ database = "postgres"
288+ hostip = service .Spec .ClusterIP
289+ if username == "postgres" {
290+ log .Debug ("got postgres user secrets" )
291+ break
292+ }
293+ }
294+
295+ //query the database for users that have expired
296+ strPort := fmt .Sprint (service .Spec .Ports [0 ].Port )
297+ info .Username = username
298+ info .Password = password
299+ info .Database = database
300+ info .Hostip = hostip
301+ info .Port = strPort
302+
303+ return info
304+ }
305+
306+ func addUser (info ConnInfo , newUser string ) {
307+ var conn * sql.DB
308+ var err error
309+
310+ conn , err = sql .Open ("postgres" , "sslmode=disable user=" + info .Username + " host=" + info .Hostip + " port=" + info .Port + " dbname=" + info .Database + " password=" + info .Password )
311+ if err != nil {
312+ log .Debug (err .Error ())
313+ os .Exit (2 )
314+ }
315+
316+ var rows * sql.Rows
317+
318+ querystr := "create user " + newUser
319+ log .Debug (querystr )
320+ rows , err = conn .Query (querystr )
321+ if err != nil {
322+ log .Debug (err .Error ())
323+ os .Exit (2 )
324+ }
325+
326+ querystr = "grant all on database userdb to " + newUser
327+ log .Debug (querystr )
328+ rows , err = conn .Query (querystr )
329+ if err != nil {
330+ log .Debug (err .Error ())
331+ os .Exit (2 )
332+ }
333+
334+ defer func () {
335+ if conn != nil {
336+ conn .Close ()
337+ }
338+ if rows != nil {
339+ rows .Close ()
340+ }
341+ }()
342+
343+ }
0 commit comments