-
Notifications
You must be signed in to change notification settings - Fork 7
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 discovery and SWIM functionality #18
Conversation
Use exclude_example for most discovery attribs Why the "timeout" is write_only: the POST needs "timeout", but GET annoyingly returns "timeOut".
The HTTP DELETE does not use the usual dna/intent/* prefix. Reason is that dna/intent/* returns 404 for DELETE, but without the prefix it works as expected on our lab.
Don't copy large file to log. First timeout: the POST itself, until CC receives the upload bytes. Second timeout on top of the first: the CC task execution.
Since API has no concept of unique id for an activation, we can compose one. Just take all attributes that define uniqueness, and concatenate them.
This reverts commit 0fa569d.
I've only included the attributes that are non-null on a couple of my test devices. The main motivation for this is to be able to filter devices based on their location (area/building/floor). There are basically two documented APIs for that: v1/device-detail and v1/membership. The reason for preferring the former here in this commit is that the latter is exceptionally slow. The v1/network-device, contrary to its documentation, does not send location or locationName data. It always sends nulls for these.
Reason: there is no harm in trying to adjust an empty subcategory, whether the golang code was auto-generated or manually specified.
It is confusing to users to show them any `id` attribute because this resource always selects all devices. In order to avoid gen/generator.go from adding `id` back I put the ds under manual maintenace. So now the only remaining contribution from gen/generator.go is partial templating of model.go, just because it will be useful for any future attribute work.
After the first apply, the CC API returns some of the strings with letter case changed. E.g. my POST contains type "RANGE" but the next GET returns "Range" instead. It means that every subsequent `terraform apply` would attempt to change the object. This fails the TF_ACC test and is also user-hostile.
Reason: The API PUT uses the same attribute specs as GET, which are both different than POST. While it can be implemented manually some day, it seems too quirky for the current gen/templates. Lack of PUT in practice requires both `no_update` and `skip_minimal_test`, otherwise the tests would always fail. Reason for no_import: the generator for now mistakenly uses name attribute instead of numerical id attribute.
name: Network Devices | ||
rest_endpoint: /dna/intent/api/v1/network-device | ||
get_no_id: true | ||
no_data_source: true |
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 we could still auto-generate the data source code and just replace specific sections of the generated code. Each rendered .go file has a number of sections (//template:begin
and //template:end
), where if you want to change a certain section you would make the necessary changes, then remove the begin/end template markers, which will prevent this specific section of code from being overwritten the next time you would run go generate
.
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.
In this particular place I had additional problem, which I couldn't solve with deleting //template:begin
and //template:end
. By default, the generated docs
and examples
of data source always tells users to use id
attribute:
data "catalystcenter_network_devices" "example" {
id = "76d24097-41c4-4558-a4d0-a8c07ac08470"
}
But in this particular case, the id
doesn't fit well. It is confusing to users to even show them an id
attribute because this source always returns all devices, whereas any user would probably confuse that id
with the device's UUID.
The no_data_source
is probably the least invasive way to prevent gen/generator.go from adding id
back to the docs
and examples
.
So now the only remaining contribution from gen/generator.go is partial templating of model.go, and I agree it will be useful for any future attribute additions.
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.
A singleton data source implementation is potentially something we might require for more data sources in the future, so we could also consider enhancing the generator to support this. For now I am fine with keeping it like this and then revisiting it once we have more data sources requiring this.
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.
Acknowledged. The phrase "singleton data source" brings back a bit of GoF memories :)
gen/definitions/device_detail.yaml
Outdated
no_delete: true | ||
no_import: true | ||
no_read: true | ||
doc_category: Devices |
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.
We already have a category Inventory
, would it make sense to add it there?
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.
done, thanks
gen/definitions/device_detail.yaml
Outdated
get_extra_query_params: '&identifier=uuid' | ||
ds_description: This data source fetches device's details, including the assigned physical location. | ||
no_resource: true | ||
no_update: true |
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.
If we are not adding a resource I think we can remove no_update
, no_delete
, no_import
and no_read
.
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.
done, thanks
gen/definitions/discovery.yaml
Outdated
requires_replace: true | ||
- model_name: enablePasswordList | ||
type: StringList | ||
# description: Enable Password of the devices to be discovered. |
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.
Is there a reason the description is commented out?
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.
In fact I wanted to comment out the entire attribute. I'm not sure about the semantics of these 3 lists. Should it be in fact a single list with nested attribs? Also I don't have a liberty to touch device credentials at all in my environment, so I cannot really play and see myself what is going on with these.
Suggestions?
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.
According to the API documentation it is a list of strings, so this would be the right type to use. I would suggest to leave it in and uncomment the descriptions. We will test this with an internal instance.
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.
done, I've added descriptions
gen/definitions/discovery.yaml
Outdated
requires_replace: true | ||
- model_name: passwordList | ||
type: StringList | ||
# description: Password of the devices to be discovered. |
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.
Is there a reason the description is commented out?
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.
done per above
gen/definitions/discovery.yaml
Outdated
requires_replace: true | ||
- model_name: userNameList | ||
type: StringList | ||
# description: Username for the devices to be discovered. |
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.
Is there a reason the description is commented out?
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.
done per above
name: Network Devices | ||
rest_endpoint: /dna/intent/api/v1/network-device | ||
get_no_id: true | ||
no_data_source: true |
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.
A singleton data source implementation is potentially something we might require for more data sources in the future, so we could also consider enhancing the generator to support this. For now I am fine with keeping it like this and then revisiting it once we have more data sources requiring this.
gen/templates/resource.go
Outdated
@@ -410,7 +410,7 @@ func (r *{{camelCase .Name}}Resource) Create(ctx context.Context, req resource.C | |||
{{- if .PutCreate}} | |||
res, err := r.client.Put(plan.getPath() + params, body) |
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.
Let's maybe also add support for the max_async_wait_time
parameter here.
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.
done, thanks
gen/templates/resource.go
Outdated
@@ -535,7 +535,7 @@ func (r *{{camelCase .Name}}Resource) Update(ctx context.Context, req resource.U | |||
params += "?{{.PutIdQueryParam}}=" + plan.Id.ValueString() | |||
{{- end}} | |||
{{- if .PostUpdate}} | |||
res, err := r.client.Post(plan.getPath() + params, body) | |||
res, err := r.client.Post(plan.getPath() + params, body {{- if .MaxAsyncWaitTime }}, func(r *cc.Req) { r.MaxAsyncWaitTime={{.MaxAsyncWaitTime}} }{{end}}) | |||
{{- else if .PutCreate}} | |||
res, err := r.client.Put(plan.getPath() + params, body) |
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.
same here
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.
done, thanks
} | ||
|
||
func testAccDataSourceCcNetworkDevicesConfig() string { | ||
config := `resource "catalystcenter_network_devices" "test" {` + "\n" |
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.
This would need to be updated as this resource does not exist. We would either need to add test_prerequisites
to add a device first or assume a certain device already exists. We can keep it like this for now and I would then update it later to work with our CI environment.
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.
With test_prerequisites
, the test becomes quite weak. It amounts to a single value response.0.management_ip_address
... All the other attributes need to be real (meaning I don't see how to POST/PUT them).
In addition to the catalystcenter_network_devices, the more acute case is catalystcenter_device_detail. The latter only seems to be working at all if the device is in managed
state.
Suggestions?
Do I lock these tests behind os.Getenv("INVENTORY")
as currently used in catalystcenter_device_role
? Do they belong approximately to the same boat?
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.
Yes, let's add a test tag for now and we will see how we can update the test to work in our ci environment.
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.
done - tag INVENTORY
First of all, thank you for the contribution and awesome work! In general I would say one resource and/or data source per PR, though this could create merge conflicts in some of the "shared" files if we work on multiple PRs in parallel. If the resources and/or data sources are somehow connected and/or have interdependencies, I am fine with more than one in a single PR as well. |
I really like the more comprehensive TF example you have added and I am wondering if it would be more "visible" if we would add it with some explanations to the "Guides" section in the documentation. |
Also, remove redundant YAML entries. If we are not adding a resource we can remove no_update, no_delete, no_import and no_read.
gen/definitions/discovery.yaml
Outdated
requires_replace: true | ||
- model_name: enablePasswordList | ||
type: StringList | ||
# description: Enable Password of the devices to be discovered. |
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.
According to the API documentation it is a list of strings, so this would be the right type to use. I would suggest to leave it in and uncomment the descriptions. We will test this with an internal instance.
} | ||
|
||
func testAccDataSourceCcNetworkDevicesConfig() string { | ||
config := `resource "catalystcenter_network_devices" "test" {` + "\n" |
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.
Yes, let's add a test tag for now and we will see how we can update the test to work in our ci environment.
Where the POST requests are slow the same would be probably true for the PUT requests (more often than not).
I'm not sure about the semantics of these 3 lists. Should it be in fact a single list with 3 nested attribs? For now going with raw API specs, but re-structuring would be probably welcome here.
Both network_devices and device_detail need their attributes to come from a real device. I don't see how to POST/PUT them. Similarly IMAGE_ACTIVATION and IMAGE_DISTRIBUTION, these tests require specific real devices and matching image binary files.
Changes brought:
catalystcenter_discovery
resource and data sourcecatalystcenter_network_devices
data sourcecatalystcenter_device_detail
resource and data sourcecatalystcenter_image
resourcecatalystcenter_image_distribution
resourcecatalystcenter_image_activation
resourceThis pull request is quite large, and I would welcome a suggestion what would be ideal PR size from reviewer's perspective.