Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple instances of the same resource #115

Merged
merged 1 commit into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/camptocamp/terraboard/config"
"github.com/camptocamp/terraboard/state"
"github.com/camptocamp/terraboard/types"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/states/statefile"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -62,22 +63,31 @@ func (db *Database) stateS3toDB(sf *statefile.File, path string, versionID strin
Path: m.Addr.String(),
}
for _, r := range m.Resources {
res := types.Resource{
Type: r.Addr.Resource.Type,
Name: r.Addr.Resource.Name,
for index, i := range r.Instances {
res := types.Resource{
Type: r.Addr.Resource.Type,
Name: r.Addr.Resource.Name,
Index: getResourceIndex(index),
Attributes: marshalAttributeValues(i.Current),
}
mod.Resources = append(mod.Resources, res)
}

for _, i := range r.Instances {
res.Attributes = marshalAttributeValues(i.Current)
}

mod.Resources = append(mod.Resources, res)
}
st.Modules = append(st.Modules, mod)
}
return
}

// getResourceIndex transforms an addrs.InstanceKey instance into a string representation
func getResourceIndex(index addrs.InstanceKey) string {
switch index.(type) {
case addrs.IntKey, addrs.StringKey:
return index.String()
}
return ""
}

func marshalAttributeValues(src *states.ResourceInstanceObjectSrc) (attrs []types.Attribute) {
vals := make(attributeValues)
if src.AttrsFlat != nil {
Expand Down Expand Up @@ -232,9 +242,9 @@ func (db *Database) SearchAttribute(query url.Values) (results []types.SearchRes

// Now get results
// gorm doesn't support subqueries...
sql := "SELECT states.path, states.version_id, states.tf_version, states.serial, modules.path as module_path, resources.type, resources.name, attributes.key, attributes.value" +
sql := "SELECT states.path, states.version_id, states.tf_version, states.serial, modules.path as module_path, resources.type, resources.name, resources.index, attributes.key, attributes.value" +
sqlQuery +
" ORDER BY states.path, states.serial, modules.path, resources.type, resources.name, attributes.key" +
" ORDER BY states.path, states.serial, modules.path, resources.type, resources.name, resources.index, attributes.key" +
" LIMIT ?"

params = append(params, pageSize)
Expand Down
9 changes: 9 additions & 0 deletions state/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ func (a *AWS) GetLocks() (locks map[string]LockInfo, err error) {

// GetStates returns a slice of State files in the S3 bucket
func (a *AWS) GetStates() (states []string, err error) {
log.WithFields(log.Fields{
"bucket": a.bucket,
"prefix": a.keyPrefix,
}).Debug("Listing states from S3")
result, err := a.svc.ListObjects(&s3.ListObjectsInput{
Bucket: aws_sdk.String(a.bucket),
Prefix: &a.keyPrefix,
Expand All @@ -106,6 +110,11 @@ func (a *AWS) GetStates() (states []string, err error) {
}
}
states = keys
log.WithFields(log.Fields{
"bucket": a.bucket,
"prefix": a.keyPrefix,
"states": len(states),
}).Debug("Found states from S3")
return states, nil
}

Expand Down
2 changes: 1 addition & 1 deletion static/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
<td>{{r.tf_version}}</td>
<td>{{r.serial}}</td>
<td>{{r.module_path}}</td>
<td>{{r.resource_name}}</td>
<td>{{r.resource_type}}.{{r.resource_name}}{{r.resource_index}}</td>
<td>{{r.attribute_key}}</td>
<td class="attr-val">{{r.attribute_value}}</td>
</tr>
Expand Down
4 changes: 2 additions & 2 deletions static/state.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ <h4>{{mod.path}}</h4>
<li ng-repeat="r in mod.resources | filter:{name:resFilter} as filteredRes"
ng-class="{selected: r == selectedres}"
ng-click="setSelected(mod, r)" class="list-group-item resource">
{{r.type}}.{{r.name}}
{{r.type}}.{{r.name}}{{r.index}}
</li>
</ul>
</li>
Expand All @@ -62,7 +62,7 @@ <h1>{{path}}</h1>
</div>
<!-- Resource details view -->
<div class="row" ng-if="display.details && selectedres">
<h2 class="node-title">{{selectedres.type}}.{{selectedres.name}}</h2>
<h2 class="node-title">{{selectedres.type}}.{{selectedres.name}}{{selectedres.index}}</h2>
<div class="panel-group">
<div class="panel panel-info">
<div class="panel-heading">
Expand Down
1 change: 1 addition & 0 deletions types/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type Resource struct {
ModuleID sql.NullInt64 `gorm:"index" json:"-"`
Type string `gorm:"index" json:"type"`
Name string `gorm:"index" json:"name"`
Index string `gorm:"index" json:"index"`
Attributes []Attribute `json:"attributes"`
}

Expand Down
1 change: 1 addition & 0 deletions types/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type SearchResult struct {
ModulePath string `gorm:"column:module_path" json:"module_path"`
ResourceType string `gorm:"column:type" json:"resource_type"`
ResourceName string `gorm:"column:name" json:"resource_name"`
ResourceIndex string `gorm:"column:index" json:"resource_index"`
AttributeKey string `gorm:"column:key" json:"attribute_key"`
AttributeValue string `gorm:"column:value" json:"attribute_value"`
}
Expand Down