Skip to content
Open
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
4 changes: 4 additions & 0 deletions cmd/bridge/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ func main() {
_ = fs.String("kubectl-client-secret-file", "", "DEPRECATED: setting this does not do anything.")

fK8sPublicEndpoint := fs.String("k8s-public-endpoint", "", "Endpoint to use to communicate to the API server.")
fCustomLoginServerURL := fs.String("custom-login-server-url", "", "Optional URL to display as the --server value in the 'oc login' command shown in the console. Does not affect API proxying. When unset the console uses the cluster API server URL.")

fBranding := fs.String("branding", "okd", "Console branding for the masthead logo and title. One of okd, openshift, ocp, online, dedicated, azure, or rosa. Defaults to okd.")
fCustomProductName := fs.String("custom-product-name", "", "Custom product name for console branding.")
Expand Down Expand Up @@ -638,6 +639,9 @@ func main() {
apiServerEndpoint = srv.K8sProxyConfig.Endpoint.String()
}
srv.KubeAPIServerURL = apiServerEndpoint
_, err = flags.ValidateFlagIsURL("custom-login-server-url", *fCustomLoginServerURL, true)
flags.FatalIfFailed(err)
srv.LoginServerURL = *fCustomLoginServerURL

clusterManagementURL, err := url.Parse(clusterManagementURL)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions frontend/@types/console/window.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ declare interface Window {
documentationBaseURL: string;
kubeAdminLogoutURL: string;
kubeAPIServerURL: string;
customLoginServerURL?: string;
loadTestFactor: number;
loginErrorURL: string;
loginSuccessURL: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ import { useFlag } from './flag';

const COPY_LOGIN_COMMANDS_ENDPOINT = '/api/copy-login-commands';

export const useCopyLoginCommands = (): [string, string] => {
export const useCopyLoginCommands = (): [string, string, string] => {
const [requestTokenURL, setRequestTokenURL] = useState<string>();
const [externalLoginCommand, setExternalLoginCommand] = useState<string>();
const [loginServerURL, setLoginServerURL] = useState<string>('');
const authEnabled = useFlag(FLAGS.AUTH_ENABLED);
useEffect(() => {
if (authEnabled) {
coFetchJSON(COPY_LOGIN_COMMANDS_ENDPOINT, 'GET', {}, 5000)
.then((resp) => {
const newRequestTokenURL = resp?.requestTokenURL ?? '';
const newExternalLoginCommand = resp?.externalLoginCommand ?? '';
const newLoginServerURL = resp?.customLoginServerURL ?? '';
setLoginServerURL(newLoginServerURL);
if (newRequestTokenURL) {
setRequestTokenURL(newRequestTokenURL);
setExternalLoginCommand('');
Expand All @@ -28,9 +31,10 @@ export const useCopyLoginCommands = (): [string, string] => {
console.warn(`GET ${COPY_LOGIN_COMMANDS_ENDPOINT} failed: ${err}`);
setRequestTokenURL('');
setExternalLoginCommand('');
setLoginServerURL('');
});
}
}, [authEnabled]);

return [requestTokenURL, externalLoginCommand];
return [requestTokenURL, externalLoginCommand, loginServerURL];
};
34 changes: 33 additions & 1 deletion pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"net/url"
"os"
"path"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -122,6 +123,7 @@ type jsGlobals struct {
InactivityTimeout int `json:"inactivityTimeout"`
KubeAdminLogoutURL string `json:"kubeAdminLogoutURL"`
KubeAPIServerURL string `json:"kubeAPIServerURL"`
CustomLoginServerURL string `json:"customLoginServerURL,omitempty"`
K8sMode string `json:"k8sMode"`
LoadTestFactor int `json:"loadTestFactor"`
LoginErrorURL string `json:"loginErrorURL"`
Expand Down Expand Up @@ -192,6 +194,7 @@ type Server struct {
KnativeChannelCRDLister ResourceLister
KnativeEventSourceCRDLister ResourceLister
KubeAPIServerURL string // JS global only. Not used for proxying.
LoginServerURL string
KubeVersion string
LoadTestFactor int
MonitoringDashboardConfigMapLister ResourceLister
Expand Down Expand Up @@ -758,6 +761,7 @@ func (s *Server) indexHandler(w http.ResponseWriter, r *http.Request) {
K8sMode: s.K8sMode,
KubeAdminLogoutURL: s.Authenticator.GetSpecialURLs().KubeAdminLogout,
KubeAPIServerURL: s.KubeAPIServerURL,
CustomLoginServerURL: s.LoginServerURL,
LoadTestFactor: s.LoadTestFactor,
LoginErrorURL: proxy.SingleJoiningSlash(s.BaseURL.String(), AuthLoginErrorEndpoint),
LoginSuccessURL: proxy.SingleJoiningSlash(s.BaseURL.String(), AuthLoginSuccessEndpoint),
Expand Down Expand Up @@ -829,6 +833,29 @@ func notFoundHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("not found"))
}

// serverFlagRe matches the --server=VALUE token in an oc login command string.
var serverFlagRe = regexp.MustCompile(`(^|\s)--server=\S+`)

// applyLoginServerURL substitutes (or appends) the --server= flag in an oc
// login command string with loginServerURL. Returns cmd unchanged when either
// argument is empty.
func applyLoginServerURL(cmd, loginServerURL string) string {
if loginServerURL == "" || cmd == "" {
return cmd
}
serverFlag := "--server=" + loginServerURL
if serverFlagRe.MatchString(cmd) {
return serverFlagRe.ReplaceAllStringFunc(cmd, func(match string) string {
// Preserve any leading whitespace captured by the group.
if strings.HasPrefix(match, " ") || strings.HasPrefix(match, "\t") {
return match[:1] + serverFlag
}
return serverFlag
})
}
return cmd + " " + serverFlag
}

func (s *Server) handleCopyLogin(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
serverutils.SendResponse(w, http.StatusMethodNotAllowed, serverutils.ApiError{Err: "Invalid method: only GET is allowed"})
Expand All @@ -840,9 +867,14 @@ func (s *Server) handleCopyLogin(w http.ResponseWriter, r *http.Request) {
serverutils.SendResponse(w, http.StatusOK, struct {
RequestTokenURL string `json:"requestTokenURL"`
ExternalLoginCommand string `json:"externalLoginCommand"`
// CustomLoginServerURL is included when the operator has configured an override
// server address (e.g. a Proxy). Empty string means the frontend
// should use the default cluster API server URL.
CustomLoginServerURL string `json:"customLoginServerURL,omitempty"`
}{
RequestTokenURL: specialAuthURLs.RequestToken,
ExternalLoginCommand: s.Authenticator.GetOCLoginCommand(),
ExternalLoginCommand: applyLoginServerURL(s.Authenticator.GetOCLoginCommand(), s.LoginServerURL),
CustomLoginServerURL: s.LoginServerURL,
})
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/serverconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,10 @@ func addCustomization(fs *flag.FlagSet, customization *Customization) {
fs.Set("capabilities", string(capabilities))
}
}

if customization.CustomLoginServerURL != "" {
fs.Set("custom-login-server-url", customization.CustomLoginServerURL)
}
}

func isAlreadySet(fs *flag.FlagSet, name string) bool {
Expand Down
5 changes: 5 additions & 0 deletions pkg/serverconfig/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ type Customization struct {
DocumentationBaseURL string `yaml:"documentationBaseURL,omitempty"`
CustomProductName string `yaml:"customProductName,omitempty"`
CustomLogoFile string `yaml:"customLogoFile,omitempty"`
// CustomLoginServerURL, when set, overrides the API server URL shown in the
// 'oc login --server=...' command displayed by the console. The actual
// API proxy target is not affected. This is an opt-in field; when omitted
// the console falls back to the cluster API server URL.
CustomLoginServerURL string `yaml:"customLoginServerURL,omitempty"`
// developerCatalog allows to configure the shown developer catalog categories and it's types.
DeveloperCatalog DeveloperConsoleCatalogCustomization `yaml:"developerCatalog,omitempty"`
QuickStarts QuickStarts `yaml:"quickStarts,omitempty"`
Expand Down
14 changes: 14 additions & 0 deletions vendor/github.com/openshift/api/operator/v1/types_console.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.