Web console OpenShift Container Platform 4.16 Getting started with the web console in OpenShift Container Platform Red Hat OpenShift Documentation Team

Commands:
INFO Install complete! INFO Run 'export KUBECONFIG=<your working directory>/auth/kubeconfig' to manage the cluster with 'oc', the OpenShift CLI. INFO The cluster is ready when 'oc login -u kubeadmin -p <provided>' succeeds (wait a few minutes). INFO Access the OpenShift web-console here: https://console-openshift-console.apps.demo1.openshift4-beta-abcorp.com INFO Login to the console with user: kubeadmin, password: <provided>
oc edit console.config.openshift.io cluster
apiVersion: config.openshift.io/v1 kind: Console metadata: name: cluster spec: authentication: logoutRedirect: "" 1 status: consoleURL: "" 2
oc create configmap console-custom-logo --from-file /path/to/console-custom-logo.png -n openshift-config
apiVersion: v1 kind: ConfigMap metadata: name: console-custom-logo namespace: openshift-config binaryData: console-custom-logo.png: <base64-encoded_logo> ... 1
oc edit consoles.operator.openshift.io cluster
apiVersion: operator.openshift.io/v1 kind: Console metadata: name: cluster spec: customization: customLogoFile: key: console-custom-logo.png name: console-custom-logo customProductName: My Console
oc get clusteroperator console -o yaml
oc get consoles.operator.openshift.io -o yaml
apiVersion: console.openshift.io/v1 kind: ConsoleLink metadata: name: example spec: href: 'https://www.example.com' location: HelpMenu 1 text: Link 1
apiVersion: console.openshift.io/v1 kind: ConsoleLink metadata: name: namespaced-dashboard-link-for-all-namespaces spec: href: 'https://www.example.com' location: NamespaceDashboard text: This appears in all namespaces
apiVersion: console.openshift.io/v1 kind: ConsoleLink metadata: name: namespaced-dashboard-for-some-namespaces spec: href: 'https://www.example.com' location: NamespaceDashboard # This text will appear in a box called "Launcher" under "namespace" or "project" in the web console text: Custom Link Text namespaceDashboard: namespaces: # for these specific namespaces - my-namespace - your-namespace - other-namespace
apiVersion: console.openshift.io/v1 kind: ConsoleLink metadata: name: application-menu-link-1 spec: href: 'https://www.example.com' location: ApplicationMenu text: Link 1 applicationMenu: section: My New Section # image that is 24x24 in size imageURL: https://via.placeholder.com/24
oc edit ingress.config.openshift.io cluster
apiVersion: config.openshift.io/v1 kind: Ingress metadata: name: cluster spec: componentRoutes: - name: console namespace: openshift-console hostname: <custom_hostname> 1 servingCertKeyPairSecret: name: <secret_name> 2
oc edit ingress.config.openshift.io cluster
apiVersion: config.openshift.io/v1 kind: Ingress metadata: name: cluster spec: componentRoutes: - name: downloads namespace: openshift-console hostname: <custom_hostname> 1 servingCertKeyPairSecret: name: <secret_name> 2
oc adm create-login-template > login.html
oc adm create-provider-selection-template > providers.html
oc adm create-error-template > errors.html
oc create secret generic login-template --from-file=login.html -n openshift-config
oc create secret generic providers-template --from-file=providers.html -n openshift-config
oc create secret generic error-template --from-file=errors.html -n openshift-config
oc edit oauths cluster
apiVersion: config.openshift.io/v1 kind: OAuth metadata: name: cluster spec: templates: error: name: error-template login: name: login-template providerSelection: name: providers-template
apiVersion: console.openshift.io/v1 kind: ConsoleExternalLogLink metadata: name: example spec: hrefTemplate: >- https://example.com/logs?resourceName=USD{resourceName}&containerName=USD{containerName}&resourceNamespace=USD{resourceNamespace}&podLabels=USD{podLabels} text: Example Logs
apiVersion: console.openshift.io/v1 kind: ConsoleNotification metadata: name: example spec: text: This is an example notification message with an optional link. location: BannerTop 1 link: href: 'https://www.example.com' text: Optional link text color: '#fff' backgroundColor: '#0088ce'
apiVersion: console.openshift.io/v1 kind: ConsoleCLIDownload metadata: name: example-cli-download-links spec: description: | This is an example of download links displayName: example links: - href: 'https://www.example.com/public/example.tar' text: example for linux - href: 'https://www.example.com/public/example.mac.zip' text: example for mac - href: 'https://www.example.com/public/example.win.zip' text: example for windows
apiVersion: console.openshift.io/v1 kind: ConsoleYAMLSample metadata: name: example spec: targetResource: apiVersion: batch/v1 kind: Job title: Example Job description: An example Job YAML sample yaml: | apiVersion: batch/v1 kind: Job metadata: name: countdown spec: template: metadata: name: countdown spec: containers: - name: counter image: centos:7 command: - "bin/bash" - "-c" - "for i in 9 8 7 6 5 4 3 2 1 ; do echo USDi ; done" restartPolicy: Never
apiVersion: operator.openshift.io/v1 kind: Console metadata: name: cluster spec: customization: perspectives: - id: admin visibility: state: Enabled - id: dev visibility: state: Enabled
apiVersion: operator.openshift.io/v1 kind: Console metadata: name: cluster spec: customization: perspectives: - id: admin requiresAccessReview: - group: rbac.authorization.k8s.io resource: clusterroles verb: list - id: dev state: Enabled
apiVersion: operator.openshift.io/v1 kind: Console metadata: name: cluster spec: customization: perspectives: - id: admin visibility: state: AccessReview accessReview: missing: - resource: deployment verb: list required: - resource: namespaces verb: list - id: dev visibility: state: Enabled
apiVersion: operator.openshift.io/v1 kind: Console metadata: name: cluster spec: customization: developerCatalog: categories: types: state: Disabled disabled: - BuilderImage - Devfile - HelmChart
apiVersion: operator.openshift.io/v1 kind: Console metadata: name: cluster spec: customization: developerCatalog: categories: types: state: Enabled
apiVersion: operator.openshift.io/v1 kind: Console metadata: name: cluster spec: customization: developerCatalog: categories: types: state: Disabled
apiVersion: operator.openshift.io/v1 kind: Console metadata: name: cluster spec: customization: developerCatalog: categories: types: state: Enabled enabled: - BuilderImage - Devfile - HelmChart -
conster Header: React.FC = () => { const { t } = useTranslation('plugin__console-demo-plugin'); return <h1>{t('Hello, World!')}</h1>; };
conster Header: React.FC = () => { const { t } = useTranslation('plugin__console-demo-plugin'); return <h1>{t('Hello, World!')}</h1>; };
spec: backend: service: basePath: / name: console-demo-plugin namespace: console-demo-plugin port: 9001 type: Service displayName: OpenShift Console Demo Plugin i18n: loadType: Preload 1
{ "type": "console.navigation/section", "properties": { "id": "admin-demo-section", "perspective": "admin", "name": "%plugin__console-plugin-template~Plugin Template%" } }
// t('plugin__console-demo-plugin~Demo Plugin')
yarn i18n
yarn install
yarn run start
oc login
yarn run start-console
podman machine ssh sudo -i rpm-ostree install qemu-user-static systemctl reboot
docker build -t quay.io/my-repositroy/my-plugin:latest .
docker run -it --rm -d -p 9001:80 quay.io/my-repository/my-plugin:latest
docker push quay.io/my-repository/my-plugin:latest
helm upgrade -i my-plugin charts/openshift-console-plugin -n my-plugin-namespace --create-namespace --set plugin.image=my-plugin-image-location
plugin: name: "" description: "" image: "" imagePullPolicy: IfNotPresent replicas: 2 port: 9443 securityContext: enabled: true podSecurityContext: enabled: true runAsNonRoot: true seccompProfile: type: RuntimeDefault containerSecurityContext: enabled: true allowPrivilegeEscalation: false capabilities: drop: - ALL resources: requests: cpu: 10m memory: 50Mi basePath: / certificateSecretName: "" serviceAccount: create: true annotations: {} name: "" patcherServiceAccount: create: true annotations: {} name: "" jobs: patchConsoles: enabled: true image: "registry.redhat.io/openshift4/ose-tools-rhel8@sha256:e44074f21e0cca6464e50cb6ff934747e0bd11162ea01d522433a1a1ae116103" podSecurityContext: enabled: true runAsNonRoot: true seccompProfile: type: RuntimeDefault containerSecurityContext: enabled: true allowPrivilegeEscalation: false capabilities: drop: - ALL resources: requests: cpu: 10m memory: 50Mi
apiVersion: console.openshift.io/v1 kind: ConsolePlugin metadata: name:<plugin-name> spec: proxy: - alias: helm-charts 1 authorization: UserToken 2 caCertificate: '-----BEGIN CERTIFICATE-----\nMIID....'en 3 endpoint: 4 service: name: <service-name> namespace: <service-namespace> port: <service-port> type: Service
"consolePlugin": { "name": "my-plugin", 1 "version": "0.0.1", 2 "displayName": "My Plugin", 3 "description": "Enjoy this shiny, new console plugin!", 4 "exposedModules": { "ExamplePage": "./components/ExamplePage" }, "dependencies": { "@console/pluginAPI": "/*" } }
{ "type": "console.tab/horizontalNav", "properties": { "page": { "name": "Example Tab", "href": "example" }, "model": { "group": "core", "version": "v1", "kind": "Pod" }, "component": { "USDcodeRef": "ExampleTab" } } }
"exposedModules": { "ExamplePage": "./components/ExamplePage", "ExampleTab": "./components/ExampleTab" }
import * as React from 'react'; export default function ExampleTab() { return ( <p>This is a custom tab added to a resource using a dynamic plugin.</p> ); }
helm upgrade -i my-plugin charts/openshift-console-plugin -n my-plugin-namespace --create-namespace --set plugin.image=my-plugin-image-location
const Component: React.FC = (props) => { const [activePerspective, setActivePerspective] = useActivePerspective(); return <select value={activePerspective} onChange={(e) => setActivePerspective(e.target.value)} > { // ...perspective options } </select> }
<GreenCheckCircleIcon title="Healthy" />
<RedExclamationCircleIcon title="Failed" />
<YellowExclamationTriangleIcon title="Warning" />
<BlueInfoCircleIcon title="Info" />
<ErrorStatus title={errorMsg} />
<InfoStatus title={infoMsg} />
<ProgressStatus title={progressMsg} />
<SuccessStatus title={successMsg} />
const [navItemExtensions, navItemsResolved] = useResolvedExtensions<NavItem>(isNavItem); // process adapted extensions and render your component
const HomePage: React.FC = (props) => { const page = { href: '/home', name: 'Home', component: () => <>Home</> } return <HorizontalNav match={props.match} pages={[page]} /> }
const MachineList: React.FC<MachineListProps> = (props) => { return ( <VirtualizedTable<MachineKind> {...props} aria-label='Machines' columns={getMachineColumns} Row={getMachineTableRow} /> ); }
const PodRow: React.FC<RowProps<K8sResourceCommon>> = ({ obj, activeColumnIDs }) => { return ( <> <TableData id={columns[0].id} activeColumnIDs={activeColumnIDs}> <ResourceLink kind="Pod" name={obj.metadata.name} namespace={obj.metadata.namespace} /> </TableData> <TableData id={columns[1].id} activeColumnIDs={activeColumnIDs}> <ResourceLink kind="Namespace" name={obj.metadata.namespace} /> </TableData> </> ); };
// See implementation for more details on TableColumn type const [activeColumns, userSettingsLoaded] = useActiveColumns({ columns, showNamespaceOverride: false, columnManagementID, }); return userSettingsAreLoaded ? <VirtualizedTable columns={activeColumns} {...otherProps} /> : null
const exampleList: React.FC = () => { return ( <> <ListPageHeader title="Example List Page"/> </> ); };
const exampleList: React.FC<MyProps> = () => { return ( <> <ListPageHeader title="Example Pod List Page"/> <ListPageCreate groupVersionKind="Pod">Create Pod</ListPageCreate> </ListPageHeader> </> ); };
const exampleList: React.FC<MyProps> = () => { return ( <> <ListPageHeader title="Example Pod List Page"/> <ListPageCreateLink to={'/link/to/my/page'}>Create Item</ListPageCreateLink> </ListPageHeader> </> ); };
const exampleList: React.FC<MyProps> = () => { return ( <> <ListPageHeader title="Example Pod List Page"/> <ListPageCreateButton createAccessReview={access}>Create Pod</ListPageCreateButton> </ListPageHeader> </> ); };
const exampleList: React.FC<MyProps> = () => { const items = { SAVE: 'Save', DELETE: 'Delete', } return ( <> <ListPageHeader title="Example Pod List Page"/> <ListPageCreateDropdown createAccessReview={access} items={items}>Actions</ListPageCreateDropdown> </ListPageHeader> </> ); };
// See implementation for more details on RowFilter and FilterValue types const [staticData, filteredData, onFilterChange] = useListPageFilter( data, rowFilters, staticFilters, ); // ListPageFilter updates filter state based on user interaction and resulting filtered data can be rendered in an independent component. return ( <> <ListPageHeader .../> <ListPagBody> <ListPageFilter data={staticData} onFilterChange={onFilterChange} /> <List data={filteredData} /> </ListPageBody> </> )
// See implementation for more details on RowFilter and FilterValue types const [staticData, filteredData, onFilterChange] = useListPageFilter( data, rowFilters, staticFilters, ); // ListPageFilter updates filter state based on user interaction and resulting filtered data can be rendered in an independent component. return ( <> <ListPageHeader .../> <ListPagBody> <ListPageFilter data={staticData} onFilterChange={onFilterChange} /> <List data={filteredData} /> </ListPageBody> </> )
<ResourceLink kind="Pod" name="testPod" title={metadata.uid} />
<ResourceIcon kind="Pod"/>
const Component: React.FC = () => { const [model, inFlight] = useK8sModel({ group: 'app'; version: 'v1'; kind: 'Deployment' }); return }
const Component: React.FC = () => { const [models, inFlight] = UseK8sModels(); return }
const Component: React.FC = () => { const watchRes = { } const [data, loaded, error] = useK8sWatchResource(watchRes) return }
const Component: React.FC = () => { const watchResources = { 'deployment': {...}, 'pod': {...} } const {deployment, pod} = useK8sWatchResources(watchResources) return }
<StatusPopupSection firstColumn={ <> <span>{title}</span> <span className="text-secondary"> My Example Item </span> </> } secondColumn='Status' >
<StatusPopupSection firstColumn='Example' secondColumn='Status' > <StatusPopupItem icon={healthStateMapping[MCGMetrics.state]?.icon}> Complete </StatusPopupItem> <StatusPopupItem icon={healthStateMapping[RGWMetrics.state]?.icon}> Pending </StatusPopupItem> </StatusPopupSection>
<Overview> <OverviewGrid mainCards={mainCards} leftCards={leftCards} rightCards={rightCards} /> </Overview>
<Overview> <OverviewGrid mainCards={mainCards} leftCards={leftCards} rightCards={rightCards} /> </Overview>
return ( <InventoryItem> <InventoryItemTitle>{title}</InventoryItemTitle> <InventoryItemBody error={loadError}> {loaded && <InventoryItemStatus count={workerNodes.length} icon={<MonitoringIcon />} />} </InventoryItemBody> </InventoryItem> )
return ( <InventoryItem> <InventoryItemTitle>{title}</InventoryItemTitle> <InventoryItemBody error={loadError}> {loaded && <InventoryItemStatus count={workerNodes.length} icon={<MonitoringIcon />} />} </InventoryItemBody> </InventoryItem> )
return ( <InventoryItem> <InventoryItemTitle>{title}</InventoryItemTitle> <InventoryItemBody error={loadError}> {loaded && <InventoryItemStatus count={workerNodes.length} icon={<MonitoringIcon />} />} </InventoryItemBody> </InventoryItem> )
return ( <InventoryItem> <InventoryItemTitle>{title}</InventoryItemTitle> <InventoryItemBody error={loadError}> {loaded && <InventoryItemStatus count={workerNodes.length} icon={<MonitoringIcon />} />} </InventoryItemBody> </InventoryItem> )
if (loadError) { title = <Link to={workerNodesLink}>{t('Worker Nodes')}</Link>; } else if (!loaded) { title = <><InventoryItemLoading /><Link to={workerNodesLink}>{t('Worker Nodes')}</Link></>; } return ( <InventoryItem> <InventoryItemTitle>{title}</InventoryItemTitle> </InventoryItem> )
<React.Suspense fallback={<LoadingBox />}> <CodeEditor value={code} language="yaml" /> </React.Suspense>
<React.Suspense fallback={<LoadingBox />}> <ResourceYAMLEditor initialResource={resource} header="Create resource" onSave={(content) => updateResource(content)} /> </React.Suspense>
const [resource, loaded, loadError] = useK8sWatchResource(clusterResource); return <ResourceEventStream resource={resource} />
const context: AppPage: React.FC = () => {<br/> const [launchModal] = useModal();<br/> const onClick = () => launchModal(ModalComponent);<br/> return (<br/> <Button onClick={onClick}>Launch a Modal</Button><br/> )<br/>}<br/>`
const context: ActionContext = { 'a-context-id': { dataFromDynamicPlugin } }; <ActionServiceProvider context={context}> {({ actions, options, loaded }) => loaded && ( <ActionMenu actions={actions} options={options} variant={ActionMenuVariant.DROPDOWN} /> ) } </ActionServiceProvider>
const logNamespaceChange = (namespace) => console.log(`New namespace: USD{namespace}`); <NamespaceBar onNamespaceChange={logNamespaceChange}> <NamespaceBarApplicationSelector /> </NamespaceBar> <Page>
//in ErrorBoundary component return ( if (this.state.hasError) { return <ErrorBoundaryFallbackPage errorMessage={errorString} componentStack={componentStackString} stack={stackTraceString} title={errorString}/>; } return this.props.children; )
<QueryBrowser defaultTimespan={15 * 60 * 1000} namespace={namespace} pollInterval={30 * 1000} queries={[ 'process_resident_memory_bytes{job="console"}', 'sum(irate(container_network_receive_bytes_total[6h:5m])) by (pod)', ]} />
const PodAnnotationsButton = ({ pod }) => { const { t } = useTranslation(); const launchAnnotationsModal = useAnnotationsModal<PodKind>(pod); return <button onClick={launchAnnotationsModal}>{t('Edit Pod Annotations')}</button> }
const DeletePodButton = ({ pod }) => { const { t } = useTranslation(); const launchDeleteModal = useDeleteModal<PodKind>(pod); return <button onClick={launchDeleteModal}>{t('Delete Pod')}</button> }
const PodLabelsButton = ({ pod }) => { const { t } = useTranslation(); const launchLabelsModal = useLabelsModal<PodKind>(pod); return <button onClick={launchLabelsModal}>{t('Edit Pod Labels')}</button> }
const Component: React.FC = (props) => { const [activeNamespace, setActiveNamespace] = useActiveNamespace(); return <select value={activeNamespace} onChange={(e) => setActiveNamespace(e.target.value)} > { // ...namespace options } </select> }
const Component: React.FC = (props) => { const [state, setState, loaded] = useUserSettings( 'devconsole.addPage.showDetails', true, true, ); return loaded ? ( <WrappedComponent {...props} userSettingState={state} setUserSettingState={setState} /> ) : null; };
const OpenQuickStartButton = ({ quickStartId }) => { const { setActiveQuickStart } = useQuickStartContext(); const onClick = React.useCallback(() => { setActiveQuickStart(quickStartId); }, [quickStartId]); return <button onClick={onClick}>{t('Open Quick Start')}</button> };
<React.Suspense fallback={<LoadingBox />}> <YAMLEditor value={code} /> </React.Suspense>
oc get console.operator.openshift.io cluster -o jsonpath='{.spec.plugins}'
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-console spec: ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: openshift-console podSelector: {} policyTypes: - Ingress
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-operators spec: ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: openshift-operators podSelector: {} policyTypes: - Ingress
oc delete devworkspaces.workspace.devfile.io --all-namespaces --all --wait
oc delete devworkspaceroutings.controller.devfile.io --all-namespaces --all --wait
oc delete customresourcedefinitions.apiextensions.k8s.io devworkspaceroutings.controller.devfile.io
oc delete customresourcedefinitions.apiextensions.k8s.io devworkspaces.workspace.devfile.io
oc delete customresourcedefinitions.apiextensions.k8s.io devworkspacetemplates.workspace.devfile.io
oc delete customresourcedefinitions.apiextensions.k8s.io devworkspaceoperatorconfigs.controller.devfile.io
oc get customresourcedefinitions.apiextensions.k8s.io | grep "devfile.io"
oc delete deployment/devworkspace-webhook-server -n openshift-operators
oc delete mutatingwebhookconfigurations controller.devfile.io
oc delete validatingwebhookconfigurations controller.devfile.io
oc delete all --selector app.kubernetes.io/part-of=devworkspace-operator,app.kubernetes.io/name=devworkspace-webhook-server -n openshift-operators
oc delete serviceaccounts devworkspace-webhook-server -n openshift-operators
oc delete clusterrole devworkspace-webhook-server
oc delete clusterrolebinding devworkspace-webhook-server
oc edit consoles.operator.openshift.io cluster
apiVersion: operator.openshift.io/v1 kind: Console metadata: name: cluster spec: managementState: Removed 1
oc get -o yaml consolequickstart spring-with-s2i > my-quick-start.yaml
oc create -f my-quick-start.yaml
oc explain consolequickstarts
summary: failed: Try the steps again. success: Your Spring application is running. title: Run the Spring application conclusion: >- Your Spring application is deployed and ready. 1
apiVersion: console.openshift.io/v1 kind: ConsoleQuickStart metadata: name: spring-with-s2i spec: description: 'Import a Spring Application from git, build, and deploy it onto OpenShift.' 1
apiVersion: console.openshift.io/v1 kind: ConsoleQuickStart metadata: name: spring-with-s2i spec: description: 'Import a Spring Application from git, build, and deploy it onto OpenShift.' displayName: Get started with Spring 1 durationMinutes: 10
apiVersion: console.openshift.io/v1 kind: ConsoleQuickStart metadata: name: spring-with-s2i spec: description: 'Import a Spring Application from git, build, and deploy it onto OpenShift.' displayName: Get started with Spring durationMinutes: 10 1
spec: description: 'Import a Spring Application from git, build, and deploy it onto OpenShift.' displayName: Get started with Spring durationMinutes: 10 icon: >- 1 data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8xIiBkYXRhLW5hbWU9IkxheWVyIDEiIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDojMTUzZDNjO30uY2xzLTJ7ZmlsbDojZDhkYTlkO30uY2xzLTN7ZmlsbDojNThjMGE4O30uY2xzLTR7ZmlsbDojZmZmO30uY2xzLTV7ZmlsbDojM2Q5MTkxO308L3N0eWxlPjwvZGVmcz48dGl0bGU+c25vd2Ryb3BfaWNvbl9yZ2JfZGVmYXVsdDwvdGl0bGU+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTAxMi42OSw1OTNjLTExLjEyLTM4LjA3LTMxLTczLTU5LjIxLTEwMy44LTkuNS0xMS4zLTIzLjIxLTI4LjI5LTM5LjA2LTQ3Ljk0QzgzMy41MywzNDEsNzQ1LjM3LDIzNC4xOCw2NzQsMTY4Ljk0Yy01LTUuMjYtMTAuMjYtMTAuMzEtMTUuNjUtMTUuMDdhMjQ2LjQ5LDI0Ni40OSwwLDAsMC0zNi41NS0yNi44LDE4Mi41LDE4Mi41LDAsMCwwLTIwLjMtMTEuNzcsMjAxLjUzLDIwMS41MywwLDAsMC00My4xOS0xNUExNTUuMjQsMTU1LjI0LDAsMCwwLDUyOCw5NS4yYy02Ljc2LS42OC0xMS43NC0uODEtMTQuMzktLjgxaDBsLTEuNjIsMC0xLjYyLDBhMTc3LjMsMTc3LjMsMCwwLDAtMzEuNzcsMy4zNSwyMDguMjMsMjA4LjIzLDAsMCwwLTU2LjEyLDE3LjU2LDE4MSwxODEsMCwwLDAtMjAuMjcsMTEuNzUsMjQ3LjQzLDI0Ny40MywwLDAsMC0zNi41NywyNi44MUMzNjAuMjUsMTU4LjYyLDM1NSwxNjMuNjgsMzUwLDE2OWMtNzEuMzUsNjUuMjUtMTU5LjUsMTcyLTI0MC4zOSwyNzIuMjhDOTMuNzMsNDYwLjg4LDgwLDQ3Ny44Nyw3MC41Miw0ODkuMTcsNDIuMzUsNTIwLDIyLjQzLDU1NC45LDExLjMxLDU5MywuNzIsNjI5LjIyLTEuNzMsNjY3LjY5LDQsNzA3LjMxLDE1LDc4Mi40OSw1NS43OCw4NTkuMTIsMTE4LjkzLDkyMy4wOWEyMiwyMiwwLDAsMCwxNS41OSw2LjUyaDEuODNsMS44Ny0uMzJjODEuMDYtMTMuOTEsMTEwLTc5LjU3LDE0My40OC0xNTUuNiwzLjkxLTguODgsNy45NS0xOC4wNSwxMi4yLTI3LjQzcTUuNDIsOC41NCwxMS4zOSwxNi4yM2MzMS44NSw0MC45MSw3NS4xMiw2NC42NywxMzIuMzIsNzIuNjNsMTguOCwyLjYyLDQuOTUtMTguMzNjMTMuMjYtNDkuMDcsMzUuMy05MC44NSw1MC42NC0xMTYuMTksMTUuMzQsMjUuMzQsMzcuMzgsNjcuMTIsNTAuNjQsMTE2LjE5bDUsMTguMzMsMTguOC0yLjYyYzU3LjItOCwxMDAuNDctMzEuNzIsMTMyLjMyLTcyLjYzcTYtNy42OCwxMS4zOS0xNi4yM2M0LjI1LDkuMzgsOC4yOSwxOC41NSwxMi4yLDI3LjQzLDMzLjQ5LDc2LDYyLjQyLDE0MS42OSwxNDMuNDgsMTU1LjZsMS44MS4zMWgxLjg5YTIyLDIyLDAsMCwwLDE1LjU5LTYuNTJjNjMuMTUtNjQsMTAzLjk1LTE0MC42LDExNC44OS0yMTUuNzhDMTAyNS43Myw2NjcuNjksMTAyMy4yOCw2MjkuMjIsMTAxMi42OSw1OTNaIi8+PHBhdGggY2xhc3M9ImNscy0yIiBkPSJNMzY0LjE1LDE4NS4yM2MxNy44OS0xNi40LDM0LjctMzAuMTUsNDkuNzctNDAuMTFhMjEyLDIxMiwwLDAsMSw2NS45My0yNS43M0ExOTgsMTk4LDAsMCwxLDUxMiwxMTYuMjdhMTk2LjExLDE5Ni4xMSwwLDAsMSwzMiwzLjFjNC41LjkxLDkuMzYsMi4wNiwxNC41MywzLjUyLDYwLjQxLDIwLjQ4LDg0LjkyLDkxLjA1LTQ3LjQ0LDI0OC4wNi0yOC43NSwzNC4xMi0xNDAuNywxOTQuODQtMTg0LjY2LDI2OC40MmE2MzAuODYsNjMwLjg2LDAsMCwwLTMzLjIyLDU4LjMyQzI3Niw2NTUuMzQsMjY1LjQsNTk4LDI2NS40LDUyMC4yOSwyNjUuNCwzNDAuNjEsMzExLjY5LDI0MC43NCwzNjQuMTUsMTg1LjIzWiIvPjxwYXRoIGNsYXNzPSJjbHMtMyIgZD0iTTUyNy41NCwzODQuODNjODQuMDYtOTkuNywxMTYuMDYtMTc3LjI4LDk1LjIyLTIzMC43NCwxMS42Miw4LjY5LDI0LDE5LjIsMzcuMDYsMzEuMTMsNTIuNDgsNTUuNSw5OC43OCwxNTUuMzgsOTguNzgsMzM1LjA3LDAsNzcuNzEtMTAuNiwxMzUuMDUtMjcuNzcsMTc3LjRhNjI4LjczLDYyOC43MywwLDAsMC0zMy4yMy01OC4zMmMtMzktNjUuMjYtMTMxLjQ1LTE5OS0xNzEuOTMtMjUyLjI3QzUyNi4zMywzODYuMjksNTI3LDM4NS41Miw1MjcuNTQsMzg0LjgzWiIvPjxwYXRoIGNsYXNzPSJjbHMtNCIgZD0iTTEzNC41OCw5MDguMDdoLS4wNmEuMzkuMzksMCwwLDEtLjI3LS4xMWMtMTE5LjUyLTEyMS4wNy0xNTUtMjg3LjQtNDcuNTQtNDA0LjU4LDM0LjYzLTQxLjE0LDEyMC0xNTEuNiwyMDIuNzUtMjQyLjE5LTMuMTMsNy02LjEyLDE0LjI1LTguOTIsMjEuNjktMjQuMzQsNjQuNDUtMzYuNjcsMTQ0LjMyLTM2LjY3LDIzNy40MSwwLDU2LjUzLDUuNTgsMTA2LDE2LjU5LDE0Ny4xNEEzMDcuNDksMzA3LjQ5LDAsMCwwLDI4MC45MSw3MjNDMjM3LDgxNi44OCwyMTYuOTMsODkzLjkzLDEzNC41OCw5MDguMDdaIi8+PHBhdGggY2xhc3M9ImNscy01IiBkPSJNNTgzLjQzLDgxMy43OUM1NjAuMTgsNzI3LjcyLDUxMiw2NjQuMTUsNTEyLDY2NC4xNXMtNDguMTcsNjMuNTctNzEuNDMsMTQ5LjY0Yy00OC40NS02Ljc0LTEwMC45MS0yNy41Mi0xMzUuNjYtOTEuMThhNjQ1LjY4LDY0NS42OCwwLDAsMSwzOS41Ny03MS41NGwuMjEtLjMyLjE5LS4zM2MzOC02My42MywxMjYuNC0xOTEuMzcsMTY3LjEyLTI0NS42Niw0MC43MSw1NC4yOCwxMjkuMSwxODIsMTY3LjEyLDI0NS42NmwuMTkuMzMuMjEuMzJhNjQ1LjY4LDY0NS42OCwwLDAsMSwzOS41Nyw3MS41NEM2ODQuMzQsNzg2LjI3LDYzMS44OCw4MDcuMDUsNTgzLjQzLDgxMy43OVoiLz48cGF0aCBjbGFzcz0iY2xzLTQiIGQ9Ik04ODkuNzUsOTA4YS4zOS4zOSwwLDAsMS0uMjcuMTFoLS4wNkM4MDcuMDcsODkzLjkzLDc4Nyw4MTYuODgsNzQzLjA5LDcyM2EzMDcuNDksMzA3LjQ5LDAsMCwwLDIwLjQ1LTU1LjU0YzExLTQxLjExLDE2LjU5LTkwLjYxLDE2LjU5LTE0Ny4xNCwwLTkzLjA4LTEyLjMzLTE3My0zNi42Ni0yMzcuNHEtNC4yMi0xMS4xNi04LjkzLTIxLjdjODIuNzUsOTAuNTksMTY4LjEyLDIwMS4wNSwyMDIuNzUsMjQyLjE5QzEwNDQuNzksNjIwLjU2LDEwMDkuMjcsNzg2Ljg5LDg4OS43NSw5MDhaIi8+PC9zdmc+Cg==
introduction: >- 1 **Spring** is a Java framework for building applications based on a distributed microservices architecture. - Spring enables easy packaging and configuration of Spring applications into a self-contained executable application which can be easily deployed as a container to OpenShift. - Spring applications can integrate OpenShift capabilities to provide a natural "Spring on OpenShift" developer experience for both existing and net-new Spring applications. For example: - Externalized configuration using Kubernetes ConfigMaps and integration with Spring Cloud Kubernetes - Service discovery using Kubernetes Services - Load balancing with Replication Controllers - Kubernetes health probes and integration with Spring Actuator - Metrics: Prometheus, Grafana, and integration with Spring Cloud Sleuth - Distributed tracing with Istio & Jaeger tracing - Developer tooling through Red Hat OpenShift and Red Hat CodeReady developer tooling to quickly scaffold new Spring projects, gain access to familiar Spring APIs in your favorite IDE, and deploy to Red Hat OpenShift
icon: >- data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHJvbGU9ImltZyIgdmlld.
accessReviewResources: - group: helm.openshift.io resource: helmchartrepositories verb: create
accessReviewResources: - group: operators.coreos.com resource: operatorgroups verb: list - group: packages.operators.coreos.com resource: packagemanifests verb: list
nextQuickStart: - add-healthchecks
[Perspective switcher]{{highlight qs-perspective-switcher}}
[Home]{{highlight qs-nav-home}} [Operators]{{highlight qs-nav-operators}} [Workloads]{{highlight qs-nav-workloads}} [Serverless]{{highlight qs-nav-serverless}} [Networking]{{highlight qs-nav-networking}} [Storage]{{highlight qs-nav-storage}} [Service catalog]{{highlight qs-nav-servicecatalog}} [Compute]{{highlight qs-nav-compute}} [User management]{{highlight qs-nav-usermanagement}} [Administration]{{highlight qs-nav-administration}}
[Add]{{highlight qs-nav-add}} [Topology]{{highlight qs-nav-topology}} [Search]{{highlight qs-nav-search}} [Project]{{highlight qs-nav-project}} [Helm]{{highlight qs-nav-helm}}
[Builds]{{highlight qs-nav-builds}} [Pipelines]{{highlight qs-nav-pipelines}} [Monitoring]{{highlight qs-nav-monitoring}}
[CloudShell]{{highlight qs-masthead-cloudshell}} [Utility Menu]{{highlight qs-masthead-utilitymenu}} [User Menu]{{highlight qs-masthead-usermenu}} [Applications]{{highlight qs-masthead-applications}} [Import]{{highlight qs-masthead-import}} [Help]{{highlight qs-masthead-help}} [Notifications]{{highlight qs-masthead-notifications}}
`code block`{{copy}} `code block`{{execute}}
``` multi line code block ```{{copy}} ``` multi line code block ```{{execute}}
Create a serverless application.
In this quick start, you will deploy a sample application to {product-title}.
This quick start shows you how to deploy a sample application to {product-title}.
Tasks to complete: Create a serverless application; Connect an event source; Force a new revision
You will complete these 3 tasks: Creating a serverless application; Connecting an event source; Forcing a new revision
Click OK.
Click on the OK button.
Enter the Developer perspective: In the main navigation, click the dropdown menu and select Developer. Enter the Administrator perspective: In the main navigation, click the dropdown menu and select Admin.
In the node.js deployment, hover over the icon.
Hover over the icon in the node.js deployment.
Change the time range of the dashboard by clicking the dropdown menu and selecting time range.
To look at data in a specific time frame, you can change the time range of the dashboard.
In the navigation menu, click Settings.
In the left-hand menu, click Settings.
The success message indicates a connection.
The message with a green icon indicates a connection.
Set up your environment.
Let's set up our environment.