func DeleteCert(cert core.CertBundle) error { // in case of failure oldCerts, err := database.GetCerts() if err != nil { return err } // apply to proxymgr err = proxymgr.DeleteCert(cert) if err != nil { return err } if !database.CentralStore { // save to backend err = database.DeleteCert(cert) if err != nil { // undo proxymgr action if uerr := proxymgr.SetCerts(oldCerts); uerr != nil { err = fmt.Errorf("%v - %v", err.Error(), uerr.Error()) } return err } } return nil }
func TestNoneDeleteCert(t *testing.T) { if err := cluster.DeleteCert(testCert); err != nil { t.Errorf("Failed to DELETE cert - %v", err) t.FailNow() } // don't use cluster.GetCerts() certs, err := database.GetCerts() if len(certs) != 0 { t.Error("Failed to DELETE cert - %v", err) } }
func TestDeleteCert(t *testing.T) { if err := database.DeleteCert(testCert); err != nil { t.Errorf("Failed to DELETE cert - %v", err) } certs, err := database.GetCerts() if err != nil { t.Error(err) } if len(certs) != 0 { t.Errorf("Failed to delete cert") } }
//////////////////////////////////////////////////////////////////////////////// // CERTS //////////////////////////////////////////////////////////////////////////////// func TestNoneSetCert(t *testing.T) { if err := cluster.SetCert(testCert); err != nil { t.Errorf("Failed to SET cert - %v", err) t.FailNow() } certs, err := database.GetCerts() if err != nil { t.Error(err) } if len(certs) != 1 || certs[0].Cert != testCert.Cert { t.Errorf("Read cert differs from written cert") } }
func TestSetCerts(t *testing.T) { certs := []core.CertBundle{testCert} if err := database.SetCerts(certs); err != nil { t.Errorf("Failed to SET certs - %v", err) } certs, err := database.GetCerts() if err != nil { t.Error(err) } if len(certs) != 1 { t.Errorf("Wrong number of certs") } }
func TestSetCert(t *testing.T) { if err := database.SetCert(testCert); err != nil { t.Errorf("Failed to SET cert - %v", err) } if err := database.SetCert(testCert); err != nil { t.Errorf("Failed to SET cert - %v", err) } certs, err := database.GetCerts() if err != nil { t.Error(err) } if len(certs) != 1 { t.Errorf("Wrong number of certs") } }
func TestNoneSetCerts(t *testing.T) { certs := []core.CertBundle{testCert} if err := cluster.SetCerts(certs); err != nil { t.Errorf("Failed to SET certs - %v", err) t.FailNow() } // don't use cluster.GetCerts() certs, err := database.GetCerts() if err != nil { t.Error(err) } if len(certs) != 1 || certs[0].Cert != testCert.Cert { t.Errorf("Read cert differs from written cert") } }
// GetCerts gets a list of certs from the database, or another cluster member. func (r *Redis) GetCerts() ([]core.CertBundle, error) { if database.CentralStore { return database.GetCerts() } conn := pool.Get() defer conn.Close() // get known members(other than me) to 'poll' for certs members, _ := redis.Strings(conn.Do("SMEMBERS", "members")) if len(members) == 0 { // should only happen on new cluster // assume i'm ok to be master so don't reset imported certs config.Log.Trace("[cluster] - Assuming OK to be master, using certs from my database...") return common.GetCerts() } for i := range members { if members[i] == self { // if i'm in the list of members, new requests should have failed while `waitForMembers`ing config.Log.Trace("[cluster] - Assuming I was in sync, using certs from my database...") return common.GetCerts() } } c, err := redis.DialURL(config.ClusterConnection, redis.DialConnectTimeout(15*time.Second), redis.DialPassword(config.ClusterToken)) if err != nil { return nil, fmt.Errorf("Failed to reach redis for certs subscriber - %v", err) } defer c.Close() message := make(chan interface{}) subconn := redis.PubSubConn{c} // subscribe to channel that certs will be published on if err := subconn.Subscribe("certs"); err != nil { return nil, fmt.Errorf("Failed to reach redis for certs subscriber - %v", err) } defer subconn.Close() // listen always go func() { for { message <- subconn.Receive() } }() // todo: maybe use ttl? // timeout is how long to wait for the listed members to come back online timeout := time.After(time.Duration(20) * time.Second) // loop attempts for timeout, allows last dead members to start back up for { select { case <-timeout: return nil, fmt.Errorf("Timed out waiting for certs from %v", strings.Join(members, ", ")) default: // request certs from each member until successful for _, member := range members { // memberTimeout is how long to wait for a member to respond with list of certs memberTimeout := time.After(3 * time.Second) // ask a member for its certs config.Log.Trace("[cluster] - Attempting to request certs from %v...", member) _, err := conn.Do("PUBLISH", "portal", fmt.Sprintf("get-certs %s", member)) if err != nil { return nil, err } // wait for member to respond for { select { case <-memberTimeout: config.Log.Debug("[cluster] - Timed out waiting for certs from %v", member) goto nextCertMember case msg := <-message: switch v := msg.(type) { case redis.Message: config.Log.Trace("[cluster] - Received message on 'certs' channel") var certs []core.CertBundle err = parseBody(v.Data, &certs) if err != nil { return nil, fmt.Errorf("Failed to marshal certs - %v", err.Error()) } config.Log.Trace("[cluster] - Certs from cluster: %#v\n", certs) return certs, nil case error: return nil, fmt.Errorf("Subscriber failed to receive certs - %v", v.Error()) } } } nextCertMember: } } } }
func GetCerts() ([]core.CertBundle, error) { return database.GetCerts() }