github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/steampipeconfig/parse/mod_parse_context_blocks.go (about)

     1  package parse
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/hashicorp/hcl/v2"
     8  	"github.com/turbot/go-kit/helpers"
     9  	"github.com/turbot/pipe-fittings/hclhelpers"
    10  	"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
    11  )
    12  
    13  func (m *ModParseContext) DetermineBlockName(block *hcl.Block) string {
    14  	var shortName string
    15  
    16  	// have we cached a name for this block (i.e. is this the second decode pass)
    17  	if name, ok := m.GetCachedBlockShortName(block); ok {
    18  		return name
    19  	}
    20  
    21  	// if there is a parent set in the parent stack, this block is a child of that parent
    22  	parentName := m.PeekParent()
    23  
    24  	anonymous := len(block.Labels) == 0
    25  	if anonymous {
    26  		shortName = m.getUniqueName(block.Type, parentName)
    27  	} else {
    28  		shortName = block.Labels[0]
    29  	}
    30  	// build unqualified name
    31  	unqualifiedName := fmt.Sprintf("%s.%s", block.Type, shortName)
    32  	m.addChildBlockForParent(parentName, unqualifiedName)
    33  	// cache this name for the second decode pass
    34  	m.cacheBlockName(block, unqualifiedName)
    35  	return shortName
    36  }
    37  
    38  func (m *ModParseContext) GetCachedBlockName(block *hcl.Block) (string, bool) {
    39  	name, ok := m.blockNameMap[m.blockHash(block)]
    40  	return name, ok
    41  }
    42  
    43  func (m *ModParseContext) GetCachedBlockShortName(block *hcl.Block) (string, bool) {
    44  	unqualifiedName, ok := m.blockNameMap[m.blockHash(block)]
    45  	if ok {
    46  		parsedName, err := modconfig.ParseResourceName(unqualifiedName)
    47  		if err != nil {
    48  			return "", false
    49  		}
    50  		return parsedName.Name, true
    51  	}
    52  	return "", false
    53  }
    54  
    55  func (m *ModParseContext) GetDecodedResourceForBlock(block *hcl.Block) (modconfig.HclResource, bool) {
    56  	if name, ok := m.GetCachedBlockName(block); ok {
    57  		// see whether the mod contains this resource already
    58  		parsedName, err := modconfig.ParseResourceName(name)
    59  		if err == nil {
    60  			return m.CurrentMod.GetResource(parsedName)
    61  		}
    62  	}
    63  	return nil, false
    64  }
    65  
    66  func (m *ModParseContext) cacheBlockName(block *hcl.Block, shortName string) {
    67  	m.blockNameMap[m.blockHash(block)] = shortName
    68  }
    69  
    70  func (m *ModParseContext) blockHash(block *hcl.Block) string {
    71  	return helpers.GetMD5Hash(hclhelpers.BlockRange(block).String())
    72  }
    73  
    74  // getUniqueName returns a name unique within the scope of this execution tree
    75  func (m *ModParseContext) getUniqueName(blockType string, parent string) string {
    76  	// count how many children of this block type the parent has
    77  	childCount := 0
    78  
    79  	for _, childName := range m.blockChildMap[parent] {
    80  		parsedName, err := modconfig.ParseResourceName(childName)
    81  		if err != nil {
    82  			// we do not expect this
    83  			continue
    84  		}
    85  		if parsedName.ItemType == blockType {
    86  			childCount++
    87  		}
    88  	}
    89  	sanitisedParentName := strings.Replace(parent, ".", "_", -1)
    90  	return fmt.Sprintf("%s_anonymous_%s_%d", sanitisedParentName, blockType, childCount)
    91  }
    92  
    93  func (m *ModParseContext) addChildBlockForParent(parent, child string) {
    94  	m.blockChildMap[parent] = append(m.blockChildMap[parent], child)
    95  }