func resourceRemoteStateRead(d *schema.ResourceData, meta interface{}) error {
	backend := d.Get("backend").(string)
	config := make(map[string]string)
	for k, v := range d.Get("config").(map[string]interface{}) {
		config[k] = v.(string)
	}

	// Create the client to access our remote state
	log.Printf("[DEBUG] Initializing remote state client: %s", backend)
	client, err := remote.NewClient(backend, config)
	if err != nil {
		return err
	}

	// Create the remote state itself and refresh it in order to load the state
	log.Printf("[DEBUG] Loading remote state...")
	state := &remote.State{Client: client}
	if err := state.RefreshState(); err != nil {
		return err
	}

	var outputs map[string]string
	if !state.State().Empty() {
		outputs = state.State().RootModule().Outputs
	}

	d.SetId(time.Now().UTC().String())
	d.Set("output", outputs)
	return nil
}
示例#2
0
func dataSourceRemoteStateRead(d *schema.ResourceData, meta interface{}) error {
	backend := d.Get("backend").(string)
	config := make(map[string]string)
	for k, v := range d.Get("config").(map[string]interface{}) {
		config[k] = v.(string)
	}

	// Create the client to access our remote state
	log.Printf("[DEBUG] Initializing remote state client: %s", backend)
	client, err := remote.NewClient(backend, config)
	if err != nil {
		return err
	}

	// Create the remote state itself and refresh it in order to load the state
	log.Printf("[DEBUG] Loading remote state...")
	state := &remote.State{Client: client}
	if err := state.RefreshState(); err != nil {
		return err
	}

	d.SetId(time.Now().UTC().String())

	outputMap := make(map[string]interface{})
	for key, val := range state.State().RootModule().Outputs {
		outputMap[key] = val.Value
	}

	mappedOutputs := remoteStateFlatten(outputMap)

	for key, val := range mappedOutputs {
		d.UnsafeSetFieldRaw(key, val)
	}
	return nil
}
示例#3
0
// validateRemoteConfig is used to verify that the remote configuration
// we have is valid
func (c *RemoteConfigCommand) validateRemoteConfig() error {
	conf := c.remoteConf
	_, err := remote.NewClient(conf.Type, conf.Config)
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"%s\n\n"+
				"If the error message above mentions requiring or modifying configuration\n"+
				"options, these are set using the `-backend-config` flag. Example:\n"+
				"-backend-config=\"name=foo\" to set the `name` configuration",
			err))
	}
	return err
}
示例#4
0
func dataSourceRemoteStateRead(d *schema.ResourceData, meta interface{}) error {
	backend := d.Get("backend").(string)
	config := make(map[string]string)
	for k, v := range d.Get("config").(map[string]interface{}) {
		config[k] = v.(string)
	}

	// Don't break people using the old _local syntax - but note warning above
	if backend == "_local" {
		log.Println(`[INFO] Switching old (unsupported) backend "_local" to "local"`)
		backend = "local"
	}

	// Create the client to access our remote state
	log.Printf("[DEBUG] Initializing remote state client: %s", backend)
	client, err := remote.NewClient(backend, config)
	if err != nil {
		return err
	}

	// Create the remote state itself and refresh it in order to load the state
	log.Printf("[DEBUG] Loading remote state...")
	state := &remote.State{Client: client}
	if err := state.RefreshState(); err != nil {
		return err
	}

	d.SetId(time.Now().UTC().String())

	outputMap := make(map[string]interface{})

	remoteState := state.State()
	if remoteState.Empty() {
		log.Println("[DEBUG] empty remote state")
		return nil
	}

	for key, val := range remoteState.RootModule().Outputs {
		outputMap[key] = val.Value
	}

	mappedOutputs := remoteStateFlatten(outputMap)

	for key, val := range mappedOutputs {
		d.UnsafeSetFieldRaw(key, val)
	}
	return nil
}
示例#5
0
func remoteState(
	local *terraform.State,
	localPath string, refresh bool) (*state.CacheState, error) {
	// If there is no remote settings, it is an error
	if local.Remote == nil {
		return nil, fmt.Errorf("Remote state cache has no remote info")
	}

	// Initialize the remote client based on the local state
	client, err := remote.NewClient(strings.ToLower(local.Remote.Type), local.Remote.Config)
	if err != nil {
		return nil, errwrap.Wrapf(fmt.Sprintf(
			"Error initializing remote driver '%s': {{err}}",
			local.Remote.Type), err)
	}

	// Create the remote client
	durable := &remote.State{Client: client}

	// Create the cached client
	cache := &state.CacheState{
		Cache:   &state.LocalState{Path: localPath},
		Durable: durable,
	}

	if refresh {
		// Refresh the cache
		if err := cache.RefreshState(); err != nil {
			return nil, errwrap.Wrapf(
				"Error reloading remote state: {{err}}", err)
		}
		switch cache.RefreshResult() {
		// All the results below can be safely ignored since it means the
		// pull was successful in some way. Noop = nothing happened.
		// Init = both are empty. UpdateLocal = local state was older and
		// updated.
		//
		// We don't have to do anything, the pull was successful.
		case state.CacheRefreshNoop:
		case state.CacheRefreshInit:
		case state.CacheRefreshUpdateLocal:

		// Our local state has a higher serial number than remote, so we
		// want to explicitly sync the remote side with our local so that
		// the remote gets the latest serial number.
		case state.CacheRefreshLocalNewer:
			// Write our local state out to the durable storage to start.
			if err := cache.WriteState(local); err != nil {
				return nil, errwrap.Wrapf(
					"Error preparing remote state: {{err}}", err)
			}
			if err := cache.PersistState(); err != nil {
				return nil, errwrap.Wrapf(
					"Error preparing remote state: {{err}}", err)
			}
		default:
			return nil, fmt.Errorf(
				"Unknown refresh result: %s", cache.RefreshResult())
		}
	}

	return cache, nil
}