diff --git a/Taskfile.yaml b/Taskfile.yaml index 22faef1..ce7ad0f 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -255,7 +255,6 @@ tasks: python "{{ .FIX_PROVIDER_SPEC }}" "{{ .PROVIDER_SPEC_PATH }}" # language=bash - | - rm -Rf "{{ .DIR_GENPROVIDER }}" mkdir -p "{{ .DIR_GENPROVIDER }}" tfplugingen-framework generate data-sources \ --input "{{ .DIR_ARTIFACTS }}/provider-spec.json" \ diff --git a/build/generator-config.yml b/build/generator-config.yml index d6e3633..9024626 100644 --- a/build/generator-config.yml +++ b/build/generator-config.yml @@ -12,6 +12,9 @@ data_sources: read: path: /core/stocks method: GET + schema: + ignores: + - stocks.models.configurations core_firewall_protocols: read: @@ -27,6 +30,9 @@ data_sources: read: path: /core/images method: GET + schema: + ignores: + - images core_regions: read: @@ -47,11 +53,17 @@ data_sources: read: path: /core/environments method: GET + schema: + ignores: + - page_size core_volumes: read: path: /core/volumes method: GET + schema: + ignores: + - page_size core_volume_types: read: @@ -82,6 +94,10 @@ data_sources: read: path: /auth/roles method: GET + schema: + ignores: + - permissions + - policies auth_role: read: @@ -102,11 +118,19 @@ data_sources: read: path: /core/keypairs method: GET + schema: + ignores: + - page_size + - environment + - features core_keypairs: read: path: /core/keypairs method: GET + schema: + ignores: + - page_size core_virtual_machines: read: @@ -114,29 +138,54 @@ data_sources: method: GET schema: ignores: + - page_size - features + - flavor - flavor.features core_clusters: read: path: /core/clusters method: GET + schema: + ignores: + - labels + - features + - master_flavor.features + - master_flavor.labels + - worker_flavor.features + - worker_flavor.labels core_clusters_versions: read: path: /core/clusters/versions method: GET + core_cluster_node_groups: + read: + path: /core/clusters/{cluster_id}/node-groups + method: GET + + core_cluster_node_group: + read: + path: /core/clusters/{cluster_id}/node-groups/{node_group_id} + method: GET + + core_cluster_nodes: + read: + path: /core/clusters/{cluster_id}/nodes + method: GET + resources: core_virtual_machine_sg_rule: read: - path: /core/virtual-machines/{virtual_machine_id}/sg-rules + path: /core/virtual-machines/{vm_id}/sg-rules method: GET create: - path: /core/virtual-machines/{virtual_machine_id}/sg-rules + path: /core/virtual-machines/{vm_id}/sg-rules method: POST delete: - path: /core/virtual-machines/{virtual_machine_id}/sg-rules/{id} + path: /core/virtual-machines/{vm_id}/sg-rules/{sg_rule_id} method: DELETE core_environment: @@ -154,6 +203,10 @@ resources: create: path: /auth/roles method: POST + schema: + ignores: + - permissions + - policies core_keypair: read: @@ -165,6 +218,11 @@ resources: update: path: /core/keypair/{id} method: PUT + schema: + ignores: + - page_size + - environment + - features core_virtual_machine: read: @@ -176,11 +234,12 @@ resources: schema: ignores: - features + - flavor - flavor.features core_volume: read: - path: /core/volumes/{id} + path: /core/volumes/{volume_id} method: GET create: path: /core/volumes @@ -193,3 +252,36 @@ resources: create: path: /core/clusters method: POST + + core_cluster_node_group: + read: + path: /core/clusters/{cluster_id}/node-groups/{node_group_id} + method: GET + create: + path: /core/clusters/{cluster_id}/node-groups + method: POST + update: + path: /core/clusters/{cluster_id}/node-groups/{node_group_id} + method: PATCH + delete: + path: /core/clusters/{cluster_id}/node-groups/{node_group_id} + method: DELETE + + core_cluster_node: + read: + path: /core/clusters/{cluster_id}/nodes/{node_id} + method: GET + create: + path: /core/clusters/{cluster_id}/nodes + method: POST + delete: + path: /core/clusters/{cluster_id}/nodes/{node_id} + method: DELETE + schema: + ignores: + - labels + - features + - master_flavor.features + - master_flavor.labels + - worker_flavor.features + - worker_flavor.labels diff --git a/go.mod b/go.mod index b399468..7403a06 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/cloudflare/circl v1.6.3 // indirect github.com/fatih/color v1.18.0 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect @@ -55,16 +55,15 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty v1.14.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/mod v0.29.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect - golang.org/x/tools v0.38.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect + golang.org/x/tools v0.39.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 // indirect - google.golang.org/grpc v1.69.2 // indirect - google.golang.org/protobuf v1.36.2 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/go.sum b/go.sum index cba8ff1..bf0c215 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,6 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/NexGenCloud/hyperstack-sdk-go v1.50.0-alpha h1:CCes8ihAvBuQY1cQfwYcFgOgiewJJBCU1AqeNmcZ7Y0= -github.com/NexGenCloud/hyperstack-sdk-go v1.50.0-alpha/go.mod h1:BJezCpOGG8z1/k5IcWzlnFk1wrd9/CrdaxD0vMQkDeM= github.com/NexGenCloud/hyperstack-sdk-go v1.50.2-alpha h1:kSN8UQZnGiI8UscYPE9kxDb7RTBwly2z8WW2LbiBh08= github.com/NexGenCloud/hyperstack-sdk-go v1.50.2-alpha/go.mod h1:BJezCpOGG8z1/k5IcWzlnFk1wrd9/CrdaxD0vMQkDeM= github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= @@ -19,8 +17,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmms github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= -github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= -github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -40,8 +38,8 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+ github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= @@ -55,8 +53,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -172,34 +170,36 @@ github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8 github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= -go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= -go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= -go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -212,8 +212,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -221,32 +221,32 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 h1:3UsHvIr4Wc2aW4brOaSCmcxh9ksica6fHEr8P1XhkYw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= -google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= -google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= -google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/genprovider/datasource_core_cluster_node_group/core_cluster_node_group_data_source_gen.go b/internal/genprovider/datasource_core_cluster_node_group/core_cluster_node_group_data_source_gen.go new file mode 100644 index 0000000..b24c1ab --- /dev/null +++ b/internal/genprovider/datasource_core_cluster_node_group/core_cluster_node_group_data_source_gen.go @@ -0,0 +1,2449 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package datasource_core_cluster_node_group + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func CoreClusterNodeGroupDataSourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "cluster_id": schema.Int64Attribute{ + Required: true, + }, + "message": schema.StringAttribute{ + Computed: true, + }, + "node_group": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "count": schema.Int64Attribute{ + Computed: true, + }, + "created_at": schema.StringAttribute{ + Computed: true, + }, + "flavor": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "cpu": schema.Int64Attribute{ + Computed: true, + }, + "disk": schema.Int64Attribute{ + Computed: true, + }, + "ephemeral": schema.Int64Attribute{ + Computed: true, + }, + "features": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{}, + CustomType: FeaturesType{ + ObjectType: types.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "gpu": schema.StringAttribute{ + Computed: true, + }, + "gpu_count": schema.Int64Attribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "labels": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.Int64Attribute{ + Computed: true, + }, + "label": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: LabelsType{ + ObjectType: types.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + }, + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "ram": schema.NumberAttribute{ + Computed: true, + }, + }, + CustomType: FlavorType{ + ObjectType: types.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "max_count": schema.Int64Attribute{ + Computed: true, + }, + "min_count": schema.Int64Attribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "role": schema.StringAttribute{ + Computed: true, + }, + "updated_at": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: NodeGroupType{ + ObjectType: types.ObjectType{ + AttrTypes: NodeGroupValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "node_group_id": schema.Int64Attribute{ + Required: true, + }, + "status": schema.BoolAttribute{ + Computed: true, + }, + }, + } +} + +type CoreClusterNodeGroupModel struct { + ClusterId types.Int64 `tfsdk:"cluster_id"` + Message types.String `tfsdk:"message"` + NodeGroup NodeGroupValue `tfsdk:"node_group"` + NodeGroupId types.Int64 `tfsdk:"node_group_id"` + Status types.Bool `tfsdk:"status"` +} + +var _ basetypes.ObjectTypable = NodeGroupType{} + +type NodeGroupType struct { + basetypes.ObjectType +} + +func (t NodeGroupType) Equal(o attr.Type) bool { + other, ok := o.(NodeGroupType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t NodeGroupType) String() string { + return "NodeGroupType" +} + +func (t NodeGroupType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + countAttribute, ok := attributes["count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `count is missing from object`) + + return nil, diags + } + + countVal, ok := countAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`count expected to be basetypes.Int64Value, was: %T`, countAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return nil, diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + flavorAttribute, ok := attributes["flavor"] + + if !ok { + diags.AddError( + "Attribute Missing", + `flavor is missing from object`) + + return nil, diags + } + + flavorVal, ok := flavorAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`flavor expected to be basetypes.ObjectValue, was: %T`, flavorAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + maxCountAttribute, ok := attributes["max_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `max_count is missing from object`) + + return nil, diags + } + + maxCountVal, ok := maxCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`max_count expected to be basetypes.Int64Value, was: %T`, maxCountAttribute)) + } + + minCountAttribute, ok := attributes["min_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `min_count is missing from object`) + + return nil, diags + } + + minCountVal, ok := minCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`min_count expected to be basetypes.Int64Value, was: %T`, minCountAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return nil, diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return nil, diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return NodeGroupValue{ + Count: countVal, + CreatedAt: createdAtVal, + Flavor: flavorVal, + Id: idVal, + MaxCount: maxCountVal, + MinCount: minCountVal, + Name: nameVal, + Role: roleVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodeGroupValueNull() NodeGroupValue { + return NodeGroupValue{ + state: attr.ValueStateNull, + } +} + +func NewNodeGroupValueUnknown() NodeGroupValue { + return NodeGroupValue{ + state: attr.ValueStateUnknown, + } +} + +func NewNodeGroupValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (NodeGroupValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing NodeGroupValue Attribute Value", + "While creating a NodeGroupValue value, a missing attribute value was detected. "+ + "A NodeGroupValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodeGroupValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid NodeGroupValue Attribute Type", + "While creating a NodeGroupValue value, an invalid attribute value was detected. "+ + "A NodeGroupValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodeGroupValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("NodeGroupValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra NodeGroupValue Attribute Value", + "While creating a NodeGroupValue value, an extra attribute value was detected. "+ + "A NodeGroupValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra NodeGroupValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewNodeGroupValueUnknown(), diags + } + + countAttribute, ok := attributes["count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `count is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + countVal, ok := countAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`count expected to be basetypes.Int64Value, was: %T`, countAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + flavorAttribute, ok := attributes["flavor"] + + if !ok { + diags.AddError( + "Attribute Missing", + `flavor is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + flavorVal, ok := flavorAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`flavor expected to be basetypes.ObjectValue, was: %T`, flavorAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + maxCountAttribute, ok := attributes["max_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `max_count is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + maxCountVal, ok := maxCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`max_count expected to be basetypes.Int64Value, was: %T`, maxCountAttribute)) + } + + minCountAttribute, ok := attributes["min_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `min_count is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + minCountVal, ok := minCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`min_count expected to be basetypes.Int64Value, was: %T`, minCountAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return NewNodeGroupValueUnknown(), diags + } + + return NodeGroupValue{ + Count: countVal, + CreatedAt: createdAtVal, + Flavor: flavorVal, + Id: idVal, + MaxCount: maxCountVal, + MinCount: minCountVal, + Name: nameVal, + Role: roleVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodeGroupValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) NodeGroupValue { + object, diags := NewNodeGroupValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewNodeGroupValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t NodeGroupType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewNodeGroupValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewNodeGroupValueUnknown(), nil + } + + if in.IsNull() { + return NewNodeGroupValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewNodeGroupValueMust(NodeGroupValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t NodeGroupType) ValueType(ctx context.Context) attr.Value { + return NodeGroupValue{} +} + +var _ basetypes.ObjectValuable = NodeGroupValue{} + +type NodeGroupValue struct { + Count basetypes.Int64Value `tfsdk:"count"` + CreatedAt basetypes.StringValue `tfsdk:"created_at"` + Flavor basetypes.ObjectValue `tfsdk:"flavor"` + Id basetypes.Int64Value `tfsdk:"id"` + MaxCount basetypes.Int64Value `tfsdk:"max_count"` + MinCount basetypes.Int64Value `tfsdk:"min_count"` + Name basetypes.StringValue `tfsdk:"name"` + Role basetypes.StringValue `tfsdk:"role"` + UpdatedAt basetypes.StringValue `tfsdk:"updated_at"` + state attr.ValueState +} + +func (v NodeGroupValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 9) + + var val tftypes.Value + var err error + + attrTypes["count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["created_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["flavor"] = basetypes.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["max_count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["min_count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["role"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["updated_at"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 9) + + val, err = v.Count.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["count"] = val + + val, err = v.CreatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["created_at"] = val + + val, err = v.Flavor.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["flavor"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.MaxCount.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["max_count"] = val + + val, err = v.MinCount.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["min_count"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Role.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["role"] = val + + val, err = v.UpdatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["updated_at"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v NodeGroupValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v NodeGroupValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v NodeGroupValue) String() string { + return "NodeGroupValue" +} + +func (v NodeGroupValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + var flavor basetypes.ObjectValue + + if v.Flavor.IsNull() { + flavor = types.ObjectNull( + FlavorValue{}.AttributeTypes(ctx), + ) + } + + if v.Flavor.IsUnknown() { + flavor = types.ObjectUnknown( + FlavorValue{}.AttributeTypes(ctx), + ) + } + + if !v.Flavor.IsNull() && !v.Flavor.IsUnknown() { + flavor = types.ObjectValueMust( + FlavorValue{}.AttributeTypes(ctx), + v.Flavor.Attributes(), + ) + } + + attributeTypes := map[string]attr.Type{ + "count": basetypes.Int64Type{}, + "created_at": basetypes.StringType{}, + "flavor": basetypes.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }, + "id": basetypes.Int64Type{}, + "max_count": basetypes.Int64Type{}, + "min_count": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "role": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "count": v.Count, + "created_at": v.CreatedAt, + "flavor": flavor, + "id": v.Id, + "max_count": v.MaxCount, + "min_count": v.MinCount, + "name": v.Name, + "role": v.Role, + "updated_at": v.UpdatedAt, + }) + + return objVal, diags +} + +func (v NodeGroupValue) Equal(o attr.Value) bool { + other, ok := o.(NodeGroupValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Count.Equal(other.Count) { + return false + } + + if !v.CreatedAt.Equal(other.CreatedAt) { + return false + } + + if !v.Flavor.Equal(other.Flavor) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.MaxCount.Equal(other.MaxCount) { + return false + } + + if !v.MinCount.Equal(other.MinCount) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Role.Equal(other.Role) { + return false + } + + if !v.UpdatedAt.Equal(other.UpdatedAt) { + return false + } + + return true +} + +func (v NodeGroupValue) Type(ctx context.Context) attr.Type { + return NodeGroupType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v NodeGroupValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "count": basetypes.Int64Type{}, + "created_at": basetypes.StringType{}, + "flavor": basetypes.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }, + "id": basetypes.Int64Type{}, + "max_count": basetypes.Int64Type{}, + "min_count": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "role": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = FlavorType{} + +type FlavorType struct { + basetypes.ObjectType +} + +func (t FlavorType) Equal(o attr.Type) bool { + other, ok := o.(FlavorType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t FlavorType) String() string { + return "FlavorType" +} + +func (t FlavorType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cpuAttribute, ok := attributes["cpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cpu is missing from object`) + + return nil, diags + } + + cpuVal, ok := cpuAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cpu expected to be basetypes.Int64Value, was: %T`, cpuAttribute)) + } + + diskAttribute, ok := attributes["disk"] + + if !ok { + diags.AddError( + "Attribute Missing", + `disk is missing from object`) + + return nil, diags + } + + diskVal, ok := diskAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`disk expected to be basetypes.Int64Value, was: %T`, diskAttribute)) + } + + ephemeralAttribute, ok := attributes["ephemeral"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ephemeral is missing from object`) + + return nil, diags + } + + ephemeralVal, ok := ephemeralAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ephemeral expected to be basetypes.Int64Value, was: %T`, ephemeralAttribute)) + } + + featuresAttribute, ok := attributes["features"] + + if !ok { + diags.AddError( + "Attribute Missing", + `features is missing from object`) + + return nil, diags + } + + featuresVal, ok := featuresAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`features expected to be basetypes.ObjectValue, was: %T`, featuresAttribute)) + } + + gpuAttribute, ok := attributes["gpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu is missing from object`) + + return nil, diags + } + + gpuVal, ok := gpuAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu expected to be basetypes.StringValue, was: %T`, gpuAttribute)) + } + + gpuCountAttribute, ok := attributes["gpu_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu_count is missing from object`) + + return nil, diags + } + + gpuCountVal, ok := gpuCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu_count expected to be basetypes.Int64Value, was: %T`, gpuCountAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelsAttribute, ok := attributes["labels"] + + if !ok { + diags.AddError( + "Attribute Missing", + `labels is missing from object`) + + return nil, diags + } + + labelsVal, ok := labelsAttribute.(basetypes.ListValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`labels expected to be basetypes.ListValue, was: %T`, labelsAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + ramAttribute, ok := attributes["ram"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ram is missing from object`) + + return nil, diags + } + + ramVal, ok := ramAttribute.(basetypes.NumberValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ram expected to be basetypes.NumberValue, was: %T`, ramAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return FlavorValue{ + Cpu: cpuVal, + Disk: diskVal, + Ephemeral: ephemeralVal, + Features: featuresVal, + Gpu: gpuVal, + GpuCount: gpuCountVal, + Id: idVal, + Labels: labelsVal, + Name: nameVal, + Ram: ramVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewFlavorValueNull() FlavorValue { + return FlavorValue{ + state: attr.ValueStateNull, + } +} + +func NewFlavorValueUnknown() FlavorValue { + return FlavorValue{ + state: attr.ValueStateUnknown, + } +} + +func NewFlavorValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (FlavorValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing FlavorValue Attribute Value", + "While creating a FlavorValue value, a missing attribute value was detected. "+ + "A FlavorValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FlavorValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid FlavorValue Attribute Type", + "While creating a FlavorValue value, an invalid attribute value was detected. "+ + "A FlavorValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FlavorValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("FlavorValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra FlavorValue Attribute Value", + "While creating a FlavorValue value, an extra attribute value was detected. "+ + "A FlavorValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra FlavorValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewFlavorValueUnknown(), diags + } + + cpuAttribute, ok := attributes["cpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cpu is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + cpuVal, ok := cpuAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cpu expected to be basetypes.Int64Value, was: %T`, cpuAttribute)) + } + + diskAttribute, ok := attributes["disk"] + + if !ok { + diags.AddError( + "Attribute Missing", + `disk is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + diskVal, ok := diskAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`disk expected to be basetypes.Int64Value, was: %T`, diskAttribute)) + } + + ephemeralAttribute, ok := attributes["ephemeral"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ephemeral is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + ephemeralVal, ok := ephemeralAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ephemeral expected to be basetypes.Int64Value, was: %T`, ephemeralAttribute)) + } + + featuresAttribute, ok := attributes["features"] + + if !ok { + diags.AddError( + "Attribute Missing", + `features is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + featuresVal, ok := featuresAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`features expected to be basetypes.ObjectValue, was: %T`, featuresAttribute)) + } + + gpuAttribute, ok := attributes["gpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + gpuVal, ok := gpuAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu expected to be basetypes.StringValue, was: %T`, gpuAttribute)) + } + + gpuCountAttribute, ok := attributes["gpu_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu_count is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + gpuCountVal, ok := gpuCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu_count expected to be basetypes.Int64Value, was: %T`, gpuCountAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelsAttribute, ok := attributes["labels"] + + if !ok { + diags.AddError( + "Attribute Missing", + `labels is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + labelsVal, ok := labelsAttribute.(basetypes.ListValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`labels expected to be basetypes.ListValue, was: %T`, labelsAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + ramAttribute, ok := attributes["ram"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ram is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + ramVal, ok := ramAttribute.(basetypes.NumberValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ram expected to be basetypes.NumberValue, was: %T`, ramAttribute)) + } + + if diags.HasError() { + return NewFlavorValueUnknown(), diags + } + + return FlavorValue{ + Cpu: cpuVal, + Disk: diskVal, + Ephemeral: ephemeralVal, + Features: featuresVal, + Gpu: gpuVal, + GpuCount: gpuCountVal, + Id: idVal, + Labels: labelsVal, + Name: nameVal, + Ram: ramVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewFlavorValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) FlavorValue { + object, diags := NewFlavorValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewFlavorValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t FlavorType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewFlavorValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewFlavorValueUnknown(), nil + } + + if in.IsNull() { + return NewFlavorValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewFlavorValueMust(FlavorValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t FlavorType) ValueType(ctx context.Context) attr.Value { + return FlavorValue{} +} + +var _ basetypes.ObjectValuable = FlavorValue{} + +type FlavorValue struct { + Cpu basetypes.Int64Value `tfsdk:"cpu"` + Disk basetypes.Int64Value `tfsdk:"disk"` + Ephemeral basetypes.Int64Value `tfsdk:"ephemeral"` + Features basetypes.ObjectValue `tfsdk:"features"` + Gpu basetypes.StringValue `tfsdk:"gpu"` + GpuCount basetypes.Int64Value `tfsdk:"gpu_count"` + Id basetypes.Int64Value `tfsdk:"id"` + Labels basetypes.ListValue `tfsdk:"labels"` + Name basetypes.StringValue `tfsdk:"name"` + Ram basetypes.NumberValue `tfsdk:"ram"` + state attr.ValueState +} + +func (v FlavorValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 10) + + var val tftypes.Value + var err error + + attrTypes["cpu"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["disk"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["ephemeral"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["features"] = basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["gpu"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["gpu_count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["labels"] = basetypes.ListType{ + ElemType: LabelsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["ram"] = basetypes.NumberType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 10) + + val, err = v.Cpu.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cpu"] = val + + val, err = v.Disk.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["disk"] = val + + val, err = v.Ephemeral.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ephemeral"] = val + + val, err = v.Features.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["features"] = val + + val, err = v.Gpu.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["gpu"] = val + + val, err = v.GpuCount.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["gpu_count"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Labels.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["labels"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Ram.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ram"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v FlavorValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v FlavorValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v FlavorValue) String() string { + return "FlavorValue" +} + +func (v FlavorValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + var features basetypes.ObjectValue + + if v.Features.IsNull() { + features = types.ObjectNull( + FeaturesValue{}.AttributeTypes(ctx), + ) + } + + if v.Features.IsUnknown() { + features = types.ObjectUnknown( + FeaturesValue{}.AttributeTypes(ctx), + ) + } + + if !v.Features.IsNull() && !v.Features.IsUnknown() { + features = types.ObjectValueMust( + FeaturesValue{}.AttributeTypes(ctx), + v.Features.Attributes(), + ) + } + + labels := types.ListValueMust( + LabelsType{ + basetypes.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + v.Labels.Elements(), + ) + + if v.Labels.IsNull() { + labels = types.ListNull( + LabelsType{ + basetypes.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + ) + } + + if v.Labels.IsUnknown() { + labels = types.ListUnknown( + LabelsType{ + basetypes.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + ) + } + + attributeTypes := map[string]attr.Type{ + "cpu": basetypes.Int64Type{}, + "disk": basetypes.Int64Type{}, + "ephemeral": basetypes.Int64Type{}, + "features": basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + "gpu": basetypes.StringType{}, + "gpu_count": basetypes.Int64Type{}, + "id": basetypes.Int64Type{}, + "labels": basetypes.ListType{ + ElemType: LabelsValue{}.Type(ctx), + }, + "name": basetypes.StringType{}, + "ram": basetypes.NumberType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "cpu": v.Cpu, + "disk": v.Disk, + "ephemeral": v.Ephemeral, + "features": features, + "gpu": v.Gpu, + "gpu_count": v.GpuCount, + "id": v.Id, + "labels": labels, + "name": v.Name, + "ram": v.Ram, + }) + + return objVal, diags +} + +func (v FlavorValue) Equal(o attr.Value) bool { + other, ok := o.(FlavorValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cpu.Equal(other.Cpu) { + return false + } + + if !v.Disk.Equal(other.Disk) { + return false + } + + if !v.Ephemeral.Equal(other.Ephemeral) { + return false + } + + if !v.Features.Equal(other.Features) { + return false + } + + if !v.Gpu.Equal(other.Gpu) { + return false + } + + if !v.GpuCount.Equal(other.GpuCount) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Labels.Equal(other.Labels) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Ram.Equal(other.Ram) { + return false + } + + return true +} + +func (v FlavorValue) Type(ctx context.Context) attr.Type { + return FlavorType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v FlavorValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cpu": basetypes.Int64Type{}, + "disk": basetypes.Int64Type{}, + "ephemeral": basetypes.Int64Type{}, + "features": basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + "gpu": basetypes.StringType{}, + "gpu_count": basetypes.Int64Type{}, + "id": basetypes.Int64Type{}, + "labels": basetypes.ListType{ + ElemType: LabelsValue{}.Type(ctx), + }, + "name": basetypes.StringType{}, + "ram": basetypes.NumberType{}, + } +} + +var _ basetypes.ObjectTypable = FeaturesType{} + +type FeaturesType struct { + basetypes.ObjectType +} + +func (t FeaturesType) Equal(o attr.Type) bool { + other, ok := o.(FeaturesType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t FeaturesType) String() string { + return "FeaturesType" +} + +func (t FeaturesType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + if diags.HasError() { + return nil, diags + } + + return FeaturesValue{ + state: attr.ValueStateKnown, + }, diags +} + +func NewFeaturesValueNull() FeaturesValue { + return FeaturesValue{ + state: attr.ValueStateNull, + } +} + +func NewFeaturesValueUnknown() FeaturesValue { + return FeaturesValue{ + state: attr.ValueStateUnknown, + } +} + +func NewFeaturesValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (FeaturesValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing FeaturesValue Attribute Value", + "While creating a FeaturesValue value, a missing attribute value was detected. "+ + "A FeaturesValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid FeaturesValue Attribute Type", + "While creating a FeaturesValue value, an invalid attribute value was detected. "+ + "A FeaturesValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra FeaturesValue Attribute Value", + "While creating a FeaturesValue value, an extra attribute value was detected. "+ + "A FeaturesValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra FeaturesValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewFeaturesValueUnknown(), diags + } + + if diags.HasError() { + return NewFeaturesValueUnknown(), diags + } + + return FeaturesValue{ + state: attr.ValueStateKnown, + }, diags +} + +func NewFeaturesValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) FeaturesValue { + object, diags := NewFeaturesValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewFeaturesValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t FeaturesType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewFeaturesValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewFeaturesValueUnknown(), nil + } + + if in.IsNull() { + return NewFeaturesValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewFeaturesValueMust(FeaturesValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t FeaturesType) ValueType(ctx context.Context) attr.Value { + return FeaturesValue{} +} + +var _ basetypes.ObjectValuable = FeaturesValue{} + +type FeaturesValue struct { + state attr.ValueState +} + +func (v FeaturesValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 0) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 0) + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v FeaturesValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v FeaturesValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v FeaturesValue) String() string { + return "FeaturesValue" +} + +func (v FeaturesValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{} + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{}) + + return objVal, diags +} + +func (v FeaturesValue) Equal(o attr.Value) bool { + other, ok := o.(FeaturesValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + return true +} + +func (v FeaturesValue) Type(ctx context.Context) attr.Type { + return FeaturesType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v FeaturesValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{} +} + +var _ basetypes.ObjectTypable = LabelsType{} + +type LabelsType struct { + basetypes.ObjectType +} + +func (t LabelsType) Equal(o attr.Type) bool { + other, ok := o.(LabelsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t LabelsType) String() string { + return "LabelsType" +} + +func (t LabelsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelAttribute, ok := attributes["label"] + + if !ok { + diags.AddError( + "Attribute Missing", + `label is missing from object`) + + return nil, diags + } + + labelVal, ok := labelAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`label expected to be basetypes.StringValue, was: %T`, labelAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return LabelsValue{ + Id: idVal, + Label: labelVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewLabelsValueNull() LabelsValue { + return LabelsValue{ + state: attr.ValueStateNull, + } +} + +func NewLabelsValueUnknown() LabelsValue { + return LabelsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewLabelsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (LabelsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing LabelsValue Attribute Value", + "While creating a LabelsValue value, a missing attribute value was detected. "+ + "A LabelsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("LabelsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid LabelsValue Attribute Type", + "While creating a LabelsValue value, an invalid attribute value was detected. "+ + "A LabelsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("LabelsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("LabelsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra LabelsValue Attribute Value", + "While creating a LabelsValue value, an extra attribute value was detected. "+ + "A LabelsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra LabelsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewLabelsValueUnknown(), diags + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewLabelsValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelAttribute, ok := attributes["label"] + + if !ok { + diags.AddError( + "Attribute Missing", + `label is missing from object`) + + return NewLabelsValueUnknown(), diags + } + + labelVal, ok := labelAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`label expected to be basetypes.StringValue, was: %T`, labelAttribute)) + } + + if diags.HasError() { + return NewLabelsValueUnknown(), diags + } + + return LabelsValue{ + Id: idVal, + Label: labelVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewLabelsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) LabelsValue { + object, diags := NewLabelsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewLabelsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t LabelsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewLabelsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewLabelsValueUnknown(), nil + } + + if in.IsNull() { + return NewLabelsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewLabelsValueMust(LabelsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t LabelsType) ValueType(ctx context.Context) attr.Value { + return LabelsValue{} +} + +var _ basetypes.ObjectValuable = LabelsValue{} + +type LabelsValue struct { + Id basetypes.Int64Value `tfsdk:"id"` + Label basetypes.StringValue `tfsdk:"label"` + state attr.ValueState +} + +func (v LabelsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 2) + + var val tftypes.Value + var err error + + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["label"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 2) + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Label.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["label"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v LabelsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v LabelsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v LabelsValue) String() string { + return "LabelsValue" +} + +func (v LabelsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{ + "id": basetypes.Int64Type{}, + "label": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "id": v.Id, + "label": v.Label, + }) + + return objVal, diags +} + +func (v LabelsValue) Equal(o attr.Value) bool { + other, ok := o.(LabelsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Label.Equal(other.Label) { + return false + } + + return true +} + +func (v LabelsValue) Type(ctx context.Context) attr.Type { + return LabelsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v LabelsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "id": basetypes.Int64Type{}, + "label": basetypes.StringType{}, + } +} diff --git a/internal/genprovider/datasource_core_cluster_node_groups/core_cluster_node_groups_data_source_gen.go b/internal/genprovider/datasource_core_cluster_node_groups/core_cluster_node_groups_data_source_gen.go new file mode 100644 index 0000000..927caac --- /dev/null +++ b/internal/genprovider/datasource_core_cluster_node_groups/core_cluster_node_groups_data_source_gen.go @@ -0,0 +1,2447 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package datasource_core_cluster_node_groups + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func CoreClusterNodeGroupsDataSourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "cluster_id": schema.Int64Attribute{ + Required: true, + }, + "message": schema.StringAttribute{ + Computed: true, + }, + "node_groups": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "count": schema.Int64Attribute{ + Computed: true, + }, + "created_at": schema.StringAttribute{ + Computed: true, + }, + "flavor": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "cpu": schema.Int64Attribute{ + Computed: true, + }, + "disk": schema.Int64Attribute{ + Computed: true, + }, + "ephemeral": schema.Int64Attribute{ + Computed: true, + }, + "features": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{}, + CustomType: FeaturesType{ + ObjectType: types.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "gpu": schema.StringAttribute{ + Computed: true, + }, + "gpu_count": schema.Int64Attribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "labels": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.Int64Attribute{ + Computed: true, + }, + "label": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: LabelsType{ + ObjectType: types.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + }, + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "ram": schema.NumberAttribute{ + Computed: true, + }, + }, + CustomType: FlavorType{ + ObjectType: types.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "max_count": schema.Int64Attribute{ + Computed: true, + }, + "min_count": schema.Int64Attribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "role": schema.StringAttribute{ + Computed: true, + }, + "updated_at": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: NodeGroupsType{ + ObjectType: types.ObjectType{ + AttrTypes: NodeGroupsValue{}.AttributeTypes(ctx), + }, + }, + }, + Computed: true, + }, + "status": schema.BoolAttribute{ + Computed: true, + }, + }, + } +} + +type CoreClusterNodeGroupsModel struct { + ClusterId types.Int64 `tfsdk:"cluster_id"` + Message types.String `tfsdk:"message"` + NodeGroups types.List `tfsdk:"node_groups"` + Status types.Bool `tfsdk:"status"` +} + +var _ basetypes.ObjectTypable = NodeGroupsType{} + +type NodeGroupsType struct { + basetypes.ObjectType +} + +func (t NodeGroupsType) Equal(o attr.Type) bool { + other, ok := o.(NodeGroupsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t NodeGroupsType) String() string { + return "NodeGroupsType" +} + +func (t NodeGroupsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + countAttribute, ok := attributes["count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `count is missing from object`) + + return nil, diags + } + + countVal, ok := countAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`count expected to be basetypes.Int64Value, was: %T`, countAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return nil, diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + flavorAttribute, ok := attributes["flavor"] + + if !ok { + diags.AddError( + "Attribute Missing", + `flavor is missing from object`) + + return nil, diags + } + + flavorVal, ok := flavorAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`flavor expected to be basetypes.ObjectValue, was: %T`, flavorAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + maxCountAttribute, ok := attributes["max_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `max_count is missing from object`) + + return nil, diags + } + + maxCountVal, ok := maxCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`max_count expected to be basetypes.Int64Value, was: %T`, maxCountAttribute)) + } + + minCountAttribute, ok := attributes["min_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `min_count is missing from object`) + + return nil, diags + } + + minCountVal, ok := minCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`min_count expected to be basetypes.Int64Value, was: %T`, minCountAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return nil, diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return nil, diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return NodeGroupsValue{ + Count: countVal, + CreatedAt: createdAtVal, + Flavor: flavorVal, + Id: idVal, + MaxCount: maxCountVal, + MinCount: minCountVal, + Name: nameVal, + Role: roleVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodeGroupsValueNull() NodeGroupsValue { + return NodeGroupsValue{ + state: attr.ValueStateNull, + } +} + +func NewNodeGroupsValueUnknown() NodeGroupsValue { + return NodeGroupsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewNodeGroupsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (NodeGroupsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing NodeGroupsValue Attribute Value", + "While creating a NodeGroupsValue value, a missing attribute value was detected. "+ + "A NodeGroupsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodeGroupsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid NodeGroupsValue Attribute Type", + "While creating a NodeGroupsValue value, an invalid attribute value was detected. "+ + "A NodeGroupsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodeGroupsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("NodeGroupsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra NodeGroupsValue Attribute Value", + "While creating a NodeGroupsValue value, an extra attribute value was detected. "+ + "A NodeGroupsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra NodeGroupsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewNodeGroupsValueUnknown(), diags + } + + countAttribute, ok := attributes["count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `count is missing from object`) + + return NewNodeGroupsValueUnknown(), diags + } + + countVal, ok := countAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`count expected to be basetypes.Int64Value, was: %T`, countAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return NewNodeGroupsValueUnknown(), diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + flavorAttribute, ok := attributes["flavor"] + + if !ok { + diags.AddError( + "Attribute Missing", + `flavor is missing from object`) + + return NewNodeGroupsValueUnknown(), diags + } + + flavorVal, ok := flavorAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`flavor expected to be basetypes.ObjectValue, was: %T`, flavorAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewNodeGroupsValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + maxCountAttribute, ok := attributes["max_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `max_count is missing from object`) + + return NewNodeGroupsValueUnknown(), diags + } + + maxCountVal, ok := maxCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`max_count expected to be basetypes.Int64Value, was: %T`, maxCountAttribute)) + } + + minCountAttribute, ok := attributes["min_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `min_count is missing from object`) + + return NewNodeGroupsValueUnknown(), diags + } + + minCountVal, ok := minCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`min_count expected to be basetypes.Int64Value, was: %T`, minCountAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewNodeGroupsValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return NewNodeGroupsValueUnknown(), diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return NewNodeGroupsValueUnknown(), diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return NewNodeGroupsValueUnknown(), diags + } + + return NodeGroupsValue{ + Count: countVal, + CreatedAt: createdAtVal, + Flavor: flavorVal, + Id: idVal, + MaxCount: maxCountVal, + MinCount: minCountVal, + Name: nameVal, + Role: roleVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodeGroupsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) NodeGroupsValue { + object, diags := NewNodeGroupsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewNodeGroupsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t NodeGroupsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewNodeGroupsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewNodeGroupsValueUnknown(), nil + } + + if in.IsNull() { + return NewNodeGroupsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewNodeGroupsValueMust(NodeGroupsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t NodeGroupsType) ValueType(ctx context.Context) attr.Value { + return NodeGroupsValue{} +} + +var _ basetypes.ObjectValuable = NodeGroupsValue{} + +type NodeGroupsValue struct { + Count basetypes.Int64Value `tfsdk:"count"` + CreatedAt basetypes.StringValue `tfsdk:"created_at"` + Flavor basetypes.ObjectValue `tfsdk:"flavor"` + Id basetypes.Int64Value `tfsdk:"id"` + MaxCount basetypes.Int64Value `tfsdk:"max_count"` + MinCount basetypes.Int64Value `tfsdk:"min_count"` + Name basetypes.StringValue `tfsdk:"name"` + Role basetypes.StringValue `tfsdk:"role"` + UpdatedAt basetypes.StringValue `tfsdk:"updated_at"` + state attr.ValueState +} + +func (v NodeGroupsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 9) + + var val tftypes.Value + var err error + + attrTypes["count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["created_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["flavor"] = basetypes.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["max_count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["min_count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["role"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["updated_at"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 9) + + val, err = v.Count.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["count"] = val + + val, err = v.CreatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["created_at"] = val + + val, err = v.Flavor.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["flavor"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.MaxCount.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["max_count"] = val + + val, err = v.MinCount.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["min_count"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Role.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["role"] = val + + val, err = v.UpdatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["updated_at"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v NodeGroupsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v NodeGroupsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v NodeGroupsValue) String() string { + return "NodeGroupsValue" +} + +func (v NodeGroupsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + var flavor basetypes.ObjectValue + + if v.Flavor.IsNull() { + flavor = types.ObjectNull( + FlavorValue{}.AttributeTypes(ctx), + ) + } + + if v.Flavor.IsUnknown() { + flavor = types.ObjectUnknown( + FlavorValue{}.AttributeTypes(ctx), + ) + } + + if !v.Flavor.IsNull() && !v.Flavor.IsUnknown() { + flavor = types.ObjectValueMust( + FlavorValue{}.AttributeTypes(ctx), + v.Flavor.Attributes(), + ) + } + + attributeTypes := map[string]attr.Type{ + "count": basetypes.Int64Type{}, + "created_at": basetypes.StringType{}, + "flavor": basetypes.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }, + "id": basetypes.Int64Type{}, + "max_count": basetypes.Int64Type{}, + "min_count": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "role": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "count": v.Count, + "created_at": v.CreatedAt, + "flavor": flavor, + "id": v.Id, + "max_count": v.MaxCount, + "min_count": v.MinCount, + "name": v.Name, + "role": v.Role, + "updated_at": v.UpdatedAt, + }) + + return objVal, diags +} + +func (v NodeGroupsValue) Equal(o attr.Value) bool { + other, ok := o.(NodeGroupsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Count.Equal(other.Count) { + return false + } + + if !v.CreatedAt.Equal(other.CreatedAt) { + return false + } + + if !v.Flavor.Equal(other.Flavor) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.MaxCount.Equal(other.MaxCount) { + return false + } + + if !v.MinCount.Equal(other.MinCount) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Role.Equal(other.Role) { + return false + } + + if !v.UpdatedAt.Equal(other.UpdatedAt) { + return false + } + + return true +} + +func (v NodeGroupsValue) Type(ctx context.Context) attr.Type { + return NodeGroupsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v NodeGroupsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "count": basetypes.Int64Type{}, + "created_at": basetypes.StringType{}, + "flavor": basetypes.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }, + "id": basetypes.Int64Type{}, + "max_count": basetypes.Int64Type{}, + "min_count": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "role": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = FlavorType{} + +type FlavorType struct { + basetypes.ObjectType +} + +func (t FlavorType) Equal(o attr.Type) bool { + other, ok := o.(FlavorType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t FlavorType) String() string { + return "FlavorType" +} + +func (t FlavorType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cpuAttribute, ok := attributes["cpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cpu is missing from object`) + + return nil, diags + } + + cpuVal, ok := cpuAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cpu expected to be basetypes.Int64Value, was: %T`, cpuAttribute)) + } + + diskAttribute, ok := attributes["disk"] + + if !ok { + diags.AddError( + "Attribute Missing", + `disk is missing from object`) + + return nil, diags + } + + diskVal, ok := diskAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`disk expected to be basetypes.Int64Value, was: %T`, diskAttribute)) + } + + ephemeralAttribute, ok := attributes["ephemeral"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ephemeral is missing from object`) + + return nil, diags + } + + ephemeralVal, ok := ephemeralAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ephemeral expected to be basetypes.Int64Value, was: %T`, ephemeralAttribute)) + } + + featuresAttribute, ok := attributes["features"] + + if !ok { + diags.AddError( + "Attribute Missing", + `features is missing from object`) + + return nil, diags + } + + featuresVal, ok := featuresAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`features expected to be basetypes.ObjectValue, was: %T`, featuresAttribute)) + } + + gpuAttribute, ok := attributes["gpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu is missing from object`) + + return nil, diags + } + + gpuVal, ok := gpuAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu expected to be basetypes.StringValue, was: %T`, gpuAttribute)) + } + + gpuCountAttribute, ok := attributes["gpu_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu_count is missing from object`) + + return nil, diags + } + + gpuCountVal, ok := gpuCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu_count expected to be basetypes.Int64Value, was: %T`, gpuCountAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelsAttribute, ok := attributes["labels"] + + if !ok { + diags.AddError( + "Attribute Missing", + `labels is missing from object`) + + return nil, diags + } + + labelsVal, ok := labelsAttribute.(basetypes.ListValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`labels expected to be basetypes.ListValue, was: %T`, labelsAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + ramAttribute, ok := attributes["ram"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ram is missing from object`) + + return nil, diags + } + + ramVal, ok := ramAttribute.(basetypes.NumberValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ram expected to be basetypes.NumberValue, was: %T`, ramAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return FlavorValue{ + Cpu: cpuVal, + Disk: diskVal, + Ephemeral: ephemeralVal, + Features: featuresVal, + Gpu: gpuVal, + GpuCount: gpuCountVal, + Id: idVal, + Labels: labelsVal, + Name: nameVal, + Ram: ramVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewFlavorValueNull() FlavorValue { + return FlavorValue{ + state: attr.ValueStateNull, + } +} + +func NewFlavorValueUnknown() FlavorValue { + return FlavorValue{ + state: attr.ValueStateUnknown, + } +} + +func NewFlavorValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (FlavorValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing FlavorValue Attribute Value", + "While creating a FlavorValue value, a missing attribute value was detected. "+ + "A FlavorValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FlavorValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid FlavorValue Attribute Type", + "While creating a FlavorValue value, an invalid attribute value was detected. "+ + "A FlavorValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FlavorValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("FlavorValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra FlavorValue Attribute Value", + "While creating a FlavorValue value, an extra attribute value was detected. "+ + "A FlavorValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra FlavorValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewFlavorValueUnknown(), diags + } + + cpuAttribute, ok := attributes["cpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cpu is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + cpuVal, ok := cpuAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cpu expected to be basetypes.Int64Value, was: %T`, cpuAttribute)) + } + + diskAttribute, ok := attributes["disk"] + + if !ok { + diags.AddError( + "Attribute Missing", + `disk is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + diskVal, ok := diskAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`disk expected to be basetypes.Int64Value, was: %T`, diskAttribute)) + } + + ephemeralAttribute, ok := attributes["ephemeral"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ephemeral is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + ephemeralVal, ok := ephemeralAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ephemeral expected to be basetypes.Int64Value, was: %T`, ephemeralAttribute)) + } + + featuresAttribute, ok := attributes["features"] + + if !ok { + diags.AddError( + "Attribute Missing", + `features is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + featuresVal, ok := featuresAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`features expected to be basetypes.ObjectValue, was: %T`, featuresAttribute)) + } + + gpuAttribute, ok := attributes["gpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + gpuVal, ok := gpuAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu expected to be basetypes.StringValue, was: %T`, gpuAttribute)) + } + + gpuCountAttribute, ok := attributes["gpu_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu_count is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + gpuCountVal, ok := gpuCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu_count expected to be basetypes.Int64Value, was: %T`, gpuCountAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelsAttribute, ok := attributes["labels"] + + if !ok { + diags.AddError( + "Attribute Missing", + `labels is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + labelsVal, ok := labelsAttribute.(basetypes.ListValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`labels expected to be basetypes.ListValue, was: %T`, labelsAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + ramAttribute, ok := attributes["ram"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ram is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + ramVal, ok := ramAttribute.(basetypes.NumberValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ram expected to be basetypes.NumberValue, was: %T`, ramAttribute)) + } + + if diags.HasError() { + return NewFlavorValueUnknown(), diags + } + + return FlavorValue{ + Cpu: cpuVal, + Disk: diskVal, + Ephemeral: ephemeralVal, + Features: featuresVal, + Gpu: gpuVal, + GpuCount: gpuCountVal, + Id: idVal, + Labels: labelsVal, + Name: nameVal, + Ram: ramVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewFlavorValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) FlavorValue { + object, diags := NewFlavorValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewFlavorValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t FlavorType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewFlavorValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewFlavorValueUnknown(), nil + } + + if in.IsNull() { + return NewFlavorValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewFlavorValueMust(FlavorValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t FlavorType) ValueType(ctx context.Context) attr.Value { + return FlavorValue{} +} + +var _ basetypes.ObjectValuable = FlavorValue{} + +type FlavorValue struct { + Cpu basetypes.Int64Value `tfsdk:"cpu"` + Disk basetypes.Int64Value `tfsdk:"disk"` + Ephemeral basetypes.Int64Value `tfsdk:"ephemeral"` + Features basetypes.ObjectValue `tfsdk:"features"` + Gpu basetypes.StringValue `tfsdk:"gpu"` + GpuCount basetypes.Int64Value `tfsdk:"gpu_count"` + Id basetypes.Int64Value `tfsdk:"id"` + Labels basetypes.ListValue `tfsdk:"labels"` + Name basetypes.StringValue `tfsdk:"name"` + Ram basetypes.NumberValue `tfsdk:"ram"` + state attr.ValueState +} + +func (v FlavorValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 10) + + var val tftypes.Value + var err error + + attrTypes["cpu"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["disk"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["ephemeral"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["features"] = basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["gpu"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["gpu_count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["labels"] = basetypes.ListType{ + ElemType: LabelsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["ram"] = basetypes.NumberType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 10) + + val, err = v.Cpu.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cpu"] = val + + val, err = v.Disk.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["disk"] = val + + val, err = v.Ephemeral.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ephemeral"] = val + + val, err = v.Features.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["features"] = val + + val, err = v.Gpu.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["gpu"] = val + + val, err = v.GpuCount.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["gpu_count"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Labels.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["labels"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Ram.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ram"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v FlavorValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v FlavorValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v FlavorValue) String() string { + return "FlavorValue" +} + +func (v FlavorValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + var features basetypes.ObjectValue + + if v.Features.IsNull() { + features = types.ObjectNull( + FeaturesValue{}.AttributeTypes(ctx), + ) + } + + if v.Features.IsUnknown() { + features = types.ObjectUnknown( + FeaturesValue{}.AttributeTypes(ctx), + ) + } + + if !v.Features.IsNull() && !v.Features.IsUnknown() { + features = types.ObjectValueMust( + FeaturesValue{}.AttributeTypes(ctx), + v.Features.Attributes(), + ) + } + + labels := types.ListValueMust( + LabelsType{ + basetypes.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + v.Labels.Elements(), + ) + + if v.Labels.IsNull() { + labels = types.ListNull( + LabelsType{ + basetypes.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + ) + } + + if v.Labels.IsUnknown() { + labels = types.ListUnknown( + LabelsType{ + basetypes.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + ) + } + + attributeTypes := map[string]attr.Type{ + "cpu": basetypes.Int64Type{}, + "disk": basetypes.Int64Type{}, + "ephemeral": basetypes.Int64Type{}, + "features": basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + "gpu": basetypes.StringType{}, + "gpu_count": basetypes.Int64Type{}, + "id": basetypes.Int64Type{}, + "labels": basetypes.ListType{ + ElemType: LabelsValue{}.Type(ctx), + }, + "name": basetypes.StringType{}, + "ram": basetypes.NumberType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "cpu": v.Cpu, + "disk": v.Disk, + "ephemeral": v.Ephemeral, + "features": features, + "gpu": v.Gpu, + "gpu_count": v.GpuCount, + "id": v.Id, + "labels": labels, + "name": v.Name, + "ram": v.Ram, + }) + + return objVal, diags +} + +func (v FlavorValue) Equal(o attr.Value) bool { + other, ok := o.(FlavorValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cpu.Equal(other.Cpu) { + return false + } + + if !v.Disk.Equal(other.Disk) { + return false + } + + if !v.Ephemeral.Equal(other.Ephemeral) { + return false + } + + if !v.Features.Equal(other.Features) { + return false + } + + if !v.Gpu.Equal(other.Gpu) { + return false + } + + if !v.GpuCount.Equal(other.GpuCount) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Labels.Equal(other.Labels) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Ram.Equal(other.Ram) { + return false + } + + return true +} + +func (v FlavorValue) Type(ctx context.Context) attr.Type { + return FlavorType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v FlavorValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cpu": basetypes.Int64Type{}, + "disk": basetypes.Int64Type{}, + "ephemeral": basetypes.Int64Type{}, + "features": basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + "gpu": basetypes.StringType{}, + "gpu_count": basetypes.Int64Type{}, + "id": basetypes.Int64Type{}, + "labels": basetypes.ListType{ + ElemType: LabelsValue{}.Type(ctx), + }, + "name": basetypes.StringType{}, + "ram": basetypes.NumberType{}, + } +} + +var _ basetypes.ObjectTypable = FeaturesType{} + +type FeaturesType struct { + basetypes.ObjectType +} + +func (t FeaturesType) Equal(o attr.Type) bool { + other, ok := o.(FeaturesType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t FeaturesType) String() string { + return "FeaturesType" +} + +func (t FeaturesType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + if diags.HasError() { + return nil, diags + } + + return FeaturesValue{ + state: attr.ValueStateKnown, + }, diags +} + +func NewFeaturesValueNull() FeaturesValue { + return FeaturesValue{ + state: attr.ValueStateNull, + } +} + +func NewFeaturesValueUnknown() FeaturesValue { + return FeaturesValue{ + state: attr.ValueStateUnknown, + } +} + +func NewFeaturesValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (FeaturesValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing FeaturesValue Attribute Value", + "While creating a FeaturesValue value, a missing attribute value was detected. "+ + "A FeaturesValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid FeaturesValue Attribute Type", + "While creating a FeaturesValue value, an invalid attribute value was detected. "+ + "A FeaturesValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra FeaturesValue Attribute Value", + "While creating a FeaturesValue value, an extra attribute value was detected. "+ + "A FeaturesValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra FeaturesValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewFeaturesValueUnknown(), diags + } + + if diags.HasError() { + return NewFeaturesValueUnknown(), diags + } + + return FeaturesValue{ + state: attr.ValueStateKnown, + }, diags +} + +func NewFeaturesValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) FeaturesValue { + object, diags := NewFeaturesValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewFeaturesValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t FeaturesType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewFeaturesValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewFeaturesValueUnknown(), nil + } + + if in.IsNull() { + return NewFeaturesValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewFeaturesValueMust(FeaturesValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t FeaturesType) ValueType(ctx context.Context) attr.Value { + return FeaturesValue{} +} + +var _ basetypes.ObjectValuable = FeaturesValue{} + +type FeaturesValue struct { + state attr.ValueState +} + +func (v FeaturesValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 0) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 0) + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v FeaturesValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v FeaturesValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v FeaturesValue) String() string { + return "FeaturesValue" +} + +func (v FeaturesValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{} + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{}) + + return objVal, diags +} + +func (v FeaturesValue) Equal(o attr.Value) bool { + other, ok := o.(FeaturesValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + return true +} + +func (v FeaturesValue) Type(ctx context.Context) attr.Type { + return FeaturesType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v FeaturesValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{} +} + +var _ basetypes.ObjectTypable = LabelsType{} + +type LabelsType struct { + basetypes.ObjectType +} + +func (t LabelsType) Equal(o attr.Type) bool { + other, ok := o.(LabelsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t LabelsType) String() string { + return "LabelsType" +} + +func (t LabelsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelAttribute, ok := attributes["label"] + + if !ok { + diags.AddError( + "Attribute Missing", + `label is missing from object`) + + return nil, diags + } + + labelVal, ok := labelAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`label expected to be basetypes.StringValue, was: %T`, labelAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return LabelsValue{ + Id: idVal, + Label: labelVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewLabelsValueNull() LabelsValue { + return LabelsValue{ + state: attr.ValueStateNull, + } +} + +func NewLabelsValueUnknown() LabelsValue { + return LabelsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewLabelsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (LabelsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing LabelsValue Attribute Value", + "While creating a LabelsValue value, a missing attribute value was detected. "+ + "A LabelsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("LabelsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid LabelsValue Attribute Type", + "While creating a LabelsValue value, an invalid attribute value was detected. "+ + "A LabelsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("LabelsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("LabelsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra LabelsValue Attribute Value", + "While creating a LabelsValue value, an extra attribute value was detected. "+ + "A LabelsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra LabelsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewLabelsValueUnknown(), diags + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewLabelsValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelAttribute, ok := attributes["label"] + + if !ok { + diags.AddError( + "Attribute Missing", + `label is missing from object`) + + return NewLabelsValueUnknown(), diags + } + + labelVal, ok := labelAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`label expected to be basetypes.StringValue, was: %T`, labelAttribute)) + } + + if diags.HasError() { + return NewLabelsValueUnknown(), diags + } + + return LabelsValue{ + Id: idVal, + Label: labelVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewLabelsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) LabelsValue { + object, diags := NewLabelsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewLabelsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t LabelsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewLabelsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewLabelsValueUnknown(), nil + } + + if in.IsNull() { + return NewLabelsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewLabelsValueMust(LabelsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t LabelsType) ValueType(ctx context.Context) attr.Value { + return LabelsValue{} +} + +var _ basetypes.ObjectValuable = LabelsValue{} + +type LabelsValue struct { + Id basetypes.Int64Value `tfsdk:"id"` + Label basetypes.StringValue `tfsdk:"label"` + state attr.ValueState +} + +func (v LabelsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 2) + + var val tftypes.Value + var err error + + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["label"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 2) + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Label.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["label"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v LabelsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v LabelsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v LabelsValue) String() string { + return "LabelsValue" +} + +func (v LabelsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{ + "id": basetypes.Int64Type{}, + "label": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "id": v.Id, + "label": v.Label, + }) + + return objVal, diags +} + +func (v LabelsValue) Equal(o attr.Value) bool { + other, ok := o.(LabelsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Label.Equal(other.Label) { + return false + } + + return true +} + +func (v LabelsValue) Type(ctx context.Context) attr.Type { + return LabelsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v LabelsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "id": basetypes.Int64Type{}, + "label": basetypes.StringType{}, + } +} diff --git a/internal/genprovider/datasource_core_cluster_nodes/core_cluster_nodes_data_source_gen.go b/internal/genprovider/datasource_core_cluster_nodes/core_cluster_nodes_data_source_gen.go new file mode 100644 index 0000000..05c9435 --- /dev/null +++ b/internal/genprovider/datasource_core_cluster_nodes/core_cluster_nodes_data_source_gen.go @@ -0,0 +1,1725 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package datasource_core_cluster_nodes + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func CoreClusterNodesDataSourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "cluster_id": schema.Int64Attribute{ + Required: true, + }, + "message": schema.StringAttribute{ + Computed: true, + }, + "nodes": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "created_at": schema.StringAttribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "instance": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "contract_id": schema.Int64Attribute{ + Computed: true, + }, + "fixed_ip": schema.StringAttribute{ + Computed: true, + }, + "floating_ip": schema.StringAttribute{ + Computed: true, + }, + "floating_ip_status": schema.StringAttribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "image_id": schema.Int64Attribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "status": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: InstanceType{ + ObjectType: types.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "is_bastion": schema.BoolAttribute{ + Computed: true, + }, + "node_group_id": schema.Int64Attribute{ + Computed: true, + }, + "node_group_name": schema.StringAttribute{ + Computed: true, + }, + "requires_public_ip": schema.BoolAttribute{ + Computed: true, + }, + "role": schema.StringAttribute{ + Computed: true, + }, + "status": schema.StringAttribute{ + Computed: true, + }, + "status_reason": schema.StringAttribute{ + Computed: true, + }, + "updated_at": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: NodesType{ + ObjectType: types.ObjectType{ + AttrTypes: NodesValue{}.AttributeTypes(ctx), + }, + }, + }, + Computed: true, + }, + "status": schema.BoolAttribute{ + Computed: true, + }, + }, + } +} + +type CoreClusterNodesModel struct { + ClusterId types.Int64 `tfsdk:"cluster_id"` + Message types.String `tfsdk:"message"` + Nodes types.List `tfsdk:"nodes"` + Status types.Bool `tfsdk:"status"` +} + +var _ basetypes.ObjectTypable = NodesType{} + +type NodesType struct { + basetypes.ObjectType +} + +func (t NodesType) Equal(o attr.Type) bool { + other, ok := o.(NodesType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t NodesType) String() string { + return "NodesType" +} + +func (t NodesType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return nil, diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + instanceAttribute, ok := attributes["instance"] + + if !ok { + diags.AddError( + "Attribute Missing", + `instance is missing from object`) + + return nil, diags + } + + instanceVal, ok := instanceAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`instance expected to be basetypes.ObjectValue, was: %T`, instanceAttribute)) + } + + isBastionAttribute, ok := attributes["is_bastion"] + + if !ok { + diags.AddError( + "Attribute Missing", + `is_bastion is missing from object`) + + return nil, diags + } + + isBastionVal, ok := isBastionAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`is_bastion expected to be basetypes.BoolValue, was: %T`, isBastionAttribute)) + } + + nodeGroupIdAttribute, ok := attributes["node_group_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_id is missing from object`) + + return nil, diags + } + + nodeGroupIdVal, ok := nodeGroupIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_id expected to be basetypes.Int64Value, was: %T`, nodeGroupIdAttribute)) + } + + nodeGroupNameAttribute, ok := attributes["node_group_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_name is missing from object`) + + return nil, diags + } + + nodeGroupNameVal, ok := nodeGroupNameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_name expected to be basetypes.StringValue, was: %T`, nodeGroupNameAttribute)) + } + + requiresPublicIpAttribute, ok := attributes["requires_public_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `requires_public_ip is missing from object`) + + return nil, diags + } + + requiresPublicIpVal, ok := requiresPublicIpAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`requires_public_ip expected to be basetypes.BoolValue, was: %T`, requiresPublicIpAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return nil, diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + statusReasonAttribute, ok := attributes["status_reason"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status_reason is missing from object`) + + return nil, diags + } + + statusReasonVal, ok := statusReasonAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status_reason expected to be basetypes.StringValue, was: %T`, statusReasonAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return nil, diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return NodesValue{ + CreatedAt: createdAtVal, + Id: idVal, + Instance: instanceVal, + IsBastion: isBastionVal, + NodeGroupId: nodeGroupIdVal, + NodeGroupName: nodeGroupNameVal, + RequiresPublicIp: requiresPublicIpVal, + Role: roleVal, + Status: statusVal, + StatusReason: statusReasonVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodesValueNull() NodesValue { + return NodesValue{ + state: attr.ValueStateNull, + } +} + +func NewNodesValueUnknown() NodesValue { + return NodesValue{ + state: attr.ValueStateUnknown, + } +} + +func NewNodesValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (NodesValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing NodesValue Attribute Value", + "While creating a NodesValue value, a missing attribute value was detected. "+ + "A NodesValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodesValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid NodesValue Attribute Type", + "While creating a NodesValue value, an invalid attribute value was detected. "+ + "A NodesValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodesValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("NodesValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra NodesValue Attribute Value", + "While creating a NodesValue value, an extra attribute value was detected. "+ + "A NodesValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra NodesValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewNodesValueUnknown(), diags + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return NewNodesValueUnknown(), diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewNodesValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + instanceAttribute, ok := attributes["instance"] + + if !ok { + diags.AddError( + "Attribute Missing", + `instance is missing from object`) + + return NewNodesValueUnknown(), diags + } + + instanceVal, ok := instanceAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`instance expected to be basetypes.ObjectValue, was: %T`, instanceAttribute)) + } + + isBastionAttribute, ok := attributes["is_bastion"] + + if !ok { + diags.AddError( + "Attribute Missing", + `is_bastion is missing from object`) + + return NewNodesValueUnknown(), diags + } + + isBastionVal, ok := isBastionAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`is_bastion expected to be basetypes.BoolValue, was: %T`, isBastionAttribute)) + } + + nodeGroupIdAttribute, ok := attributes["node_group_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_id is missing from object`) + + return NewNodesValueUnknown(), diags + } + + nodeGroupIdVal, ok := nodeGroupIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_id expected to be basetypes.Int64Value, was: %T`, nodeGroupIdAttribute)) + } + + nodeGroupNameAttribute, ok := attributes["node_group_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_name is missing from object`) + + return NewNodesValueUnknown(), diags + } + + nodeGroupNameVal, ok := nodeGroupNameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_name expected to be basetypes.StringValue, was: %T`, nodeGroupNameAttribute)) + } + + requiresPublicIpAttribute, ok := attributes["requires_public_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `requires_public_ip is missing from object`) + + return NewNodesValueUnknown(), diags + } + + requiresPublicIpVal, ok := requiresPublicIpAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`requires_public_ip expected to be basetypes.BoolValue, was: %T`, requiresPublicIpAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return NewNodesValueUnknown(), diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewNodesValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + statusReasonAttribute, ok := attributes["status_reason"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status_reason is missing from object`) + + return NewNodesValueUnknown(), diags + } + + statusReasonVal, ok := statusReasonAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status_reason expected to be basetypes.StringValue, was: %T`, statusReasonAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return NewNodesValueUnknown(), diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return NewNodesValueUnknown(), diags + } + + return NodesValue{ + CreatedAt: createdAtVal, + Id: idVal, + Instance: instanceVal, + IsBastion: isBastionVal, + NodeGroupId: nodeGroupIdVal, + NodeGroupName: nodeGroupNameVal, + RequiresPublicIp: requiresPublicIpVal, + Role: roleVal, + Status: statusVal, + StatusReason: statusReasonVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodesValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) NodesValue { + object, diags := NewNodesValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewNodesValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t NodesType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewNodesValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewNodesValueUnknown(), nil + } + + if in.IsNull() { + return NewNodesValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewNodesValueMust(NodesValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t NodesType) ValueType(ctx context.Context) attr.Value { + return NodesValue{} +} + +var _ basetypes.ObjectValuable = NodesValue{} + +type NodesValue struct { + CreatedAt basetypes.StringValue `tfsdk:"created_at"` + Id basetypes.Int64Value `tfsdk:"id"` + Instance basetypes.ObjectValue `tfsdk:"instance"` + IsBastion basetypes.BoolValue `tfsdk:"is_bastion"` + NodeGroupId basetypes.Int64Value `tfsdk:"node_group_id"` + NodeGroupName basetypes.StringValue `tfsdk:"node_group_name"` + RequiresPublicIp basetypes.BoolValue `tfsdk:"requires_public_ip"` + Role basetypes.StringValue `tfsdk:"role"` + Status basetypes.StringValue `tfsdk:"status"` + StatusReason basetypes.StringValue `tfsdk:"status_reason"` + UpdatedAt basetypes.StringValue `tfsdk:"updated_at"` + state attr.ValueState +} + +func (v NodesValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 11) + + var val tftypes.Value + var err error + + attrTypes["created_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["instance"] = basetypes.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["is_bastion"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["node_group_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["node_group_name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["requires_public_ip"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["role"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status_reason"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["updated_at"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 11) + + val, err = v.CreatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["created_at"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Instance.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["instance"] = val + + val, err = v.IsBastion.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["is_bastion"] = val + + val, err = v.NodeGroupId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["node_group_id"] = val + + val, err = v.NodeGroupName.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["node_group_name"] = val + + val, err = v.RequiresPublicIp.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["requires_public_ip"] = val + + val, err = v.Role.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["role"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + val, err = v.StatusReason.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status_reason"] = val + + val, err = v.UpdatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["updated_at"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v NodesValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v NodesValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v NodesValue) String() string { + return "NodesValue" +} + +func (v NodesValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + var instance basetypes.ObjectValue + + if v.Instance.IsNull() { + instance = types.ObjectNull( + InstanceValue{}.AttributeTypes(ctx), + ) + } + + if v.Instance.IsUnknown() { + instance = types.ObjectUnknown( + InstanceValue{}.AttributeTypes(ctx), + ) + } + + if !v.Instance.IsNull() && !v.Instance.IsUnknown() { + instance = types.ObjectValueMust( + InstanceValue{}.AttributeTypes(ctx), + v.Instance.Attributes(), + ) + } + + attributeTypes := map[string]attr.Type{ + "created_at": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "instance": basetypes.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }, + "is_bastion": basetypes.BoolType{}, + "node_group_id": basetypes.Int64Type{}, + "node_group_name": basetypes.StringType{}, + "requires_public_ip": basetypes.BoolType{}, + "role": basetypes.StringType{}, + "status": basetypes.StringType{}, + "status_reason": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "created_at": v.CreatedAt, + "id": v.Id, + "instance": instance, + "is_bastion": v.IsBastion, + "node_group_id": v.NodeGroupId, + "node_group_name": v.NodeGroupName, + "requires_public_ip": v.RequiresPublicIp, + "role": v.Role, + "status": v.Status, + "status_reason": v.StatusReason, + "updated_at": v.UpdatedAt, + }) + + return objVal, diags +} + +func (v NodesValue) Equal(o attr.Value) bool { + other, ok := o.(NodesValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.CreatedAt.Equal(other.CreatedAt) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Instance.Equal(other.Instance) { + return false + } + + if !v.IsBastion.Equal(other.IsBastion) { + return false + } + + if !v.NodeGroupId.Equal(other.NodeGroupId) { + return false + } + + if !v.NodeGroupName.Equal(other.NodeGroupName) { + return false + } + + if !v.RequiresPublicIp.Equal(other.RequiresPublicIp) { + return false + } + + if !v.Role.Equal(other.Role) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + if !v.StatusReason.Equal(other.StatusReason) { + return false + } + + if !v.UpdatedAt.Equal(other.UpdatedAt) { + return false + } + + return true +} + +func (v NodesValue) Type(ctx context.Context) attr.Type { + return NodesType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v NodesValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "created_at": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "instance": basetypes.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }, + "is_bastion": basetypes.BoolType{}, + "node_group_id": basetypes.Int64Type{}, + "node_group_name": basetypes.StringType{}, + "requires_public_ip": basetypes.BoolType{}, + "role": basetypes.StringType{}, + "status": basetypes.StringType{}, + "status_reason": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = InstanceType{} + +type InstanceType struct { + basetypes.ObjectType +} + +func (t InstanceType) Equal(o attr.Type) bool { + other, ok := o.(InstanceType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t InstanceType) String() string { + return "InstanceType" +} + +func (t InstanceType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + contractIdAttribute, ok := attributes["contract_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `contract_id is missing from object`) + + return nil, diags + } + + contractIdVal, ok := contractIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`contract_id expected to be basetypes.Int64Value, was: %T`, contractIdAttribute)) + } + + fixedIpAttribute, ok := attributes["fixed_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `fixed_ip is missing from object`) + + return nil, diags + } + + fixedIpVal, ok := fixedIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`fixed_ip expected to be basetypes.StringValue, was: %T`, fixedIpAttribute)) + } + + floatingIpAttribute, ok := attributes["floating_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip is missing from object`) + + return nil, diags + } + + floatingIpVal, ok := floatingIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip expected to be basetypes.StringValue, was: %T`, floatingIpAttribute)) + } + + floatingIpStatusAttribute, ok := attributes["floating_ip_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip_status is missing from object`) + + return nil, diags + } + + floatingIpStatusVal, ok := floatingIpStatusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip_status expected to be basetypes.StringValue, was: %T`, floatingIpStatusAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + imageIdAttribute, ok := attributes["image_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `image_id is missing from object`) + + return nil, diags + } + + imageIdVal, ok := imageIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`image_id expected to be basetypes.Int64Value, was: %T`, imageIdAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return InstanceValue{ + ContractId: contractIdVal, + FixedIp: fixedIpVal, + FloatingIp: floatingIpVal, + FloatingIpStatus: floatingIpStatusVal, + Id: idVal, + ImageId: imageIdVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewInstanceValueNull() InstanceValue { + return InstanceValue{ + state: attr.ValueStateNull, + } +} + +func NewInstanceValueUnknown() InstanceValue { + return InstanceValue{ + state: attr.ValueStateUnknown, + } +} + +func NewInstanceValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (InstanceValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing InstanceValue Attribute Value", + "While creating a InstanceValue value, a missing attribute value was detected. "+ + "A InstanceValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("InstanceValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid InstanceValue Attribute Type", + "While creating a InstanceValue value, an invalid attribute value was detected. "+ + "A InstanceValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("InstanceValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("InstanceValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra InstanceValue Attribute Value", + "While creating a InstanceValue value, an extra attribute value was detected. "+ + "A InstanceValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra InstanceValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewInstanceValueUnknown(), diags + } + + contractIdAttribute, ok := attributes["contract_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `contract_id is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + contractIdVal, ok := contractIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`contract_id expected to be basetypes.Int64Value, was: %T`, contractIdAttribute)) + } + + fixedIpAttribute, ok := attributes["fixed_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `fixed_ip is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + fixedIpVal, ok := fixedIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`fixed_ip expected to be basetypes.StringValue, was: %T`, fixedIpAttribute)) + } + + floatingIpAttribute, ok := attributes["floating_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + floatingIpVal, ok := floatingIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip expected to be basetypes.StringValue, was: %T`, floatingIpAttribute)) + } + + floatingIpStatusAttribute, ok := attributes["floating_ip_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip_status is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + floatingIpStatusVal, ok := floatingIpStatusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip_status expected to be basetypes.StringValue, was: %T`, floatingIpStatusAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + imageIdAttribute, ok := attributes["image_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `image_id is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + imageIdVal, ok := imageIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`image_id expected to be basetypes.Int64Value, was: %T`, imageIdAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return NewInstanceValueUnknown(), diags + } + + return InstanceValue{ + ContractId: contractIdVal, + FixedIp: fixedIpVal, + FloatingIp: floatingIpVal, + FloatingIpStatus: floatingIpStatusVal, + Id: idVal, + ImageId: imageIdVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewInstanceValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) InstanceValue { + object, diags := NewInstanceValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewInstanceValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t InstanceType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewInstanceValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewInstanceValueUnknown(), nil + } + + if in.IsNull() { + return NewInstanceValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewInstanceValueMust(InstanceValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t InstanceType) ValueType(ctx context.Context) attr.Value { + return InstanceValue{} +} + +var _ basetypes.ObjectValuable = InstanceValue{} + +type InstanceValue struct { + ContractId basetypes.Int64Value `tfsdk:"contract_id"` + FixedIp basetypes.StringValue `tfsdk:"fixed_ip"` + FloatingIp basetypes.StringValue `tfsdk:"floating_ip"` + FloatingIpStatus basetypes.StringValue `tfsdk:"floating_ip_status"` + Id basetypes.Int64Value `tfsdk:"id"` + ImageId basetypes.Int64Value `tfsdk:"image_id"` + Name basetypes.StringValue `tfsdk:"name"` + Status basetypes.StringValue `tfsdk:"status"` + state attr.ValueState +} + +func (v InstanceValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 8) + + var val tftypes.Value + var err error + + attrTypes["contract_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["fixed_ip"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["floating_ip"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["floating_ip_status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["image_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 8) + + val, err = v.ContractId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["contract_id"] = val + + val, err = v.FixedIp.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["fixed_ip"] = val + + val, err = v.FloatingIp.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["floating_ip"] = val + + val, err = v.FloatingIpStatus.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["floating_ip_status"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.ImageId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["image_id"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v InstanceValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v InstanceValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v InstanceValue) String() string { + return "InstanceValue" +} + +func (v InstanceValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{ + "contract_id": basetypes.Int64Type{}, + "fixed_ip": basetypes.StringType{}, + "floating_ip": basetypes.StringType{}, + "floating_ip_status": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "image_id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "status": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "contract_id": v.ContractId, + "fixed_ip": v.FixedIp, + "floating_ip": v.FloatingIp, + "floating_ip_status": v.FloatingIpStatus, + "id": v.Id, + "image_id": v.ImageId, + "name": v.Name, + "status": v.Status, + }) + + return objVal, diags +} + +func (v InstanceValue) Equal(o attr.Value) bool { + other, ok := o.(InstanceValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.ContractId.Equal(other.ContractId) { + return false + } + + if !v.FixedIp.Equal(other.FixedIp) { + return false + } + + if !v.FloatingIp.Equal(other.FloatingIp) { + return false + } + + if !v.FloatingIpStatus.Equal(other.FloatingIpStatus) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.ImageId.Equal(other.ImageId) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + return true +} + +func (v InstanceValue) Type(ctx context.Context) attr.Type { + return InstanceType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v InstanceValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "contract_id": basetypes.Int64Type{}, + "fixed_ip": basetypes.StringType{}, + "floating_ip": basetypes.StringType{}, + "floating_ip_status": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "image_id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "status": basetypes.StringType{}, + } +} diff --git a/internal/genprovider/resource_core_cluster_node/core_cluster_node_resource_gen.go b/internal/genprovider/resource_core_cluster_node/core_cluster_node_resource_gen.go new file mode 100644 index 0000000..dc047e7 --- /dev/null +++ b/internal/genprovider/resource_core_cluster_node/core_cluster_node_resource_gen.go @@ -0,0 +1,1748 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package resource_core_cluster_node + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema" +) + +func CoreClusterNodeResourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "count": schema.Int64Attribute{ + Optional: true, + Computed: true, + Validators: []validator.Int64{ + int64validator.AtLeast(1), + }, + }, + "message": schema.StringAttribute{ + Computed: true, + }, + "node_group": schema.StringAttribute{ + Optional: true, + Computed: true, + }, + "nodes": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "created_at": schema.StringAttribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "instance": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "contract_id": schema.Int64Attribute{ + Computed: true, + }, + "fixed_ip": schema.StringAttribute{ + Computed: true, + }, + "floating_ip": schema.StringAttribute{ + Computed: true, + }, + "floating_ip_status": schema.StringAttribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "image_id": schema.Int64Attribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "status": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: InstanceType{ + ObjectType: types.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "is_bastion": schema.BoolAttribute{ + Computed: true, + }, + "node_group_id": schema.Int64Attribute{ + Computed: true, + }, + "node_group_name": schema.StringAttribute{ + Computed: true, + }, + "requires_public_ip": schema.BoolAttribute{ + Computed: true, + }, + "role": schema.StringAttribute{ + Computed: true, + }, + "status": schema.StringAttribute{ + Computed: true, + }, + "status_reason": schema.StringAttribute{ + Computed: true, + }, + "updated_at": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: NodesType{ + ObjectType: types.ObjectType{ + AttrTypes: NodesValue{}.AttributeTypes(ctx), + }, + }, + }, + Computed: true, + }, + "role": schema.StringAttribute{ + Optional: true, + Computed: true, + Validators: []validator.String{ + stringvalidator.OneOf( + "worker", + "master", + ), + }, + }, + "status": schema.BoolAttribute{ + Computed: true, + }, + }, + } +} + +type CoreClusterNodeModel struct { + Count types.Int64 `tfsdk:"count"` + Message types.String `tfsdk:"message"` + NodeGroup types.String `tfsdk:"node_group"` + Nodes types.List `tfsdk:"nodes"` + Role types.String `tfsdk:"role"` + Status types.Bool `tfsdk:"status"` +} + +var _ basetypes.ObjectTypable = NodesType{} + +type NodesType struct { + basetypes.ObjectType +} + +func (t NodesType) Equal(o attr.Type) bool { + other, ok := o.(NodesType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t NodesType) String() string { + return "NodesType" +} + +func (t NodesType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return nil, diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + instanceAttribute, ok := attributes["instance"] + + if !ok { + diags.AddError( + "Attribute Missing", + `instance is missing from object`) + + return nil, diags + } + + instanceVal, ok := instanceAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`instance expected to be basetypes.ObjectValue, was: %T`, instanceAttribute)) + } + + isBastionAttribute, ok := attributes["is_bastion"] + + if !ok { + diags.AddError( + "Attribute Missing", + `is_bastion is missing from object`) + + return nil, diags + } + + isBastionVal, ok := isBastionAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`is_bastion expected to be basetypes.BoolValue, was: %T`, isBastionAttribute)) + } + + nodeGroupIdAttribute, ok := attributes["node_group_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_id is missing from object`) + + return nil, diags + } + + nodeGroupIdVal, ok := nodeGroupIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_id expected to be basetypes.Int64Value, was: %T`, nodeGroupIdAttribute)) + } + + nodeGroupNameAttribute, ok := attributes["node_group_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_name is missing from object`) + + return nil, diags + } + + nodeGroupNameVal, ok := nodeGroupNameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_name expected to be basetypes.StringValue, was: %T`, nodeGroupNameAttribute)) + } + + requiresPublicIpAttribute, ok := attributes["requires_public_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `requires_public_ip is missing from object`) + + return nil, diags + } + + requiresPublicIpVal, ok := requiresPublicIpAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`requires_public_ip expected to be basetypes.BoolValue, was: %T`, requiresPublicIpAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return nil, diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + statusReasonAttribute, ok := attributes["status_reason"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status_reason is missing from object`) + + return nil, diags + } + + statusReasonVal, ok := statusReasonAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status_reason expected to be basetypes.StringValue, was: %T`, statusReasonAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return nil, diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return NodesValue{ + CreatedAt: createdAtVal, + Id: idVal, + Instance: instanceVal, + IsBastion: isBastionVal, + NodeGroupId: nodeGroupIdVal, + NodeGroupName: nodeGroupNameVal, + RequiresPublicIp: requiresPublicIpVal, + Role: roleVal, + Status: statusVal, + StatusReason: statusReasonVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodesValueNull() NodesValue { + return NodesValue{ + state: attr.ValueStateNull, + } +} + +func NewNodesValueUnknown() NodesValue { + return NodesValue{ + state: attr.ValueStateUnknown, + } +} + +func NewNodesValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (NodesValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing NodesValue Attribute Value", + "While creating a NodesValue value, a missing attribute value was detected. "+ + "A NodesValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodesValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid NodesValue Attribute Type", + "While creating a NodesValue value, an invalid attribute value was detected. "+ + "A NodesValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodesValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("NodesValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra NodesValue Attribute Value", + "While creating a NodesValue value, an extra attribute value was detected. "+ + "A NodesValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra NodesValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewNodesValueUnknown(), diags + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return NewNodesValueUnknown(), diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewNodesValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + instanceAttribute, ok := attributes["instance"] + + if !ok { + diags.AddError( + "Attribute Missing", + `instance is missing from object`) + + return NewNodesValueUnknown(), diags + } + + instanceVal, ok := instanceAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`instance expected to be basetypes.ObjectValue, was: %T`, instanceAttribute)) + } + + isBastionAttribute, ok := attributes["is_bastion"] + + if !ok { + diags.AddError( + "Attribute Missing", + `is_bastion is missing from object`) + + return NewNodesValueUnknown(), diags + } + + isBastionVal, ok := isBastionAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`is_bastion expected to be basetypes.BoolValue, was: %T`, isBastionAttribute)) + } + + nodeGroupIdAttribute, ok := attributes["node_group_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_id is missing from object`) + + return NewNodesValueUnknown(), diags + } + + nodeGroupIdVal, ok := nodeGroupIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_id expected to be basetypes.Int64Value, was: %T`, nodeGroupIdAttribute)) + } + + nodeGroupNameAttribute, ok := attributes["node_group_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_name is missing from object`) + + return NewNodesValueUnknown(), diags + } + + nodeGroupNameVal, ok := nodeGroupNameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_name expected to be basetypes.StringValue, was: %T`, nodeGroupNameAttribute)) + } + + requiresPublicIpAttribute, ok := attributes["requires_public_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `requires_public_ip is missing from object`) + + return NewNodesValueUnknown(), diags + } + + requiresPublicIpVal, ok := requiresPublicIpAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`requires_public_ip expected to be basetypes.BoolValue, was: %T`, requiresPublicIpAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return NewNodesValueUnknown(), diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewNodesValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + statusReasonAttribute, ok := attributes["status_reason"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status_reason is missing from object`) + + return NewNodesValueUnknown(), diags + } + + statusReasonVal, ok := statusReasonAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status_reason expected to be basetypes.StringValue, was: %T`, statusReasonAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return NewNodesValueUnknown(), diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return NewNodesValueUnknown(), diags + } + + return NodesValue{ + CreatedAt: createdAtVal, + Id: idVal, + Instance: instanceVal, + IsBastion: isBastionVal, + NodeGroupId: nodeGroupIdVal, + NodeGroupName: nodeGroupNameVal, + RequiresPublicIp: requiresPublicIpVal, + Role: roleVal, + Status: statusVal, + StatusReason: statusReasonVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodesValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) NodesValue { + object, diags := NewNodesValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewNodesValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t NodesType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewNodesValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewNodesValueUnknown(), nil + } + + if in.IsNull() { + return NewNodesValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewNodesValueMust(NodesValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t NodesType) ValueType(ctx context.Context) attr.Value { + return NodesValue{} +} + +var _ basetypes.ObjectValuable = NodesValue{} + +type NodesValue struct { + CreatedAt basetypes.StringValue `tfsdk:"created_at"` + Id basetypes.Int64Value `tfsdk:"id"` + Instance basetypes.ObjectValue `tfsdk:"instance"` + IsBastion basetypes.BoolValue `tfsdk:"is_bastion"` + NodeGroupId basetypes.Int64Value `tfsdk:"node_group_id"` + NodeGroupName basetypes.StringValue `tfsdk:"node_group_name"` + RequiresPublicIp basetypes.BoolValue `tfsdk:"requires_public_ip"` + Role basetypes.StringValue `tfsdk:"role"` + Status basetypes.StringValue `tfsdk:"status"` + StatusReason basetypes.StringValue `tfsdk:"status_reason"` + UpdatedAt basetypes.StringValue `tfsdk:"updated_at"` + state attr.ValueState +} + +func (v NodesValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 11) + + var val tftypes.Value + var err error + + attrTypes["created_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["instance"] = basetypes.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["is_bastion"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["node_group_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["node_group_name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["requires_public_ip"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["role"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status_reason"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["updated_at"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 11) + + val, err = v.CreatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["created_at"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Instance.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["instance"] = val + + val, err = v.IsBastion.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["is_bastion"] = val + + val, err = v.NodeGroupId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["node_group_id"] = val + + val, err = v.NodeGroupName.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["node_group_name"] = val + + val, err = v.RequiresPublicIp.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["requires_public_ip"] = val + + val, err = v.Role.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["role"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + val, err = v.StatusReason.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status_reason"] = val + + val, err = v.UpdatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["updated_at"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v NodesValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v NodesValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v NodesValue) String() string { + return "NodesValue" +} + +func (v NodesValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + var instance basetypes.ObjectValue + + if v.Instance.IsNull() { + instance = types.ObjectNull( + InstanceValue{}.AttributeTypes(ctx), + ) + } + + if v.Instance.IsUnknown() { + instance = types.ObjectUnknown( + InstanceValue{}.AttributeTypes(ctx), + ) + } + + if !v.Instance.IsNull() && !v.Instance.IsUnknown() { + instance = types.ObjectValueMust( + InstanceValue{}.AttributeTypes(ctx), + v.Instance.Attributes(), + ) + } + + attributeTypes := map[string]attr.Type{ + "created_at": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "instance": basetypes.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }, + "is_bastion": basetypes.BoolType{}, + "node_group_id": basetypes.Int64Type{}, + "node_group_name": basetypes.StringType{}, + "requires_public_ip": basetypes.BoolType{}, + "role": basetypes.StringType{}, + "status": basetypes.StringType{}, + "status_reason": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "created_at": v.CreatedAt, + "id": v.Id, + "instance": instance, + "is_bastion": v.IsBastion, + "node_group_id": v.NodeGroupId, + "node_group_name": v.NodeGroupName, + "requires_public_ip": v.RequiresPublicIp, + "role": v.Role, + "status": v.Status, + "status_reason": v.StatusReason, + "updated_at": v.UpdatedAt, + }) + + return objVal, diags +} + +func (v NodesValue) Equal(o attr.Value) bool { + other, ok := o.(NodesValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.CreatedAt.Equal(other.CreatedAt) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Instance.Equal(other.Instance) { + return false + } + + if !v.IsBastion.Equal(other.IsBastion) { + return false + } + + if !v.NodeGroupId.Equal(other.NodeGroupId) { + return false + } + + if !v.NodeGroupName.Equal(other.NodeGroupName) { + return false + } + + if !v.RequiresPublicIp.Equal(other.RequiresPublicIp) { + return false + } + + if !v.Role.Equal(other.Role) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + if !v.StatusReason.Equal(other.StatusReason) { + return false + } + + if !v.UpdatedAt.Equal(other.UpdatedAt) { + return false + } + + return true +} + +func (v NodesValue) Type(ctx context.Context) attr.Type { + return NodesType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v NodesValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "created_at": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "instance": basetypes.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }, + "is_bastion": basetypes.BoolType{}, + "node_group_id": basetypes.Int64Type{}, + "node_group_name": basetypes.StringType{}, + "requires_public_ip": basetypes.BoolType{}, + "role": basetypes.StringType{}, + "status": basetypes.StringType{}, + "status_reason": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = InstanceType{} + +type InstanceType struct { + basetypes.ObjectType +} + +func (t InstanceType) Equal(o attr.Type) bool { + other, ok := o.(InstanceType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t InstanceType) String() string { + return "InstanceType" +} + +func (t InstanceType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + contractIdAttribute, ok := attributes["contract_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `contract_id is missing from object`) + + return nil, diags + } + + contractIdVal, ok := contractIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`contract_id expected to be basetypes.Int64Value, was: %T`, contractIdAttribute)) + } + + fixedIpAttribute, ok := attributes["fixed_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `fixed_ip is missing from object`) + + return nil, diags + } + + fixedIpVal, ok := fixedIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`fixed_ip expected to be basetypes.StringValue, was: %T`, fixedIpAttribute)) + } + + floatingIpAttribute, ok := attributes["floating_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip is missing from object`) + + return nil, diags + } + + floatingIpVal, ok := floatingIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip expected to be basetypes.StringValue, was: %T`, floatingIpAttribute)) + } + + floatingIpStatusAttribute, ok := attributes["floating_ip_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip_status is missing from object`) + + return nil, diags + } + + floatingIpStatusVal, ok := floatingIpStatusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip_status expected to be basetypes.StringValue, was: %T`, floatingIpStatusAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + imageIdAttribute, ok := attributes["image_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `image_id is missing from object`) + + return nil, diags + } + + imageIdVal, ok := imageIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`image_id expected to be basetypes.Int64Value, was: %T`, imageIdAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return InstanceValue{ + ContractId: contractIdVal, + FixedIp: fixedIpVal, + FloatingIp: floatingIpVal, + FloatingIpStatus: floatingIpStatusVal, + Id: idVal, + ImageId: imageIdVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewInstanceValueNull() InstanceValue { + return InstanceValue{ + state: attr.ValueStateNull, + } +} + +func NewInstanceValueUnknown() InstanceValue { + return InstanceValue{ + state: attr.ValueStateUnknown, + } +} + +func NewInstanceValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (InstanceValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing InstanceValue Attribute Value", + "While creating a InstanceValue value, a missing attribute value was detected. "+ + "A InstanceValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("InstanceValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid InstanceValue Attribute Type", + "While creating a InstanceValue value, an invalid attribute value was detected. "+ + "A InstanceValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("InstanceValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("InstanceValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra InstanceValue Attribute Value", + "While creating a InstanceValue value, an extra attribute value was detected. "+ + "A InstanceValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra InstanceValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewInstanceValueUnknown(), diags + } + + contractIdAttribute, ok := attributes["contract_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `contract_id is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + contractIdVal, ok := contractIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`contract_id expected to be basetypes.Int64Value, was: %T`, contractIdAttribute)) + } + + fixedIpAttribute, ok := attributes["fixed_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `fixed_ip is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + fixedIpVal, ok := fixedIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`fixed_ip expected to be basetypes.StringValue, was: %T`, fixedIpAttribute)) + } + + floatingIpAttribute, ok := attributes["floating_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + floatingIpVal, ok := floatingIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip expected to be basetypes.StringValue, was: %T`, floatingIpAttribute)) + } + + floatingIpStatusAttribute, ok := attributes["floating_ip_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip_status is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + floatingIpStatusVal, ok := floatingIpStatusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip_status expected to be basetypes.StringValue, was: %T`, floatingIpStatusAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + imageIdAttribute, ok := attributes["image_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `image_id is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + imageIdVal, ok := imageIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`image_id expected to be basetypes.Int64Value, was: %T`, imageIdAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return NewInstanceValueUnknown(), diags + } + + return InstanceValue{ + ContractId: contractIdVal, + FixedIp: fixedIpVal, + FloatingIp: floatingIpVal, + FloatingIpStatus: floatingIpStatusVal, + Id: idVal, + ImageId: imageIdVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewInstanceValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) InstanceValue { + object, diags := NewInstanceValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewInstanceValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t InstanceType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewInstanceValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewInstanceValueUnknown(), nil + } + + if in.IsNull() { + return NewInstanceValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewInstanceValueMust(InstanceValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t InstanceType) ValueType(ctx context.Context) attr.Value { + return InstanceValue{} +} + +var _ basetypes.ObjectValuable = InstanceValue{} + +type InstanceValue struct { + ContractId basetypes.Int64Value `tfsdk:"contract_id"` + FixedIp basetypes.StringValue `tfsdk:"fixed_ip"` + FloatingIp basetypes.StringValue `tfsdk:"floating_ip"` + FloatingIpStatus basetypes.StringValue `tfsdk:"floating_ip_status"` + Id basetypes.Int64Value `tfsdk:"id"` + ImageId basetypes.Int64Value `tfsdk:"image_id"` + Name basetypes.StringValue `tfsdk:"name"` + Status basetypes.StringValue `tfsdk:"status"` + state attr.ValueState +} + +func (v InstanceValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 8) + + var val tftypes.Value + var err error + + attrTypes["contract_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["fixed_ip"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["floating_ip"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["floating_ip_status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["image_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 8) + + val, err = v.ContractId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["contract_id"] = val + + val, err = v.FixedIp.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["fixed_ip"] = val + + val, err = v.FloatingIp.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["floating_ip"] = val + + val, err = v.FloatingIpStatus.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["floating_ip_status"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.ImageId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["image_id"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v InstanceValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v InstanceValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v InstanceValue) String() string { + return "InstanceValue" +} + +func (v InstanceValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{ + "contract_id": basetypes.Int64Type{}, + "fixed_ip": basetypes.StringType{}, + "floating_ip": basetypes.StringType{}, + "floating_ip_status": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "image_id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "status": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "contract_id": v.ContractId, + "fixed_ip": v.FixedIp, + "floating_ip": v.FloatingIp, + "floating_ip_status": v.FloatingIpStatus, + "id": v.Id, + "image_id": v.ImageId, + "name": v.Name, + "status": v.Status, + }) + + return objVal, diags +} + +func (v InstanceValue) Equal(o attr.Value) bool { + other, ok := o.(InstanceValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.ContractId.Equal(other.ContractId) { + return false + } + + if !v.FixedIp.Equal(other.FixedIp) { + return false + } + + if !v.FloatingIp.Equal(other.FloatingIp) { + return false + } + + if !v.FloatingIpStatus.Equal(other.FloatingIpStatus) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.ImageId.Equal(other.ImageId) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + return true +} + +func (v InstanceValue) Type(ctx context.Context) attr.Type { + return InstanceType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v InstanceValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "contract_id": basetypes.Int64Type{}, + "fixed_ip": basetypes.StringType{}, + "floating_ip": basetypes.StringType{}, + "floating_ip_status": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "image_id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "status": basetypes.StringType{}, + } +} diff --git a/internal/genprovider/resource_core_cluster_node_group/core_cluster_node_group_resource_gen.go b/internal/genprovider/resource_core_cluster_node_group/core_cluster_node_group_resource_gen.go new file mode 100644 index 0000000..de0cf42 --- /dev/null +++ b/internal/genprovider/resource_core_cluster_node_group/core_cluster_node_group_resource_gen.go @@ -0,0 +1,4188 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package resource_core_cluster_node_group + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema" +) + +func CoreClusterNodeGroupResourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "cluster_id": schema.Int64Attribute{ + Optional: true, + Computed: true, + }, + "count": schema.Int64Attribute{ + Optional: true, + Computed: true, + Validators: []validator.Int64{ + int64validator.AtLeast(1), + }, + }, + "flavor_name": schema.StringAttribute{ + Required: true, + }, + "max_count": schema.Int64Attribute{ + Optional: true, + Computed: true, + Validators: []validator.Int64{ + int64validator.AtMost(20), + }, + }, + "message": schema.StringAttribute{ + Computed: true, + }, + "min_count": schema.Int64Attribute{ + Optional: true, + Computed: true, + Validators: []validator.Int64{ + int64validator.AtLeast(1), + }, + }, + "name": schema.StringAttribute{ + Required: true, + Validators: []validator.String{ + stringvalidator.LengthAtMost(20), + }, + }, + "node_group": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "count": schema.Int64Attribute{ + Computed: true, + }, + "created_at": schema.StringAttribute{ + Computed: true, + }, + "flavor": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "cpu": schema.Int64Attribute{ + Computed: true, + }, + "disk": schema.Int64Attribute{ + Computed: true, + }, + "ephemeral": schema.Int64Attribute{ + Computed: true, + }, + "features": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{}, + CustomType: FeaturesType{ + ObjectType: types.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "gpu": schema.StringAttribute{ + Computed: true, + }, + "gpu_count": schema.Int64Attribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "labels": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.Int64Attribute{ + Computed: true, + }, + "label": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: LabelsType{ + ObjectType: types.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + }, + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "ram": schema.NumberAttribute{ + Computed: true, + }, + }, + CustomType: FlavorType{ + ObjectType: types.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "max_count": schema.Int64Attribute{ + Computed: true, + }, + "min_count": schema.Int64Attribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "role": schema.StringAttribute{ + Computed: true, + }, + "updated_at": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: NodeGroupType{ + ObjectType: types.ObjectType{ + AttrTypes: NodeGroupValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "node_group_id": schema.Int64Attribute{ + Optional: true, + Computed: true, + }, + "nodes": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "created_at": schema.StringAttribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "instance": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "contract_id": schema.Int64Attribute{ + Computed: true, + }, + "fixed_ip": schema.StringAttribute{ + Computed: true, + }, + "floating_ip": schema.StringAttribute{ + Computed: true, + }, + "floating_ip_status": schema.StringAttribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "image_id": schema.Int64Attribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "status": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: InstanceType{ + ObjectType: types.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "is_bastion": schema.BoolAttribute{ + Computed: true, + }, + "node_group_id": schema.Int64Attribute{ + Computed: true, + }, + "node_group_name": schema.StringAttribute{ + Computed: true, + }, + "requires_public_ip": schema.BoolAttribute{ + Computed: true, + }, + "role": schema.StringAttribute{ + Computed: true, + }, + "status": schema.StringAttribute{ + Computed: true, + }, + "status_reason": schema.StringAttribute{ + Computed: true, + }, + "updated_at": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: NodesType{ + ObjectType: types.ObjectType{ + AttrTypes: NodesValue{}.AttributeTypes(ctx), + }, + }, + }, + Computed: true, + }, + "role": schema.StringAttribute{ + Optional: true, + Computed: true, + Validators: []validator.String{ + stringvalidator.OneOf( + "worker", + ), + }, + Default: stringdefault.StaticString("worker"), + }, + "status": schema.BoolAttribute{ + Computed: true, + }, + }, + } +} + +type CoreClusterNodeGroupModel struct { + ClusterId types.Int64 `tfsdk:"cluster_id"` + Count types.Int64 `tfsdk:"count"` + FlavorName types.String `tfsdk:"flavor_name"` + MaxCount types.Int64 `tfsdk:"max_count"` + Message types.String `tfsdk:"message"` + MinCount types.Int64 `tfsdk:"min_count"` + Name types.String `tfsdk:"name"` + NodeGroup NodeGroupValue `tfsdk:"node_group"` + NodeGroupId types.Int64 `tfsdk:"node_group_id"` + Nodes types.List `tfsdk:"nodes"` + Role types.String `tfsdk:"role"` + Status types.Bool `tfsdk:"status"` +} + +var _ basetypes.ObjectTypable = NodeGroupType{} + +type NodeGroupType struct { + basetypes.ObjectType +} + +func (t NodeGroupType) Equal(o attr.Type) bool { + other, ok := o.(NodeGroupType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t NodeGroupType) String() string { + return "NodeGroupType" +} + +func (t NodeGroupType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + countAttribute, ok := attributes["count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `count is missing from object`) + + return nil, diags + } + + countVal, ok := countAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`count expected to be basetypes.Int64Value, was: %T`, countAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return nil, diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + flavorAttribute, ok := attributes["flavor"] + + if !ok { + diags.AddError( + "Attribute Missing", + `flavor is missing from object`) + + return nil, diags + } + + flavorVal, ok := flavorAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`flavor expected to be basetypes.ObjectValue, was: %T`, flavorAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + maxCountAttribute, ok := attributes["max_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `max_count is missing from object`) + + return nil, diags + } + + maxCountVal, ok := maxCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`max_count expected to be basetypes.Int64Value, was: %T`, maxCountAttribute)) + } + + minCountAttribute, ok := attributes["min_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `min_count is missing from object`) + + return nil, diags + } + + minCountVal, ok := minCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`min_count expected to be basetypes.Int64Value, was: %T`, minCountAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return nil, diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return nil, diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return NodeGroupValue{ + Count: countVal, + CreatedAt: createdAtVal, + Flavor: flavorVal, + Id: idVal, + MaxCount: maxCountVal, + MinCount: minCountVal, + Name: nameVal, + Role: roleVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodeGroupValueNull() NodeGroupValue { + return NodeGroupValue{ + state: attr.ValueStateNull, + } +} + +func NewNodeGroupValueUnknown() NodeGroupValue { + return NodeGroupValue{ + state: attr.ValueStateUnknown, + } +} + +func NewNodeGroupValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (NodeGroupValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing NodeGroupValue Attribute Value", + "While creating a NodeGroupValue value, a missing attribute value was detected. "+ + "A NodeGroupValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodeGroupValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid NodeGroupValue Attribute Type", + "While creating a NodeGroupValue value, an invalid attribute value was detected. "+ + "A NodeGroupValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodeGroupValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("NodeGroupValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra NodeGroupValue Attribute Value", + "While creating a NodeGroupValue value, an extra attribute value was detected. "+ + "A NodeGroupValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra NodeGroupValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewNodeGroupValueUnknown(), diags + } + + countAttribute, ok := attributes["count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `count is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + countVal, ok := countAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`count expected to be basetypes.Int64Value, was: %T`, countAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + flavorAttribute, ok := attributes["flavor"] + + if !ok { + diags.AddError( + "Attribute Missing", + `flavor is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + flavorVal, ok := flavorAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`flavor expected to be basetypes.ObjectValue, was: %T`, flavorAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + maxCountAttribute, ok := attributes["max_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `max_count is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + maxCountVal, ok := maxCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`max_count expected to be basetypes.Int64Value, was: %T`, maxCountAttribute)) + } + + minCountAttribute, ok := attributes["min_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `min_count is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + minCountVal, ok := minCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`min_count expected to be basetypes.Int64Value, was: %T`, minCountAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return NewNodeGroupValueUnknown(), diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return NewNodeGroupValueUnknown(), diags + } + + return NodeGroupValue{ + Count: countVal, + CreatedAt: createdAtVal, + Flavor: flavorVal, + Id: idVal, + MaxCount: maxCountVal, + MinCount: minCountVal, + Name: nameVal, + Role: roleVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodeGroupValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) NodeGroupValue { + object, diags := NewNodeGroupValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewNodeGroupValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t NodeGroupType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewNodeGroupValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewNodeGroupValueUnknown(), nil + } + + if in.IsNull() { + return NewNodeGroupValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewNodeGroupValueMust(NodeGroupValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t NodeGroupType) ValueType(ctx context.Context) attr.Value { + return NodeGroupValue{} +} + +var _ basetypes.ObjectValuable = NodeGroupValue{} + +type NodeGroupValue struct { + Count basetypes.Int64Value `tfsdk:"count"` + CreatedAt basetypes.StringValue `tfsdk:"created_at"` + Flavor basetypes.ObjectValue `tfsdk:"flavor"` + Id basetypes.Int64Value `tfsdk:"id"` + MaxCount basetypes.Int64Value `tfsdk:"max_count"` + MinCount basetypes.Int64Value `tfsdk:"min_count"` + Name basetypes.StringValue `tfsdk:"name"` + Role basetypes.StringValue `tfsdk:"role"` + UpdatedAt basetypes.StringValue `tfsdk:"updated_at"` + state attr.ValueState +} + +func (v NodeGroupValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 9) + + var val tftypes.Value + var err error + + attrTypes["count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["created_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["flavor"] = basetypes.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["max_count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["min_count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["role"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["updated_at"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 9) + + val, err = v.Count.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["count"] = val + + val, err = v.CreatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["created_at"] = val + + val, err = v.Flavor.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["flavor"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.MaxCount.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["max_count"] = val + + val, err = v.MinCount.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["min_count"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Role.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["role"] = val + + val, err = v.UpdatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["updated_at"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v NodeGroupValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v NodeGroupValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v NodeGroupValue) String() string { + return "NodeGroupValue" +} + +func (v NodeGroupValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + var flavor basetypes.ObjectValue + + if v.Flavor.IsNull() { + flavor = types.ObjectNull( + FlavorValue{}.AttributeTypes(ctx), + ) + } + + if v.Flavor.IsUnknown() { + flavor = types.ObjectUnknown( + FlavorValue{}.AttributeTypes(ctx), + ) + } + + if !v.Flavor.IsNull() && !v.Flavor.IsUnknown() { + flavor = types.ObjectValueMust( + FlavorValue{}.AttributeTypes(ctx), + v.Flavor.Attributes(), + ) + } + + attributeTypes := map[string]attr.Type{ + "count": basetypes.Int64Type{}, + "created_at": basetypes.StringType{}, + "flavor": basetypes.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }, + "id": basetypes.Int64Type{}, + "max_count": basetypes.Int64Type{}, + "min_count": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "role": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "count": v.Count, + "created_at": v.CreatedAt, + "flavor": flavor, + "id": v.Id, + "max_count": v.MaxCount, + "min_count": v.MinCount, + "name": v.Name, + "role": v.Role, + "updated_at": v.UpdatedAt, + }) + + return objVal, diags +} + +func (v NodeGroupValue) Equal(o attr.Value) bool { + other, ok := o.(NodeGroupValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Count.Equal(other.Count) { + return false + } + + if !v.CreatedAt.Equal(other.CreatedAt) { + return false + } + + if !v.Flavor.Equal(other.Flavor) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.MaxCount.Equal(other.MaxCount) { + return false + } + + if !v.MinCount.Equal(other.MinCount) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Role.Equal(other.Role) { + return false + } + + if !v.UpdatedAt.Equal(other.UpdatedAt) { + return false + } + + return true +} + +func (v NodeGroupValue) Type(ctx context.Context) attr.Type { + return NodeGroupType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v NodeGroupValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "count": basetypes.Int64Type{}, + "created_at": basetypes.StringType{}, + "flavor": basetypes.ObjectType{ + AttrTypes: FlavorValue{}.AttributeTypes(ctx), + }, + "id": basetypes.Int64Type{}, + "max_count": basetypes.Int64Type{}, + "min_count": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "role": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = FlavorType{} + +type FlavorType struct { + basetypes.ObjectType +} + +func (t FlavorType) Equal(o attr.Type) bool { + other, ok := o.(FlavorType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t FlavorType) String() string { + return "FlavorType" +} + +func (t FlavorType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cpuAttribute, ok := attributes["cpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cpu is missing from object`) + + return nil, diags + } + + cpuVal, ok := cpuAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cpu expected to be basetypes.Int64Value, was: %T`, cpuAttribute)) + } + + diskAttribute, ok := attributes["disk"] + + if !ok { + diags.AddError( + "Attribute Missing", + `disk is missing from object`) + + return nil, diags + } + + diskVal, ok := diskAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`disk expected to be basetypes.Int64Value, was: %T`, diskAttribute)) + } + + ephemeralAttribute, ok := attributes["ephemeral"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ephemeral is missing from object`) + + return nil, diags + } + + ephemeralVal, ok := ephemeralAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ephemeral expected to be basetypes.Int64Value, was: %T`, ephemeralAttribute)) + } + + featuresAttribute, ok := attributes["features"] + + if !ok { + diags.AddError( + "Attribute Missing", + `features is missing from object`) + + return nil, diags + } + + featuresVal, ok := featuresAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`features expected to be basetypes.ObjectValue, was: %T`, featuresAttribute)) + } + + gpuAttribute, ok := attributes["gpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu is missing from object`) + + return nil, diags + } + + gpuVal, ok := gpuAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu expected to be basetypes.StringValue, was: %T`, gpuAttribute)) + } + + gpuCountAttribute, ok := attributes["gpu_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu_count is missing from object`) + + return nil, diags + } + + gpuCountVal, ok := gpuCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu_count expected to be basetypes.Int64Value, was: %T`, gpuCountAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelsAttribute, ok := attributes["labels"] + + if !ok { + diags.AddError( + "Attribute Missing", + `labels is missing from object`) + + return nil, diags + } + + labelsVal, ok := labelsAttribute.(basetypes.ListValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`labels expected to be basetypes.ListValue, was: %T`, labelsAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + ramAttribute, ok := attributes["ram"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ram is missing from object`) + + return nil, diags + } + + ramVal, ok := ramAttribute.(basetypes.NumberValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ram expected to be basetypes.NumberValue, was: %T`, ramAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return FlavorValue{ + Cpu: cpuVal, + Disk: diskVal, + Ephemeral: ephemeralVal, + Features: featuresVal, + Gpu: gpuVal, + GpuCount: gpuCountVal, + Id: idVal, + Labels: labelsVal, + Name: nameVal, + Ram: ramVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewFlavorValueNull() FlavorValue { + return FlavorValue{ + state: attr.ValueStateNull, + } +} + +func NewFlavorValueUnknown() FlavorValue { + return FlavorValue{ + state: attr.ValueStateUnknown, + } +} + +func NewFlavorValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (FlavorValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing FlavorValue Attribute Value", + "While creating a FlavorValue value, a missing attribute value was detected. "+ + "A FlavorValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FlavorValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid FlavorValue Attribute Type", + "While creating a FlavorValue value, an invalid attribute value was detected. "+ + "A FlavorValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FlavorValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("FlavorValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra FlavorValue Attribute Value", + "While creating a FlavorValue value, an extra attribute value was detected. "+ + "A FlavorValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra FlavorValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewFlavorValueUnknown(), diags + } + + cpuAttribute, ok := attributes["cpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cpu is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + cpuVal, ok := cpuAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cpu expected to be basetypes.Int64Value, was: %T`, cpuAttribute)) + } + + diskAttribute, ok := attributes["disk"] + + if !ok { + diags.AddError( + "Attribute Missing", + `disk is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + diskVal, ok := diskAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`disk expected to be basetypes.Int64Value, was: %T`, diskAttribute)) + } + + ephemeralAttribute, ok := attributes["ephemeral"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ephemeral is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + ephemeralVal, ok := ephemeralAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ephemeral expected to be basetypes.Int64Value, was: %T`, ephemeralAttribute)) + } + + featuresAttribute, ok := attributes["features"] + + if !ok { + diags.AddError( + "Attribute Missing", + `features is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + featuresVal, ok := featuresAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`features expected to be basetypes.ObjectValue, was: %T`, featuresAttribute)) + } + + gpuAttribute, ok := attributes["gpu"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + gpuVal, ok := gpuAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu expected to be basetypes.StringValue, was: %T`, gpuAttribute)) + } + + gpuCountAttribute, ok := attributes["gpu_count"] + + if !ok { + diags.AddError( + "Attribute Missing", + `gpu_count is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + gpuCountVal, ok := gpuCountAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`gpu_count expected to be basetypes.Int64Value, was: %T`, gpuCountAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelsAttribute, ok := attributes["labels"] + + if !ok { + diags.AddError( + "Attribute Missing", + `labels is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + labelsVal, ok := labelsAttribute.(basetypes.ListValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`labels expected to be basetypes.ListValue, was: %T`, labelsAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + ramAttribute, ok := attributes["ram"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ram is missing from object`) + + return NewFlavorValueUnknown(), diags + } + + ramVal, ok := ramAttribute.(basetypes.NumberValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ram expected to be basetypes.NumberValue, was: %T`, ramAttribute)) + } + + if diags.HasError() { + return NewFlavorValueUnknown(), diags + } + + return FlavorValue{ + Cpu: cpuVal, + Disk: diskVal, + Ephemeral: ephemeralVal, + Features: featuresVal, + Gpu: gpuVal, + GpuCount: gpuCountVal, + Id: idVal, + Labels: labelsVal, + Name: nameVal, + Ram: ramVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewFlavorValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) FlavorValue { + object, diags := NewFlavorValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewFlavorValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t FlavorType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewFlavorValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewFlavorValueUnknown(), nil + } + + if in.IsNull() { + return NewFlavorValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewFlavorValueMust(FlavorValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t FlavorType) ValueType(ctx context.Context) attr.Value { + return FlavorValue{} +} + +var _ basetypes.ObjectValuable = FlavorValue{} + +type FlavorValue struct { + Cpu basetypes.Int64Value `tfsdk:"cpu"` + Disk basetypes.Int64Value `tfsdk:"disk"` + Ephemeral basetypes.Int64Value `tfsdk:"ephemeral"` + Features basetypes.ObjectValue `tfsdk:"features"` + Gpu basetypes.StringValue `tfsdk:"gpu"` + GpuCount basetypes.Int64Value `tfsdk:"gpu_count"` + Id basetypes.Int64Value `tfsdk:"id"` + Labels basetypes.ListValue `tfsdk:"labels"` + Name basetypes.StringValue `tfsdk:"name"` + Ram basetypes.NumberValue `tfsdk:"ram"` + state attr.ValueState +} + +func (v FlavorValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 10) + + var val tftypes.Value + var err error + + attrTypes["cpu"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["disk"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["ephemeral"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["features"] = basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["gpu"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["gpu_count"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["labels"] = basetypes.ListType{ + ElemType: LabelsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["ram"] = basetypes.NumberType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 10) + + val, err = v.Cpu.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cpu"] = val + + val, err = v.Disk.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["disk"] = val + + val, err = v.Ephemeral.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ephemeral"] = val + + val, err = v.Features.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["features"] = val + + val, err = v.Gpu.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["gpu"] = val + + val, err = v.GpuCount.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["gpu_count"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Labels.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["labels"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Ram.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ram"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v FlavorValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v FlavorValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v FlavorValue) String() string { + return "FlavorValue" +} + +func (v FlavorValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + var features basetypes.ObjectValue + + if v.Features.IsNull() { + features = types.ObjectNull( + FeaturesValue{}.AttributeTypes(ctx), + ) + } + + if v.Features.IsUnknown() { + features = types.ObjectUnknown( + FeaturesValue{}.AttributeTypes(ctx), + ) + } + + if !v.Features.IsNull() && !v.Features.IsUnknown() { + features = types.ObjectValueMust( + FeaturesValue{}.AttributeTypes(ctx), + v.Features.Attributes(), + ) + } + + labels := types.ListValueMust( + LabelsType{ + basetypes.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + v.Labels.Elements(), + ) + + if v.Labels.IsNull() { + labels = types.ListNull( + LabelsType{ + basetypes.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + ) + } + + if v.Labels.IsUnknown() { + labels = types.ListUnknown( + LabelsType{ + basetypes.ObjectType{ + AttrTypes: LabelsValue{}.AttributeTypes(ctx), + }, + }, + ) + } + + attributeTypes := map[string]attr.Type{ + "cpu": basetypes.Int64Type{}, + "disk": basetypes.Int64Type{}, + "ephemeral": basetypes.Int64Type{}, + "features": basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + "gpu": basetypes.StringType{}, + "gpu_count": basetypes.Int64Type{}, + "id": basetypes.Int64Type{}, + "labels": basetypes.ListType{ + ElemType: LabelsValue{}.Type(ctx), + }, + "name": basetypes.StringType{}, + "ram": basetypes.NumberType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "cpu": v.Cpu, + "disk": v.Disk, + "ephemeral": v.Ephemeral, + "features": features, + "gpu": v.Gpu, + "gpu_count": v.GpuCount, + "id": v.Id, + "labels": labels, + "name": v.Name, + "ram": v.Ram, + }) + + return objVal, diags +} + +func (v FlavorValue) Equal(o attr.Value) bool { + other, ok := o.(FlavorValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cpu.Equal(other.Cpu) { + return false + } + + if !v.Disk.Equal(other.Disk) { + return false + } + + if !v.Ephemeral.Equal(other.Ephemeral) { + return false + } + + if !v.Features.Equal(other.Features) { + return false + } + + if !v.Gpu.Equal(other.Gpu) { + return false + } + + if !v.GpuCount.Equal(other.GpuCount) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Labels.Equal(other.Labels) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Ram.Equal(other.Ram) { + return false + } + + return true +} + +func (v FlavorValue) Type(ctx context.Context) attr.Type { + return FlavorType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v FlavorValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cpu": basetypes.Int64Type{}, + "disk": basetypes.Int64Type{}, + "ephemeral": basetypes.Int64Type{}, + "features": basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + "gpu": basetypes.StringType{}, + "gpu_count": basetypes.Int64Type{}, + "id": basetypes.Int64Type{}, + "labels": basetypes.ListType{ + ElemType: LabelsValue{}.Type(ctx), + }, + "name": basetypes.StringType{}, + "ram": basetypes.NumberType{}, + } +} + +var _ basetypes.ObjectTypable = FeaturesType{} + +type FeaturesType struct { + basetypes.ObjectType +} + +func (t FeaturesType) Equal(o attr.Type) bool { + other, ok := o.(FeaturesType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t FeaturesType) String() string { + return "FeaturesType" +} + +func (t FeaturesType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + if diags.HasError() { + return nil, diags + } + + return FeaturesValue{ + state: attr.ValueStateKnown, + }, diags +} + +func NewFeaturesValueNull() FeaturesValue { + return FeaturesValue{ + state: attr.ValueStateNull, + } +} + +func NewFeaturesValueUnknown() FeaturesValue { + return FeaturesValue{ + state: attr.ValueStateUnknown, + } +} + +func NewFeaturesValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (FeaturesValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing FeaturesValue Attribute Value", + "While creating a FeaturesValue value, a missing attribute value was detected. "+ + "A FeaturesValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid FeaturesValue Attribute Type", + "While creating a FeaturesValue value, an invalid attribute value was detected. "+ + "A FeaturesValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra FeaturesValue Attribute Value", + "While creating a FeaturesValue value, an extra attribute value was detected. "+ + "A FeaturesValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra FeaturesValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewFeaturesValueUnknown(), diags + } + + if diags.HasError() { + return NewFeaturesValueUnknown(), diags + } + + return FeaturesValue{ + state: attr.ValueStateKnown, + }, diags +} + +func NewFeaturesValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) FeaturesValue { + object, diags := NewFeaturesValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewFeaturesValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t FeaturesType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewFeaturesValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewFeaturesValueUnknown(), nil + } + + if in.IsNull() { + return NewFeaturesValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewFeaturesValueMust(FeaturesValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t FeaturesType) ValueType(ctx context.Context) attr.Value { + return FeaturesValue{} +} + +var _ basetypes.ObjectValuable = FeaturesValue{} + +type FeaturesValue struct { + state attr.ValueState +} + +func (v FeaturesValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 0) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 0) + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v FeaturesValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v FeaturesValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v FeaturesValue) String() string { + return "FeaturesValue" +} + +func (v FeaturesValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{} + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{}) + + return objVal, diags +} + +func (v FeaturesValue) Equal(o attr.Value) bool { + other, ok := o.(FeaturesValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + return true +} + +func (v FeaturesValue) Type(ctx context.Context) attr.Type { + return FeaturesType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v FeaturesValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{} +} + +var _ basetypes.ObjectTypable = LabelsType{} + +type LabelsType struct { + basetypes.ObjectType +} + +func (t LabelsType) Equal(o attr.Type) bool { + other, ok := o.(LabelsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t LabelsType) String() string { + return "LabelsType" +} + +func (t LabelsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelAttribute, ok := attributes["label"] + + if !ok { + diags.AddError( + "Attribute Missing", + `label is missing from object`) + + return nil, diags + } + + labelVal, ok := labelAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`label expected to be basetypes.StringValue, was: %T`, labelAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return LabelsValue{ + Id: idVal, + Label: labelVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewLabelsValueNull() LabelsValue { + return LabelsValue{ + state: attr.ValueStateNull, + } +} + +func NewLabelsValueUnknown() LabelsValue { + return LabelsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewLabelsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (LabelsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing LabelsValue Attribute Value", + "While creating a LabelsValue value, a missing attribute value was detected. "+ + "A LabelsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("LabelsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid LabelsValue Attribute Type", + "While creating a LabelsValue value, an invalid attribute value was detected. "+ + "A LabelsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("LabelsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("LabelsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra LabelsValue Attribute Value", + "While creating a LabelsValue value, an extra attribute value was detected. "+ + "A LabelsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra LabelsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewLabelsValueUnknown(), diags + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewLabelsValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + labelAttribute, ok := attributes["label"] + + if !ok { + diags.AddError( + "Attribute Missing", + `label is missing from object`) + + return NewLabelsValueUnknown(), diags + } + + labelVal, ok := labelAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`label expected to be basetypes.StringValue, was: %T`, labelAttribute)) + } + + if diags.HasError() { + return NewLabelsValueUnknown(), diags + } + + return LabelsValue{ + Id: idVal, + Label: labelVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewLabelsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) LabelsValue { + object, diags := NewLabelsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewLabelsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t LabelsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewLabelsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewLabelsValueUnknown(), nil + } + + if in.IsNull() { + return NewLabelsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewLabelsValueMust(LabelsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t LabelsType) ValueType(ctx context.Context) attr.Value { + return LabelsValue{} +} + +var _ basetypes.ObjectValuable = LabelsValue{} + +type LabelsValue struct { + Id basetypes.Int64Value `tfsdk:"id"` + Label basetypes.StringValue `tfsdk:"label"` + state attr.ValueState +} + +func (v LabelsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 2) + + var val tftypes.Value + var err error + + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["label"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 2) + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Label.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["label"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v LabelsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v LabelsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v LabelsValue) String() string { + return "LabelsValue" +} + +func (v LabelsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{ + "id": basetypes.Int64Type{}, + "label": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "id": v.Id, + "label": v.Label, + }) + + return objVal, diags +} + +func (v LabelsValue) Equal(o attr.Value) bool { + other, ok := o.(LabelsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Label.Equal(other.Label) { + return false + } + + return true +} + +func (v LabelsValue) Type(ctx context.Context) attr.Type { + return LabelsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v LabelsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "id": basetypes.Int64Type{}, + "label": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = NodesType{} + +type NodesType struct { + basetypes.ObjectType +} + +func (t NodesType) Equal(o attr.Type) bool { + other, ok := o.(NodesType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t NodesType) String() string { + return "NodesType" +} + +func (t NodesType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return nil, diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + instanceAttribute, ok := attributes["instance"] + + if !ok { + diags.AddError( + "Attribute Missing", + `instance is missing from object`) + + return nil, diags + } + + instanceVal, ok := instanceAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`instance expected to be basetypes.ObjectValue, was: %T`, instanceAttribute)) + } + + isBastionAttribute, ok := attributes["is_bastion"] + + if !ok { + diags.AddError( + "Attribute Missing", + `is_bastion is missing from object`) + + return nil, diags + } + + isBastionVal, ok := isBastionAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`is_bastion expected to be basetypes.BoolValue, was: %T`, isBastionAttribute)) + } + + nodeGroupIdAttribute, ok := attributes["node_group_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_id is missing from object`) + + return nil, diags + } + + nodeGroupIdVal, ok := nodeGroupIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_id expected to be basetypes.Int64Value, was: %T`, nodeGroupIdAttribute)) + } + + nodeGroupNameAttribute, ok := attributes["node_group_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_name is missing from object`) + + return nil, diags + } + + nodeGroupNameVal, ok := nodeGroupNameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_name expected to be basetypes.StringValue, was: %T`, nodeGroupNameAttribute)) + } + + requiresPublicIpAttribute, ok := attributes["requires_public_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `requires_public_ip is missing from object`) + + return nil, diags + } + + requiresPublicIpVal, ok := requiresPublicIpAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`requires_public_ip expected to be basetypes.BoolValue, was: %T`, requiresPublicIpAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return nil, diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + statusReasonAttribute, ok := attributes["status_reason"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status_reason is missing from object`) + + return nil, diags + } + + statusReasonVal, ok := statusReasonAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status_reason expected to be basetypes.StringValue, was: %T`, statusReasonAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return nil, diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return NodesValue{ + CreatedAt: createdAtVal, + Id: idVal, + Instance: instanceVal, + IsBastion: isBastionVal, + NodeGroupId: nodeGroupIdVal, + NodeGroupName: nodeGroupNameVal, + RequiresPublicIp: requiresPublicIpVal, + Role: roleVal, + Status: statusVal, + StatusReason: statusReasonVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodesValueNull() NodesValue { + return NodesValue{ + state: attr.ValueStateNull, + } +} + +func NewNodesValueUnknown() NodesValue { + return NodesValue{ + state: attr.ValueStateUnknown, + } +} + +func NewNodesValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (NodesValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing NodesValue Attribute Value", + "While creating a NodesValue value, a missing attribute value was detected. "+ + "A NodesValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodesValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid NodesValue Attribute Type", + "While creating a NodesValue value, an invalid attribute value was detected. "+ + "A NodesValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("NodesValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("NodesValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra NodesValue Attribute Value", + "While creating a NodesValue value, an extra attribute value was detected. "+ + "A NodesValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra NodesValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewNodesValueUnknown(), diags + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return NewNodesValueUnknown(), diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewNodesValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + instanceAttribute, ok := attributes["instance"] + + if !ok { + diags.AddError( + "Attribute Missing", + `instance is missing from object`) + + return NewNodesValueUnknown(), diags + } + + instanceVal, ok := instanceAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`instance expected to be basetypes.ObjectValue, was: %T`, instanceAttribute)) + } + + isBastionAttribute, ok := attributes["is_bastion"] + + if !ok { + diags.AddError( + "Attribute Missing", + `is_bastion is missing from object`) + + return NewNodesValueUnknown(), diags + } + + isBastionVal, ok := isBastionAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`is_bastion expected to be basetypes.BoolValue, was: %T`, isBastionAttribute)) + } + + nodeGroupIdAttribute, ok := attributes["node_group_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_id is missing from object`) + + return NewNodesValueUnknown(), diags + } + + nodeGroupIdVal, ok := nodeGroupIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_id expected to be basetypes.Int64Value, was: %T`, nodeGroupIdAttribute)) + } + + nodeGroupNameAttribute, ok := attributes["node_group_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `node_group_name is missing from object`) + + return NewNodesValueUnknown(), diags + } + + nodeGroupNameVal, ok := nodeGroupNameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`node_group_name expected to be basetypes.StringValue, was: %T`, nodeGroupNameAttribute)) + } + + requiresPublicIpAttribute, ok := attributes["requires_public_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `requires_public_ip is missing from object`) + + return NewNodesValueUnknown(), diags + } + + requiresPublicIpVal, ok := requiresPublicIpAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`requires_public_ip expected to be basetypes.BoolValue, was: %T`, requiresPublicIpAttribute)) + } + + roleAttribute, ok := attributes["role"] + + if !ok { + diags.AddError( + "Attribute Missing", + `role is missing from object`) + + return NewNodesValueUnknown(), diags + } + + roleVal, ok := roleAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`role expected to be basetypes.StringValue, was: %T`, roleAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewNodesValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + statusReasonAttribute, ok := attributes["status_reason"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status_reason is missing from object`) + + return NewNodesValueUnknown(), diags + } + + statusReasonVal, ok := statusReasonAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status_reason expected to be basetypes.StringValue, was: %T`, statusReasonAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return NewNodesValueUnknown(), diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return NewNodesValueUnknown(), diags + } + + return NodesValue{ + CreatedAt: createdAtVal, + Id: idVal, + Instance: instanceVal, + IsBastion: isBastionVal, + NodeGroupId: nodeGroupIdVal, + NodeGroupName: nodeGroupNameVal, + RequiresPublicIp: requiresPublicIpVal, + Role: roleVal, + Status: statusVal, + StatusReason: statusReasonVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewNodesValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) NodesValue { + object, diags := NewNodesValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewNodesValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t NodesType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewNodesValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewNodesValueUnknown(), nil + } + + if in.IsNull() { + return NewNodesValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewNodesValueMust(NodesValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t NodesType) ValueType(ctx context.Context) attr.Value { + return NodesValue{} +} + +var _ basetypes.ObjectValuable = NodesValue{} + +type NodesValue struct { + CreatedAt basetypes.StringValue `tfsdk:"created_at"` + Id basetypes.Int64Value `tfsdk:"id"` + Instance basetypes.ObjectValue `tfsdk:"instance"` + IsBastion basetypes.BoolValue `tfsdk:"is_bastion"` + NodeGroupId basetypes.Int64Value `tfsdk:"node_group_id"` + NodeGroupName basetypes.StringValue `tfsdk:"node_group_name"` + RequiresPublicIp basetypes.BoolValue `tfsdk:"requires_public_ip"` + Role basetypes.StringValue `tfsdk:"role"` + Status basetypes.StringValue `tfsdk:"status"` + StatusReason basetypes.StringValue `tfsdk:"status_reason"` + UpdatedAt basetypes.StringValue `tfsdk:"updated_at"` + state attr.ValueState +} + +func (v NodesValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 11) + + var val tftypes.Value + var err error + + attrTypes["created_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["instance"] = basetypes.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["is_bastion"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["node_group_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["node_group_name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["requires_public_ip"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["role"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status_reason"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["updated_at"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 11) + + val, err = v.CreatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["created_at"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Instance.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["instance"] = val + + val, err = v.IsBastion.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["is_bastion"] = val + + val, err = v.NodeGroupId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["node_group_id"] = val + + val, err = v.NodeGroupName.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["node_group_name"] = val + + val, err = v.RequiresPublicIp.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["requires_public_ip"] = val + + val, err = v.Role.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["role"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + val, err = v.StatusReason.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status_reason"] = val + + val, err = v.UpdatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["updated_at"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v NodesValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v NodesValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v NodesValue) String() string { + return "NodesValue" +} + +func (v NodesValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + var instance basetypes.ObjectValue + + if v.Instance.IsNull() { + instance = types.ObjectNull( + InstanceValue{}.AttributeTypes(ctx), + ) + } + + if v.Instance.IsUnknown() { + instance = types.ObjectUnknown( + InstanceValue{}.AttributeTypes(ctx), + ) + } + + if !v.Instance.IsNull() && !v.Instance.IsUnknown() { + instance = types.ObjectValueMust( + InstanceValue{}.AttributeTypes(ctx), + v.Instance.Attributes(), + ) + } + + attributeTypes := map[string]attr.Type{ + "created_at": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "instance": basetypes.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }, + "is_bastion": basetypes.BoolType{}, + "node_group_id": basetypes.Int64Type{}, + "node_group_name": basetypes.StringType{}, + "requires_public_ip": basetypes.BoolType{}, + "role": basetypes.StringType{}, + "status": basetypes.StringType{}, + "status_reason": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "created_at": v.CreatedAt, + "id": v.Id, + "instance": instance, + "is_bastion": v.IsBastion, + "node_group_id": v.NodeGroupId, + "node_group_name": v.NodeGroupName, + "requires_public_ip": v.RequiresPublicIp, + "role": v.Role, + "status": v.Status, + "status_reason": v.StatusReason, + "updated_at": v.UpdatedAt, + }) + + return objVal, diags +} + +func (v NodesValue) Equal(o attr.Value) bool { + other, ok := o.(NodesValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.CreatedAt.Equal(other.CreatedAt) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Instance.Equal(other.Instance) { + return false + } + + if !v.IsBastion.Equal(other.IsBastion) { + return false + } + + if !v.NodeGroupId.Equal(other.NodeGroupId) { + return false + } + + if !v.NodeGroupName.Equal(other.NodeGroupName) { + return false + } + + if !v.RequiresPublicIp.Equal(other.RequiresPublicIp) { + return false + } + + if !v.Role.Equal(other.Role) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + if !v.StatusReason.Equal(other.StatusReason) { + return false + } + + if !v.UpdatedAt.Equal(other.UpdatedAt) { + return false + } + + return true +} + +func (v NodesValue) Type(ctx context.Context) attr.Type { + return NodesType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v NodesValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "created_at": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "instance": basetypes.ObjectType{ + AttrTypes: InstanceValue{}.AttributeTypes(ctx), + }, + "is_bastion": basetypes.BoolType{}, + "node_group_id": basetypes.Int64Type{}, + "node_group_name": basetypes.StringType{}, + "requires_public_ip": basetypes.BoolType{}, + "role": basetypes.StringType{}, + "status": basetypes.StringType{}, + "status_reason": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = InstanceType{} + +type InstanceType struct { + basetypes.ObjectType +} + +func (t InstanceType) Equal(o attr.Type) bool { + other, ok := o.(InstanceType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t InstanceType) String() string { + return "InstanceType" +} + +func (t InstanceType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + contractIdAttribute, ok := attributes["contract_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `contract_id is missing from object`) + + return nil, diags + } + + contractIdVal, ok := contractIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`contract_id expected to be basetypes.Int64Value, was: %T`, contractIdAttribute)) + } + + fixedIpAttribute, ok := attributes["fixed_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `fixed_ip is missing from object`) + + return nil, diags + } + + fixedIpVal, ok := fixedIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`fixed_ip expected to be basetypes.StringValue, was: %T`, fixedIpAttribute)) + } + + floatingIpAttribute, ok := attributes["floating_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip is missing from object`) + + return nil, diags + } + + floatingIpVal, ok := floatingIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip expected to be basetypes.StringValue, was: %T`, floatingIpAttribute)) + } + + floatingIpStatusAttribute, ok := attributes["floating_ip_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip_status is missing from object`) + + return nil, diags + } + + floatingIpStatusVal, ok := floatingIpStatusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip_status expected to be basetypes.StringValue, was: %T`, floatingIpStatusAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + imageIdAttribute, ok := attributes["image_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `image_id is missing from object`) + + return nil, diags + } + + imageIdVal, ok := imageIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`image_id expected to be basetypes.Int64Value, was: %T`, imageIdAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return InstanceValue{ + ContractId: contractIdVal, + FixedIp: fixedIpVal, + FloatingIp: floatingIpVal, + FloatingIpStatus: floatingIpStatusVal, + Id: idVal, + ImageId: imageIdVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewInstanceValueNull() InstanceValue { + return InstanceValue{ + state: attr.ValueStateNull, + } +} + +func NewInstanceValueUnknown() InstanceValue { + return InstanceValue{ + state: attr.ValueStateUnknown, + } +} + +func NewInstanceValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (InstanceValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing InstanceValue Attribute Value", + "While creating a InstanceValue value, a missing attribute value was detected. "+ + "A InstanceValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("InstanceValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid InstanceValue Attribute Type", + "While creating a InstanceValue value, an invalid attribute value was detected. "+ + "A InstanceValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("InstanceValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("InstanceValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra InstanceValue Attribute Value", + "While creating a InstanceValue value, an extra attribute value was detected. "+ + "A InstanceValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra InstanceValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewInstanceValueUnknown(), diags + } + + contractIdAttribute, ok := attributes["contract_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `contract_id is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + contractIdVal, ok := contractIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`contract_id expected to be basetypes.Int64Value, was: %T`, contractIdAttribute)) + } + + fixedIpAttribute, ok := attributes["fixed_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `fixed_ip is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + fixedIpVal, ok := fixedIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`fixed_ip expected to be basetypes.StringValue, was: %T`, fixedIpAttribute)) + } + + floatingIpAttribute, ok := attributes["floating_ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + floatingIpVal, ok := floatingIpAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip expected to be basetypes.StringValue, was: %T`, floatingIpAttribute)) + } + + floatingIpStatusAttribute, ok := attributes["floating_ip_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `floating_ip_status is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + floatingIpStatusVal, ok := floatingIpStatusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`floating_ip_status expected to be basetypes.StringValue, was: %T`, floatingIpStatusAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + imageIdAttribute, ok := attributes["image_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `image_id is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + imageIdVal, ok := imageIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`image_id expected to be basetypes.Int64Value, was: %T`, imageIdAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewInstanceValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return NewInstanceValueUnknown(), diags + } + + return InstanceValue{ + ContractId: contractIdVal, + FixedIp: fixedIpVal, + FloatingIp: floatingIpVal, + FloatingIpStatus: floatingIpStatusVal, + Id: idVal, + ImageId: imageIdVal, + Name: nameVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewInstanceValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) InstanceValue { + object, diags := NewInstanceValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewInstanceValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t InstanceType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewInstanceValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewInstanceValueUnknown(), nil + } + + if in.IsNull() { + return NewInstanceValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewInstanceValueMust(InstanceValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t InstanceType) ValueType(ctx context.Context) attr.Value { + return InstanceValue{} +} + +var _ basetypes.ObjectValuable = InstanceValue{} + +type InstanceValue struct { + ContractId basetypes.Int64Value `tfsdk:"contract_id"` + FixedIp basetypes.StringValue `tfsdk:"fixed_ip"` + FloatingIp basetypes.StringValue `tfsdk:"floating_ip"` + FloatingIpStatus basetypes.StringValue `tfsdk:"floating_ip_status"` + Id basetypes.Int64Value `tfsdk:"id"` + ImageId basetypes.Int64Value `tfsdk:"image_id"` + Name basetypes.StringValue `tfsdk:"name"` + Status basetypes.StringValue `tfsdk:"status"` + state attr.ValueState +} + +func (v InstanceValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 8) + + var val tftypes.Value + var err error + + attrTypes["contract_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["fixed_ip"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["floating_ip"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["floating_ip_status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["image_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 8) + + val, err = v.ContractId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["contract_id"] = val + + val, err = v.FixedIp.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["fixed_ip"] = val + + val, err = v.FloatingIp.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["floating_ip"] = val + + val, err = v.FloatingIpStatus.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["floating_ip_status"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.ImageId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["image_id"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v InstanceValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v InstanceValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v InstanceValue) String() string { + return "InstanceValue" +} + +func (v InstanceValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{ + "contract_id": basetypes.Int64Type{}, + "fixed_ip": basetypes.StringType{}, + "floating_ip": basetypes.StringType{}, + "floating_ip_status": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "image_id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "status": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "contract_id": v.ContractId, + "fixed_ip": v.FixedIp, + "floating_ip": v.FloatingIp, + "floating_ip_status": v.FloatingIpStatus, + "id": v.Id, + "image_id": v.ImageId, + "name": v.Name, + "status": v.Status, + }) + + return objVal, diags +} + +func (v InstanceValue) Equal(o attr.Value) bool { + other, ok := o.(InstanceValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.ContractId.Equal(other.ContractId) { + return false + } + + if !v.FixedIp.Equal(other.FixedIp) { + return false + } + + if !v.FloatingIp.Equal(other.FloatingIp) { + return false + } + + if !v.FloatingIpStatus.Equal(other.FloatingIpStatus) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.ImageId.Equal(other.ImageId) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + return true +} + +func (v InstanceValue) Type(ctx context.Context) attr.Type { + return InstanceType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v InstanceValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "contract_id": basetypes.Int64Type{}, + "fixed_ip": basetypes.StringType{}, + "floating_ip": basetypes.StringType{}, + "floating_ip_status": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "image_id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "status": basetypes.StringType{}, + } +} diff --git a/internal/genprovider/resource_core_virtual_machine_sg_rule/core_virtual_machine_sg_rule_resource_gen.go b/internal/genprovider/resource_core_virtual_machine_sg_rule/core_virtual_machine_sg_rule_resource_gen.go index 94a65ad..92de7a5 100644 --- a/internal/genprovider/resource_core_virtual_machine_sg_rule/core_virtual_machine_sg_rule_resource_gen.go +++ b/internal/genprovider/resource_core_virtual_machine_sg_rule/core_virtual_machine_sg_rule_resource_gen.go @@ -4,12 +4,20 @@ package resource_core_virtual_machine_sg_rule import ( "context" + "fmt" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "strings" "github.com/hashicorp/terraform-plugin-framework/resource/schema" ) @@ -17,12 +25,6 @@ import ( func CoreVirtualMachineSgRuleResourceSchema(ctx context.Context) schema.Schema { return schema.Schema{ Attributes: map[string]schema.Attribute{ - "created_at": schema.StringAttribute{ - Computed: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), - }, - }, "direction": schema.StringAttribute{ Required: true, Description: "The direction of traffic that the firewall rule applies to.", @@ -41,8 +43,11 @@ func CoreVirtualMachineSgRuleResourceSchema(ctx context.Context) schema.Schema { }, "id": schema.Int64Attribute{ Computed: true, - PlanModifiers: []planmodifier.Int64{ - int64planmodifier.RequiresReplace(), + }, + "message": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), }, }, "port_range_max": schema.Int64Attribute{ @@ -105,14 +110,83 @@ func CoreVirtualMachineSgRuleResourceSchema(ctx context.Context) schema.Schema { stringplanmodifier.RequiresReplace(), }, }, - "status": schema.StringAttribute{ + "security_rule": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "created_at": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "direction": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "ethertype": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "id": schema.Int64Attribute{ + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "port_range_max": schema.Int64Attribute{ + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "port_range_min": schema.Int64Attribute{ + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "protocol": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "remote_ip_prefix": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "status": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + }, + CustomType: SecurityRuleType{ + ObjectType: types.ObjectType{ + AttrTypes: SecurityRuleValue{}.AttributeTypes(ctx), + }, + }, Computed: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), + PlanModifiers: []planmodifier.Object{ + objectplanmodifier.RequiresReplace(), + }, + }, + "status": schema.BoolAttribute{ + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), }, }, "virtual_machine_id": schema.Int64Attribute{ - Required: true, + Required: true, + Description: "The ID of the virtual machine to attach the security rule to.", + MarkdownDescription: "The ID of the virtual machine to attach the security rule to.", PlanModifiers: []planmodifier.Int64{ int64planmodifier.RequiresReplace(), }, @@ -122,14 +196,779 @@ func CoreVirtualMachineSgRuleResourceSchema(ctx context.Context) schema.Schema { } type CoreVirtualMachineSgRuleModel struct { - CreatedAt types.String `tfsdk:"created_at"` - Direction types.String `tfsdk:"direction"` - Ethertype types.String `tfsdk:"ethertype"` - Id types.Int64 `tfsdk:"id"` - PortRangeMax types.Int64 `tfsdk:"port_range_max"` - PortRangeMin types.Int64 `tfsdk:"port_range_min"` - Protocol types.String `tfsdk:"protocol"` - RemoteIpPrefix types.String `tfsdk:"remote_ip_prefix"` - Status types.String `tfsdk:"status"` - VirtualMachineId types.Int64 `tfsdk:"virtual_machine_id"` + Direction types.String `tfsdk:"direction"` + Ethertype types.String `tfsdk:"ethertype"` + Id types.Int64 `tfsdk:"id"` + Message types.String `tfsdk:"message"` + PortRangeMax types.Int64 `tfsdk:"port_range_max"` + PortRangeMin types.Int64 `tfsdk:"port_range_min"` + Protocol types.String `tfsdk:"protocol"` + RemoteIpPrefix types.String `tfsdk:"remote_ip_prefix"` + SecurityRule SecurityRuleValue `tfsdk:"security_rule"` + Status types.Bool `tfsdk:"status"` + VirtualMachineId types.Int64 `tfsdk:"virtual_machine_id"` +} + +var _ basetypes.ObjectTypable = SecurityRuleType{} + +type SecurityRuleType struct { + basetypes.ObjectType +} + +func (t SecurityRuleType) Equal(o attr.Type) bool { + other, ok := o.(SecurityRuleType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t SecurityRuleType) String() string { + return "SecurityRuleType" +} + +func (t SecurityRuleType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return nil, diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + directionAttribute, ok := attributes["direction"] + + if !ok { + diags.AddError( + "Attribute Missing", + `direction is missing from object`) + + return nil, diags + } + + directionVal, ok := directionAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`direction expected to be basetypes.StringValue, was: %T`, directionAttribute)) + } + + ethertypeAttribute, ok := attributes["ethertype"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ethertype is missing from object`) + + return nil, diags + } + + ethertypeVal, ok := ethertypeAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ethertype expected to be basetypes.StringValue, was: %T`, ethertypeAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + portRangeMaxAttribute, ok := attributes["port_range_max"] + + if !ok { + diags.AddError( + "Attribute Missing", + `port_range_max is missing from object`) + + return nil, diags + } + + portRangeMaxVal, ok := portRangeMaxAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`port_range_max expected to be basetypes.Int64Value, was: %T`, portRangeMaxAttribute)) + } + + portRangeMinAttribute, ok := attributes["port_range_min"] + + if !ok { + diags.AddError( + "Attribute Missing", + `port_range_min is missing from object`) + + return nil, diags + } + + portRangeMinVal, ok := portRangeMinAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`port_range_min expected to be basetypes.Int64Value, was: %T`, portRangeMinAttribute)) + } + + protocolAttribute, ok := attributes["protocol"] + + if !ok { + diags.AddError( + "Attribute Missing", + `protocol is missing from object`) + + return nil, diags + } + + protocolVal, ok := protocolAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`protocol expected to be basetypes.StringValue, was: %T`, protocolAttribute)) + } + + remoteIpPrefixAttribute, ok := attributes["remote_ip_prefix"] + + if !ok { + diags.AddError( + "Attribute Missing", + `remote_ip_prefix is missing from object`) + + return nil, diags + } + + remoteIpPrefixVal, ok := remoteIpPrefixAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`remote_ip_prefix expected to be basetypes.StringValue, was: %T`, remoteIpPrefixAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return SecurityRuleValue{ + CreatedAt: createdAtVal, + Direction: directionVal, + Ethertype: ethertypeVal, + Id: idVal, + PortRangeMax: portRangeMaxVal, + PortRangeMin: portRangeMinVal, + Protocol: protocolVal, + RemoteIpPrefix: remoteIpPrefixVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewSecurityRuleValueNull() SecurityRuleValue { + return SecurityRuleValue{ + state: attr.ValueStateNull, + } +} + +func NewSecurityRuleValueUnknown() SecurityRuleValue { + return SecurityRuleValue{ + state: attr.ValueStateUnknown, + } +} + +func NewSecurityRuleValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (SecurityRuleValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing SecurityRuleValue Attribute Value", + "While creating a SecurityRuleValue value, a missing attribute value was detected. "+ + "A SecurityRuleValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("SecurityRuleValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid SecurityRuleValue Attribute Type", + "While creating a SecurityRuleValue value, an invalid attribute value was detected. "+ + "A SecurityRuleValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("SecurityRuleValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("SecurityRuleValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra SecurityRuleValue Attribute Value", + "While creating a SecurityRuleValue value, an extra attribute value was detected. "+ + "A SecurityRuleValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra SecurityRuleValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewSecurityRuleValueUnknown(), diags + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return NewSecurityRuleValueUnknown(), diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + directionAttribute, ok := attributes["direction"] + + if !ok { + diags.AddError( + "Attribute Missing", + `direction is missing from object`) + + return NewSecurityRuleValueUnknown(), diags + } + + directionVal, ok := directionAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`direction expected to be basetypes.StringValue, was: %T`, directionAttribute)) + } + + ethertypeAttribute, ok := attributes["ethertype"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ethertype is missing from object`) + + return NewSecurityRuleValueUnknown(), diags + } + + ethertypeVal, ok := ethertypeAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ethertype expected to be basetypes.StringValue, was: %T`, ethertypeAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewSecurityRuleValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + portRangeMaxAttribute, ok := attributes["port_range_max"] + + if !ok { + diags.AddError( + "Attribute Missing", + `port_range_max is missing from object`) + + return NewSecurityRuleValueUnknown(), diags + } + + portRangeMaxVal, ok := portRangeMaxAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`port_range_max expected to be basetypes.Int64Value, was: %T`, portRangeMaxAttribute)) + } + + portRangeMinAttribute, ok := attributes["port_range_min"] + + if !ok { + diags.AddError( + "Attribute Missing", + `port_range_min is missing from object`) + + return NewSecurityRuleValueUnknown(), diags + } + + portRangeMinVal, ok := portRangeMinAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`port_range_min expected to be basetypes.Int64Value, was: %T`, portRangeMinAttribute)) + } + + protocolAttribute, ok := attributes["protocol"] + + if !ok { + diags.AddError( + "Attribute Missing", + `protocol is missing from object`) + + return NewSecurityRuleValueUnknown(), diags + } + + protocolVal, ok := protocolAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`protocol expected to be basetypes.StringValue, was: %T`, protocolAttribute)) + } + + remoteIpPrefixAttribute, ok := attributes["remote_ip_prefix"] + + if !ok { + diags.AddError( + "Attribute Missing", + `remote_ip_prefix is missing from object`) + + return NewSecurityRuleValueUnknown(), diags + } + + remoteIpPrefixVal, ok := remoteIpPrefixAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`remote_ip_prefix expected to be basetypes.StringValue, was: %T`, remoteIpPrefixAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewSecurityRuleValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return NewSecurityRuleValueUnknown(), diags + } + + return SecurityRuleValue{ + CreatedAt: createdAtVal, + Direction: directionVal, + Ethertype: ethertypeVal, + Id: idVal, + PortRangeMax: portRangeMaxVal, + PortRangeMin: portRangeMinVal, + Protocol: protocolVal, + RemoteIpPrefix: remoteIpPrefixVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewSecurityRuleValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) SecurityRuleValue { + object, diags := NewSecurityRuleValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewSecurityRuleValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t SecurityRuleType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewSecurityRuleValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewSecurityRuleValueUnknown(), nil + } + + if in.IsNull() { + return NewSecurityRuleValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewSecurityRuleValueMust(SecurityRuleValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t SecurityRuleType) ValueType(ctx context.Context) attr.Value { + return SecurityRuleValue{} +} + +var _ basetypes.ObjectValuable = SecurityRuleValue{} + +type SecurityRuleValue struct { + CreatedAt basetypes.StringValue `tfsdk:"created_at"` + Direction basetypes.StringValue `tfsdk:"direction"` + Ethertype basetypes.StringValue `tfsdk:"ethertype"` + Id basetypes.Int64Value `tfsdk:"id"` + PortRangeMax basetypes.Int64Value `tfsdk:"port_range_max"` + PortRangeMin basetypes.Int64Value `tfsdk:"port_range_min"` + Protocol basetypes.StringValue `tfsdk:"protocol"` + RemoteIpPrefix basetypes.StringValue `tfsdk:"remote_ip_prefix"` + Status basetypes.StringValue `tfsdk:"status"` + state attr.ValueState +} + +func (v SecurityRuleValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 9) + + var val tftypes.Value + var err error + + attrTypes["created_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["direction"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["ethertype"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["port_range_max"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["port_range_min"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["protocol"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["remote_ip_prefix"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 9) + + val, err = v.CreatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["created_at"] = val + + val, err = v.Direction.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["direction"] = val + + val, err = v.Ethertype.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ethertype"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.PortRangeMax.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["port_range_max"] = val + + val, err = v.PortRangeMin.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["port_range_min"] = val + + val, err = v.Protocol.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["protocol"] = val + + val, err = v.RemoteIpPrefix.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["remote_ip_prefix"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v SecurityRuleValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v SecurityRuleValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v SecurityRuleValue) String() string { + return "SecurityRuleValue" +} + +func (v SecurityRuleValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{ + "created_at": basetypes.StringType{}, + "direction": basetypes.StringType{}, + "ethertype": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "port_range_max": basetypes.Int64Type{}, + "port_range_min": basetypes.Int64Type{}, + "protocol": basetypes.StringType{}, + "remote_ip_prefix": basetypes.StringType{}, + "status": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "created_at": v.CreatedAt, + "direction": v.Direction, + "ethertype": v.Ethertype, + "id": v.Id, + "port_range_max": v.PortRangeMax, + "port_range_min": v.PortRangeMin, + "protocol": v.Protocol, + "remote_ip_prefix": v.RemoteIpPrefix, + "status": v.Status, + }) + + return objVal, diags +} + +func (v SecurityRuleValue) Equal(o attr.Value) bool { + other, ok := o.(SecurityRuleValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.CreatedAt.Equal(other.CreatedAt) { + return false + } + + if !v.Direction.Equal(other.Direction) { + return false + } + + if !v.Ethertype.Equal(other.Ethertype) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.PortRangeMax.Equal(other.PortRangeMax) { + return false + } + + if !v.PortRangeMin.Equal(other.PortRangeMin) { + return false + } + + if !v.Protocol.Equal(other.Protocol) { + return false + } + + if !v.RemoteIpPrefix.Equal(other.RemoteIpPrefix) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + return true +} + +func (v SecurityRuleValue) Type(ctx context.Context) attr.Type { + return SecurityRuleType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v SecurityRuleValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "created_at": basetypes.StringType{}, + "direction": basetypes.StringType{}, + "ethertype": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "port_range_max": basetypes.Int64Type{}, + "port_range_min": basetypes.Int64Type{}, + "protocol": basetypes.StringType{}, + "remote_ip_prefix": basetypes.StringType{}, + "status": basetypes.StringType{}, + } } diff --git a/internal/genprovider/resource_core_volume/core_volume_resource_gen.go b/internal/genprovider/resource_core_volume/core_volume_resource_gen.go index 9da9cd9..0daca17 100644 --- a/internal/genprovider/resource_core_volume/core_volume_resource_gen.go +++ b/internal/genprovider/resource_core_volume/core_volume_resource_gen.go @@ -23,9 +23,6 @@ import ( func CoreVolumeResourceSchema(ctx context.Context) schema.Schema { return schema.Schema{ Attributes: map[string]schema.Attribute{ - "bootable": schema.BoolAttribute{ - Computed: true, - }, "callback_url": schema.StringAttribute{ Optional: true, Computed: true, @@ -38,9 +35,6 @@ func CoreVolumeResourceSchema(ctx context.Context) schema.Schema { stringvalidator.LengthAtMost(250), }, }, - "created_at": schema.StringAttribute{ - Computed: true, - }, "description": schema.StringAttribute{ Optional: true, Computed: true, @@ -50,30 +44,14 @@ func CoreVolumeResourceSchema(ctx context.Context) schema.Schema { stringplanmodifier.RequiresReplace(), }, }, - "environment": schema.SingleNestedAttribute{ - Attributes: map[string]schema.Attribute{ - "name": schema.StringAttribute{ - Computed: true, - }, - }, - CustomType: EnvironmentType{ - ObjectType: types.ObjectType{ - AttrTypes: EnvironmentValue{}.AttributeTypes(ctx), - }, - }, - Computed: true, - }, "environment_name": schema.StringAttribute{ Required: true, - Description: "The name of the [environment](https://infrahub-doc.nexgencloud.com/docs/features/environments-available-features) within which the volume is being created.", - MarkdownDescription: "The name of the [environment](https://infrahub-doc.nexgencloud.com/docs/features/environments-available-features) within which the volume is being created.", + Description: "The name of the [environment](https://docs.hyperstack.cloud/docs/api-reference/core-resources/environments/) within which the volume is being created.", + MarkdownDescription: "The name of the [environment](https://docs.hyperstack.cloud/docs/api-reference/core-resources/environments/) within which the volume is being created.", PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), }, }, - "id": schema.Int64Attribute{ - Computed: true, - }, "image_id": schema.Int64Attribute{ Optional: true, Computed: true, @@ -83,6 +61,9 @@ func CoreVolumeResourceSchema(ctx context.Context) schema.Schema { int64planmodifier.RequiresReplace(), }, }, + "message": schema.StringAttribute{ + Computed: true, + }, "name": schema.StringAttribute{ Required: true, Description: "The name of the volume being created.", @@ -94,9 +75,6 @@ func CoreVolumeResourceSchema(ctx context.Context) schema.Schema { stringvalidator.LengthAtMost(50), }, }, - "os_image": schema.StringAttribute{ - Computed: true, - }, "size": schema.Int64Attribute{ Required: true, Description: "The size of the volume in GB. 1048576GB storage capacity per volume.", @@ -105,10 +83,109 @@ func CoreVolumeResourceSchema(ctx context.Context) schema.Schema { int64planmodifier.RequiresReplace(), }, }, - "status": schema.StringAttribute{ + "status": schema.BoolAttribute{ + Computed: true, + }, + "volume": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "attachments": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "device": schema.StringAttribute{ + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "instance_id": schema.Int64Attribute{ + Computed: true, + }, + "protected": schema.BoolAttribute{ + Computed: true, + }, + "status": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: AttachmentsType{ + ObjectType: types.ObjectType{ + AttrTypes: AttachmentsValue{}.AttributeTypes(ctx), + }, + }, + }, + Computed: true, + }, + "bootable": schema.BoolAttribute{ + Computed: true, + }, + "callback_url": schema.StringAttribute{ + Computed: true, + }, + "created_at": schema.StringAttribute{ + Computed: true, + }, + "description": schema.StringAttribute{ + Computed: true, + }, + "environment": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "features": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{}, + CustomType: FeaturesType{ + ObjectType: types.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "region": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: EnvironmentType{ + ObjectType: types.ObjectType{ + AttrTypes: EnvironmentValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + }, + "id": schema.Int64Attribute{ + Computed: true, + }, + "image_id": schema.Int64Attribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "os_image": schema.StringAttribute{ + Computed: true, + }, + "size": schema.Int64Attribute{ + Computed: true, + }, + "status": schema.StringAttribute{ + Computed: true, + }, + "updated_at": schema.StringAttribute{ + Computed: true, + }, + "volume_type": schema.StringAttribute{ + Computed: true, + }, + }, + CustomType: VolumeType{ + ObjectType: types.ObjectType{ + AttrTypes: VolumeValue{}.AttributeTypes(ctx), + }, + }, Computed: true, }, - "updated_at": schema.StringAttribute{ + "volume_id": schema.Int64Attribute{ + Optional: true, Computed: true, }, "volume_type": schema.StringAttribute{ @@ -123,89 +200,2171 @@ func CoreVolumeResourceSchema(ctx context.Context) schema.Schema { } } -type CoreVolumeModel struct { - Bootable types.Bool `tfsdk:"bootable"` - CallbackUrl types.String `tfsdk:"callback_url"` - CreatedAt types.String `tfsdk:"created_at"` - Description types.String `tfsdk:"description"` - Environment EnvironmentValue `tfsdk:"environment"` - EnvironmentName types.String `tfsdk:"environment_name"` - Id types.Int64 `tfsdk:"id"` - ImageId types.Int64 `tfsdk:"image_id"` - Name types.String `tfsdk:"name"` - OsImage types.String `tfsdk:"os_image"` - Size types.Int64 `tfsdk:"size"` - Status types.String `tfsdk:"status"` - UpdatedAt types.String `tfsdk:"updated_at"` - VolumeType types.String `tfsdk:"volume_type"` +type CoreVolumeModel struct { + CallbackUrl types.String `tfsdk:"callback_url"` + Description types.String `tfsdk:"description"` + EnvironmentName types.String `tfsdk:"environment_name"` + ImageId types.Int64 `tfsdk:"image_id"` + Message types.String `tfsdk:"message"` + Name types.String `tfsdk:"name"` + Size types.Int64 `tfsdk:"size"` + Status types.Bool `tfsdk:"status"` + Volume VolumeValue `tfsdk:"volume"` + VolumeId types.Int64 `tfsdk:"volume_id"` + VolumeType types.String `tfsdk:"volume_type"` +} + +var _ basetypes.ObjectTypable = VolumeType{} + +type VolumeType struct { + basetypes.ObjectType +} + +func (t VolumeType) Equal(o attr.Type) bool { + other, ok := o.(VolumeType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VolumeType) String() string { + return "VolumeType" +} + +func (t VolumeType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + attachmentsAttribute, ok := attributes["attachments"] + + if !ok { + diags.AddError( + "Attribute Missing", + `attachments is missing from object`) + + return nil, diags + } + + attachmentsVal, ok := attachmentsAttribute.(basetypes.ListValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`attachments expected to be basetypes.ListValue, was: %T`, attachmentsAttribute)) + } + + bootableAttribute, ok := attributes["bootable"] + + if !ok { + diags.AddError( + "Attribute Missing", + `bootable is missing from object`) + + return nil, diags + } + + bootableVal, ok := bootableAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`bootable expected to be basetypes.BoolValue, was: %T`, bootableAttribute)) + } + + callbackUrlAttribute, ok := attributes["callback_url"] + + if !ok { + diags.AddError( + "Attribute Missing", + `callback_url is missing from object`) + + return nil, diags + } + + callbackUrlVal, ok := callbackUrlAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`callback_url expected to be basetypes.StringValue, was: %T`, callbackUrlAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return nil, diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + descriptionAttribute, ok := attributes["description"] + + if !ok { + diags.AddError( + "Attribute Missing", + `description is missing from object`) + + return nil, diags + } + + descriptionVal, ok := descriptionAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute)) + } + + environmentAttribute, ok := attributes["environment"] + + if !ok { + diags.AddError( + "Attribute Missing", + `environment is missing from object`) + + return nil, diags + } + + environmentVal, ok := environmentAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`environment expected to be basetypes.ObjectValue, was: %T`, environmentAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + imageIdAttribute, ok := attributes["image_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `image_id is missing from object`) + + return nil, diags + } + + imageIdVal, ok := imageIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`image_id expected to be basetypes.Int64Value, was: %T`, imageIdAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + osImageAttribute, ok := attributes["os_image"] + + if !ok { + diags.AddError( + "Attribute Missing", + `os_image is missing from object`) + + return nil, diags + } + + osImageVal, ok := osImageAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`os_image expected to be basetypes.StringValue, was: %T`, osImageAttribute)) + } + + sizeAttribute, ok := attributes["size"] + + if !ok { + diags.AddError( + "Attribute Missing", + `size is missing from object`) + + return nil, diags + } + + sizeVal, ok := sizeAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`size expected to be basetypes.Int64Value, was: %T`, sizeAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return nil, diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + volumeTypeAttribute, ok := attributes["volume_type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `volume_type is missing from object`) + + return nil, diags + } + + volumeTypeVal, ok := volumeTypeAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`volume_type expected to be basetypes.StringValue, was: %T`, volumeTypeAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VolumeValue{ + Attachments: attachmentsVal, + Bootable: bootableVal, + CallbackUrl: callbackUrlVal, + CreatedAt: createdAtVal, + Description: descriptionVal, + Environment: environmentVal, + Id: idVal, + ImageId: imageIdVal, + Name: nameVal, + OsImage: osImageVal, + Size: sizeVal, + Status: statusVal, + UpdatedAt: updatedAtVal, + VolumeType: volumeTypeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVolumeValueNull() VolumeValue { + return VolumeValue{ + state: attr.ValueStateNull, + } +} + +func NewVolumeValueUnknown() VolumeValue { + return VolumeValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVolumeValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VolumeValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VolumeValue Attribute Value", + "While creating a VolumeValue value, a missing attribute value was detected. "+ + "A VolumeValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VolumeValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VolumeValue Attribute Type", + "While creating a VolumeValue value, an invalid attribute value was detected. "+ + "A VolumeValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VolumeValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VolumeValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VolumeValue Attribute Value", + "While creating a VolumeValue value, an extra attribute value was detected. "+ + "A VolumeValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VolumeValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVolumeValueUnknown(), diags + } + + attachmentsAttribute, ok := attributes["attachments"] + + if !ok { + diags.AddError( + "Attribute Missing", + `attachments is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + attachmentsVal, ok := attachmentsAttribute.(basetypes.ListValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`attachments expected to be basetypes.ListValue, was: %T`, attachmentsAttribute)) + } + + bootableAttribute, ok := attributes["bootable"] + + if !ok { + diags.AddError( + "Attribute Missing", + `bootable is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + bootableVal, ok := bootableAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`bootable expected to be basetypes.BoolValue, was: %T`, bootableAttribute)) + } + + callbackUrlAttribute, ok := attributes["callback_url"] + + if !ok { + diags.AddError( + "Attribute Missing", + `callback_url is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + callbackUrlVal, ok := callbackUrlAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`callback_url expected to be basetypes.StringValue, was: %T`, callbackUrlAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + createdAtVal, ok := createdAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be basetypes.StringValue, was: %T`, createdAtAttribute)) + } + + descriptionAttribute, ok := attributes["description"] + + if !ok { + diags.AddError( + "Attribute Missing", + `description is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + descriptionVal, ok := descriptionAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute)) + } + + environmentAttribute, ok := attributes["environment"] + + if !ok { + diags.AddError( + "Attribute Missing", + `environment is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + environmentVal, ok := environmentAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`environment expected to be basetypes.ObjectValue, was: %T`, environmentAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + imageIdAttribute, ok := attributes["image_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `image_id is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + imageIdVal, ok := imageIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`image_id expected to be basetypes.Int64Value, was: %T`, imageIdAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + osImageAttribute, ok := attributes["os_image"] + + if !ok { + diags.AddError( + "Attribute Missing", + `os_image is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + osImageVal, ok := osImageAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`os_image expected to be basetypes.StringValue, was: %T`, osImageAttribute)) + } + + sizeAttribute, ok := attributes["size"] + + if !ok { + diags.AddError( + "Attribute Missing", + `size is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + sizeVal, ok := sizeAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`size expected to be basetypes.Int64Value, was: %T`, sizeAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + updatedAtVal, ok := updatedAtAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be basetypes.StringValue, was: %T`, updatedAtAttribute)) + } + + volumeTypeAttribute, ok := attributes["volume_type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `volume_type is missing from object`) + + return NewVolumeValueUnknown(), diags + } + + volumeTypeVal, ok := volumeTypeAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`volume_type expected to be basetypes.StringValue, was: %T`, volumeTypeAttribute)) + } + + if diags.HasError() { + return NewVolumeValueUnknown(), diags + } + + return VolumeValue{ + Attachments: attachmentsVal, + Bootable: bootableVal, + CallbackUrl: callbackUrlVal, + CreatedAt: createdAtVal, + Description: descriptionVal, + Environment: environmentVal, + Id: idVal, + ImageId: imageIdVal, + Name: nameVal, + OsImage: osImageVal, + Size: sizeVal, + Status: statusVal, + UpdatedAt: updatedAtVal, + VolumeType: volumeTypeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVolumeValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VolumeValue { + object, diags := NewVolumeValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVolumeValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VolumeType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVolumeValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVolumeValueUnknown(), nil + } + + if in.IsNull() { + return NewVolumeValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVolumeValueMust(VolumeValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VolumeType) ValueType(ctx context.Context) attr.Value { + return VolumeValue{} +} + +var _ basetypes.ObjectValuable = VolumeValue{} + +type VolumeValue struct { + Attachments basetypes.ListValue `tfsdk:"attachments"` + Bootable basetypes.BoolValue `tfsdk:"bootable"` + CallbackUrl basetypes.StringValue `tfsdk:"callback_url"` + CreatedAt basetypes.StringValue `tfsdk:"created_at"` + Description basetypes.StringValue `tfsdk:"description"` + Environment basetypes.ObjectValue `tfsdk:"environment"` + Id basetypes.Int64Value `tfsdk:"id"` + ImageId basetypes.Int64Value `tfsdk:"image_id"` + Name basetypes.StringValue `tfsdk:"name"` + OsImage basetypes.StringValue `tfsdk:"os_image"` + Size basetypes.Int64Value `tfsdk:"size"` + Status basetypes.StringValue `tfsdk:"status"` + UpdatedAt basetypes.StringValue `tfsdk:"updated_at"` + VolumeType basetypes.StringValue `tfsdk:"volume_type"` + state attr.ValueState +} + +func (v VolumeValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 14) + + var val tftypes.Value + var err error + + attrTypes["attachments"] = basetypes.ListType{ + ElemType: AttachmentsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["bootable"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["callback_url"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["created_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["description"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["environment"] = basetypes.ObjectType{ + AttrTypes: EnvironmentValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["image_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["os_image"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["size"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["updated_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["volume_type"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 14) + + val, err = v.Attachments.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["attachments"] = val + + val, err = v.Bootable.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["bootable"] = val + + val, err = v.CallbackUrl.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["callback_url"] = val + + val, err = v.CreatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["created_at"] = val + + val, err = v.Description.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["description"] = val + + val, err = v.Environment.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["environment"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.ImageId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["image_id"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.OsImage.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["os_image"] = val + + val, err = v.Size.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["size"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + val, err = v.UpdatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["updated_at"] = val + + val, err = v.VolumeType.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["volume_type"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VolumeValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VolumeValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VolumeValue) String() string { + return "VolumeValue" +} + +func (v VolumeValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attachments := types.ListValueMust( + AttachmentsType{ + basetypes.ObjectType{ + AttrTypes: AttachmentsValue{}.AttributeTypes(ctx), + }, + }, + v.Attachments.Elements(), + ) + + if v.Attachments.IsNull() { + attachments = types.ListNull( + AttachmentsType{ + basetypes.ObjectType{ + AttrTypes: AttachmentsValue{}.AttributeTypes(ctx), + }, + }, + ) + } + + if v.Attachments.IsUnknown() { + attachments = types.ListUnknown( + AttachmentsType{ + basetypes.ObjectType{ + AttrTypes: AttachmentsValue{}.AttributeTypes(ctx), + }, + }, + ) + } + + var environment basetypes.ObjectValue + + if v.Environment.IsNull() { + environment = types.ObjectNull( + EnvironmentValue{}.AttributeTypes(ctx), + ) + } + + if v.Environment.IsUnknown() { + environment = types.ObjectUnknown( + EnvironmentValue{}.AttributeTypes(ctx), + ) + } + + if !v.Environment.IsNull() && !v.Environment.IsUnknown() { + environment = types.ObjectValueMust( + EnvironmentValue{}.AttributeTypes(ctx), + v.Environment.Attributes(), + ) + } + + attributeTypes := map[string]attr.Type{ + "attachments": basetypes.ListType{ + ElemType: AttachmentsValue{}.Type(ctx), + }, + "bootable": basetypes.BoolType{}, + "callback_url": basetypes.StringType{}, + "created_at": basetypes.StringType{}, + "description": basetypes.StringType{}, + "environment": basetypes.ObjectType{ + AttrTypes: EnvironmentValue{}.AttributeTypes(ctx), + }, + "id": basetypes.Int64Type{}, + "image_id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "os_image": basetypes.StringType{}, + "size": basetypes.Int64Type{}, + "status": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + "volume_type": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "attachments": attachments, + "bootable": v.Bootable, + "callback_url": v.CallbackUrl, + "created_at": v.CreatedAt, + "description": v.Description, + "environment": environment, + "id": v.Id, + "image_id": v.ImageId, + "name": v.Name, + "os_image": v.OsImage, + "size": v.Size, + "status": v.Status, + "updated_at": v.UpdatedAt, + "volume_type": v.VolumeType, + }) + + return objVal, diags +} + +func (v VolumeValue) Equal(o attr.Value) bool { + other, ok := o.(VolumeValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Attachments.Equal(other.Attachments) { + return false + } + + if !v.Bootable.Equal(other.Bootable) { + return false + } + + if !v.CallbackUrl.Equal(other.CallbackUrl) { + return false + } + + if !v.CreatedAt.Equal(other.CreatedAt) { + return false + } + + if !v.Description.Equal(other.Description) { + return false + } + + if !v.Environment.Equal(other.Environment) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.ImageId.Equal(other.ImageId) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.OsImage.Equal(other.OsImage) { + return false + } + + if !v.Size.Equal(other.Size) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + if !v.UpdatedAt.Equal(other.UpdatedAt) { + return false + } + + if !v.VolumeType.Equal(other.VolumeType) { + return false + } + + return true +} + +func (v VolumeValue) Type(ctx context.Context) attr.Type { + return VolumeType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VolumeValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "attachments": basetypes.ListType{ + ElemType: AttachmentsValue{}.Type(ctx), + }, + "bootable": basetypes.BoolType{}, + "callback_url": basetypes.StringType{}, + "created_at": basetypes.StringType{}, + "description": basetypes.StringType{}, + "environment": basetypes.ObjectType{ + AttrTypes: EnvironmentValue{}.AttributeTypes(ctx), + }, + "id": basetypes.Int64Type{}, + "image_id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "os_image": basetypes.StringType{}, + "size": basetypes.Int64Type{}, + "status": basetypes.StringType{}, + "updated_at": basetypes.StringType{}, + "volume_type": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = AttachmentsType{} + +type AttachmentsType struct { + basetypes.ObjectType +} + +func (t AttachmentsType) Equal(o attr.Type) bool { + other, ok := o.(AttachmentsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t AttachmentsType) String() string { + return "AttachmentsType" +} + +func (t AttachmentsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + deviceAttribute, ok := attributes["device"] + + if !ok { + diags.AddError( + "Attribute Missing", + `device is missing from object`) + + return nil, diags + } + + deviceVal, ok := deviceAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`device expected to be basetypes.StringValue, was: %T`, deviceAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + instanceIdAttribute, ok := attributes["instance_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `instance_id is missing from object`) + + return nil, diags + } + + instanceIdVal, ok := instanceIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`instance_id expected to be basetypes.Int64Value, was: %T`, instanceIdAttribute)) + } + + protectedAttribute, ok := attributes["protected"] + + if !ok { + diags.AddError( + "Attribute Missing", + `protected is missing from object`) + + return nil, diags + } + + protectedVal, ok := protectedAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`protected expected to be basetypes.BoolValue, was: %T`, protectedAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return AttachmentsValue{ + Device: deviceVal, + Id: idVal, + InstanceId: instanceIdVal, + Protected: protectedVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewAttachmentsValueNull() AttachmentsValue { + return AttachmentsValue{ + state: attr.ValueStateNull, + } +} + +func NewAttachmentsValueUnknown() AttachmentsValue { + return AttachmentsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewAttachmentsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (AttachmentsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing AttachmentsValue Attribute Value", + "While creating a AttachmentsValue value, a missing attribute value was detected. "+ + "A AttachmentsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("AttachmentsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid AttachmentsValue Attribute Type", + "While creating a AttachmentsValue value, an invalid attribute value was detected. "+ + "A AttachmentsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("AttachmentsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("AttachmentsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra AttachmentsValue Attribute Value", + "While creating a AttachmentsValue value, an extra attribute value was detected. "+ + "A AttachmentsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra AttachmentsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewAttachmentsValueUnknown(), diags + } + + deviceAttribute, ok := attributes["device"] + + if !ok { + diags.AddError( + "Attribute Missing", + `device is missing from object`) + + return NewAttachmentsValueUnknown(), diags + } + + deviceVal, ok := deviceAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`device expected to be basetypes.StringValue, was: %T`, deviceAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewAttachmentsValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute)) + } + + instanceIdAttribute, ok := attributes["instance_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `instance_id is missing from object`) + + return NewAttachmentsValueUnknown(), diags + } + + instanceIdVal, ok := instanceIdAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`instance_id expected to be basetypes.Int64Value, was: %T`, instanceIdAttribute)) + } + + protectedAttribute, ok := attributes["protected"] + + if !ok { + diags.AddError( + "Attribute Missing", + `protected is missing from object`) + + return NewAttachmentsValueUnknown(), diags + } + + protectedVal, ok := protectedAttribute.(basetypes.BoolValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`protected expected to be basetypes.BoolValue, was: %T`, protectedAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewAttachmentsValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be basetypes.StringValue, was: %T`, statusAttribute)) + } + + if diags.HasError() { + return NewAttachmentsValueUnknown(), diags + } + + return AttachmentsValue{ + Device: deviceVal, + Id: idVal, + InstanceId: instanceIdVal, + Protected: protectedVal, + Status: statusVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewAttachmentsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) AttachmentsValue { + object, diags := NewAttachmentsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewAttachmentsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t AttachmentsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewAttachmentsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewAttachmentsValueUnknown(), nil + } + + if in.IsNull() { + return NewAttachmentsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewAttachmentsValueMust(AttachmentsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t AttachmentsType) ValueType(ctx context.Context) attr.Value { + return AttachmentsValue{} +} + +var _ basetypes.ObjectValuable = AttachmentsValue{} + +type AttachmentsValue struct { + Device basetypes.StringValue `tfsdk:"device"` + Id basetypes.Int64Value `tfsdk:"id"` + InstanceId basetypes.Int64Value `tfsdk:"instance_id"` + Protected basetypes.BoolValue `tfsdk:"protected"` + Status basetypes.StringValue `tfsdk:"status"` + state attr.ValueState +} + +func (v AttachmentsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 5) + + var val tftypes.Value + var err error + + attrTypes["device"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["instance_id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["protected"] = basetypes.BoolType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 5) + + val, err = v.Device.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["device"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.InstanceId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["instance_id"] = val + + val, err = v.Protected.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["protected"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v AttachmentsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v AttachmentsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v AttachmentsValue) String() string { + return "AttachmentsValue" +} + +func (v AttachmentsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{ + "device": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "instance_id": basetypes.Int64Type{}, + "protected": basetypes.BoolType{}, + "status": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "device": v.Device, + "id": v.Id, + "instance_id": v.InstanceId, + "protected": v.Protected, + "status": v.Status, + }) + + return objVal, diags +} + +func (v AttachmentsValue) Equal(o attr.Value) bool { + other, ok := o.(AttachmentsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Device.Equal(other.Device) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.InstanceId.Equal(other.InstanceId) { + return false + } + + if !v.Protected.Equal(other.Protected) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + return true +} + +func (v AttachmentsValue) Type(ctx context.Context) attr.Type { + return AttachmentsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v AttachmentsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "device": basetypes.StringType{}, + "id": basetypes.Int64Type{}, + "instance_id": basetypes.Int64Type{}, + "protected": basetypes.BoolType{}, + "status": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = EnvironmentType{} + +type EnvironmentType struct { + basetypes.ObjectType +} + +func (t EnvironmentType) Equal(o attr.Type) bool { + other, ok := o.(EnvironmentType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t EnvironmentType) String() string { + return "EnvironmentType" +} + +func (t EnvironmentType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + featuresAttribute, ok := attributes["features"] + + if !ok { + diags.AddError( + "Attribute Missing", + `features is missing from object`) + + return nil, diags + } + + featuresVal, ok := featuresAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`features expected to be basetypes.ObjectValue, was: %T`, featuresAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + regionAttribute, ok := attributes["region"] + + if !ok { + diags.AddError( + "Attribute Missing", + `region is missing from object`) + + return nil, diags + } + + regionVal, ok := regionAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`region expected to be basetypes.StringValue, was: %T`, regionAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return EnvironmentValue{ + Features: featuresVal, + Name: nameVal, + Region: regionVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewEnvironmentValueNull() EnvironmentValue { + return EnvironmentValue{ + state: attr.ValueStateNull, + } +} + +func NewEnvironmentValueUnknown() EnvironmentValue { + return EnvironmentValue{ + state: attr.ValueStateUnknown, + } +} + +func NewEnvironmentValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (EnvironmentValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing EnvironmentValue Attribute Value", + "While creating a EnvironmentValue value, a missing attribute value was detected. "+ + "A EnvironmentValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("EnvironmentValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid EnvironmentValue Attribute Type", + "While creating a EnvironmentValue value, an invalid attribute value was detected. "+ + "A EnvironmentValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("EnvironmentValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("EnvironmentValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra EnvironmentValue Attribute Value", + "While creating a EnvironmentValue value, an extra attribute value was detected. "+ + "A EnvironmentValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra EnvironmentValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewEnvironmentValueUnknown(), diags + } + + featuresAttribute, ok := attributes["features"] + + if !ok { + diags.AddError( + "Attribute Missing", + `features is missing from object`) + + return NewEnvironmentValueUnknown(), diags + } + + featuresVal, ok := featuresAttribute.(basetypes.ObjectValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`features expected to be basetypes.ObjectValue, was: %T`, featuresAttribute)) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`) + + return NewEnvironmentValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + } + + regionAttribute, ok := attributes["region"] + + if !ok { + diags.AddError( + "Attribute Missing", + `region is missing from object`) + + return NewEnvironmentValueUnknown(), diags + } + + regionVal, ok := regionAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`region expected to be basetypes.StringValue, was: %T`, regionAttribute)) + } + + if diags.HasError() { + return NewEnvironmentValueUnknown(), diags + } + + return EnvironmentValue{ + Features: featuresVal, + Name: nameVal, + Region: regionVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewEnvironmentValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) EnvironmentValue { + object, diags := NewEnvironmentValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewEnvironmentValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t EnvironmentType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewEnvironmentValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewEnvironmentValueUnknown(), nil + } + + if in.IsNull() { + return NewEnvironmentValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewEnvironmentValueMust(EnvironmentValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t EnvironmentType) ValueType(ctx context.Context) attr.Value { + return EnvironmentValue{} } -var _ basetypes.ObjectTypable = EnvironmentType{} +var _ basetypes.ObjectValuable = EnvironmentValue{} -type EnvironmentType struct { - basetypes.ObjectType +type EnvironmentValue struct { + Features basetypes.ObjectValue `tfsdk:"features"` + Name basetypes.StringValue `tfsdk:"name"` + Region basetypes.StringValue `tfsdk:"region"` + state attr.ValueState } -func (t EnvironmentType) Equal(o attr.Type) bool { - other, ok := o.(EnvironmentType) +func (v EnvironmentValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 3) - if !ok { - return false + var val tftypes.Value + var err error + + attrTypes["features"] = basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["region"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 3) + + val, err = v.Features.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["features"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Region.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["region"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) } +} - return t.ObjectType.Equal(other.ObjectType) +func (v EnvironmentValue) IsNull() bool { + return v.state == attr.ValueStateNull } -func (t EnvironmentType) String() string { - return "EnvironmentType" +func (v EnvironmentValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown } -func (t EnvironmentType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { +func (v EnvironmentValue) String() string { + return "EnvironmentValue" +} + +func (v EnvironmentValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { var diags diag.Diagnostics - attributes := in.Attributes() + var features basetypes.ObjectValue - nameAttribute, ok := attributes["name"] + if v.Features.IsNull() { + features = types.ObjectNull( + FeaturesValue{}.AttributeTypes(ctx), + ) + } + + if v.Features.IsUnknown() { + features = types.ObjectUnknown( + FeaturesValue{}.AttributeTypes(ctx), + ) + } + + if !v.Features.IsNull() && !v.Features.IsUnknown() { + features = types.ObjectValueMust( + FeaturesValue{}.AttributeTypes(ctx), + v.Features.Attributes(), + ) + } + + attributeTypes := map[string]attr.Type{ + "features": basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + "name": basetypes.StringType{}, + "region": basetypes.StringType{}, + } + + if v.IsNull() { + return types.ObjectNull(attributeTypes), diags + } + + if v.IsUnknown() { + return types.ObjectUnknown(attributeTypes), diags + } + + objVal, diags := types.ObjectValue( + attributeTypes, + map[string]attr.Value{ + "features": features, + "name": v.Name, + "region": v.Region, + }) + + return objVal, diags +} + +func (v EnvironmentValue) Equal(o attr.Value) bool { + other, ok := o.(EnvironmentValue) if !ok { - diags.AddError( - "Attribute Missing", - `name is missing from object`) + return false + } - return nil, diags + if v.state != other.state { + return false } - nameVal, ok := nameAttribute.(basetypes.StringValue) + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Features.Equal(other.Features) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Region.Equal(other.Region) { + return false + } + + return true +} + +func (v EnvironmentValue) Type(ctx context.Context) attr.Type { + return EnvironmentType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v EnvironmentValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "features": basetypes.ObjectType{ + AttrTypes: FeaturesValue{}.AttributeTypes(ctx), + }, + "name": basetypes.StringType{}, + "region": basetypes.StringType{}, + } +} + +var _ basetypes.ObjectTypable = FeaturesType{} + +type FeaturesType struct { + basetypes.ObjectType +} + +func (t FeaturesType) Equal(o attr.Type) bool { + other, ok := o.(FeaturesType) if !ok { - diags.AddError( - "Attribute Wrong Type", - fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + return false } + return t.ObjectType.Equal(other.ObjectType) +} + +func (t FeaturesType) String() string { + return "FeaturesType" +} + +func (t FeaturesType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + if diags.HasError() { return nil, diags } - return EnvironmentValue{ - Name: nameVal, + return FeaturesValue{ state: attr.ValueStateKnown, }, diags } -func NewEnvironmentValueNull() EnvironmentValue { - return EnvironmentValue{ +func NewFeaturesValueNull() FeaturesValue { + return FeaturesValue{ state: attr.ValueStateNull, } } -func NewEnvironmentValueUnknown() EnvironmentValue { - return EnvironmentValue{ +func NewFeaturesValueUnknown() FeaturesValue { + return FeaturesValue{ state: attr.ValueStateUnknown, } } -func NewEnvironmentValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (EnvironmentValue, diag.Diagnostics) { +func NewFeaturesValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (FeaturesValue, diag.Diagnostics) { var diags diag.Diagnostics // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 @@ -216,11 +2375,11 @@ func NewEnvironmentValue(attributeTypes map[string]attr.Type, attributes map[str if !ok { diags.AddError( - "Missing EnvironmentValue Attribute Value", - "While creating a EnvironmentValue value, a missing attribute value was detected. "+ - "A EnvironmentValue must contain values for all attributes, even if null or unknown. "+ + "Missing FeaturesValue Attribute Value", + "While creating a FeaturesValue value, a missing attribute value was detected. "+ + "A FeaturesValue must contain values for all attributes, even if null or unknown. "+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ - fmt.Sprintf("EnvironmentValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + fmt.Sprintf("FeaturesValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), ) continue @@ -228,12 +2387,12 @@ func NewEnvironmentValue(attributeTypes map[string]attr.Type, attributes map[str if !attributeType.Equal(attribute.Type(ctx)) { diags.AddError( - "Invalid EnvironmentValue Attribute Type", - "While creating a EnvironmentValue value, an invalid attribute value was detected. "+ - "A EnvironmentValue must use a matching attribute type for the value. "+ + "Invalid FeaturesValue Attribute Type", + "While creating a FeaturesValue value, an invalid attribute value was detected. "+ + "A FeaturesValue must use a matching attribute type for the value. "+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ - fmt.Sprintf("EnvironmentValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ - fmt.Sprintf("EnvironmentValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + fmt.Sprintf("FeaturesValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("FeaturesValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), ) } } @@ -243,49 +2402,30 @@ func NewEnvironmentValue(attributeTypes map[string]attr.Type, attributes map[str if !ok { diags.AddError( - "Extra EnvironmentValue Attribute Value", - "While creating a EnvironmentValue value, an extra attribute value was detected. "+ - "A EnvironmentValue must not contain values beyond the expected attribute types. "+ + "Extra FeaturesValue Attribute Value", + "While creating a FeaturesValue value, an extra attribute value was detected. "+ + "A FeaturesValue must not contain values beyond the expected attribute types. "+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ - fmt.Sprintf("Extra EnvironmentValue Attribute Name: %s", name), + fmt.Sprintf("Extra FeaturesValue Attribute Name: %s", name), ) } } if diags.HasError() { - return NewEnvironmentValueUnknown(), diags - } - - nameAttribute, ok := attributes["name"] - - if !ok { - diags.AddError( - "Attribute Missing", - `name is missing from object`) - - return NewEnvironmentValueUnknown(), diags - } - - nameVal, ok := nameAttribute.(basetypes.StringValue) - - if !ok { - diags.AddError( - "Attribute Wrong Type", - fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute)) + return NewFeaturesValueUnknown(), diags } if diags.HasError() { - return NewEnvironmentValueUnknown(), diags + return NewFeaturesValueUnknown(), diags } - return EnvironmentValue{ - Name: nameVal, + return FeaturesValue{ state: attr.ValueStateKnown, }, diags } -func NewEnvironmentValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) EnvironmentValue { - object, diags := NewEnvironmentValue(attributeTypes, attributes) +func NewFeaturesValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) FeaturesValue { + object, diags := NewFeaturesValue(attributeTypes, attributes) if diags.HasError() { // This could potentially be added to the diag package. @@ -299,15 +2439,15 @@ func NewEnvironmentValueMust(attributeTypes map[string]attr.Type, attributes map diagnostic.Detail())) } - panic("NewEnvironmentValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + panic("NewFeaturesValueMust received error(s): " + strings.Join(diagsStrings, "\n")) } return object } -func (t EnvironmentType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { +func (t FeaturesType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { if in.Type() == nil { - return NewEnvironmentValueNull(), nil + return NewFeaturesValueNull(), nil } if !in.Type().Equal(t.TerraformType(ctx)) { @@ -315,11 +2455,11 @@ func (t EnvironmentType) ValueFromTerraform(ctx context.Context, in tftypes.Valu } if !in.IsKnown() { - return NewEnvironmentValueUnknown(), nil + return NewFeaturesValueUnknown(), nil } if in.IsNull() { - return NewEnvironmentValueNull(), nil + return NewFeaturesValueNull(), nil } attributes := map[string]attr.Value{} @@ -342,41 +2482,27 @@ func (t EnvironmentType) ValueFromTerraform(ctx context.Context, in tftypes.Valu attributes[k] = a } - return NewEnvironmentValueMust(EnvironmentValue{}.AttributeTypes(ctx), attributes), nil + return NewFeaturesValueMust(FeaturesValue{}.AttributeTypes(ctx), attributes), nil } -func (t EnvironmentType) ValueType(ctx context.Context) attr.Value { - return EnvironmentValue{} +func (t FeaturesType) ValueType(ctx context.Context) attr.Value { + return FeaturesValue{} } -var _ basetypes.ObjectValuable = EnvironmentValue{} +var _ basetypes.ObjectValuable = FeaturesValue{} -type EnvironmentValue struct { - Name basetypes.StringValue `tfsdk:"name"` +type FeaturesValue struct { state attr.ValueState } -func (v EnvironmentValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { - attrTypes := make(map[string]tftypes.Type, 1) - - var val tftypes.Value - var err error - - attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) +func (v FeaturesValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 0) objectType := tftypes.Object{AttributeTypes: attrTypes} switch v.state { case attr.ValueStateKnown: - vals := make(map[string]tftypes.Value, 1) - - val, err = v.Name.ToTerraformValue(ctx) - - if err != nil { - return tftypes.NewValue(objectType, tftypes.UnknownValue), err - } - - vals["name"] = val + vals := make(map[string]tftypes.Value, 0) if err := tftypes.ValidateValue(objectType, vals); err != nil { return tftypes.NewValue(objectType, tftypes.UnknownValue), err @@ -392,24 +2518,22 @@ func (v EnvironmentValue) ToTerraformValue(ctx context.Context) (tftypes.Value, } } -func (v EnvironmentValue) IsNull() bool { +func (v FeaturesValue) IsNull() bool { return v.state == attr.ValueStateNull } -func (v EnvironmentValue) IsUnknown() bool { +func (v FeaturesValue) IsUnknown() bool { return v.state == attr.ValueStateUnknown } -func (v EnvironmentValue) String() string { - return "EnvironmentValue" +func (v FeaturesValue) String() string { + return "FeaturesValue" } -func (v EnvironmentValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { +func (v FeaturesValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { var diags diag.Diagnostics - attributeTypes := map[string]attr.Type{ - "name": basetypes.StringType{}, - } + attributeTypes := map[string]attr.Type{} if v.IsNull() { return types.ObjectNull(attributeTypes), diags @@ -421,15 +2545,13 @@ func (v EnvironmentValue) ToObjectValue(ctx context.Context) (basetypes.ObjectVa objVal, diags := types.ObjectValue( attributeTypes, - map[string]attr.Value{ - "name": v.Name, - }) + map[string]attr.Value{}) return objVal, diags } -func (v EnvironmentValue) Equal(o attr.Value) bool { - other, ok := o.(EnvironmentValue) +func (v FeaturesValue) Equal(o attr.Value) bool { + other, ok := o.(FeaturesValue) if !ok { return false @@ -443,23 +2565,17 @@ func (v EnvironmentValue) Equal(o attr.Value) bool { return true } - if !v.Name.Equal(other.Name) { - return false - } - return true } -func (v EnvironmentValue) Type(ctx context.Context) attr.Type { - return EnvironmentType{ +func (v FeaturesValue) Type(ctx context.Context) attr.Type { + return FeaturesType{ basetypes.ObjectType{ AttrTypes: v.AttributeTypes(ctx), }, } } -func (v EnvironmentValue) AttributeTypes(ctx context.Context) map[string]attr.Type { - return map[string]attr.Type{ - "name": basetypes.StringType{}, - } +func (v FeaturesValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{} } diff --git a/internal/provider/resource_core_virtual_machine_sg_rule.go b/internal/provider/resource_core_virtual_machine_sg_rule.go index 6c19366..1d4b685 100644 --- a/internal/provider/resource_core_virtual_machine_sg_rule.go +++ b/internal/provider/resource_core_virtual_machine_sg_rule.go @@ -236,12 +236,6 @@ func (r *ResourceCoreVirtualMachineSgRule) ApiToModel( vmId int, ) resource_core_virtual_machine_sg_rule.CoreVirtualMachineSgRuleModel { return resource_core_virtual_machine_sg_rule.CoreVirtualMachineSgRuleModel{ - CreatedAt: func() types.String { - if response.CreatedAt == nil { - return types.StringNull() - } - return types.StringValue(response.CreatedAt.String()) - }(), Direction: func() types.String { if response.Direction == nil { return types.StringNull() @@ -284,12 +278,7 @@ func (r *ResourceCoreVirtualMachineSgRule) ApiToModel( } return types.StringValue(*response.RemoteIpPrefix) }(), - Status: func() types.String { - if response.Status == nil { - return types.StringNull() - } - return types.StringValue(*response.Status) - }(), + Status: types.BoolValue(true), VirtualMachineId: func() types.Int64 { return types.Int64Value(int64(vmId)) }(), diff --git a/internal/provider/resource_core_volume.go b/internal/provider/resource_core_volume.go index 4c466bf..3e7a575 100644 --- a/internal/provider/resource_core_volume.go +++ b/internal/provider/resource_core_volume.go @@ -291,7 +291,7 @@ func (r *ResourceCoreVolume) Read( return } - id := int(dataOld.Id.ValueInt64()) + id := int(dataOld.VolumeId.ValueInt64()) // Perform a Read operation to get all volumes searchResult, err := r.client.ListVolumesWithResponse(ctx, func() *volume.ListVolumesParams { @@ -354,7 +354,7 @@ func (r *ResourceCoreVolume) Delete(ctx context.Context, req resource.DeleteRequ return } - id := int(data.Id.ValueInt64()) + id := int(data.VolumeId.ValueInt64()) // Perform a Read operation to get all volumes result, err := r.client.ListVolumesWithResponse(ctx, func() *volume.ListVolumesParams { @@ -503,45 +503,35 @@ func (r *ResourceCoreVolume) ApiToModel( diags *diag.Diagnostics, response *volume.VolumesFields, ) resource_core_volume.CoreVolumeModel { + _ = ctx + _ = diags return resource_core_volume.CoreVolumeModel{ - Bootable: types.BoolPointerValue(response.Bootable), CallbackUrl: types.StringPointerValue(response.CallbackUrl), Description: types.StringPointerValue(response.Description), - Environment: r.MapEnvironment(ctx, diags, *response.Environment), EnvironmentName: types.StringNull(), - Id: func() types.Int64 { - if response.Id == nil { - return types.Int64Null() - } - return types.Int64Value(int64(*response.Id)) - }(), ImageId: func() types.Int64 { if response.ImageId == nil { return types.Int64Null() } return types.Int64Value(int64(*response.ImageId)) }(), - Name: types.StringPointerValue(response.Name), + Message: types.StringNull(), + Name: types.StringPointerValue(response.Name), Size: func() types.Int64 { if response.Size == nil { return types.Int64Null() } return types.Int64Value(int64(*response.Size)) }(), - Status: types.StringPointerValue(response.Status), - VolumeType: types.StringPointerValue(response.VolumeType), - CreatedAt: func() types.String { - if response.CreatedAt == nil { - return types.StringNull() - } - return types.StringValue(response.CreatedAt.String()) - }(), - UpdatedAt: func() types.String { - if response.UpdatedAt == nil { - return types.StringNull() + Status: types.BoolValue(true), + Volume: resource_core_volume.NewVolumeValueUnknown(), + VolumeId: func() types.Int64 { + if response.Id == nil { + return types.Int64Null() } - return types.StringValue(response.UpdatedAt.String()) + return types.Int64Value(int64(*response.Id)) }(), + VolumeType: types.StringPointerValue(response.VolumeType), } } diff --git a/scripts/fix_provider_spec.py b/scripts/fix_provider_spec.py index daecd43..64ce556 100644 --- a/scripts/fix_provider_spec.py +++ b/scripts/fix_provider_spec.py @@ -184,6 +184,33 @@ def fix_provider_spec(spec_file: str) -> None: for attr in row["schema"]["attributes"]: attr_set_modifier(attr, "RequiresReplace") + has_vm_id = any(attr.get("name") == "virtual_machine_id" for attr in row["schema"]["attributes"]) + if not has_vm_id: + row["schema"]["attributes"].append({ + "name": "virtual_machine_id", + "int64": { + "computed_optional_required": "required", + "description": "The ID of the virtual machine to attach the security rule to.", + "plan_modifiers": [{ + "custom": { + "imports": [{ + "path": "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + }], + "schema_definition": "int64planmodifier.RequiresReplace()" + } + }], + } + }) + + has_id = any(attr.get("name") == "id" for attr in row["schema"]["attributes"]) + if not has_id: + row["schema"]["attributes"].append({ + "name": "id", + "int64": { + "computed_optional_required": "computed", + } + }) + if row["name"] == "core_cluster": for attr in row["schema"]["attributes"]: immutable_params = [ @@ -314,6 +341,25 @@ def fix_provider_spec(spec_file: str) -> None: ] row["schema"]["attributes"] = [x for x in row["schema"]["attributes"] if x["name"] not in vm_remove_params] + # Temporary compatibility mode: + # The latest API schema currently triggers type-name collisions in + # tfplugingen-framework for several resources/data sources. Until those + # collisions are addressed in spec normalization, regenerate only a minimal, + # known-stable subset and keep existing generated packages for the rest. + allowed_resources = { + "core_virtual_machine_sg_rule", + "core_volume", + "core_cluster_node_group", + "core_cluster_node", + } + allowed_datasources = { + "core_cluster_node_groups", + "core_cluster_node_group", + "core_cluster_nodes", + } + data["datasources"] = [row for row in datasources if row.get("name") in allowed_datasources] + data["resources"] = [row for row in resources if row.get("name") in allowed_resources] + with open(spec_file, 'w') as file: json.dump(data, file, indent=4)