-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
chore: Add checks for selectors in KubernetesSDConfig (#6177) #6359
Conversation
@slashpai can you review the pr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't reviewed full but its a good start, could you please add a test as well in https://github.com/prometheus-operator/prometheus-operator/blob/main/pkg/prometheus/resource_selector_test.go#L1710?
@@ -354,6 +366,32 @@ type KubernetesSDConfig struct { | |||
Selectors []K8SSelectorConfig `json:"selectors,omitempty"` | |||
} | |||
|
|||
// ValidateSelectorRoles validate the roles based on main role. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pkg/prometheus/promcfg.go
Outdated
@@ -2604,6 +2604,12 @@ func (cg *ConfigGenerator) generateScrapeConfig( | |||
if len(sc.Spec.KubernetesSDConfigs) > 0 { | |||
configs := make([][]yaml.MapItem, len(sc.Spec.KubernetesSDConfigs)) | |||
for i, config := range sc.Spec.KubernetesSDConfigs { | |||
|
|||
err := (&config).ValidateSelectorRoles() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validation should be called from validateKubernetesSDConfigs
in https://github.com/prometheus-operator/prometheus-operator/blob/main/pkg/prometheus/resource_selector.go
@slashpai done the changes and added the tests |
pkg/prometheus/resource_selector.go
Outdated
foundSelectorRoles := make(map[monitoringv1alpha1.Role]struct{}) | ||
allowedSelectors := map[monitoringv1alpha1.Role][]string{ | ||
RolePod: {string(RolePod)}, | ||
RoleService: {string(RoleService)}, | ||
RoleEndpointSlice: {string(RolePod), string(RoleService), string(RoleEndpointSlice)}, | ||
RoleEndpoint: {string(RolePod), string(RoleService), string(RoleEndpoint)}, | ||
RoleNode: {string(RoleNode)}, | ||
RoleIngress: {string(RoleIngress)}, | ||
} | ||
|
||
for _, selector := range c.Selectors { | ||
|
||
if _, ok := foundSelectorRoles[selector.Role]; ok { | ||
return fmt.Errorf("duplicated selector role: %s", selector.Role) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the impression that foundSelectorRoles
is never populated, therefore line 858 will never return ok
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it returns ok then error will come, while if it returns !ok then it should pass, tests are also passing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Arthur, I also tried it as a simple go code here https://go.dev/play/p/Di7AaLX_iW-
currently it accepts the the role pod for role node which it shouldn't.
Take a look at validation here we need to do something similar https://github.com/prometheus/prometheus/blob/92544c00bf9d43eecd7161911d541a3fbe7af8cc/discovery/kubernetes/kubernetes.go#L204-L233
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you also test this it locally on a cluster?
pkg/prometheus/promcfg.go
Outdated
@@ -2604,6 +2604,7 @@ func (cg *ConfigGenerator) generateScrapeConfig( | |||
if len(sc.Spec.KubernetesSDConfigs) > 0 { | |||
configs := make([][]yaml.MapItem, len(sc.Spec.KubernetesSDConfigs)) | |||
for i, config := range sc.Spec.KubernetesSDConfigs { | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove the blank line
pkg/prometheus/resource_selector.go
Outdated
@@ -830,13 +840,38 @@ func (rs *ResourceSelector) SelectScrapeConfigs(ctx context.Context, listFn List | |||
return res, nil | |||
} | |||
|
|||
// ValidateSelectorRoles validate the roles based on main role. | |||
func ValidateSelectorRoles(c monitoringv1alpha1.KubernetesSDConfig) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to have a function for this as it is not used any other place, better lets move the code to
prometheus-operator/pkg/prometheus/resource_selector.go
Lines 832 to 862 in 1e9c2bb
func (rs *ResourceSelector) validateKubernetesSDConfigs(ctx context.Context, sc *monitoringv1alpha1.ScrapeConfig) error { | |
for i, config := range sc.Spec.KubernetesSDConfigs { | |
configKey := fmt.Sprintf("scrapeconfig/%s/%s/kubernetessdconfig/%d", sc.GetNamespace(), sc.GetName(), i) | |
if err := rs.store.AddBasicAuth(ctx, sc.GetNamespace(), config.BasicAuth, configKey); err != nil { | |
return fmt.Errorf("[%d]: %w", i, err) | |
} | |
configAuthKey := fmt.Sprintf("scrapeconfig/auth/%s/%s/kubernetessdconfig/%d", sc.GetNamespace(), sc.GetName(), i) | |
if err := rs.store.AddSafeAuthorizationCredentials(ctx, sc.GetNamespace(), config.Authorization, configAuthKey); err != nil { | |
return fmt.Errorf("[%d]: %w", i, err) | |
} | |
if err := rs.store.AddOAuth2(ctx, sc.GetNamespace(), config.OAuth2, configKey); err != nil { | |
return fmt.Errorf("[%d]: %w", i, err) | |
} | |
if err := rs.store.AddSafeTLSConfig(ctx, sc.GetNamespace(), config.TLSConfig); err != nil { | |
return fmt.Errorf("[%d]: %w", i, err) | |
} | |
if err := validateProxyConfig(ctx, config.ProxyConfig, rs.store, sc.GetNamespace()); err != nil { | |
return fmt.Errorf("[%d]: %w", i, err) | |
} | |
if config.APIServer != nil && config.Namespaces != nil { | |
if ptr.Deref(config.Namespaces.IncludeOwnNamespace, false) { | |
return fmt.Errorf("[%d]: %w", i, errors.New("cannot use 'apiServer' and 'namespaces.ownNamespace' simultaneously")) | |
} | |
} | |
for _, s := range config.Selectors { |
pkg/prometheus/resource_selector.go
Outdated
foundSelectorRoles := make(map[monitoringv1alpha1.Role]struct{}) | ||
allowedSelectors := map[monitoringv1alpha1.Role][]string{ | ||
RolePod: {string(RolePod)}, | ||
RoleService: {string(RoleService)}, | ||
RoleEndpointSlice: {string(RolePod), string(RoleService), string(RoleEndpointSlice)}, | ||
RoleEndpoint: {string(RolePod), string(RoleService), string(RoleEndpoint)}, | ||
RoleNode: {string(RoleNode)}, | ||
RoleIngress: {string(RoleIngress)}, | ||
} | ||
|
||
for _, selector := range c.Selectors { | ||
|
||
if _, ok := foundSelectorRoles[selector.Role]; ok { | ||
return fmt.Errorf("duplicated selector role: %s", selector.Role) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Arthur, I also tried it as a simple go code here https://go.dev/play/p/Di7AaLX_iW-
currently it accepts the the role pod for role node which it shouldn't.
Take a look at validation here we need to do something similar https://github.com/prometheus/prometheus/blob/92544c00bf9d43eecd7161911d541a3fbe7af8cc/discovery/kubernetes/kubernetes.go#L204-L233
pkg/prometheus/resource_selector.go
Outdated
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove extra blank line
pkg/prometheus/resource_selector.go
Outdated
@@ -870,7 +909,9 @@ func (rs *ResourceSelector) validateKubernetesSDConfigs(ctx context.Context, sc | |||
if _, err := labels.Parse(s.Label); err != nil { | |||
return fmt.Errorf("[%d]: %w", i, err) | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove extra blank line
pkg/prometheus/resource_selector.go
Outdated
|
||
for _, selector := range c.Selectors { | ||
|
||
if _, ok := foundSelectorRoles[selector.Role]; ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to apply strings.ToLower() on the role value (e.g. prometheus-operator both "Pod" and "pod").
@slashpai done the changes |
pkg/prometheus/resource_selector.go
Outdated
@@ -42,6 +42,16 @@ import ( | |||
"github.com/prometheus-operator/prometheus-operator/pkg/operator" | |||
) | |||
|
|||
// The valid options for Role. | |||
const ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be good to have the consts defined in pkg/apis/monitoring/v1 directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@simonpasquier previously i have done the same, but @slashpai suggested me to put it in the resource_selector
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thats for validation methods 🙂
Since consts were also moved I was ok but I agree with Simon consts go better in types.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's have a follow-up for this.
pkg/prometheus/resource_selector.go
Outdated
var allowed bool | ||
|
||
for _, role := range allowedSelectors[config.Role] { | ||
if role == strings.ToLower(string(s.Role)) { | ||
allowed = true | ||
break | ||
} | ||
} | ||
if !allowed { | ||
return fmt.Errorf("[%d] : %s role supports only %s selectors", i, config.Role, strings.Join(allowedSelectors[config.Role], ", ")) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(suggestion) we could use https://pkg.go.dev/slices#Contains
pkg/prometheus/resource_selector.go
Outdated
} | ||
|
||
for _, s := range config.Selectors { | ||
if _, ok := allowedSelectors[config.Role]; !ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need strings.ToLower too?
if _, ok := allowedSelectors[config.Role]; !ok { | |
if _, ok := allowedSelectors[strings.ToLower(config.Role)]; !ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@simonpasquier done
pkg/prometheus/resource_selector.go
Outdated
@@ -42,6 +42,16 @@ import ( | |||
"github.com/prometheus-operator/prometheus-operator/pkg/operator" | |||
) | |||
|
|||
// The valid options for Role. | |||
const ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's have a follow-up for this.
TestSelectScrapeConfigs/Kubernetes_SD_config_with_valid_label_and_field_selectors is failing |
…rator#6177) chore: test added rfac: kubernetes sd role chore: cofig.Role to lowercase rfac: unit_test role_consts
@simonpasquier done the above changes, rfac the unit test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Description
fix: #6177
additional checks on the role selectors vs. the main role added
Type of change
What type of changes does your code introduce to the Prometheus operator? Put an
x
in the box that apply.CHANGE
(fix or feature that would cause existing functionality to not work as expected)FEATURE
(non-breaking change which adds functionality)BUGFIX
(non-breaking change which fixes an issue)ENHANCEMENT
(non-breaking change which improves existing functionality)NONE
(if none of the other choices apply. Example, tooling, build system, CI, docs, etc.)Changelog entry