-
Notifications
You must be signed in to change notification settings - Fork 26
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
TerraformConfig: Add KeyValues method #506
base: main
Are you sure you want to change the base?
TerraformConfig: Add KeyValues method #506
Conversation
@wilkermichael Is this the way we should go over all the structs? |
Hey @thisisommore, thanks for taking a look at this! This solution definitely is an improvement towards querying and computer parsing. After doing some investigation myself, I realised that the log library we’re using supports JSON output which would be the ideal format for querying tools. Therefore, it makes more sense to make sure the JSON is queryable, and the focus of the human-readable output should be on clarity. For example, I've written a test case that demos what that might look like with your change: func TestInterface(t *testing.T) {
tc := TerraformConfig{
Version: String("test"),
Log: Bool(true),
WorkingDir: String("test"),
}
var cc ConsulConfig
cc.Finalize()
tc.Finalize(&cc)
// Output human readable
logging.Global().Info("test", tc.KeyValues()...)
logger := hclog.New(&hclog.LoggerOptions{
JSONFormat: true, // in the future support a flag to toggle this JSON format
TimeFormat: hclog.TimeFormat,
})
hclog.SetDefault(logger)
// Output JSON
logging.Global().Info("test", tc.KeyValues()...)
} Which outputs the human readable:
and the json {
"@level":"info",
"@message":"test",
"@timestamp":"2021-11-16T11:49:13.914-0800",
"Backend":{
"consul":{
"address":"localhost:8500",
"gzip":true,
"path":"consul-terraform-sync/terraform"
}
},
"Log":true,
"Path":"/Users/mwilkerson/dev/consul-terraform-sync/config",
"PersistLog":false,
"RequiredProviders":{
},
"Version":"test",
"WorkingDir":"test"
} One limitation with the solution here is that the JSON object doesn't include any reference to the original object, in this case TerraformConfig, so a user wouldn't be able to query for example terraformConfig.Version="test". After investigating a bit more, I’ve added a possible alternative solution, more information and examples can now be found in the issue details. Let me know how you feel about them. I know it's a lot of information at once, so don’t hesitate to reach out if you have more questions. |
@wilkermichael Sorry for the late response, was going through a lot of study work, and now I am looking at this. |
Hey @wilkermichael
|
Hey @thisisommore, thanks for your patience while I got back to you. I'll address each question here: (1) I just did a quick test to verify the current default behaviour of that squashed field when logging json: c := &CatalogServicesConditionConfig{
CatalogServicesMonitorConfig{
Regexp: String(".*"),
SourceIncludesVar: Bool(true),
Datacenter: String("dc2"),
Namespace: String("ns2"),
NodeMeta: map[string]string{
"key1": "value1",
"key2": "value2",
},
},
}
// JSON logging enabled
logging.Global().Info("this is a json log", "catalogServicesConditionConfig", c)` yields the following log: {
"@level": "info",
"@message": "this is a json log",
"@timestamp": "2021-12-20T11:31:26.262-0800",
"catalogServicesConditionConfig": {
"Regexp": ".*",
"SourceIncludesVar": true,
"Datacenter": "dc2",
"Namespace": "ns2",
"NodeMeta": {
"key1": "value1",
"key2": "value2"
}
}
} Ignoring the field names since I didn't setup struct tags for them, the general structure of this json makes sense to me. It looks like it doesn't include the squashed field name in the JSON which I think is good. If you add the (2) I think renaming the interface method to String() makes sense! |
@wilkermichael Thanks for addressing this, I have committed the changes, and now will try creating tests. |
@wilkermichael do I have a write the test for each struct? |
@thisisommore thanks for your patience, I've been on holidays the last couple of weeks. I think it would be a good idea to have a test for each struct, however, you can just test whether or not the object marshal's successfully. You don't need to check that the string matches for each case. |
@thisisommore I was looking through again and noticed you asked me to do a preliminary review. I'm happy to do one for you, however, can you please rebase your changes onto main first and resolve the conflicts? There have been a number of changes to the config since work was started on this PR. |
…ruct-key-values-377
@wilkermichael sorry for being late, I have merged main into this PR, also I was not going into the test due to now sure where to start, I hope this is not urgent or feel free to assign this to someone else, I will be trying hands on it again this Sunday. Also Happy New Year 🥳, hope you are doing well. |
@thisisommore Happy New Year! No rush on this, take your time. I probably won't get a chance to review until next week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @thisisommore I have reviewed some of your submission, but noticed that there are some build issues as well as some tests which I don't think will pass. Can you please resolve all build issues and confirm the unit tests are passing?
You can run the following to verify this behaviour:
make dev
will attempt to build CTSmake test
will run the unit tests
Thanks for all your hard work, an I will continue the review after these are resolved
@@ -181,7 +181,7 @@ func (cli *CLI) runBinary(configFiles, inspectTasks config.FlagAppendSliceValue, | |||
|
|||
// Print information on startup for debugging | |||
logger.Info(version.GetHumanVersion()) | |||
logger.Debug("configuration", "config", conf.GoString()) | |||
logger.Debug("configuration", "config", conf.String()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cool thing about the Stringer interface is that the logger will actually try and call the interface without the implementer needing to explicitly call the String() method. In this way the logger can marshal to JSON or call String() when printing plaintext.
Can you remove the String() call from instances where the logger calls the String() method?
eg. in this case logger.Debug("configuration", "config", conf)
Password *string `mapstructure:"password"` | ||
Enabled *bool `mapstructure:"enabled" json"enabled"` | ||
Username *string `mapstructure:"username" json"username"` | ||
Password *string `mapstructure:"password" json"password"` | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need a :
between json and the field name
i.e. json:"enabled"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you also use json:"-"
for the password string, this shouldn't be included when printing the json
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try to catch similar scenarios where you should use json:"-"
but if you see it's printing the value using the sensitiveGoString() function in the String()
method, then the json tag should be redacted as well.
"%s"+ | ||
"}", | ||
c.CatalogServicesMonitorConfig.GoString(), | ||
c.CatalogServicesMonitorConfig.String(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can remove .String() usage here as well, and all other usages like this
return fmt.Sprintf("&ConsulKVConditionConfig{"+ | ||
"%s, "+ | ||
"UseAsModuleInput:%v"+ | ||
"}", | ||
c.ConsulKVMonitorConfig.GoString(), | ||
BoolVal(c.UseAsModuleInput), | ||
>>>>>>> upstream/main |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix this merge conflict
|
||
return fmt.Sprintf("&ScheduleConditionConfig{"+ | ||
return fmt.Sprintf("{"+ | ||
"Cron:%s, "+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing json tag for Cron (json:"cron") on above ScheduleConditionConfig struct (line: 15)
|
||
return fmt.Sprintf("&ServicesConditionConfig{"+ | ||
"%s, "+ | ||
"UseAsModuleInput:%v"+ | ||
"}", | ||
c.ServicesMonitorConfig.GoString(), | ||
c.ServicesMonitorConfig.String(), | ||
BoolVal(c.UseAsModuleInput), | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing json tags on ServicesConditionConfig
struct. Most likely these were added after you merged main
sensitiveGoString(c.Token), | ||
c.Transport.GoString(), | ||
c.Transport.String(), | ||
) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing json struct tags on ConsulConfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a special case here, notice how c.Token is "sensitive" in this case I think it would be appropriate to use the special json tag json:"-"
so as to not include this field when printing out
3437cd4
to
00ea382
Compare
@thisisommore I changed some settings on our end as I noticed that the pipeline wasn't running for your PR. The checks should now show the areas where the PR is failing. |
You can ignore the Slack failure, that one is on our end. It requires a setting change, but won't affect your PR. EDIT: This has been resolved now in the latest main, if you rebase on the latest main it should resolve the slack failure in the pipeline |
Work in progress PR to fix #377