Skip to content

Fixes accidental override of file conf settings with defaults#1044

Merged
dcbw merged 2 commits into
ovn-kubernetes:masterfrom
trozet:dont_override_with_defaults
Feb 18, 2020
Merged

Fixes accidental override of file conf settings with defaults#1044
dcbw merged 2 commits into
ovn-kubernetes:masterfrom
trozet:dont_override_with_defaults

Conversation

@trozet

@trozet trozet commented Feb 4, 2020

Copy link
Copy Markdown
Contributor

When config is read, the config file is parsed first. After these
settings are loaded, the CLI settings are parsed and override any
settings read from the file. This is fine, except for the CLI settings
may be defaulted, which will just override any specified config file
settings with defaults.

This patch addresses the problem by checking during config override if
the the configuration option has a default specified, and if so, ignores
overriding the current config option.

Additionally, this patch adds real default values for settings.

Signed-off-by: Tim Rozet trozet@redhat.com

@trozet trozet requested review from dcbw and girishmg February 4, 2020 21:54
@trozet

trozet commented Feb 5, 2020

Copy link
Copy Markdown
Contributor Author

@danwinship

Comment thread go-controller/pkg/config/config.go Outdated
}
// And CLI overrides over config file and default values
if err := overrideFields(&Gateway, &cli.Gateway); err != nil {
if err := overrideFields(&Gateway, &cli.Gateway, nil); err != nil {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some config savedGateway is just empty values and no real defaults, so I just pass nil for those. Maybe I should pass var instead in case in the future there is a default value assigned for these...

@danwinship

Copy link
Copy Markdown
Contributor

Hm... looks ugly but I don't know the config/defaulting code in ovn-kubernetes so I don't really have any suggestions (and maybe this is the best way).

(FYI among other things this breaks IPv6 with ovn-kubernetes in OCP 4.4 because the IPv6 clusterSubnet passed in via the config file gets overridden with the IPv4 default value.)

@dcbw

dcbw commented Feb 6, 2020

Copy link
Copy Markdown
Contributor

This is fine, except for the CLI settings
may be defaulted, which will just override any specified config file
settings with defaults.

Looks like the only places that the CLI settings could get defaulted is for RawClusterSubnets and for boolean values? I think we should fix the defaulting for RawClusterSubnets by removing the Value: assignment in CommonFlags since that already has the same value in Default.RawClusterSubnets. And for booleans I don't think we need to care about supporting the config file setting the value to TRUE and then the CLI overriding that back to FALSE. So for bools perhaps we just logically OR the values together in overrideFields()? Is that enough to fix the problem?

@trozet

trozet commented Feb 6, 2020

Copy link
Copy Markdown
Contributor Author

This is fine, except for the CLI settings
may be defaulted, which will just override any specified config file
settings with defaults.

Looks like the only places that the CLI settings could get defaulted is for RawClusterSubnets and for boolean values? I think we should fix the defaulting for RawClusterSubnets by removing the Value: assignment in CommonFlags since that already has the same value in Default.RawClusterSubnets. And for booleans I don't think we need to care about supporting the config file setting the value to TRUE and then the CLI overriding that back to FALSE. So for bools perhaps we just logically OR the values together in overrideFields()? Is that enough to fix the problem?

I would argue that is just masking a bigger problem that settings are missing default values. For example,
cli.IntFlag{
Name: "mtu",
Usage: "MTU value used for the overlay networks (default: 1400)",
Destination: &cliConfig.Default.MTU,
},

Default value says 1400, but it has no default. We just assume here that the config will be set to 1400 by default by the config file when it gets deployed? We should probably add real defaults here to match, and then the code I added will ensure proper overriding occurs.

When config is read, the config file is parsed first. After these
settings are loaded, the CLI settings are parsed and override any
settings read from the file. This is fine, except for the CLI settings
may be defaulted, which will just override any specified config file
settings with defaults.

This patch addresses the problem by checking during config override if
the the configuration option has a default specified, and if so, ignores
overriding the current config option.

Additionally, this patch adds real default values for settings.

Signed-off-by: Tim Rozet <trozet@redhat.com>
@trozet trozet force-pushed the dont_override_with_defaults branch from ce209da to 3051cca Compare February 7, 2020 02:14
@dcbw

dcbw commented Feb 7, 2020

Copy link
Copy Markdown
Contributor

Default value says 1400, but it has no default. We just assume here that the config will be set to 1400 by default by the config file when it gets deployed? We should probably add real defaults here to match, and then the code I added will ensure proper overriding occurs.

@trozet not sure what you mean here. The "default" value mentioned there actually comes from the top-level Default structure in config.go (around line 37). In this case, the way the code should work (though perhaps you've found that reality doesn't match specification) is that:

  1. Default.MTU = 1400 (around line 37 of config.go)
  2. cliConfig.Default.MTU = 0 (because the --mtu flag was not passed)
  3. file Default.MTU = 0 (because nothing set it in the file)
  4. buildDefaultConfig() calls overrideFields(&Default, &file.Default) but because file.Default.MTU is the empty value (0) the 1400 is left in Default.MTU.
  5. buildDefaultConfig() calls overrideFields(&Default, &cli.Default) but because cli.Default.MTU is the empty value (0) the 1400 is left in Default.MTU.
  6. and all the code looks in that top-level Default.MTU value and finds 1400

Basically, the top-level structures around lines 20 - 100 are (a) filled with the default values and (b) what the code actually looks at when all config is handled. Then as other config comes in (file, CLI, env vars, special files from kubernetes) those override the top-level structure values in a defined order.

This is quite probably confusing and could be documented better. But the end goal (however it gets done) is to have a precedence of defaults < kube SA < env-vars < config file < CLI. A clearer way to achieve this would certainly be welcome.

@trozet

trozet commented Feb 8, 2020

Copy link
Copy Markdown
Contributor Author

Yeah I mean the CLI settings themselves have no defaults. My latest patch sets them. I think this is a lot less ambiguous than the previous behavior. The problem is the configOverride method assumes what values are invalid. For example, it wont override if a setting is 0. What if a setting was added where 0 was a valid value? It also wont override if the boolean is false. What if a new setting was default true and we wanted to set it to false? That's why it is better to determine defaults in the settings themselves.

I'll add a follow up commit that will remove the checks for 0, true, etc from config override as they are not necessary.

With this change, any config setting is checked against its default to
determine if the value is valid when parsed. The only case where empty
string values are considered "unset" is with environment variables.

Signed-off-by: Tim Rozet <trozet@redhat.com>
@trozet trozet force-pushed the dont_override_with_defaults branch from c62792b to a158c45 Compare February 10, 2020 19:33
return err
}

// Grab default values from OVS external IDs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note I moved this down here, so that if the behavior is if the booleans are set to detect from OVS, they will override all other settings. Not sure if that is the desired behavior or not.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@girishmg will this be OK with you? We don't use the OVS external IDs, so I think this would only affect your setups.

@trozet

trozet commented Feb 10, 2020

Copy link
Copy Markdown
Contributor Author

@dcbw take a look at the latest changes and see what you think. The checks with the switch statement for specific types are gone. Now it just compares against default values.

@trozet

trozet commented Feb 12, 2020

Copy link
Copy Markdown
Contributor Author

@danwinship noticed the latest patch isn't working, hold while I investigate it

@trozet

trozet commented Feb 12, 2020

Copy link
Copy Markdown
Contributor Author

Looks like the patch is working as expected. The issue was CLI arguments being passed via CNO setting cluster-subnets to nothing:
exec /usr/bin/ovnkube --init-node ovn-control-plane --cluster-subnets '' --k8s-service-cidr '' --k8s-apiserver https://192.168.1.5:11337

@danwinship

Copy link
Copy Markdown
Contributor

Though it's reasonable to expect that in

ovnkube --init-node --config-file=/blah/blah --cluster-subnets=10.0.0.0/8

the --cluster-subnets arg overrides the config file, while in

ovnkube --init-node --cluster-subnets=10.0.0.0/8 ...  --config-file=/blah/blah

the config file overrides the --cluster-subnets arg

@trozet

trozet commented Feb 12, 2020

Copy link
Copy Markdown
Contributor Author

Though it's reasonable to expect that in

ovnkube --init-node --config-file=/blah/blah --cluster-subnets=10.0.0.0/8

the --cluster-subnets arg overrides the config file, while in

ovnkube --init-node --cluster-subnets=10.0.0.0/8 ...  --config-file=/blah/blah

the config file overrides the --cluster-subnets arg

I don't think so. That then implies ordering of arguments matters, which I don't think is the case today. IMO we should just make it known that CLI takes precedence over config file (should be in the usage) and not add more caveats (there's already too many ways to determine config). If others feel strongly the ordering should matter, we can take that up in another PR.

@dcbw

dcbw commented Feb 13, 2020

Copy link
Copy Markdown
Contributor

Though it's reasonable to expect that in

ovnkube --init-node --config-file=/blah/blah --cluster-subnets=10.0.0.0/8

the --cluster-subnets arg overrides the config file, while in

ovnkube --init-node --cluster-subnets=10.0.0.0/8 ...  --config-file=/blah/blah

the config file overrides the --cluster-subnets arg

@danwinship current implementation has a clearly defined override, where CLI always overrides everything (config file, env args, kubernetes stuff, etc).

@dcbw dcbw left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@danwinship

Copy link
Copy Markdown
Contributor

lgtm

@trozet

trozet commented Feb 17, 2020

Copy link
Copy Markdown
Contributor Author

@girishmg PTAL

@dcbw dcbw merged commit 3bbdf51 into ovn-kubernetes:master Feb 18, 2020
kyrtapz pushed a commit to kyrtapz/ovn-kubernetes that referenced this pull request Jun 22, 2022
Bug 2077129: [release-4.10] Fixes secondary bridge
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants