github.com/paultyng/terraform@v0.6.11-0.20180227224804-66ff8f8bed40/configs/configload/loader_load.go (about)

     1  package configload
     2  
     3  import (
     4  	"fmt"
     5  
     6  	version "github.com/hashicorp/go-version"
     7  	"github.com/hashicorp/hcl2/hcl"
     8  	"github.com/hashicorp/terraform/configs"
     9  )
    10  
    11  // LoadConfig reads the Terraform module in the given directory and uses it as the
    12  // root module to build the static module tree that represents a configuration,
    13  // assuming that all required descendent modules have already been installed.
    14  //
    15  // If error diagnostics are returned, the returned configuration may be either
    16  // nil or incomplete. In the latter case, cautious static analysis is possible
    17  // in spite of the errors.
    18  //
    19  // LoadConfig performs the basic syntax and uniqueness validations that are
    20  // required to process the individual modules, and also detects
    21  func (l *Loader) LoadConfig(rootDir string) (*configs.Config, hcl.Diagnostics) {
    22  	rootMod, diags := l.parser.LoadConfigDir(rootDir)
    23  	if rootMod == nil {
    24  		return nil, diags
    25  	}
    26  
    27  	cfg, cDiags := configs.BuildConfig(rootMod, configs.ModuleWalkerFunc(l.moduleWalkerLoad))
    28  	diags = append(diags, cDiags...)
    29  
    30  	return cfg, diags
    31  }
    32  
    33  // moduleWalkerLoad is a configs.ModuleWalkerFunc for loading modules that
    34  // are presumed to have already been installed. A different function
    35  // (moduleWalkerInstall) is used for installation.
    36  func (l *Loader) moduleWalkerLoad(req *configs.ModuleRequest) (*configs.Module, *version.Version, hcl.Diagnostics) {
    37  	// Since we're just loading here, we expect that all referenced modules
    38  	// will be already installed and described in our manifest. However, we
    39  	// do verify that the manifest and the configuration are in agreement
    40  	// so that we can prompt the user to run "terraform init" if not.
    41  
    42  	key := manifestKey(req.Path)
    43  	record, exists := l.modules.manifest[key]
    44  
    45  	if !exists {
    46  		return nil, nil, hcl.Diagnostics{
    47  			{
    48  				Severity: hcl.DiagError,
    49  				Summary:  "Module not installed",
    50  				Detail:   "This module is not yet installed. Run \"terraform init\" to install all modules required by this configuration.",
    51  				Subject:  &req.CallRange,
    52  			},
    53  		}
    54  	}
    55  
    56  	var diags hcl.Diagnostics
    57  
    58  	// Check for inconsistencies between manifest and config
    59  	if req.SourceAddr != record.SourceAddr {
    60  		diags = append(diags, &hcl.Diagnostic{
    61  			Severity: hcl.DiagError,
    62  			Summary:  "Module source has changed",
    63  			Detail:   "The source address was changed since this module was installed. Run \"terraform init\" to install all modules required by this configuration.",
    64  			Subject:  &req.SourceAddrRange,
    65  		})
    66  	}
    67  	if !req.VersionConstraint.Required.Check(record.Version) {
    68  		diags = append(diags, &hcl.Diagnostic{
    69  			Severity: hcl.DiagError,
    70  			Summary:  "Module version requirements have changed",
    71  			Detail: fmt.Sprintf(
    72  				"The version requirements have changed since this module was installed and the installed version (%s) is no longer acceptable. Run \"terraform init\" to install all modules required by this configuration.",
    73  				record.Version,
    74  			),
    75  			Subject: &req.SourceAddrRange,
    76  		})
    77  	}
    78  
    79  	mod, mDiags := l.parser.LoadConfigDir(record.Dir)
    80  	diags = append(diags, mDiags...)
    81  	if mod == nil {
    82  		// nil specifically indicates that the directory does not exist or
    83  		// cannot be read, so in this case we'll discard any generic diagnostics
    84  		// returned from LoadConfigDir and produce our own context-sensitive
    85  		// error message.
    86  		return nil, nil, hcl.Diagnostics{
    87  			{
    88  				Severity: hcl.DiagError,
    89  				Summary:  "Module not installed",
    90  				Detail:   fmt.Sprintf("This module's local cache directory %s could not be read. Run \"terraform init\" to install all modules required by this configuration.", record.Dir),
    91  				Subject:  &req.CallRange,
    92  			},
    93  		}
    94  	}
    95  
    96  	return mod, record.Version, diags
    97  }