// Verify that any module calls only refer to named providers, and that
// those providers will have a configuration at runtime. This way we can
// direct users where to add the missing configuration, because the runtime
// error is only "missing provider X".
for_,modCall:=rangemod.ModuleCalls{
for_,passed:=rangemodCall.Providers{
// aliased providers are handled more strictly, and are never
// inherited, so they are validated within modules further down.
// Skip these checks to prevent redundant diagnostics.
ifpassed.InParent.Alias!=""{
continue
}
name:=passed.InParent.String()
_,confOK:=configured[name]
_,localOK:=localNames[name]
_,passedOK:=passedIn[name]
// This name was not declared somewhere within in the
// configuration. We ignore empty configs, because they will
// already produce a warning.
if!(confOK||localOK){
diags=append(diags,&hcl.Diagnostic{
Severity:hcl.DiagWarning,
Summary:fmt.Sprintf("Provider %s is undefined",name),
Detail:fmt.Sprintf("No provider named %s has been declared in %s.\n",name,moduleText)+
fmt.Sprintf("If you wish to refer to the %s provider within the module, add a provider configuration, or an entry in the required_providers block.",name),
Subject:&passed.InParent.NameRange,
})
continue
}
// Now we may have named this provider within the module, but
// there won't be a configuration available at runtime if the
// parent module did not pass one in.
if!cfg.Path.IsRoot()&&!(confOK||passedOK){
diags=append(diags,&hcl.Diagnostic{
Severity:hcl.DiagWarning,
Summary:fmt.Sprintf("No configuration passed in for provider %s in %s",name,cfg.Path),
Detail:fmt.Sprintf("Provider %s is referenced within %s, but no configuration has been supplied.\n",name,moduleText)+
fmt.Sprintf("Add a provider named %s to the providers map for %s in %s.",name,cfg.Path,parentModuleText),
// we still allow default configs, so switch to a warning if the incoming provider is a default
ifproviderAddr.Provider.IsDefault(){
severity=hcl.DiagWarning
}
diags=append(diags,&hcl.Diagnostic{
Severity:severity,
Summary:fmt.Sprintf("Provider %s is undefined",name),
Detail:fmt.Sprintf("Module %s does not declare a provider named %s.\n",cfg.Path,name)+
fmt.Sprintf("If you wish to specify a provider configuration for the module, add an entry for %s in the required_providers block within the module.",name),
Subject:&passed.InChild.NameRange,
})
}
// The provider being passed in must also be of the correct type.
Summary:fmt.Sprintf("Invalid type for provider %s",providerAddr),
Detail:fmt.Sprintf("Cannot use configuration from %s for %s. ",parentAddr,providerAddr)+
"The given provider configuration is for a different provider type.",
Subject:&passed.InChild.NameRange,
})
}
}
// Empty configurations are no longer needed
forname,src:=rangeemptyConfigs{
detail:=fmt.Sprintf("Remove the %s provider block from %s.",name,cfg.Path)
isAlias:=strings.Contains(name,".")
_,isConfigAlias:=configAliases[name]
_,isLocalName:=localNames[name]
ifisAlias&&!isConfigAlias{
localName:=strings.Split(name,".")[0]
detail=fmt.Sprintf("Remove the %s provider block from %s. Add %s to the list of configuration_aliases for %s in required_providers to define the provider configuration name.",name,cfg.Path,name,localName)
}
if!isAlias&&!isLocalName{
// if there is no local name, add a note to include it in the
// required_provider block
detail+=fmt.Sprintf("\nTo ensure the correct provider configuration is used, add %s to the required_providers configuration",name)
}
diags=append(diags,&hcl.Diagnostic{
Severity:hcl.DiagWarning,
Summary:"Empty provider configuration blocks are not required",