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

[WIP] Protect query frontend using oauth proxy #997

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
16 changes: 16 additions & 0 deletions .chloggen/protect_query_frontend_oauthproxy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. tempostack, tempomonolithic, github action)
component: tempostack,tempomonolithic

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Protect query-frontend using oauth-proxy on OpenShift

# One or more tracking issues related to the change
issues: [998]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
4 changes: 2 additions & 2 deletions apis/tempo/v1alpha1/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ type ExtraConfigSpec struct {
Tempo apiextensionsv1.JSON `json:"tempo,omitempty"`
}

// JaegerQueryAuthenticationSpec defines options applied to proxy sidecar that controls the authentication of the jaeger UI.
type JaegerQueryAuthenticationSpec struct {
// OAuthAuthenticationSpec defines options applied to proxy sidecar that controls the authentication of the jaeger UI.
type OAuthAuthenticationSpec struct {
// Defines if the authentication will be enabled for jaeger UI.
//
// +optional
Expand Down
39 changes: 28 additions & 11 deletions apis/tempo/v1alpha1/tempomonolithic_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,18 @@ func (r *TempoMonolithic) Default(ctrlConfig configv1alpha1.ProjectConfig) {
Enabled: true,
}
}

if r.Spec.Query != nil {
r.Spec.Query.Authentication = r.defaultAuthentication(r.Spec.Query.Authentication, ctrlConfig)
} else {
r.Spec.Query = &QuerySpec{}
r.Spec.Query.Authentication = r.defaultAuthentication(r.Spec.Query.Authentication, ctrlConfig)
}

if r.Spec.JaegerUI != nil && r.Spec.JaegerUI.Enabled {

r.Spec.JaegerUI.Authentication = r.defaultAuthentication(r.Spec.JaegerUI.Authentication, ctrlConfig)

if r.Spec.JaegerUI.Route != nil && r.Spec.JaegerUI.Route.Enabled {

if r.Spec.JaegerUI.Route.Termination == "" {
Expand All @@ -71,21 +81,28 @@ func (r *TempoMonolithic) Default(ctrlConfig configv1alpha1.ProjectConfig) {
r.Spec.JaegerUI.Route.Termination = TLSRouteTerminationTypeEdge
}
}

if r.Spec.JaegerUI.Authentication == nil {
r.Spec.JaegerUI.Authentication = &JaegerQueryAuthenticationSpec{
Enabled: ctrlConfig.Gates.OpenShift.OauthProxy.DefaultEnabled,
}
}

if len(strings.TrimSpace(r.Spec.JaegerUI.Authentication.SAR)) == 0 {
defaultSAR := fmt.Sprintf("{\"namespace\": \"%s\", \"resource\": \"pods\", \"verb\": \"get\"}", r.Namespace)
r.Spec.JaegerUI.Authentication.SAR = defaultSAR
}
}

if r.Spec.JaegerUI.ServicesQueryDuration == nil {
r.Spec.JaegerUI.ServicesQueryDuration = &defaultServicesDuration
}
}
}

func (r *TempoMonolithic) defaultAuthentication(spec *OAuthAuthenticationSpec, ctrlConfig configv1alpha1.ProjectConfig) *OAuthAuthenticationSpec {
newSpec := spec

if ctrlConfig.Gates.OpenShift.OauthProxy.DefaultEnabled {
if spec == nil {
newSpec = &OAuthAuthenticationSpec{
Enabled: true,
}
}
}

if newSpec != nil && newSpec.Enabled && len(strings.TrimSpace(newSpec.SAR)) == 0 {
newSpec.SAR = fmt.Sprintf("{\"namespace\": \"%s\", \"resource\": \"pods\", \"verb\": \"get\"}", r.Namespace)
}

return newSpec
}
67 changes: 52 additions & 15 deletions apis/tempo/v1alpha1/tempomonolithic_defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func TestMonolithicDefault(t *testing.T) {
},
},
},
Query: &QuerySpec{},
Management: "Managed",
},
},
Expand Down Expand Up @@ -78,6 +79,7 @@ func TestMonolithicDefault(t *testing.T) {
},
},
},
Query: &QuerySpec{},
Management: "Managed",
},
},
Expand All @@ -103,6 +105,7 @@ func TestMonolithicDefault(t *testing.T) {
},
},
},
Query: &QuerySpec{},
Management: "Unmanaged",
},
},
Expand All @@ -124,12 +127,13 @@ func TestMonolithicDefault(t *testing.T) {
},
},
},
Query: &QuerySpec{},
Management: "Unmanaged",
},
},
},
{
name: "enable jaeger ui oauth when feature gate is enabled",
name: "enable oauth when feature gate is enabled",
ctrlConfig: configv1alpha1.ProjectConfig{
Gates: configv1alpha1.FeatureGates{
OpenShift: configv1alpha1.OpenShiftFeatureGates{
Expand Down Expand Up @@ -187,12 +191,18 @@ func TestMonolithicDefault(t *testing.T) {
Enabled: true,
Termination: TLSRouteTerminationTypeEdge,
},
Authentication: &JaegerQueryAuthenticationSpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: true,
SAR: "{\"namespace\": \"testns\", \"resource\": \"pods\", \"verb\": \"get\"}",
},
ServicesQueryDuration: &defaultServicesDuration,
},
Query: &QuerySpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: true,
SAR: "{\"namespace\": \"testns\", \"resource\": \"pods\", \"verb\": \"get\"}",
},
},
Management: "Managed",
},
},
Expand Down Expand Up @@ -225,7 +235,12 @@ func TestMonolithicDefault(t *testing.T) {
Route: &MonolithicJaegerUIRouteSpec{
Enabled: true,
},
Authentication: &JaegerQueryAuthenticationSpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: false,
},
},
Query: &QuerySpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: false,
},
},
Expand Down Expand Up @@ -259,18 +274,22 @@ func TestMonolithicDefault(t *testing.T) {
Enabled: true,
Termination: TLSRouteTerminationTypeEdge,
},
Authentication: &JaegerQueryAuthenticationSpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: false,
SAR: "{\"namespace\": \"testns\", \"resource\": \"pods\", \"verb\": \"get\"}",
},
ServicesQueryDuration: &defaultServicesDuration,
},
Query: &QuerySpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: false,
},
},
Management: "Managed",
},
},
},
{
name: "no touch jaeger ui oauth when feature gate is disabled (true case)",
name: "no touch oauth when feature gate is disabled (true case)",
input: &TempoMonolithic{
ObjectMeta: v1.ObjectMeta{
Name: "test",
Expand All @@ -288,7 +307,13 @@ func TestMonolithicDefault(t *testing.T) {
Route: &MonolithicJaegerUIRouteSpec{
Enabled: true,
},
Authentication: &JaegerQueryAuthenticationSpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: true,
SAR: "{\"namespace\": \"testns\", \"resource\": \"pods\", \"verb\": \"get\"}",
},
},
Query: &QuerySpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: true,
SAR: "{\"namespace\": \"testns\", \"resource\": \"pods\", \"verb\": \"get\"}",
},
Expand Down Expand Up @@ -323,12 +348,18 @@ func TestMonolithicDefault(t *testing.T) {
Enabled: true,
Termination: TLSRouteTerminationTypeEdge,
},
Authentication: &JaegerQueryAuthenticationSpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: true,
SAR: "{\"namespace\": \"testns\", \"resource\": \"pods\", \"verb\": \"get\"}",
},
ServicesQueryDuration: &defaultServicesDuration,
},
Query: &QuerySpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: true,
SAR: "{\"namespace\": \"testns\", \"resource\": \"pods\", \"verb\": \"get\"}",
},
},
Management: "Managed",
},
},
Expand All @@ -352,7 +383,12 @@ func TestMonolithicDefault(t *testing.T) {
Route: &MonolithicJaegerUIRouteSpec{
Enabled: true,
},
Authentication: &JaegerQueryAuthenticationSpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: false,
},
},
Query: &QuerySpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: false,
},
},
Expand Down Expand Up @@ -386,12 +422,16 @@ func TestMonolithicDefault(t *testing.T) {
Enabled: true,
Termination: TLSRouteTerminationTypeEdge,
},
Authentication: &JaegerQueryAuthenticationSpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: false,
SAR: "{\"namespace\": \"testns\", \"resource\": \"pods\", \"verb\": \"get\"}",
},
ServicesQueryDuration: &defaultServicesDuration,
},
Query: &QuerySpec{
Authentication: &OAuthAuthenticationSpec{
Enabled: false,
},
},
Management: "Managed",
},
},
Expand Down Expand Up @@ -447,12 +487,9 @@ func TestMonolithicDefault(t *testing.T) {
Enabled: true,
Termination: TLSRouteTerminationTypeEdge,
},
Authentication: &JaegerQueryAuthenticationSpec{
Enabled: false,
SAR: "{\"namespace\": \"testns\", \"resource\": \"pods\", \"verb\": \"get\"}",
},
ServicesQueryDuration: &v1.Duration{Duration: time.Duration(100 * 100)},
},
Query: &QuerySpec{},
Management: "Managed",
},
},
Expand Down
18 changes: 17 additions & 1 deletion apis/tempo/v1alpha1/tempomonolithic_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ type TempoMonolithicSpec struct {
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Extra Configuration",xDescriptors="urn:alm:descriptor:com.tectonic.ui:advanced"
ExtraConfig *ExtraConfigSpec `json:"extraConfig,omitempty"`

// QuerySpec defines configurations for query path
//
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Query",xDescriptors="urn:alm:descriptor:com.tectonic.ui:advanced"
Query *QuerySpec `json:"query,omitempty"`

MonolithicSchedulerSpec `json:",inline"`
}

Expand Down Expand Up @@ -249,7 +255,7 @@ type MonolithicJaegerUISpec struct {
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Jaeger UI authentication configuration",order=5
Authentication *JaegerQueryAuthenticationSpec `json:"authentication,omitempty"`
Authentication *OAuthAuthenticationSpec `json:"authentication,omitempty"`

// ServicesQueryDuration defines how long the services will be available in the services list
//
Expand All @@ -258,6 +264,16 @@ type MonolithicJaegerUISpec struct {
ServicesQueryDuration *metav1.Duration `json:"servicesQueryDuration,omitempty"`
}

// QuerySpec specific configuratitons for query frontend.
type QuerySpec struct {
// Authentication defines the options for the oauth proxy used to protect jaeger UI
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Jaeger UI authentication configuration",order=5
Authentication *OAuthAuthenticationSpec `json:"authentication,omitempty"`
}

// MonolithicJaegerUIIngressSpec defines the settings for the Jaeger UI ingress.
type MonolithicJaegerUIIngressSpec struct {
// Enabled defines if an Ingress object should be created for Jaeger UI.
Expand Down
9 changes: 8 additions & 1 deletion apis/tempo/v1alpha1/tempostack_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,13 @@ type TempoQueryFrontendSpec struct {
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Jaeger Query Settings"
JaegerQuery JaegerQuerySpec `json:"jaegerQuery"`

// Authentication defines the options for the oauth proxy used to protect query frontend
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Query Frontend authentication configuration"
Authentication *OAuthAuthenticationSpec `json:"authentication,omitempty"`
}

// JaegerQuerySpec defines Jaeger Query options.
Expand Down Expand Up @@ -605,7 +612,7 @@ type JaegerQuerySpec struct {
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Jaeger UI authentication configuration"
Authentication *JaegerQueryAuthenticationSpec `json:"authentication,omitempty"`
Authentication *OAuthAuthenticationSpec `json:"authentication,omitempty"`
}

// JaegerQueryMonitor defines configuration for the service monitoring tab in the Jaeger console.
Expand Down
Loading
Loading