{"action":"created","comment":{"url":"https://api.github.com/repos/hashicorp/terraform/pulls/comments/171329255","pull_request_review_id":100162821,"id":171329255,"diff_hunk":"@@ -234,6 +236,19 @@ func (d *ResourceDiff) clear(key string) error {\n \treturn nil\n }\n \n+// GetDiffAttributes helps to implement resourceDiffer\n+// where we need to act on all nested fields\n+// without calling out each field separately\n+func (d *ResourceDiff) GetDiffAttributes(prefix string) map[string]*terraform.ResourceAttrDiff {","path":"helper/schema/resource_diff.go","position":20,"original_position":20,"commit_id":"a229e83daee69c32516362403f07aaaedffb8d1b","original_commit_id":"a229e83daee69c32516362403f07aaaedffb8d1b","user":{"login":"radeksimko","id":287584,"avatar_url":"https://avatars1.githubusercontent.com/u/287584?v=4","gravatar_id":"","url":"https://api.github.com/users/radeksimko","html_url":"https://github.com/radeksimko","followers_url":"https://api.github.com/users/radeksimko/followers","following_url":"https://api.github.com/users/radeksimko/following{/other_user}","gists_url":"https://api.github.com/users/radeksimko/gists{/gist_id}","starred_url":"https://api.github.com/users/radeksimko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/radeksimko/subscriptions","organizations_url":"https://api.github.com/users/radeksimko/orgs","repos_url":"https://api.github.com/users/radeksimko/repos","events_url":"https://api.github.com/users/radeksimko/events{/privacy}","received_events_url":"https://api.github.com/users/radeksimko/received_events","type":"User","site_admin":false},"body":"> hard-code the keys you want to mark as `ForceNew`\r\n\r\nThe schema is really deeply nested and long and it is likely to grow in the future:\r\nhttps://github.com/terraform-providers/terraform-provider-kubernetes/blob/master/kubernetes/schema_volume_source.go#L14\r\nso checking each field seems like a rather tedious approach.\r\n\r\n> maybe in the example that you are giving, you could probably just either walk the schema itself directly\r\n\r\nThat means we'd have to take the schema and try to \"guess\" how does it (or may) translate into keys (indexes) in the diff, which is difficult to do specifically for TypeList/TypeSet/TypeMap. It also seems like that's a logic that should be somewhere in core anyway - the provider IMO shouldn't have to traverse its own schema and know how to translate it to \"diff-like format\" in order to call `d.Get(key)` or `d.GetChange(key)`.\r\n\r\nHowever I understand what you're saying and I did have similar feelings when cobbling the PR. It does not feel right to expose the diff like this, so thanks for confirming my thoughts. 😃\r\n\r\nI'm playing with two ideas at this point:\r\n\r\n - `func (d *ResourceDiff) ForceNewPrefix(prefix) error` which would basically go through the schema and mark all nested fields (those which have the given prefix in state) as `ForceNew`\r\n - `func (d *ResourceDiff) GetChangedKeys(prefix) []string` - here we'd be still exposing the diff, but only keys, so the bare minimum we need to (in order to call `d.Get()` and `d.ForceNew()` on them), not the whole `map[string]*terraform.ResourceAttrDiff`\r\n\r\nWhat do you think?","created_at":"2018-02-28T17:51:28Z","updated_at":"2018-02-28T17:51:28Z","html_url":"https://github.com/hashicorp/terraform/pull/17463#discussion_r171329255","pull_request_url":"https://api.github.com/repos/hashicorp/terraform/pulls/17463","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/hashicorp/terraform/pulls/comments/171329255"},"html":{"href":"https://github.com/hashicorp/terraform/pull/17463#discussion_r171329255"},"pull_request":{"href":"https://api.github.com/repos/hashicorp/terraform/pulls/17463"}},"in_reply_to_id":171292520},"pull_request":{"url":"https://api.github.com/repos/hashicorp/terraform/pulls/17463","id":171948922,"html_url":"https://github.com/hashicorp/terraform/pull/17463","diff_url":"https://github.com/hashicorp/terraform/pull/17463.diff","patch_url":"https://github.com/hashicorp/terraform/pull/17463.patch","issue_url":"https://api.github.com/repos/hashicorp/terraform/issues/17463","number":17463,"state":"open","locked":false,"title":"helper/schema: Allow ResourceDiff.ForceNew on nested fields (avoid crash)","user":{"login":"radeksimko","id":287584,"avatar_url":"https://avatars1.githubusercontent.com/u/287584?v=4","gravatar_id":"","url":"https://api.github.com/users/radeksimko","html_url":"https://github.com/radeksimko","followers_url":"https://api.github.com/users/radeksimko/followers","following_url":"https://api.github.com/users/radeksimko/following{/other_user}","gists_url":"https://api.github.com/users/radeksimko/gists{/gist_id}","starred_url":"https://api.github.com/users/radeksimko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/radeksimko/subscriptions","organizations_url":"https://api.github.com/users/radeksimko/orgs","repos_url":"https://api.github.com/users/radeksimko/repos","events_url":"https://api.github.com/users/radeksimko/events{/privacy}","received_events_url":"https://api.github.com/users/radeksimko/received_events","type":"User","site_admin":false},"body":"I bumped into this when trying to resolve a bug in the K8S provider, where certain fields in the schema become immutable from a certain version of K8S.\r\n\r\nThe end-developer use-case follows:\r\n\r\n```go\r\nCustomizeDiff: func(diff *schema.ResourceDiff, meta interface{}) error {\r\n\t// Mutation of PersistentVolumeSource after creation is no longer allowed in 1.9+\r\n\t// See https://github.com/kubernetes/kubernetes/blob/v1.9.3/CHANGELOG-1.9.md#storage-3\r\n\tconn := meta.(*kubernetes.Clientset)\r\n\tserverVersion, err := conn.ServerVersion()\r\n\tif err != nil {\r\n\t\treturn err\r\n\t}\r\n\r\n\tk8sVersion, err := gversion.NewVersion(serverVersion.String())\r\n\tif err != nil {\r\n\t\treturn err\r\n\t}\r\n\r\n\tv1_9_0, _ := gversion.NewVersion(\"1.9.0\")\r\n\tif k8sVersion.Equal(v1_9_0) || k8sVersion.GreaterThan(v1_9_0) {\r\n\t\tif diff.HasChange(\"spec.0.persistent_volume_source\") {\r\n\t\t\tattributes := diff.GetDiffAttributes(\"spec.0.persistent_volume_source\")\r\n\t\t\tfor k, _ := range attributes {\r\n\t\t\t\terr := diff.ForceNew(k)\r\n\t\t\t\tif err != nil {\r\n\t\t\t\t\treturn err\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn nil\r\n\t\t}\r\n\t}\r\n\r\n\treturn nil\r\n}\r\n```\r\n\r\n## Test result before patch\r\n\r\n```\r\n make test TEST=./helper/schema\r\n==> Checking that code complies with gofmt requirements...\r\ngo generate ./...\r\n2018/02/28 12:57:59 Generated command/internal_plugin_list.go\r\ngo list ./helper/schema | xargs -t -n4 go test  -timeout=60s -parallel=4\r\ngo test -timeout=60s -parallel=4 github.com/hashicorp/terraform/helper/schema\r\n2018/02/28 12:58:04 [INFO] Resource foo has dynamic attributes\r\npanic: runtime error: invalid memory address or nil pointer dereference [recovered]\r\n\tpanic: runtime error: invalid memory address or nil pointer dereference\r\n[signal SIGSEGV: segmentation violation code=0x1 addr=0x51 pc=0x165a3da]\r\n\r\ngoroutine 718 [running]:\r\ntesting.tRunner.func1(0xc4202b13b0)\r\n\t/usr/local/Cellar/go/1.10/libexec/src/testing/testing.go:742 +0x29d\r\npanic(0x17c2200, 0x1d88230)\r\n\t/usr/local/Cellar/go/1.10/libexec/src/runtime/panic.go:505 +0x229\r\ngithub.com/hashicorp/terraform/helper/schema.(*ResourceDiff).ForceNew(0xc420466b00, 0x18a38c0, 0x9, 0xc42046e0a0, 0xc420466b00)\r\n\t/Users/radeksimko/gopath/src/github.com/hashicorp/terraform/helper/schema/resource_diff.go:313 +0xda\r\ngithub.com/hashicorp/terraform/helper/schema.TestForceNew.func1(0xc4202b13b0)\r\n\t/Users/radeksimko/gopath/src/github.com/hashicorp/terraform/helper/schema/resource_diff_test.go:769 +0x9b\r\ntesting.tRunner(0xc4202b13b0, 0xc42046aa70)\r\n\t/usr/local/Cellar/go/1.10/libexec/src/testing/testing.go:777 +0xd0\r\ncreated by testing.(*T).Run\r\n\t/usr/local/Cellar/go/1.10/libexec/src/testing/testing.go:824 +0x2e0\r\nFAIL\tgithub.com/hashicorp/terraform/helper/schema\t0.061s\r\nmake: *** [test] Error 1\r\n```","created_at":"2018-02-28T13:11:16Z","updated_at":"2018-02-28T17:51:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1cc5281412ed1dec312019db86fcd72c94bc9b7c","assignee":null,"assignees":[],"requested_reviewers":[{"login":"apparentlymart","id":20180,"avatar_url":"https://avatars1.githubusercontent.com/u/20180?v=4","gravatar_id":"","url":"https://api.github.com/users/apparentlymart","html_url":"https://github.com/apparentlymart","followers_url":"https://api.github.com/users/apparentlymart/followers","following_url":"https://api.github.com/users/apparentlymart/following{/other_user}","gists_url":"https://api.github.com/users/apparentlymart/gists{/gist_id}","starred_url":"https://api.github.com/users/apparentlymart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apparentlymart/subscriptions","organizations_url":"https://api.github.com/users/apparentlymart/orgs","repos_url":"https://api.github.com/users/apparentlymart/repos","events_url":"https://api.github.com/users/apparentlymart/events{/privacy}","received_events_url":"https://api.github.com/users/apparentlymart/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":85946957,"url":"https://api.github.com/repos/hashicorp/terraform/labels/bug","name":"bug","color":"f7c6c7","default":true}],"milestone":null,"commits_url":"https://api.github.com/repos/hashicorp/terraform/pulls/17463/commits","review_comments_url":"https://api.github.com/repos/hashicorp/terraform/pulls/17463/comments","review_comment_url":"https://api.github.com/repos/hashicorp/terraform/pulls/comments{/number}","comments_url":"https://api.github.com/repos/hashicorp/terraform/issues/17463/comments","statuses_url":"https://api.github.com/repos/hashicorp/terraform/statuses/a229e83daee69c32516362403f07aaaedffb8d1b","head":{"label":"hashicorp:b-helper-r-diff-nested-keys","ref":"b-helper-r-diff-nested-keys","sha":"a229e83daee69c32516362403f07aaaedffb8d1b","user":{"login":"hashicorp","id":761456,"avatar_url":"https://avatars2.githubusercontent.com/u/761456?v=4","gravatar_id":"","url":"https://api.github.com/users/hashicorp","html_url":"https://github.com/hashicorp","followers_url":"https://api.github.com/users/hashicorp/followers","following_url":"https://api.github.com/users/hashicorp/following{/other_user}","gists_url":"https://api.github.com/users/hashicorp/gists{/gist_id}","starred_url":"https://api.github.com/users/hashicorp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hashicorp/subscriptions","organizations_url":"https://api.github.com/users/hashicorp/orgs","repos_url":"https://api.github.com/users/hashicorp/repos","events_url":"https://api.github.com/users/hashicorp/events{/privacy}","received_events_url":"https://api.github.com/users/hashicorp/received_events","type":"Organization","site_admin":false},"repo":{"id":17728164,"name":"terraform","full_name":"hashicorp/terraform","owner":{"login":"hashicorp","id":761456,"avatar_url":"https://avatars2.githubusercontent.com/u/761456?v=4","gravatar_id":"","url":"https://api.github.com/users/hashicorp","html_url":"https://github.com/hashicorp","followers_url":"https://api.github.com/users/hashicorp/followers","following_url":"https://api.github.com/users/hashicorp/following{/other_user}","gists_url":"https://api.github.com/users/hashicorp/gists{/gist_id}","starred_url":"https://api.github.com/users/hashicorp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hashicorp/subscriptions","organizations_url":"https://api.github.com/users/hashicorp/orgs","repos_url":"https://api.github.com/users/hashicorp/repos","events_url":"https://api.github.com/users/hashicorp/events{/privacy}","received_events_url":"https://api.github.com/users/hashicorp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/hashicorp/terraform","description":"Terraform is a tool for building, changing, and combining infrastructure safely and efficiently.","fork":false,"url":"https://api.github.com/repos/hashicorp/terraform","forks_url":"https://api.github.com/repos/hashicorp/terraform/forks","keys_url":"https://api.github.com/repos/hashicorp/terraform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hashicorp/terraform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hashicorp/terraform/teams","hooks_url":"https://api.github.com/repos/hashicorp/terraform/hooks","issue_events_url":"https://api.github.com/repos/hashicorp/terraform/issues/events{/number}","events_url":"https://api.github.com/repos/hashicorp/terraform/events","assignees_url":"https://api.github.com/repos/hashicorp/terraform/assignees{/user}","branches_url":"https://api.github.com/repos/hashicorp/terraform/branches{/branch}","tags_url":"https://api.github.com/repos/hashicorp/terraform/tags","blobs_url":"https://api.github.com/repos/hashicorp/terraform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hashicorp/terraform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hashicorp/terraform/git/refs{/sha}","trees_url":"https://api.github.com/repos/hashicorp/terraform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hashicorp/terraform/statuses/{sha}","languages_url":"https://api.github.com/repos/hashicorp/terraform/languages","stargazers_url":"https://api.github.com/repos/hashicorp/terraform/stargazers","contributors_url":"https://api.github.com/repos/hashicorp/terraform/contributors","subscribers_url":"https://api.github.com/repos/hashicorp/terraform/subscribers","subscription_url":"https://api.github.com/repos/hashicorp/terraform/subscription","commits_url":"https://api.github.com/repos/hashicorp/terraform/commits{/sha}","git_commits_url":"https://api.github.com/repos/hashicorp/terraform/git/commits{/sha}","comments_url":"https://api.github.com/repos/hashicorp/terraform/comments{/number}","issue_comment_url":"https://api.github.com/repos/hashicorp/terraform/issues/comments{/number}","contents_url":"https://api.github.com/repos/hashicorp/terraform/contents/{+path}","compare_url":"https://api.github.com/repos/hashicorp/terraform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hashicorp/terraform/merges","archive_url":"https://api.github.com/repos/hashicorp/terraform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hashicorp/terraform/downloads","issues_url":"https://api.github.com/repos/hashicorp/terraform/issues{/number}","pulls_url":"https://api.github.com/repos/hashicorp/terraform/pulls{/number}","milestones_url":"https://api.github.com/repos/hashicorp/terraform/milestones{/number}","notifications_url":"https://api.github.com/repos/hashicorp/terraform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hashicorp/terraform/labels{/name}","releases_url":"https://api.github.com/repos/hashicorp/terraform/releases{/id}","deployments_url":"https://api.github.com/repos/hashicorp/terraform/deployments","created_at":"2014-03-13T22:25:48Z","updated_at":"2018-02-28T15:44:15Z","pushed_at":"2018-02-28T17:11:16Z","git_url":"git://github.com/hashicorp/terraform.git","ssh_url":"git@github.com:hashicorp/terraform.git","clone_url":"https://github.com/hashicorp/terraform.git","svn_url":"https://github.com/hashicorp/terraform","homepage":"https://www.terraform.io/","size":126514,"stargazers_count":11213,"watchers_count":11213,"language":"Go","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":3724,"mirror_url":null,"archived":false,"open_issues_count":1186,"license":{"key":"mpl-2.0","name":"Mozilla Public License 2.0","spdx_id":"MPL-2.0","url":"https://api.github.com/licenses/mpl-2.0"},"forks":3724,"open_issues":1186,"watchers":11213,"default_branch":"master"}},"base":{"label":"hashicorp:master","ref":"master","sha":"66ff8f8bed40293bd8a3ba827ca0b0838666c821","user":{"login":"hashicorp","id":761456,"avatar_url":"https://avatars2.githubusercontent.com/u/761456?v=4","gravatar_id":"","url":"https://api.github.com/users/hashicorp","html_url":"https://github.com/hashicorp","followers_url":"https://api.github.com/users/hashicorp/followers","following_url":"https://api.github.com/users/hashicorp/following{/other_user}","gists_url":"https://api.github.com/users/hashicorp/gists{/gist_id}","starred_url":"https://api.github.com/users/hashicorp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hashicorp/subscriptions","organizations_url":"https://api.github.com/users/hashicorp/orgs","repos_url":"https://api.github.com/users/hashicorp/repos","events_url":"https://api.github.com/users/hashicorp/events{/privacy}","received_events_url":"https://api.github.com/users/hashicorp/received_events","type":"Organization","site_admin":false},"repo":{"id":17728164,"name":"terraform","full_name":"hashicorp/terraform","owner":{"login":"hashicorp","id":761456,"avatar_url":"https://avatars2.githubusercontent.com/u/761456?v=4","gravatar_id":"","url":"https://api.github.com/users/hashicorp","html_url":"https://github.com/hashicorp","followers_url":"https://api.github.com/users/hashicorp/followers","following_url":"https://api.github.com/users/hashicorp/following{/other_user}","gists_url":"https://api.github.com/users/hashicorp/gists{/gist_id}","starred_url":"https://api.github.com/users/hashicorp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hashicorp/subscriptions","organizations_url":"https://api.github.com/users/hashicorp/orgs","repos_url":"https://api.github.com/users/hashicorp/repos","events_url":"https://api.github.com/users/hashicorp/events{/privacy}","received_events_url":"https://api.github.com/users/hashicorp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/hashicorp/terraform","description":"Terraform is a tool for building, changing, and combining infrastructure safely and efficiently.","fork":false,"url":"https://api.github.com/repos/hashicorp/terraform","forks_url":"https://api.github.com/repos/hashicorp/terraform/forks","keys_url":"https://api.github.com/repos/hashicorp/terraform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hashicorp/terraform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hashicorp/terraform/teams","hooks_url":"https://api.github.com/repos/hashicorp/terraform/hooks","issue_events_url":"https://api.github.com/repos/hashicorp/terraform/issues/events{/number}","events_url":"https://api.github.com/repos/hashicorp/terraform/events","assignees_url":"https://api.github.com/repos/hashicorp/terraform/assignees{/user}","branches_url":"https://api.github.com/repos/hashicorp/terraform/branches{/branch}","tags_url":"https://api.github.com/repos/hashicorp/terraform/tags","blobs_url":"https://api.github.com/repos/hashicorp/terraform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hashicorp/terraform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hashicorp/terraform/git/refs{/sha}","trees_url":"https://api.github.com/repos/hashicorp/terraform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hashicorp/terraform/statuses/{sha}","languages_url":"https://api.github.com/repos/hashicorp/terraform/languages","stargazers_url":"https://api.github.com/repos/hashicorp/terraform/stargazers","contributors_url":"https://api.github.com/repos/hashicorp/terraform/contributors","subscribers_url":"https://api.github.com/repos/hashicorp/terraform/subscribers","subscription_url":"https://api.github.com/repos/hashicorp/terraform/subscription","commits_url":"https://api.github.com/repos/hashicorp/terraform/commits{/sha}","git_commits_url":"https://api.github.com/repos/hashicorp/terraform/git/commits{/sha}","comments_url":"https://api.github.com/repos/hashicorp/terraform/comments{/number}","issue_comment_url":"https://api.github.com/repos/hashicorp/terraform/issues/comments{/number}","contents_url":"https://api.github.com/repos/hashicorp/terraform/contents/{+path}","compare_url":"https://api.github.com/repos/hashicorp/terraform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hashicorp/terraform/merges","archive_url":"https://api.github.com/repos/hashicorp/terraform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hashicorp/terraform/downloads","issues_url":"https://api.github.com/repos/hashicorp/terraform/issues{/number}","pulls_url":"https://api.github.com/repos/hashicorp/terraform/pulls{/number}","milestones_url":"https://api.github.com/repos/hashicorp/terraform/milestones{/number}","notifications_url":"https://api.github.com/repos/hashicorp/terraform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hashicorp/terraform/labels{/name}","releases_url":"https://api.github.com/repos/hashicorp/terraform/releases{/id}","deployments_url":"https://api.github.com/repos/hashicorp/terraform/deployments","created_at":"2014-03-13T22:25:48Z","updated_at":"2018-02-28T15:44:15Z","pushed_at":"2018-02-28T17:11:16Z","git_url":"git://github.com/hashicorp/terraform.git","ssh_url":"git@github.com:hashicorp/terraform.git","clone_url":"https://github.com/hashicorp/terraform.git","svn_url":"https://github.com/hashicorp/terraform","homepage":"https://www.terraform.io/","size":126514,"stargazers_count":11213,"watchers_count":11213,"language":"Go","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":3724,"mirror_url":null,"archived":false,"open_issues_count":1186,"license":{"key":"mpl-2.0","name":"Mozilla Public License 2.0","spdx_id":"MPL-2.0","url":"https://api.github.com/licenses/mpl-2.0"},"forks":3724,"open_issues":1186,"watchers":11213,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/hashicorp/terraform/pulls/17463"},"html":{"href":"https://github.com/hashicorp/terraform/pull/17463"},"issue":{"href":"https://api.github.com/repos/hashicorp/terraform/issues/17463"},"comments":{"href":"https://api.github.com/repos/hashicorp/terraform/issues/17463/comments"},"review_comments":{"href":"https://api.github.com/repos/hashicorp/terraform/pulls/17463/comments"},"review_comment":{"href":"https://api.github.com/repos/hashicorp/terraform/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/hashicorp/terraform/pulls/17463/commits"},"statuses":{"href":"https://api.github.com/repos/hashicorp/terraform/statuses/a229e83daee69c32516362403f07aaaedffb8d1b"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"radeksimko"}}