Пример #1
0
func (s *ConsulSuite) TestDatastore(c *check.C) {
	s.setupConsul(c)
	consulHost := s.composeProject.Container(c, "consul").NetworkSettings.IPAddress
	kvSource, err := staert.NewKvSource(store.CONSUL, []string{consulHost + ":8500"}, &store.Config{
		ConnectionTimeout: 10 * time.Second,
	}, "traefik")
	c.Assert(err, checker.IsNil)

	ctx := context.Background()
	datastore1, err := cluster.NewDataStore(ctx, *kvSource, &TestStruct{}, nil)
	c.Assert(err, checker.IsNil)
	datastore2, err := cluster.NewDataStore(ctx, *kvSource, &TestStruct{}, nil)
	c.Assert(err, checker.IsNil)

	setter1, _, err := datastore1.Begin()
	c.Assert(err, checker.IsNil)
	err = setter1.Commit(&TestStruct{
		String: "foo",
		Int:    1,
	})
	c.Assert(err, checker.IsNil)
	time.Sleep(2 * time.Second)
	test1 := datastore1.Get().(*TestStruct)
	c.Assert(test1.String, checker.Equals, "foo")

	test2 := datastore2.Get().(*TestStruct)
	c.Assert(test2.String, checker.Equals, "foo")

	setter2, _, err := datastore2.Begin()
	c.Assert(err, checker.IsNil)
	err = setter2.Commit(&TestStruct{
		String: "bar",
		Int:    2,
	})
	c.Assert(err, checker.IsNil)
	time.Sleep(2 * time.Second)
	test1 = datastore1.Get().(*TestStruct)
	c.Assert(test1.String, checker.Equals, "bar")

	test2 = datastore2.Get().(*TestStruct)
	c.Assert(test2.String, checker.Equals, "bar")

	wg := &sync.WaitGroup{}
	wg.Add(4)
	go func() {
		for i := 0; i < 100; i++ {
			setter1, _, err := datastore1.Begin()
			c.Assert(err, checker.IsNil)
			err = setter1.Commit(&TestStruct{
				String: "datastore1",
				Int:    i,
			})
			c.Assert(err, checker.IsNil)
		}
		wg.Done()
	}()
	go func() {
		for i := 0; i < 100; i++ {
			setter2, _, err := datastore2.Begin()
			c.Assert(err, checker.IsNil)
			err = setter2.Commit(&TestStruct{
				String: "datastore2",
				Int:    i,
			})
			c.Assert(err, checker.IsNil)
		}
		wg.Done()
	}()
	go func() {
		for i := 0; i < 100; i++ {
			test1 := datastore1.Get().(*TestStruct)
			c.Assert(test1, checker.NotNil)
		}
		wg.Done()
	}()
	go func() {
		for i := 0; i < 100; i++ {
			test2 := datastore2.Get().(*TestStruct)
			c.Assert(test2, checker.NotNil)
		}
		wg.Done()
	}()
	wg.Wait()
}
Пример #2
0
// CreateClusterConfig creates a tls.config using ACME configuration in cluster mode
func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tls.Config, checkOnDemandDomain func(domain string) bool) error {
	err := a.init()
	if err != nil {
		return err
	}
	if len(a.Storage) == 0 {
		return errors.New("Empty Store, please provide a key for certs storage")
	}
	a.checkOnDemandDomain = checkOnDemandDomain
	tlsConfig.Certificates = append(tlsConfig.Certificates, *a.defaultCertificate)
	tlsConfig.GetCertificate = a.getCertificate
	listener := func(object cluster.Object) error {
		account := object.(*Account)
		account.Init()
		if !leadership.IsLeader() {
			a.client, err = a.buildACMEClient(account)
			if err != nil {
				log.Errorf("Error building ACME client %+v: %s", object, err.Error())
			}
		}
		return nil
	}

	datastore, err := cluster.NewDataStore(
		leadership.Pool.Ctx(),
		staert.KvSource{
			Store:  leadership.Store,
			Prefix: a.Storage,
		},
		&Account{},
		listener)
	if err != nil {
		return err
	}

	a.store = datastore
	a.challengeProvider = &challengeProvider{store: a.store}

	ticker := time.NewTicker(24 * time.Hour)
	leadership.Pool.AddGoCtx(func(ctx context.Context) {
		log.Infof("Starting ACME renew job...")
		defer log.Infof("Stopped ACME renew job...")
		for {
			select {
			case <-ctx.Done():
				return
			case <-ticker.C:
				if err := a.renewCertificates(); err != nil {
					log.Errorf("Error renewing ACME certificate: %s", err.Error())
				}
			}
		}
	})

	leadership.AddListener(func(elected bool) error {
		if elected {
			object, err := a.store.Load()
			if err != nil {
				return err
			}
			transaction, object, err := a.store.Begin()
			if err != nil {
				return err
			}
			account := object.(*Account)
			account.Init()
			var needRegister bool
			if account == nil || len(account.Email) == 0 {
				account, err = NewAccount(a.Email)
				if err != nil {
					return err
				}
				needRegister = true
			}
			if err != nil {
				return err
			}
			a.client, err = a.buildACMEClient(account)
			if err != nil {
				return err
			}
			if needRegister {
				// New users will need to register; be sure to save it
				log.Debugf("Register...")
				reg, err := a.client.Register()
				if err != nil {
					return err
				}
				account.Registration = reg
			}
			// The client has a URL to the current Let's Encrypt Subscriber
			// Agreement. The user will need to agree to it.
			log.Debugf("AgreeToTOS...")
			err = a.client.AgreeToTOS()
			if err != nil {
				// Let's Encrypt Subscriber Agreement renew ?
				reg, err := a.client.QueryRegistration()
				if err != nil {
					return err
				}
				account.Registration = reg
				err = a.client.AgreeToTOS()
				if err != nil {
					log.Errorf("Error sending ACME agreement to TOS: %+v: %s", account, err.Error())
				}
			}
			err = transaction.Commit(account)
			if err != nil {
				return err
			}
			safe.Go(func() {
				a.retrieveCertificates()
				if err := a.renewCertificates(); err != nil {
					log.Errorf("Error renewing ACME certificate %+v: %s", account, err.Error())
				}
			})
		}
		return nil
	})
	return nil
}