Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Provider schema attributes ordering causes errors #16

Closed
iwarapter opened this issue Nov 25, 2020 · 3 comments · Fixed by #18
Closed

Provider schema attributes ordering causes errors #16

iwarapter opened this issue Nov 25, 2020 · 3 comments · Fixed by #18
Labels
bug Something isn't working

Comments

@iwarapter
Copy link

terraform-plugin-mux version

{
  "Path": "github.com/hashicorp/terraform-plugin-mux",
  "Version": "v0.1.0"
}

Relevant provider source code

tfprotov5.ProviderServer

Attributes: []*tfprotov5.SchemaAttribute{
	{
		Name:            "context",
		Optional:        true,
		Type:            tftypes.String,
		Description:     "The context path of the pingaccess API.",
		DescriptionKind: tfprotov5.StringKindPlain,
	},
	{
		Name:            "base_url",
		Optional:        true,
		Type:            tftypes.String,
		Description:     "The base url of the pingaccess API.",
		DescriptionKind: tfprotov5.StringKindPlain,
	},
	{
		Name:            "password",
		Optional:        true,
		Type:            tftypes.String,
		Description:     "The password for pingaccess API.",
		DescriptionKind: tfprotov5.StringKindPlain,
		Sensitive:       true,
	},
	{
		Name:            "username",
		Optional:        true,
		Type:            tftypes.String,
		Description:     "The username for pingaccess API.",
		DescriptionKind: tfprotov5.StringKindPlain,
	},
},

schema.Provider

Schema: map[string]*schema.Schema{
	"username": {
		Type:        schema.TypeString,
		Optional:    true,
		Description: descriptions["username"],
		DefaultFunc: schema.MultiEnvDefaultFunc([]string{"PINGACCESS_USERNAME"}, "Administrator"),
	},
	"password": {
		Type:        schema.TypeString,
		Optional:    true,
		Sensitive:   true,
		Description: descriptions["password"],
		DefaultFunc: schema.MultiEnvDefaultFunc([]string{"PINGACCESS_PASSWORD"}, "2Access"),
	},
	"context": {
		Type:        schema.TypeString,
		Optional:    true,
		Description: descriptions["context"],
		DefaultFunc: schema.MultiEnvDefaultFunc([]string{"PINGACCESS_CONTEXT"}, "/pa-admin-api/v3"),
	},
	"base_url": {
		Type:        schema.TypeString,
		Optional:    true,
		Description: descriptions["base_url"],
		DefaultFunc: schema.MultiEnvDefaultFunc([]string{"PINGACCESS_BASEURL"}, "https://localhost:9000"),
	},
},

Expected Behavior

I would expect the schemas to be acceptable, however when debugging i found that the schema.Provider is sorted alphabetically and so the tfprotov5.ProviderServer must be manually ordered alphabetically.

Actual Behavior

panic: got a different provider schema from two servers (*schema.GRPCProviderServer, *protocol.provider). Provider schemas must be identical across providers.

I patched the error message with a diff highlighting the issue below.

return factory, fmt.Errorf("got a different provider schema from two servers (%T, %T). Provider schemas must be identical across providers.\n%s", factory.servers[factory.providerSchemaFrom](), s, cmp.Diff(resp.Provider, factory.providerSchema))
panic: got a different provider schema from two servers (*schema.GRPCProviderServer, *protocol.provider). Provider schemas must be identical across providers.
:   &tfprotov5.Schema{
:        Version: 0,
:        Block: &tfprotov5.SchemaBlock{
:                Version: 0,
:                Attributes: []*tfprotov5.SchemaAttribute{
:                        &{
: -                              Name:        "context",
: +                              Name:        "base_url",
:                                Type:        s"tftypes.String",
: -                              Description: "The context path of the pingaccess API.",
: +                              Description: "The base url of the pingaccess API.",
:                                Required:    false,
:                                Optional:    true,
:                                ... // 4 identical fields
:                        },
:                        &{
: -                              Name:        "base_url",
: +                              Name:        "context",
:                                Type:        s"tftypes.String",
: -                              Description: "The base url of the pingaccess API.",
: +                              Description: "The context path of the pingaccess API.",
:                                Required:    false,
:                                Optional:    true,
:                                ... // 4 identical fields
:                        },
:                        &{Name: "password", Type: s"tftypes.String", Description: "The password for pingaccess API.", Optional: true, ...},
:                        &{Name: "username", Type: s"tftypes.String", Description: "The username for pingaccess API.", Optional: true, ...},
:                },
:                BlockTypes:  nil,
:                Description: "",
:                ... // 2 identical fields
:        },
:   }
: 
: 
: goroutine 1 [running]:
: main.main()
:        github.com/iwarapter/terraform-provider-pingaccess/main.go:17 +0x238

Steps to Reproduce

  • Define a sdkv2 and tfprotov5 schema with snippets above
  • build and plan
@iwarapter iwarapter added the bug Something isn't working label Nov 25, 2020
@iwarapter
Copy link
Author

I also had a quick play with patching in a transformer into the compare -

trans := cmp.Transformer("Sort", func(in []*tfprotov5.SchemaAttribute) []*tfprotov5.SchemaAttribute {
			sort.Slice(in, func(i, j int) bool { return in[i].Name < in[j].Name })
			return in
		})
		if resp.Provider != nil && factory.providerSchema != nil && !cmp.Equal(resp.Provider, factory.providerSchema, trans) {

Which would allow the ordering to pass - but haven't tested any of the many other provider schema configurations :D

@paddycarver
Copy link
Contributor

Thanks for the suggestion! I opened #18 to resolve this. I needed to copy the values of the slice to avoid reordering the slices, which I'm not sure if it would matter or not, but I'd prefer to not do it if we don't need to.

Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants