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

fix(extension): add header to support apps-in-any-namespace (cherry-pick #20123) #20126

Merged
merged 1 commit into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions server/extension/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ const (
DefaultIdleConnectionTimeout = 60 * time.Second
DefaultMaxIdleConnections = 30

// HeaderArgoCDNamespace defines the namespace of the
// argo control plane to be passed to the extension handler.
// Example:
// Argocd-Namespace: "namespace"
HeaderArgoCDNamespace = "Argocd-Namespace"

// HeaderArgoCDApplicationName defines the name of the
// expected application header to be passed to the extension
// handler. The header value must follow the format:
Expand Down Expand Up @@ -333,6 +339,7 @@ type RbacEnforcer interface {
// and handling proxy extensions.
type Manager struct {
log *log.Entry
namespace string
settings SettingsGetter
application ApplicationGetter
project ProjectGetter
Expand All @@ -355,9 +362,10 @@ type ExtensionMetricsRegistry interface {
}

// NewManager will initialize a new manager.
func NewManager(log *log.Entry, sg SettingsGetter, ag ApplicationGetter, pg ProjectGetter, rbac RbacEnforcer, ug UserGetter) *Manager {
func NewManager(log *log.Entry, namespace string, sg SettingsGetter, ag ApplicationGetter, pg ProjectGetter, rbac RbacEnforcer, ug UserGetter) *Manager {
return &Manager{
log: log,
namespace: namespace,
settings: sg,
application: ag,
project: pg,
Expand Down Expand Up @@ -740,7 +748,7 @@ func (m *Manager) CallExtension() func(http.ResponseWriter, *http.Request) {

user := m.userGetter.GetUser(r.Context())
groups := m.userGetter.GetGroups(r.Context())
prepareRequest(r, extName, app, user, groups)
prepareRequest(r, m.namespace, extName, app, user, groups)
m.log.Debugf("proxing request for extension %q", extName)
// httpsnoop package is used to properly wrap the responseWriter
// and avoid optional intefaces issue:
Expand All @@ -763,11 +771,13 @@ func registerMetrics(extName string, metrics httpsnoop.Metrics, extensionMetrics
// the Argo CD extension API section from it. It provides additional information to
// the backend service appending them in the outgoing request headers. The appended
// headers are:
// - Control plane namespace
// - Cluster destination name
// - Cluster destination server
// - Argo CD authenticated username
func prepareRequest(r *http.Request, extName string, app *v1alpha1.Application, username string, groups []string) {
func prepareRequest(r *http.Request, namespace string, extName string, app *v1alpha1.Application, username string, groups []string) {
r.URL.Path = strings.TrimPrefix(r.URL.Path, fmt.Sprintf("%s/%s", URLPrefix, extName))
r.Header.Set(HeaderArgoCDNamespace, namespace)
if app.Spec.Destination.Name != "" {
r.Header.Set(HeaderArgoCDTargetClusterName, app.Spec.Destination.Name)
}
Expand Down
6 changes: 4 additions & 2 deletions server/extension/extension_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func TestRegisterExtensions(t *testing.T) {

logger, _ := test.NewNullLogger()
logEntry := logger.WithContext(context.Background())
m := extension.NewManager(logEntry, settMock, nil, nil, nil, nil)
m := extension.NewManager(logEntry, "", settMock, nil, nil, nil, nil)

return &fixture{
settingsGetterMock: settMock,
Expand Down Expand Up @@ -248,6 +248,7 @@ func TestCallExtension(t *testing.T) {
userMock *mocks.UserGetter
manager *extension.Manager
}
defaultServerNamespace := "control-plane-ns"
defaultProjectName := "project-name"

setup := func() *fixture {
Expand All @@ -260,7 +261,7 @@ func TestCallExtension(t *testing.T) {

logger, _ := test.NewNullLogger()
logEntry := logger.WithContext(context.Background())
m := extension.NewManager(logEntry, settMock, appMock, projMock, rbacMock, userMock)
m := extension.NewManager(logEntry, defaultServerNamespace, settMock, appMock, projMock, rbacMock, userMock)
m.AddMetricsRegistry(metricsMock)

mux := http.NewServeMux()
Expand Down Expand Up @@ -444,6 +445,7 @@ func TestCallExtension(t *testing.T) {
require.NoError(t, err)
actual := strings.TrimSuffix(string(body), "\n")
assert.Equal(t, backendResponse, actual)
assert.Equal(t, defaultServerNamespace, resp.Header.Get(extension.HeaderArgoCDNamespace))
assert.Equal(t, clusterURL, resp.Header.Get(extension.HeaderArgoCDTargetClusterURL))
assert.Equal(t, "Bearer some-bearer-token", resp.Header.Get("Authorization"))
assert.Equal(t, "some-user", resp.Header.Get(extension.HeaderArgoCDUsername))
Expand Down
2 changes: 1 addition & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts, appsetOpts Applicatio
ag := extension.NewDefaultApplicationGetter(appLister)
pg := extension.NewDefaultProjectGetter(projLister, dbInstance)
ug := extension.NewDefaultUserGetter(policyEnf)
em := extension.NewManager(logger, sg, ag, pg, enf, ug)
em := extension.NewManager(logger, opts.Namespace, sg, ag, pg, enf, ug)

a := &ArgoCDServer{
ArgoCDServerOpts: opts,
Expand Down
Loading