Example #1
0
func main() {
	logger := lager.NewLogger("backup")
	logger.RegisterSink(log.NewCliSink(lager.INFO))
	logger.RegisterSink(lager.NewWriterSink(os.Stdout, lager.INFO))

	var configPath string
	flag.StringVar(&configPath, "config", "", "Path to YML config file")

	flag.Parse()

	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		logger.Error("snapshot-main", err, lager.Data{"event": "failed", "config_file": configPath})
		os.Exit(2)
	}

	backupConfig, err := backup.LoadBackupConfig(configPath)
	exitOnError(err, 78, logger, configPath)

	logFile, err := os.OpenFile(backupConfig.LogFilepath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0660)
	if err != nil {
		logger.Error("snapshot-main", err, lager.Data{"event": "failed", "LogFilepath": backupConfig.LogFilepath})
	}
	logger.RegisterSink(lager.NewWriterSink(logFile, lager.INFO))

	// TODO: Should this really be a pointer not a struct?
	if (backupConfig.S3Config == backup.S3Configuration{}) {
		logger.Info("snapshot-main", lager.Data{"event": "cancelled", "message": "S3 configuration not found - skipping backup"})
		os.Exit(0)
	}

	backuper, err := backup.NewInstanceBackuper(*backupConfig, logger)
	exitOnError(err, 70, logger, configPath)

	backupResults := backuper.Backup()
	hasError := false
	for _, result := range backupResults {
		if result.Err != nil {
			hasError = true
			logger.Error(
				"snapshot-main",
				result.Err,
				lager.Data{
					"event":           "failed",
					"InstanceID":      result.InstanceID,
					"RedisConfigPath": result.RedisConfigPath,
					"NodeIP":          result.NodeIP,
				},
			)
		}
	}

	if hasError {
		os.Exit(70)
	}
}
package backup_test

import (
	"path"
	"path/filepath"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/pivotal-cf/cf-redis-broker/instance/backup"
)

var _ = Describe("LoadBackupConfig", func() {
	Context("when the file does not exist", func() {
		It("returns an error", func() {
			_, err := backup.LoadBackupConfig("/this/is/an/invalid/path")
			Expect(err.Error()).To(Equal("open /this/is/an/invalid/path: no such file or directory"))
		})
	})

	Context("when the file is successfully loaded", func() {
		var config *backup.BackupConfig

		BeforeEach(func() {
			path, err := filepath.Abs(path.Join("assets", "backup.yml"))
			Expect(err).ToNot(HaveOccurred())

			config, err = backup.LoadBackupConfig(path)
			Expect(err).ToNot(HaveOccurred())
		})

		It("has the correct endpoint_url", func() {
		providerFactory.RedisBackuperProviderReturns(redisBackuper)

		redisConfigFinder = new(fakes.FakeRedisConfigFinder)
		providerFactory.RedisConfigFinderProviderReturns(redisConfigFinder)

		instanceIDLocator = new(fakes.FakeInstanceIDLocator)
		providerFactory.SharedInstanceIDLocatorProviderReturns(instanceIDLocator)
		providerFactory.DedicatedInstanceIDLocatorProviderReturns(instanceIDLocator)

		providerFactory.TimeProviderStub = func() time.Time {
			now, _ := time.Parse("200601020304", "200102030405")
			return now
		}

		var err error
		backupConfig, err = backup.LoadBackupConfig(filepath.Join("assets", "backup.yml"))
		Expect(err).ToNot(HaveOccurred())

		backupConfig.PlanName = broker.PlanNameShared
	})

	Describe(".Backup", func() {
		var backupResults []backup.BackupResult

		JustBeforeEach(func() {
			backuper, err := backup.NewInstanceBackuper(
				*backupConfig,
				logger,
				backup.InjectTimeProvider(providerFactory.TimeProvider),
				backup.InjectRedisClientProvider(providerFactory.RedisClientProvider),
				backup.InjectRedisBackuperProvider(providerFactory.RedisBackuperProvider),